require 'rails_helper' describe SiteCustomization do before do SiteCustomization.clear_cache! end let :user do Fabricate(:user) end let :customization_params do {name: 'my name', user_id: user.id, header: "my awesome header", stylesheet: "my awesome css", mobile_stylesheet: nil, mobile_header: nil} end let :customization do SiteCustomization.create!(customization_params) end let :customization_with_mobile do SiteCustomization.create!(customization_params.merge(mobile_stylesheet: ".mobile {better: true;}", mobile_header: "fancy mobile stuff")) end it 'should set default key when creating a new customization' do s = SiteCustomization.create!(name: 'my name', user_id: user.id) expect(s.key).not_to eq(nil) end it 'can enable more than one style at once' do c1 = SiteCustomization.create!(name: '2', user_id: user.id, header: 'World', enabled: true, mobile_header: 'hi', footer: 'footer', stylesheet: '.hello{.world {color: blue;}}') SiteCustomization.create!(name: '1', user_id: user.id, header: 'Hello', enabled: true, mobile_footer: 'mfooter', mobile_stylesheet: '.hello{margin: 1px;}', stylesheet: 'p{width: 1px;}' ) expect(SiteCustomization.custom_header).to eq("Hello\nWorld") expect(SiteCustomization.custom_header(nil, :mobile)).to eq("hi") expect(SiteCustomization.custom_footer(nil, :mobile)).to eq("mfooter") expect(SiteCustomization.custom_footer).to eq("footer") desktop_css = SiteCustomization.custom_stylesheet expect(desktop_css).to match(Regexp.new("#{SiteCustomization::ENABLED_KEY}.css\\?target=desktop")) mobile_css = SiteCustomization.custom_stylesheet(nil, :mobile) expect(mobile_css).to match(Regexp.new("#{SiteCustomization::ENABLED_KEY}.css\\?target=mobile")) expect(SiteCustomization.enabled_stylesheet_contents).to match(/\.hello \.world/) # cache expiry c1.enabled = false c1.save expect(SiteCustomization.custom_stylesheet).not_to eq(desktop_css) expect(SiteCustomization.enabled_stylesheet_contents).not_to match(/\.hello \.world/) end it 'should be able to look up stylesheets by key' do c = SiteCustomization.create!(name: '2', user_id: user.id, enabled: true, stylesheet: '.hello{.world {color: blue;}}', mobile_stylesheet: '.world{.hello{color: black;}}') expect(SiteCustomization.custom_stylesheet(c.key, :mobile)).to match(Regexp.new("#{c.key}.css\\?target=mobile")) expect(SiteCustomization.custom_stylesheet(c.key)).to match(Regexp.new("#{c.key}.css\\?target=desktop")) end it 'should allow including discourse styles' do c = SiteCustomization.create!(user_id: user.id, name: "test", stylesheet: '@import "desktop";', mobile_stylesheet: '@import "mobile";') expect(c.stylesheet_baked).not_to match(/Syntax error/) expect(c.stylesheet_baked.length).to be > 1000 expect(c.mobile_stylesheet_baked).not_to match(/Syntax error/) expect(c.mobile_stylesheet_baked.length).to be > 1000 end it 'should provide an awesome error on failure' do c = SiteCustomization.create!(user_id: user.id, name: "test", stylesheet: "$black: #000; #a { color: $black; }\n\n\nboom", header: '') expect(c.stylesheet_baked).to match(/Syntax error/) expect(c.mobile_stylesheet_baked).not_to be_present end it 'should provide an awesome error on failure for mobile too' do c = SiteCustomization.create!(user_id: user.id, name: "test", stylesheet: '', header: '', mobile_stylesheet: "$black: #000; #a { color: $black; }\n\n\nboom", mobile_header: '') expect(c.mobile_stylesheet_baked).to match(/Syntax error/) expect(c.stylesheet_baked).not_to be_present end it 'should correct bad html in body_tag_baked and head_tag_baked' do c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: "I am bold", body_tag: "I am bold") expect(c.head_tag_baked).to eq("I am bold") expect(c.body_tag_baked).to eq("I am bold") end it 'should precompile fragments in body and head tags' do with_template = < {{hello}} HTML c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: with_template, body_tag: with_template) expect(c.head_tag_baked).to match(/HTMLBars/) expect(c.body_tag_baked).to match(/HTMLBars/) expect(c.body_tag_baked).to match(/raw-handlebars/) expect(c.head_tag_baked).to match(/raw-handlebars/) end it 'should create body_tag_baked on demand if needed' do c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: "test", enabled: true) c.update_columns(head_tag_baked: nil) expect(SiteCustomization.custom_head_tag).to match(/test<\/b>/) end context "plugin api" do def transpile(html) c = SiteCustomization.create!(user_id: -1, name: "test", head_tag: html, body_tag: html) c.head_tag_baked end it "transpiles ES6 code" do html = < const x = 1; HTML transpiled = transpile(html) expect(transpiled).to match(/\/) expect(transpiled).to match(/var x = 1;/) expect(transpiled).to match(/_registerPluginCode\('0.1'/) end it "converts errors to a script type that is not evaluated" do html = < const x = 1; x = 2; HTML transpiled = transpile(html) expect(transpiled).to match(/text\/discourse-js-error/) expect(transpiled).to match(/read-only/) end end end