# frozen_string_literal: true RSpec.describe "tasks/themes" do 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 { invoke_rake_task("themes:update") } } 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 { invoke_rake_task("themes:update") } } 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