mirror of
https://github.com/discourse/discourse.git
synced 2024-11-30 18:55:27 +08:00
d1474e94a1
There are three modifiers: - serialize_topic_excerpts (boolean) - csp_extensions (array of strings) - svg_icons (array of strings) When multiple themes are active, the values will be combined. The combination method varies based on the setting. CSP/SVG arrays will be combined. serialize_topic_excerpts will use `Enumerable#any`.
259 lines
9.0 KiB
Ruby
259 lines
9.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
describe RemoteTheme do
|
|
context '#import_remote' do
|
|
def setup_git_repo(files)
|
|
dir = Dir.tmpdir
|
|
repo_dir = "#{dir}/#{SecureRandom.hex}"
|
|
`mkdir #{repo_dir}`
|
|
`cd #{repo_dir} && git init . `
|
|
`cd #{repo_dir} && git config user.email 'someone@cool.com'`
|
|
`cd #{repo_dir} && git config user.name 'The Cool One'`
|
|
`cd #{repo_dir} && git config commit.gpgsign 'false'`
|
|
files.each do |name, data|
|
|
FileUtils.mkdir_p(Pathname.new("#{repo_dir}/#{name}").dirname)
|
|
File.write("#{repo_dir}/#{name}", data)
|
|
`cd #{repo_dir} && git add #{name}`
|
|
end
|
|
`cd #{repo_dir} && git commit -am 'first commit'`
|
|
repo_dir
|
|
end
|
|
|
|
def about_json(love_color: "FAFAFA", tertiary_low_color: "FFFFFF", color_scheme_name: "Amazing", about_url: "https://www.site.com/about")
|
|
<<~JSON
|
|
{
|
|
"name": "awesome theme",
|
|
"about_url": "#{about_url}",
|
|
"license_url": "https://www.site.com/license",
|
|
"theme_version": "1.0",
|
|
"minimum_discourse_version": "1.0.0",
|
|
"assets": {
|
|
"font": "assets/font.woff2"
|
|
},
|
|
"color_schemes": {
|
|
"#{color_scheme_name}": {
|
|
"love": "#{love_color}",
|
|
"tertiary-low": "#{tertiary_low_color}"
|
|
}
|
|
},
|
|
"modifiers": {
|
|
"serialize_topic_excerpts": true
|
|
}
|
|
}
|
|
JSON
|
|
end
|
|
|
|
let :scss_data do
|
|
"@font-face { font-family: magic; src: url($font)}; body {color: $color; content: $name;}"
|
|
end
|
|
|
|
let :initial_repo do
|
|
setup_git_repo(
|
|
"about.json" => about_json,
|
|
"desktop/desktop.scss" => scss_data,
|
|
"scss/oldpath.scss" => ".class2{color:blue}",
|
|
"stylesheets/file.scss" => ".class1{color:red}",
|
|
"stylesheets/empty.scss" => "",
|
|
"javascripts/discourse/controllers/test.js.es6" => "console.log('test');",
|
|
"common/header.html" => "I AM HEADER",
|
|
"common/random.html" => "I AM SILLY",
|
|
"common/embedded.scss" => "EMBED",
|
|
"assets/font.woff2" => "FAKE FONT",
|
|
"settings.yaml" => "boolean_setting: true",
|
|
"locales/en.yml" => "sometranslations"
|
|
)
|
|
end
|
|
|
|
after do
|
|
`rm -fr #{initial_repo}`
|
|
end
|
|
|
|
it 'can correctly import a remote theme' do
|
|
|
|
time = Time.new('2000')
|
|
freeze_time time
|
|
|
|
@theme = RemoteTheme.import_theme(initial_repo)
|
|
remote = @theme.remote_theme
|
|
|
|
expect(@theme.name).to eq('awesome theme')
|
|
expect(remote.remote_url).to eq(initial_repo)
|
|
expect(remote.remote_version).to eq(`cd #{initial_repo} && git rev-parse HEAD`.strip)
|
|
expect(remote.local_version).to eq(`cd #{initial_repo} && git rev-parse HEAD`.strip)
|
|
|
|
expect(remote.about_url).to eq("https://www.site.com/about")
|
|
expect(remote.license_url).to eq("https://www.site.com/license")
|
|
expect(remote.theme_version).to eq("1.0")
|
|
expect(remote.minimum_discourse_version).to eq("1.0.0")
|
|
|
|
expect(@theme.theme_modifier_set.serialize_topic_excerpts).to eq(true)
|
|
|
|
expect(@theme.theme_fields.length).to eq(9)
|
|
|
|
mapped = Hash[*@theme.theme_fields.map { |f| ["#{f.target_id}-#{f.name}", f.value] }.flatten]
|
|
expect(mapped["0-header"]).to eq("I AM HEADER")
|
|
expect(mapped["1-scss"]).to eq(scss_data)
|
|
expect(mapped["0-embedded_scss"]).to eq("EMBED")
|
|
|
|
expect(mapped["0-font"]).to eq("")
|
|
|
|
expect(mapped["3-yaml"]).to eq("boolean_setting: true")
|
|
|
|
expect(mapped["4-en"]).to eq("sometranslations")
|
|
|
|
expect(mapped.length).to eq(9)
|
|
|
|
expect(@theme.settings.length).to eq(1)
|
|
expect(@theme.settings.first.value).to eq(true)
|
|
|
|
expect(remote.remote_updated_at).to eq_time(time)
|
|
|
|
scheme = ColorScheme.find_by(theme_id: @theme.id)
|
|
expect(scheme.name).to eq("Amazing")
|
|
expect(scheme.colors.find_by(name: 'love').hex).to eq('fafafa')
|
|
expect(scheme.colors.find_by(name: 'tertiary-low').hex).to eq('ffffff')
|
|
|
|
expect(@theme.color_scheme_id).to eq(scheme.id)
|
|
@theme.update(color_scheme_id: nil)
|
|
|
|
File.write("#{initial_repo}/common/header.html", "I AM UPDATED")
|
|
File.write("#{initial_repo}/about.json", about_json(love_color: "EAEAEA", about_url: "https://newsite.com/about"))
|
|
|
|
File.write("#{initial_repo}/settings.yml", "integer_setting: 32")
|
|
`cd #{initial_repo} && git add settings.yml`
|
|
|
|
File.delete("#{initial_repo}/settings.yaml")
|
|
File.delete("#{initial_repo}/stylesheets/file.scss")
|
|
`cd #{initial_repo} && git commit -am "update"`
|
|
|
|
time = Time.new('2001')
|
|
freeze_time time
|
|
|
|
remote.update_remote_version
|
|
expect(remote.commits_behind).to eq(1)
|
|
expect(remote.remote_version).to eq(`cd #{initial_repo} && git rev-parse HEAD`.strip)
|
|
|
|
remote.update_from_remote
|
|
@theme.save!
|
|
@theme.reload
|
|
|
|
scheme = ColorScheme.find_by(theme_id: @theme.id)
|
|
expect(scheme.name).to eq("Amazing")
|
|
expect(scheme.colors.find_by(name: 'love').hex).to eq('eaeaea')
|
|
expect(@theme.color_scheme_id).to eq(nil) # Should only be set on first import
|
|
|
|
mapped = Hash[*@theme.theme_fields.map { |f| ["#{f.target_id}-#{f.name}", f.value] }.flatten]
|
|
|
|
# Scss file was deleted
|
|
expect(mapped["5-file"]).to eq(nil)
|
|
|
|
expect(mapped["0-header"]).to eq("I AM UPDATED")
|
|
expect(mapped["1-scss"]).to eq(scss_data)
|
|
|
|
expect(@theme.settings.length).to eq(1)
|
|
expect(@theme.settings.first.value).to eq(32)
|
|
|
|
expect(remote.remote_updated_at).to eq_time(time)
|
|
expect(remote.about_url).to eq("https://newsite.com/about")
|
|
|
|
# It should be able to remove old colors as well
|
|
File.write("#{initial_repo}/about.json", about_json(love_color: "BABABA", tertiary_low_color: "", color_scheme_name: "Amazing 2"))
|
|
`cd #{initial_repo} && git commit -am "update"`
|
|
|
|
remote.update_from_remote
|
|
@theme.save
|
|
@theme.reload
|
|
|
|
scheme_count = ColorScheme.where(theme_id: @theme.id).count
|
|
expect(scheme_count).to eq(1)
|
|
|
|
scheme = ColorScheme.find_by(theme_id: @theme.id)
|
|
expect(scheme.colors.find_by(name: 'tertiary_low_color')).to eq(nil)
|
|
|
|
# It should detect local changes
|
|
@theme.set_field(target: :common, name: :scss, value: 'body {background-color: blue};')
|
|
@theme.save
|
|
@theme.reload
|
|
|
|
expect(remote.diff_local_changes[:diff]).not_to include("similarity index 100%")
|
|
expect(remote.diff_local_changes[:diff]).to include("background-color: blue")
|
|
end
|
|
end
|
|
|
|
let(:github_repo) do
|
|
RemoteTheme.create!(
|
|
remote_url: "https://github.com/org/testtheme.git",
|
|
local_version: "a2ec030e551fc8d8579790e1954876fe769fe40a",
|
|
remote_version: "21122230dbfed804067849393c3332083ddd0c07",
|
|
commits_behind: 2
|
|
)
|
|
end
|
|
|
|
let(:gitlab_repo) do
|
|
RemoteTheme.create!(
|
|
remote_url: "https://gitlab.com/org/repo.git",
|
|
local_version: "a2ec030e551fc8d8579790e1954876fe769fe40a",
|
|
remote_version: "21122230dbfed804067849393c3332083ddd0c07",
|
|
commits_behind: 5
|
|
)
|
|
end
|
|
|
|
context "#github_diff_link" do
|
|
it "is blank for non-github repos" do
|
|
expect(gitlab_repo.github_diff_link).to be_blank
|
|
end
|
|
|
|
it "returns URL for comparing between local_version and remote_version" do
|
|
expect(github_repo.github_diff_link).to eq(
|
|
"https://github.com/org/testtheme/compare/#{github_repo.local_version}...#{github_repo.remote_version}"
|
|
)
|
|
end
|
|
|
|
it "is blank when theme is up-to-date" do
|
|
github_repo.update!(local_version: github_repo.remote_version, commits_behind: 0)
|
|
expect(github_repo.reload.github_diff_link).to be_blank
|
|
end
|
|
end
|
|
|
|
context ".joined_remotes" do
|
|
it "finds records that are associated with themes" do
|
|
github_repo
|
|
gitlab_repo
|
|
expect(RemoteTheme.joined_remotes).to eq([])
|
|
|
|
Fabricate(:theme, remote_theme: github_repo)
|
|
expect(RemoteTheme.joined_remotes).to eq([github_repo])
|
|
|
|
Fabricate(:theme, remote_theme: gitlab_repo)
|
|
expect(RemoteTheme.joined_remotes).to contain_exactly(github_repo, gitlab_repo)
|
|
end
|
|
end
|
|
|
|
context ".out_of_date_themes" do
|
|
let(:remote) { RemoteTheme.create!(remote_url: "https://github.com/org/testtheme") }
|
|
let!(:theme) { Fabricate(:theme, remote_theme: remote) }
|
|
|
|
it "finds out of date themes" do
|
|
remote.update!(local_version: "old version", remote_version: "new version", commits_behind: 2)
|
|
expect(described_class.out_of_date_themes).to eq([[theme.name, theme.id]])
|
|
|
|
remote.update!(local_version: "new version", commits_behind: 0)
|
|
expect(described_class.out_of_date_themes).to eq([])
|
|
end
|
|
end
|
|
|
|
context ".unreachable_themes" do
|
|
let(:remote) { RemoteTheme.create!(remote_url: "https://github.com/org/testtheme", last_error_text: "can't contact this repo :(") }
|
|
let!(:theme) { Fabricate(:theme, remote_theme: remote) }
|
|
|
|
it "finds out of date themes" do
|
|
expect(described_class.unreachable_themes).to eq([[theme.name, theme.id]])
|
|
|
|
remote.update!(last_error_text: nil)
|
|
expect(described_class.unreachable_themes).to eq([])
|
|
end
|
|
end
|
|
end
|