mirror of
https://github.com/discourse/discourse.git
synced 2025-06-01 17:40:43 +08:00
FEATURE: backend support for user-selectable components
* FEATURE: backend support for user-selectable components * fix problems with previewing default theme * rename preview_key => preview_theme_id * omit default theme from child themes dropdown and try a different fix * cache & freeze stylesheets arrays
This commit is contained in:
@ -19,15 +19,16 @@ describe Theme do
|
||||
end
|
||||
|
||||
let :customization do
|
||||
Theme.create!(customization_params)
|
||||
Fabricate(:theme, customization_params)
|
||||
end
|
||||
|
||||
let(:theme) { Fabricate(:theme, user: user) }
|
||||
let(:child) { Fabricate(:theme, user: user) }
|
||||
it 'can properly clean up color schemes' do
|
||||
theme = Theme.create!(name: 'bob', user_id: -1)
|
||||
scheme = ColorScheme.create!(theme_id: theme.id, name: 'test')
|
||||
scheme2 = ColorScheme.create!(theme_id: theme.id, name: 'test2')
|
||||
|
||||
Theme.create!(name: 'bob', user_id: -1, color_scheme_id: scheme2.id)
|
||||
Fabricate(:theme, color_scheme_id: scheme2.id)
|
||||
|
||||
theme.destroy!
|
||||
scheme2.reload
|
||||
@ -38,8 +39,6 @@ describe Theme do
|
||||
end
|
||||
|
||||
it 'can support child themes' do
|
||||
child = Theme.new(name: '2', user_id: user.id)
|
||||
|
||||
child.set_field(target: :common, name: "header", value: "World")
|
||||
child.set_field(target: :desktop, name: "header", value: "Desktop")
|
||||
child.set_field(target: :mobile, name: "header", value: "Mobile")
|
||||
@ -54,7 +53,7 @@ describe Theme do
|
||||
|
||||
expect(Theme.lookup_field(child.id, :mobile, :header)).to eq("Worldie\nMobile")
|
||||
|
||||
parent = Theme.new(name: '1', user_id: user.id)
|
||||
parent = Fabricate(:theme, user: user)
|
||||
|
||||
parent.set_field(target: :common, name: "header", value: "Common Parent")
|
||||
parent.set_field(target: :mobile, name: "header", value: "Mobile Parent")
|
||||
@ -68,18 +67,39 @@ describe Theme do
|
||||
end
|
||||
|
||||
it 'can correctly find parent themes' do
|
||||
grandchild = Theme.create!(name: 'grandchild', user_id: user.id)
|
||||
child = Theme.create!(name: 'child', user_id: user.id)
|
||||
theme = Theme.create!(name: 'theme', user_id: user.id)
|
||||
theme.add_child_theme!(child)
|
||||
|
||||
expect(child.dependant_themes.length).to eq(1)
|
||||
end
|
||||
|
||||
it "doesn't allow multi-level theme components" do
|
||||
grandchild = Fabricate(:theme, user: user)
|
||||
grandparent = Fabricate(:theme, user: user)
|
||||
|
||||
theme.add_child_theme!(child)
|
||||
child.add_child_theme!(grandchild)
|
||||
expect do
|
||||
child.add_child_theme!(grandchild)
|
||||
end.to raise_error(Discourse::InvalidParameters, I18n.t("themes.errors.no_multilevels_components"))
|
||||
|
||||
expect(grandchild.dependant_themes.length).to eq(2)
|
||||
expect do
|
||||
grandparent.add_child_theme!(theme)
|
||||
end.to raise_error(Discourse::InvalidParameters, I18n.t("themes.errors.no_multilevels_components"))
|
||||
end
|
||||
|
||||
it "doesn't allow a child to be user selectable" do
|
||||
theme.add_child_theme!(child)
|
||||
child.update(user_selectable: true)
|
||||
expect(child.errors.full_messages).to contain_exactly(I18n.t("themes.errors.component_no_user_selectable"))
|
||||
end
|
||||
|
||||
it "doesn't allow a child to be set as the default theme" do
|
||||
theme.add_child_theme!(child)
|
||||
expect do
|
||||
child.set_default!
|
||||
end.to raise_error(Discourse::InvalidParameters, I18n.t("themes.errors.component_no_default"))
|
||||
end
|
||||
|
||||
it 'should correct bad html in body_tag_baked and head_tag_baked' do
|
||||
theme = Theme.new(user_id: -1, name: "test")
|
||||
theme.set_field(target: :common, name: "head_tag", value: "<b>I am bold")
|
||||
theme.save!
|
||||
|
||||
@ -95,7 +115,6 @@ describe Theme do
|
||||
{{hello}}
|
||||
</script>
|
||||
HTML
|
||||
theme = Theme.new(user_id: -1, name: "test")
|
||||
theme.set_field(target: :common, name: "header", value: with_template)
|
||||
theme.save!
|
||||
|
||||
@ -106,8 +125,6 @@ HTML
|
||||
end
|
||||
|
||||
it 'should create body_tag_baked on demand if needed' do
|
||||
|
||||
theme = Theme.new(user_id: -1, name: "test")
|
||||
theme.set_field(target: :common, name: :body_tag, value: "<b>test")
|
||||
theme.save
|
||||
|
||||
@ -116,6 +133,41 @@ HTML
|
||||
expect(Theme.lookup_field(theme.id, :desktop, :body_tag)).to match(/<b>test<\/b>/)
|
||||
end
|
||||
|
||||
it 'can find fields for multiple themes' do
|
||||
theme2 = Fabricate(:theme)
|
||||
|
||||
theme.set_field(target: :common, name: :body_tag, value: "<b>testtheme1</b>")
|
||||
theme2.set_field(target: :common, name: :body_tag, value: "<b>theme2test</b>")
|
||||
theme.save!
|
||||
theme2.save!
|
||||
|
||||
field = Theme.lookup_field([theme.id, theme2.id], :desktop, :body_tag)
|
||||
expect(field).to match(/<b>testtheme1<\/b>/)
|
||||
expect(field).to match(/<b>theme2test<\/b>/)
|
||||
end
|
||||
|
||||
describe ".transform_ids" do
|
||||
it "adds the child themes of the parent" do
|
||||
child = Fabricate(:theme, id: 97)
|
||||
child2 = Fabricate(:theme, id: 96)
|
||||
|
||||
theme.add_child_theme!(child)
|
||||
theme.add_child_theme!(child2)
|
||||
expect(Theme.transform_ids([theme.id])).to eq([theme.id, child2.id, child.id])
|
||||
expect(Theme.transform_ids([theme.id, 94, 90])).to eq([theme.id, 90, 94, child2.id, child.id])
|
||||
end
|
||||
|
||||
it "doesn't insert children when extend is false" do
|
||||
child = Fabricate(:theme, id: 97)
|
||||
child2 = Fabricate(:theme, id: 96)
|
||||
|
||||
theme.add_child_theme!(child)
|
||||
theme.add_child_theme!(child2)
|
||||
expect(Theme.transform_ids([theme.id], extend: false)).to eq([theme.id])
|
||||
expect(Theme.transform_ids([theme.id, 94, 90, 70, 70], extend: false)).to eq([theme.id, 70, 90, 94])
|
||||
end
|
||||
end
|
||||
|
||||
context "plugin api" do
|
||||
def transpile(html)
|
||||
f = ThemeField.create!(target_id: Theme.targets[:mobile], theme_id: 1, name: "after_header", value: html)
|
||||
@ -152,14 +204,12 @@ HTML
|
||||
context 'theme vars' do
|
||||
|
||||
it 'works in parent theme' do
|
||||
|
||||
theme = Theme.new(name: 'theme', user_id: -1)
|
||||
theme.set_field(target: :common, name: :scss, value: 'body {color: $magic; }')
|
||||
theme.set_field(target: :common, name: :magic, value: 'red', type: :theme_var)
|
||||
theme.set_field(target: :common, name: :not_red, value: 'red', type: :theme_var)
|
||||
theme.save
|
||||
|
||||
parent_theme = Theme.new(name: 'parent theme', user_id: -1)
|
||||
parent_theme = Fabricate(:theme)
|
||||
parent_theme.set_field(target: :common, name: :scss, value: 'body {background-color: $not_red; }')
|
||||
parent_theme.set_field(target: :common, name: :not_red, value: 'blue', type: :theme_var)
|
||||
parent_theme.save
|
||||
@ -171,7 +221,6 @@ HTML
|
||||
end
|
||||
|
||||
it 'can generate scss based off theme vars' do
|
||||
theme = Theme.new(name: 'theme', user_id: -1)
|
||||
theme.set_field(target: :common, name: :scss, value: 'body {color: $magic; content: quote($content)}')
|
||||
theme.set_field(target: :common, name: :magic, value: 'red', type: :theme_var)
|
||||
theme.set_field(target: :common, name: :content, value: 'Sam\'s Test', type: :theme_var)
|
||||
@ -187,7 +236,6 @@ HTML
|
||||
end
|
||||
|
||||
it 'can handle uploads based of ThemeField' do
|
||||
theme = Theme.new(name: 'theme', user_id: -1)
|
||||
upload = UploadCreator.new(image, "logo.png").create_for(-1)
|
||||
theme.set_field(target: :common, name: :logo, upload_id: upload.id, type: :theme_upload_var)
|
||||
theme.set_field(target: :common, name: :scss, value: 'body {background-image: url($logo)}')
|
||||
@ -210,7 +258,6 @@ HTML
|
||||
|
||||
context "theme settings" do
|
||||
it "allows values to be used in scss" do
|
||||
theme = Theme.new(name: "awesome theme", user_id: -1)
|
||||
theme.set_field(target: :settings, name: :yaml, value: "background_color: red\nfont_size: 25px")
|
||||
theme.set_field(target: :common, name: :scss, value: 'body {background-color: $background_color; font-size: $font-size}')
|
||||
theme.save!
|
||||
@ -227,7 +274,6 @@ HTML
|
||||
end
|
||||
|
||||
it "allows values to be used in JS" do
|
||||
theme = Theme.new(name: "awesome theme", user_id: -1)
|
||||
theme.set_field(target: :settings, name: :yaml, value: "name: bob")
|
||||
theme.set_field(target: :common, name: :after_header, value: '<script type="text/discourse-plugin" version="1.0">alert(settings.name); let a = ()=>{};</script>')
|
||||
theme.save!
|
||||
@ -263,26 +309,30 @@ HTML
|
||||
it 'correctly caches theme ids' do
|
||||
Theme.destroy_all
|
||||
|
||||
theme = Theme.create!(name: "bob", user_id: -1)
|
||||
theme
|
||||
theme2 = Fabricate(:theme)
|
||||
|
||||
expect(Theme.theme_ids).to eq(Set.new([theme.id]))
|
||||
expect(Theme.user_theme_ids).to eq(Set.new([]))
|
||||
expect(Theme.theme_ids).to contain_exactly(theme.id, theme2.id)
|
||||
expect(Theme.user_theme_ids).to eq([])
|
||||
|
||||
theme.user_selectable = true
|
||||
theme.save
|
||||
theme.update!(user_selectable: true)
|
||||
|
||||
expect(Theme.user_theme_ids).to eq(Set.new([theme.id]))
|
||||
expect(Theme.user_theme_ids).to contain_exactly(theme.id)
|
||||
|
||||
theme.user_selectable = false
|
||||
theme.save
|
||||
theme2.update!(user_selectable: true)
|
||||
expect(Theme.user_theme_ids).to contain_exactly(theme.id, theme2.id)
|
||||
|
||||
theme.update!(user_selectable: false)
|
||||
theme2.update!(user_selectable: false)
|
||||
|
||||
theme.set_default!
|
||||
expect(Theme.user_theme_ids).to eq(Set.new([theme.id]))
|
||||
expect(Theme.user_theme_ids).to contain_exactly(theme.id)
|
||||
|
||||
theme.destroy
|
||||
theme2.destroy
|
||||
|
||||
expect(Theme.theme_ids).to eq(Set.new([]))
|
||||
expect(Theme.user_theme_ids).to eq(Set.new([]))
|
||||
expect(Theme.theme_ids).to eq([])
|
||||
expect(Theme.user_theme_ids).to eq([])
|
||||
end
|
||||
|
||||
it 'correctly caches user_themes template' do
|
||||
@ -292,8 +342,7 @@ HTML
|
||||
user_themes = JSON.parse(json)["user_themes"]
|
||||
expect(user_themes).to eq([])
|
||||
|
||||
theme = Theme.create!(name: "bob", user_id: -1, user_selectable: true)
|
||||
theme.save!
|
||||
theme = Fabricate(:theme, name: "bob", user_selectable: true)
|
||||
|
||||
json = Site.json_for(guardian)
|
||||
user_themes = JSON.parse(json)["user_themes"].map { |t| t["name"] }
|
||||
@ -320,7 +369,6 @@ HTML
|
||||
it 'handles settings cache correctly' do
|
||||
Theme.destroy_all
|
||||
|
||||
theme = Theme.create!(name: "awesome theme", user_id: -1)
|
||||
expect(cached_settings(theme.id)).to eq("{}")
|
||||
|
||||
theme.set_field(target: :settings, name: "yaml", value: "boolean_setting: true")
|
||||
@ -330,7 +378,6 @@ HTML
|
||||
theme.settings.first.value = "false"
|
||||
expect(cached_settings(theme.id)).to match(/\"boolean_setting\":false/)
|
||||
|
||||
child = Theme.create!(name: "child theme", user_id: -1)
|
||||
child.set_field(target: :settings, name: "yaml", value: "integer_setting: 54")
|
||||
|
||||
child.save!
|
||||
@ -347,5 +394,4 @@ HTML
|
||||
expect(json).not_to match(/\"integer_setting\":54/)
|
||||
expect(json).to match(/\"boolean_setting\":false/)
|
||||
end
|
||||
|
||||
end
|
||||
|
Reference in New Issue
Block a user