0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-05 21:57:36 +08:00
discourse/spec/services/site_setting/upsert_groups_spec.rb
Martin Brennan dcf6da9cef
UX: Allow more specific enabled for options for upcoming changes (#39916)
Certain upcoming changes do not make sense to enable for "Everyone",
like changes that will only affect the admin UI. We currently have
a disallow_enabled_for_groups option that changes the "Enabled for"
dropdown to only show Everyone and No one, but this is a bit of a blunt
instrument.

This change adds an `allow_enabled_for` option for upcoming changes
which is a YAML array:

* When omitted, the "Enabled for" dropdown will show Everyone, Staff,
Specific group(s) and No one.
* When set to everyone, the dropdown will only show Everyone and No one.
* When set to staff, the dropdown will only show Staff and No one.
* It can also be set to staff and specific_groups

This commit also changes the reporting_improvements upcoming change
to be staff, specific_groups and adds a DB migration to account for
this.
2026-05-13 10:22:06 +10:00

218 lines
6.6 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe SiteSetting::UpsertGroups do
describe described_class::Contract, type: :model do
it { is_expected.to validate_presence_of :setting }
end
describe ".call" do
subject(:result) { described_class.call(params:, **dependencies) }
fab!(:admin)
let(:params) { { group_names:, setting: } }
let(:dependencies) { { guardian: } }
let(:group_names) { %w[trust_level_0 admins] }
let(:setting) { "enable_upload_debug_mode" }
let(:guardian) { admin.guardian }
context "when setting is blank" do
let(:setting) { nil }
it { is_expected.to fail_a_contract }
end
context "when group names don't match any existing groups" do
let(:group_names) { ["nonexistent_group"] }
it { is_expected.to fail_to_find_a_model(:group_ids) }
end
context "when some group names exist and some don't" do
let(:group_names) { %w[trust_level_0 nonexistent_group admins] }
it { is_expected.to run_successfully }
it "only includes the existing groups" do
result
site_setting_group = SiteSettingGroup.find_by(name: setting)
expect(site_setting_group.group_ids).to eq("1|10")
end
end
context "when a non-admin user tries to upsert groups" do
let(:guardian) { Guardian.new }
it { is_expected.to fail_a_policy(:current_user_is_admin) }
end
context "when the setting is an upcoming change with allow_enabled_for restrictions" do
let(:setting) { "enable_form_templates" }
context "when allow_enabled_for is [everyone]" do
before do
mock_upcoming_change_metadata(
enable_form_templates: {
impact: "feature,all_members",
status: :experimental,
impact_type: "feature",
impact_role: "all_members",
allow_enabled_for: [:everyone],
},
)
end
it { is_expected.to fail_a_policy(:allowed_enabled_for_target) }
context "when group_names is empty" do
let(:group_names) { [] }
it { is_expected.to run_successfully }
end
end
context "when allow_enabled_for is [staff]" do
before do
mock_upcoming_change_metadata(
enable_form_templates: {
impact: "feature,all_members",
status: :experimental,
impact_type: "feature",
impact_role: "all_members",
allow_enabled_for: [:staff],
},
)
end
context "with only the staff group" do
let(:group_names) { ["staff"] }
it { is_expected.to run_successfully }
end
context "with non-staff groups" do
let(:group_names) { %w[trust_level_0 admins] }
it { is_expected.to fail_a_policy(:allowed_enabled_for_target) }
end
end
context "when allow_enabled_for is [staff, specific_groups]" do
before do
mock_upcoming_change_metadata(
enable_form_templates: {
impact: "feature,all_members",
status: :experimental,
impact_type: "feature",
impact_role: "all_members",
allow_enabled_for: %i[staff specific_groups],
},
)
end
let(:group_names) { %w[trust_level_0 admins] }
it { is_expected.to run_successfully }
end
end
context "when an admin user upserts groups for a setting" do
it { is_expected.to run_successfully }
it "creates a new site setting group record" do
expect { result }.to change { SiteSettingGroup.count }.by(1)
end
it "stores the group ids in pipe-delimited format" do
result
site_setting_group = SiteSettingGroup.find_by(name: setting)
expect(site_setting_group.group_ids).to eq("1|10")
end
it "creates an entry in the staff action logs" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting_groups],
subject: setting,
).count
}.by(1)
history = UserHistory.where(subject: setting).last
expect(history.previous_value).to be_nil
expect(history.new_value).to eq("1|10")
end
it "notifies that site settings have changed" do
SiteSetting.expects(:notify_changed!).once
result
end
it "refreshes the site setting group ids for this process" do
SiteSetting.expects(:refresh_site_setting_group_ids!).once
result
end
end
context "when an admin user updates groups for an existing setting" do
before { SiteSettingGroup.create!(name: setting, group_ids: "10|13") }
let(:group_names) { %w[admins trust_level_3] }
it { is_expected.to run_successfully }
it "does not create a new record" do
expect { result }.not_to change { SiteSettingGroup.count }
end
it "updates the existing site setting group record" do
expect { result }.to change { SiteSettingGroup.find_by(name: setting).group_ids }.from(
"10|13",
).to("1|13")
end
it "creates an entry in the staff action logs with previous value" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting_groups],
subject: setting,
).count
}.by(1)
history = UserHistory.where(subject: setting).last
expect(history.previous_value).to eq("10|13")
expect(history.new_value).to eq("1|13")
end
it "notifies that site settings have changed" do
SiteSetting.expects(:notify_changed!).once
result
end
context "when group_names are empty" do
let(:group_names) { [] }
it "deletes the existing site setting group record" do
expect { result }.to change { SiteSettingGroup.where(name: setting).count }.by(-1)
end
it "refreshes the site setting group ids for this process" do
SiteSetting.expects(:refresh_site_setting_group_ids!).once
result
end
it "creates an entry in the staff action logs with previous value and empty new value" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting_groups],
subject: setting,
).count
}.by(1)
history = UserHistory.where(subject: setting).last
expect(history.previous_value).to eq("10|13")
expect(history.new_value).to eq("")
end
end
end
end
end