discourse/spec/tasks/themes_spec.rb
Alan Guo Xiang Tan 9d96fcb821
DEV: Improve test coverage of themes:update rake task (#26764)
This commit adds a test to ensure that settings for a theme are retained
even if saving a theme setting after a theme setting migration fails.
Prior to the fix introduced in 35bc27a36d,
failing to save the new settings will actually cause some or all of the
theme's setting to be lost.
2024-04-26 10:04:15 +08:00

127 lines
3.9 KiB
Ruby

# frozen_string_literal: true
RSpec.describe "tasks/themes" do
before do
Rake::Task.clear
Discourse::Application.load_tasks
end
describe "themes:update" do
let(:initial_repo) do
about_json = <<~JSON
{
"name": "awesome theme",
"about_url": "https://www.site.com/about",
"license_url": "https://www.site.com/license",
"theme_version": "1.0",
"minimum_discourse_version": "1.0.0"
}
JSON
settings_yaml = <<~YAML
some_setting:
type: string
default: some default value
string_setting:
type: string
default: default value
YAML
setup_git_repo(
"about.json" => about_json,
"common/header.html" => "I AM A HEADER",
"settings.yml" => settings_yaml,
)
end
let(:initial_repo_url) do
MockGitImporter.register("https://example.com/initial_repo.git", initial_repo)
end
let!(:theme) { RemoteTheme.import_theme(initial_repo_url) }
around(:each) { |group| MockGitImporter.with_mock { group.run } }
after { `rm -fr #{initial_repo}` }
it "should retain a theme's settings and not update the theme when a theme's setting fails to save" do
theme.update_setting(:some_setting, "some setting value")
migration_content = <<~JS
export default function migrate(settings) {
const oldSetting = settings.get("string_setting");
settings.set("string_setting", [{}]);
return settings;
}
JS
settings_yaml = <<~YAML
string_setting:
type: objects
default: []
schema:
name: some object
properties:
title:
type: string
required: true
YAML
add_to_git_repo(
initial_repo,
"migrations/settings/0001-a-migration.js" => migration_content,
"settings.yml" => settings_yaml,
"common/header.html" => "I AM UPDATED HEADER",
)
original_remote_version = theme.remote_theme.remote_version
original_local_version = theme.remote_theme.local_version
stderr = capture_stderr { capture_stdout { Rake::Task["themes:update"].invoke } }
expect(stderr.chomp).to eq(
"[default] Failed to update 'awesome theme' (#{theme.id}): The property at JSON Pointer '/0/title' must be present.",
)
theme.reload
expect(theme.theme_fields.count).to eq(2)
expect(theme.theme_fields.where(name: "header").first.value).to eq("I AM A HEADER")
expect(theme.theme_settings_migrations.count).to eq(0)
expect(theme.remote_theme.commits_behind).to eq(0)
expect(theme.remote_theme.remote_version).to eq(original_remote_version)
expect(theme.remote_theme.local_version).to eq(original_local_version)
expect(theme.settings[:some_setting].value).to eq("some setting value")
expect(theme.settings[:string_setting].value).to eq("default value")
end
it "should not update the theme if a theme setting migration fails during the update" do
migration_content = <<~JS
export default function migrate(settings) {
throw "error";
}
JS
add_to_git_repo(
initial_repo,
"migrations/settings/0001-a-migration.js" => migration_content,
"common/header.html" => "I AM UPDATED HEADER",
)
original_remote_version = theme.remote_theme.remote_version
original_local_version = theme.remote_theme.local_version
capture_stderr { capture_stdout { Rake::Task["themes:update"].invoke } }
theme.reload
expect(theme.theme_fields.count).to eq(2)
expect(theme.theme_fields.where(name: "header").first.value).to eq("I AM A HEADER")
expect(theme.theme_settings_migrations.count).to eq(0)
expect(theme.remote_theme.commits_behind).to eq(0)
expect(theme.remote_theme.remote_version).to eq(original_remote_version)
expect(theme.remote_theme.local_version).to eq(original_local_version)
end
end
end