discourse/spec/lib/system_themes_manager_spec.rb
Martin Brennan 7504805f89
FIX: allow out-of-sequence theme settings migrations on re-sync (#38705)
When SystemThemesManager.sync! re-syncs an existing core theme,
the theme settings migration runner would raise an error because
migrations had already been recorded in the DB from a prior sync:

```
ThemeSettingsMigrationsRunner#raise_error (raise_error)
ThemeSettingsMigrationsRunner#run (out_of_sequence check)
Theme#migrate_settings
RemoteTheme#update_from_remote
RemoteTheme.import_theme_from_directory
SystemThemesManager.sync_theme!
SeedFu::Runner#run_file
```

Thread the existing `allow_out_of_sequence_migration` parameter
through `import_theme_from_directory` → `update_theme` →
`update_from_remote` → `migrate_settings`, and set it to true
when re-syncing an already-installed system theme.
2026-03-20 11:16:22 +10:00

57 lines
2.2 KiB
Ruby

# frozen_string_literal: true
RSpec.describe SystemThemesManager do
# This is necessary since the theme settings migrations happen
# when `SystemThemesManager.sync!` is called as part of app boot,
# and we want to ensure that any previous migration records for the core themes are cleared to properly test idempotency.
before { ThemeSettingsMigration.where(theme_id: Theme::CORE_THEMES.values).delete_all }
it "is idempotent" do
Theme.delete_all
expect { SystemThemesManager.sync! }.to change { Theme.system.count }.by(2)
expect { SystemThemesManager.sync! }.not_to change { Theme.count }
expect(Theme.horizon_theme.color_scheme.user_selectable).to be false
expect(
Theme.horizon_theme.color_schemes.where(name: "Horizon Dark").first.user_selectable,
).to be false
expect(Theme.horizon_theme.color_schemes.where(user_selectable: false).count).to eq(12)
end
it "renables themes" do
SystemThemesManager.sync!
Theme.horizon_theme.update_column(:enabled, false)
SystemThemesManager.sync!
expect(Theme.horizon_theme.reload.enabled).to be true
end
it "sets up the default light and dark palettes for Horizon on the initial install" do
Theme.delete_all
expect { SystemThemesManager.sync! }.to change { Theme.system.count }.by(2)
expect(Theme.horizon_theme.color_scheme.name).to eq("Horizon")
expect(Theme.horizon_theme.dark_color_scheme.name).to eq("Horizon Dark")
Theme.horizon_theme.update!(color_scheme: nil)
Theme.horizon_theme.update!(dark_color_scheme: nil)
expect { SystemThemesManager.sync! }.not_to change { Theme.system.count }
expect(Theme.horizon_theme.color_scheme).to eq(nil)
expect(Theme.horizon_theme.dark_color_scheme).to eq(nil)
end
it "does not raise when re-syncing themes with existing settings migrations" do
Theme.delete_all
SystemThemesManager.sync!
themes_with_migrations =
Theme::CORE_THEMES.select { |_, id| ThemeSettingsMigration.exists?(theme_id: id) }
skip "no core themes have settings migrations" if themes_with_migrations.empty?
themes_with_migrations.each_key do |theme_name|
expect { SystemThemesManager.sync_theme!(theme_name) }.not_to raise_error
end
end
end