0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 09:44:06 +08:00
discourse/spec/lib/site_settings/defaults_provider_spec.rb
Martin Brennan dd8c16cbd6
FEATURE: Allow upcoming changes to control site setting defaults (#38815)
We often need to change site setting defaults when we
would like to change default behaviour for the Discourse software.
However, we want to be non-disruptive to existing sites, as
some default changes can modify the behaviour of existing features
quite a lot.

In the past, when we did this we would write the old default to the
database for anyone who hadn't changed the setting, and then change
it for new sites going forward. However in practice means that there
are large portions of Discourse sites with "bad" defaults that we
no longer agree with, that slows adoption of best practices and makes
it harder to reason about our different features.

This change adds a way for upcoming changes to control the rollout
of changes to site setting defaults via additional metadata attached
to the setting whose default is changing.

This way, we can have a more gradual rollout of new defaults, and we can
also inform site admins about the upcoming change and give them a chance
to opt in early if they want to.
2026-04-08 13:05:44 +10:00

237 lines
7.5 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe SiteSettings::DefaultsProvider do
let(:provider_local) { SiteSettings::LocalProcessProvider.new }
before { MessageBus.off }
after { MessageBus.on }
let(:settings) { new_settings(provider_local) }
describe ".db_all" do
it "can collect values from db" do
settings.provider.save("try_a", 1, SiteSetting.types[:integer])
settings.provider.save("try_b", 2, SiteSetting.types[:integer])
expect(settings.defaults.db_all.count).to eq 2
end
end
describe "expose default cache according to locale" do
before do
settings.setting(:test_override, "default", locale_default: { zh_CN: "cn" })
settings.setting(:test_boolean_override, true, locale_default: { zh_CN: false })
settings.setting(:test_default, "test", regex: '^\S+$')
settings.refresh!
end
describe ".all" do
it "returns all values according to locale" do
expect(settings.defaults.all).to eq(
test_override: "default",
test_default: "test",
test_boolean_override: true,
)
expect(settings.defaults.all("zh_CN")).to eq(
test_override: "cn",
test_default: "test",
test_boolean_override: false,
)
end
end
describe ".get" do
it "returns the default value to a site setting" do
expect(settings.defaults.get(:test_override)).to eq "default"
end
it "accepts a string as the parameters" do
expect(settings.defaults.get("test_override")).to eq "default"
end
it "returns the locale_default value if it exists" do
expect(settings.defaults.get(:test_override, :zh_CN)).to eq "cn"
expect(settings.defaults.get(:test_override, :de)).to eq "default"
expect(settings.defaults.get(:test_default, :zh_CN)).to eq "test"
end
it "returns the correct locale_default for boolean site settings" do
expect(settings.defaults.get(:test_boolean_override, :zh_CN)).to eq false
end
end
describe ".set_regardless_of_locale" do
let(:val) { "env_overridden" }
it "sets the default value to a site setting regardless the locale" do
settings.defaults.set_regardless_of_locale(:test_override, val)
expect(settings.defaults.get(:test_override)).to eq val
expect(settings.defaults.get(:test_override, "zh_CN")).to eq val
end
it "handles the string" do
settings.defaults.set_regardless_of_locale("test_override", val)
expect(settings.defaults.get(:test_override)).to eq val
end
it "converts the data type" do
settings.defaults.set_regardless_of_locale(:test_override, 1)
expect(settings.defaults.get(:test_override)).to eq "1"
end
it "raises when the setting does not exists" do
expect { settings.defaults.set_regardless_of_locale(:not_exist, 1) }.to raise_error(
ArgumentError,
)
end
it "raises when the value is not valid" do
expect {
settings.defaults.set_regardless_of_locale(:test_default, "regex will fail")
}.to raise_error(Discourse::InvalidParameters)
end
end
end
describe ".load_setting" do
it "adds a setting to the cache correctly" do
settings.defaults.load_setting("new_a", 1, zh_CN: 7)
expect(settings.defaults[:new_a]).to eq 1
expect(settings.defaults.get(:new_a, "zh_CN")).to eq 7
end
end
describe ".has_setting?" do
before do
settings.setting(:r, 1)
settings.setting(:question?, 1)
end
it "returns true when it's present in the cache" do
expect(settings.defaults.has_setting?(:r)).to be_truthy
end
it '"responds when the arg is string' do
expect(settings.defaults.has_setting?("r")).to be_truthy
end
it "default_locale always exists" do
expect(settings.defaults.has_setting?(:default_locale)).to be_truthy
end
it "returns false when the key is not exist" do
expect(settings.defaults.has_setting?("no_key")).to be_falsey
end
it "checks name with question mark" do
expect(settings.defaults.has_setting?(:question)).to be_truthy
expect(settings.defaults.has_setting?("question")).to be_truthy
end
end
describe "plugin modifier" do
before { settings.setting(:my_setting, "defaultval") }
class TestFilterPlugInstance < Plugin::Instance
end
let(:plugin_instance) { TestFilterPlugInstance.new }
it "can change defaults" do
expect(settings.defaults.get(:my_setting)).to eq "defaultval"
expect(settings.defaults.all[:my_setting]).to eq "defaultval"
plugin_instance.register_modifier(:site_setting_defaults) do |defaults|
defaults.merge({ my_setting: "overridden default" })
end
expect(settings.defaults.get(:my_setting)).to eq "overridden default"
expect(settings.defaults.all[:my_setting]).to eq "overridden default"
ensure
DiscoursePluginRegistry.reset!
end
end
describe "upcoming change default overrides" do
before do
settings.setting(:suggested_topics_max_days_old, 365)
settings.instance_variable_set(
:@upcoming_change_default_overrides,
{
suggested_topics_max_days_old: {
new_default: 1000,
upcoming_change: :increase_suggested_topics_max_days_old_default,
},
},
)
end
describe ".all" do
context "when the upcoming change override is active" do
before do
settings.defaults.activate_upcoming_change_override(
:increase_suggested_topics_max_days_old_default,
)
end
it "uses upcoming change default overrides by default" do
expect(settings.defaults.all[:suggested_topics_max_days_old]).to eq(1000)
end
context "when include_upcoming_changes_overrides is false" do
it "does not use upcoming change default overrides" do
expect(
settings.defaults.all(include_upcoming_changes_overrides: false)[
:suggested_topics_max_days_old
],
).to eq(365)
end
end
end
context "when the upcoming change override is not active" do
before do
settings.defaults.deactivate_upcoming_change_override(
:increase_suggested_topics_max_days_old_default,
)
end
it "does not use upcoming change default overrides" do
expect(settings.defaults.all[:suggested_topics_max_days_old]).to eq(365)
end
end
end
describe ".upcoming_change_override_metadata" do
before do
settings.defaults.activate_upcoming_change_override(
:increase_suggested_topics_max_days_old_default,
)
end
it "returns the upcoming change override metadata" do
expect(
settings.defaults.upcoming_change_override_metadata(:suggested_topics_max_days_old),
).to eq(
old_default: "365",
new_default: "1000",
change_setting_name: :increase_suggested_topics_max_days_old_default,
)
end
context "when the upcoming change override is not active" do
before do
settings.defaults.deactivate_upcoming_change_override(
:increase_suggested_topics_max_days_old_default,
)
end
it "returns nil" do
expect(
settings.defaults.upcoming_change_override_metadata(:suggested_topics_max_days_old),
).to be_nil
end
end
end
end
end