discourse/spec/components/stylesheet/manager_spec.rb
Sam Saffron 4ea21fa2d0 DEV: use #frozen_string_literal: true on all spec
This change both speeds up specs (less strings to allocate) and helps catch
cases where methods in Discourse are mutating inputs.

Overall we will be migrating everything to use #frozen_string_literal: true
it will take a while, but this is the first and safest move in this direction
2019-04-30 10:27:42 +10:00

229 lines
7.4 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
require 'stylesheet/compiler'
describe Stylesheet::Manager do
it 'does not crash for missing theme' do
Theme.clear_default!
link = Stylesheet::Manager.stylesheet_link_tag(:embedded_theme)
expect(link).to eq("")
theme = Fabricate(:theme)
SiteSetting.default_theme_id = theme.id
link = Stylesheet::Manager.stylesheet_link_tag(:embedded_theme)
expect(link).not_to eq("")
end
it "still returns something for no themes" do
link = Stylesheet::Manager.stylesheet_link_tag(:desktop, 'all', [])
expect(link).not_to eq("")
end
it 'can correctly compile theme css' do
theme = Fabricate(:theme)
theme.set_field(target: :common, name: "scss", value: ".common{.scss{color: red;}}")
theme.set_field(target: :desktop, name: "scss", value: ".desktop{.scss{color: red;}}")
theme.set_field(target: :mobile, name: "scss", value: ".mobile{.scss{color: red;}}")
theme.set_field(target: :common, name: "embedded_scss", value: ".embedded{.scss{color: red;}}")
theme.save!
child_theme = Fabricate(:theme, component: true)
child_theme.set_field(target: :common, name: "scss", value: ".child_common{.scss{color: red;}}")
child_theme.set_field(target: :desktop, name: "scss", value: ".child_desktop{.scss{color: red;}}")
child_theme.set_field(target: :mobile, name: "scss", value: ".child_mobile{.scss{color: red;}}")
child_theme.set_field(target: :common, name: "embedded_scss", value: ".child_embedded{.scss{color: red;}}")
child_theme.save!
theme.add_child_theme!(child_theme)
old_link = Stylesheet::Manager.stylesheet_link_tag(:desktop_theme, 'all', theme.id)
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
manager.compile(force: true)
css = File.read(manager.stylesheet_fullpath)
_source_map = File.read(manager.source_map_fullpath)
expect(css).to match(/child_common/)
expect(css).to match(/child_desktop/)
expect(css).to match(/\.common/)
expect(css).to match(/\.desktop/)
child_theme.set_field(target: :desktop, name: :scss, value: ".nothing{color: green;}")
child_theme.save!
new_link = Stylesheet::Manager.stylesheet_link_tag(:desktop_theme, 'all', theme.id)
expect(new_link).not_to eq(old_link)
# our theme better have a name with the theme_id as part of it
expect(new_link).to include("/stylesheets/desktop_theme_#{theme.id}_")
end
describe 'digest' do
after do
DiscoursePluginRegistry.stylesheets.delete "fake_file"
end
it 'can correctly account for plugins in digest' do
theme = Fabricate(:theme)
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest1 = manager.digest
DiscoursePluginRegistry.stylesheets.add "fake_file"
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest2 = manager.digest
expect(digest1).not_to eq(digest2)
end
it "can correctly account for settings in theme's components" do
theme = Fabricate(:theme)
child = Fabricate(:theme, component: true)
theme.add_child_theme!(child)
child.set_field(target: :settings, name: :yaml, value: "childcolor: red")
child.set_field(target: :common, name: :scss, value: "body {background-color: $childcolor}")
child.save!
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest1 = manager.digest
child.update_setting(:childcolor, "green")
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest2 = manager.digest
expect(digest1).not_to eq(digest2)
end
let(:image) { file_from_fixtures("logo.png") }
let(:image2) { file_from_fixtures("logo-dev.png") }
it 'can correctly account for theme uploads in digest' do
theme = Fabricate(:theme)
upload = UploadCreator.new(image, "logo.png").create_for(-1)
field = ThemeField.create!(
theme_id: theme.id,
target_id: Theme.targets[:common],
name: "logo",
value: "",
upload_id: upload.id,
type_id: ThemeField.types[:theme_upload_var]
)
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest1 = manager.digest
field.destroy!
upload = UploadCreator.new(image2, "logo.png").create_for(-1)
field = ThemeField.create!(
theme_id: theme.id,
target_id: Theme.targets[:common],
name: "logo",
value: "",
upload_id: upload.id,
type_id: ThemeField.types[:theme_upload_var]
)
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest2 = manager.digest
expect(digest1).not_to eq(digest2)
end
end
describe 'color_scheme_digest' do
it "changes with category background image" do
theme = Fabricate(:theme)
category1 = Fabricate(:category, uploaded_background_id: 123, updated_at: 1.week.ago)
category2 = Fabricate(:category, uploaded_background_id: 456, updated_at: 2.days.ago)
manager = Stylesheet::Manager.new(:desktop_theme, theme.id)
digest1 = manager.color_scheme_digest
category2.update(uploaded_background_id: 789, updated_at: 1.day.ago)
digest2 = manager.color_scheme_digest
expect(digest2).to_not eq(digest1)
category1.update(uploaded_background_id: nil, updated_at: 5.minutes.ago)
digest3 = manager.color_scheme_digest
expect(digest3).to_not eq(digest2)
expect(digest3).to_not eq(digest1)
end
end
# this test takes too long, we don't run it by default
describe ".precompile_css", if: ENV["RUN_LONG_TESTS"] == "1" do
before do
class << STDERR
alias_method :orig_write, :write
def write(x)
end
end
end
after do
class << STDERR
def write(x)
orig_write(x)
end
end
FileUtils.rm_rf("tmp/stylesheet-cache")
end
it "correctly generates precompiled CSS" do
scheme1 = ColorScheme.create!(name: "scheme1")
scheme2 = ColorScheme.create!(name: "scheme2")
core_targets = [:desktop, :mobile, :desktop_rtl, :mobile_rtl, :admin]
theme_targets = [:desktop_theme, :mobile_theme]
Theme.update_all(user_selectable: false)
user_theme = Fabricate(:theme, user_selectable: true, color_scheme: scheme1)
default_theme = Fabricate(:theme, user_selectable: true, color_scheme: scheme2)
default_theme.set_default!
StylesheetCache.destroy_all
Stylesheet::Manager.precompile_css
results = StylesheetCache.pluck(:target)
expect(results.size).to eq(14) # 2 themes x 7 targets
core_targets.each do |tar|
expect(results.count { |target| target =~ /^#{tar}_(#{scheme1.id}|#{scheme2.id})$/ }).to eq(2)
end
theme_targets.each do |tar|
expect(results.count { |target| target =~ /^#{tar}_(#{user_theme.id}|#{default_theme.id})$/ }).to eq(2)
end
Theme.clear_default!
StylesheetCache.destroy_all
Stylesheet::Manager.precompile_css
results = StylesheetCache.pluck(:target)
expect(results.size).to eq(19) # (2 themes x 7 targets) + (1 no/default/core theme x 5 core targets)
core_targets.each do |tar|
expect(results.count { |target| target =~ /^(#{tar}_(#{scheme1.id}|#{scheme2.id})|#{tar})$/ }).to eq(3)
end
theme_targets.each do |tar|
expect(results.count { |target| target =~ /^#{tar}_(#{user_theme.id}|#{default_theme.id})$/ }).to eq(2)
end
end
end
end