2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/spec/services/upcoming_changes/toggle_spec.rb
Martin Brennan e154a90427
FEATURE: Disallow selecting groups for some upcoming changes (#37801)
Some upcoming changes are all-or-nothing — they affect the whole site
or only admins, so enabling them per-group makes no sense. This adds a
`disallow_enabled_for_groups` flag to upcoming change metadata that
restricts the "Enabled for" dropdown to only "Everyone" and "No One",
and clears any existing group assignments server-side as a safety net.
2026-02-16 10:19:01 +10:00

396 lines
13 KiB
Ruby

# frozen_string_literal: true
RSpec.describe UpcomingChanges::Toggle do
describe UpcomingChanges::Toggle::Contract, type: :model do
it { is_expected.to validate_presence_of :setting_name }
end
describe ".call" do
subject(:result) { described_class.call(params:, **dependencies, options:) }
fab!(:admin)
let(:params) { { setting_name:, enabled: } }
let(:enabled) { true }
let(:setting_name) { :enable_form_templates }
let(:dependencies) { { guardian: } }
let(:options) { {} }
let(:guardian) { admin.guardian }
context "when data is invalid" do
let(:setting_name) { nil }
it { is_expected.to fail_a_contract }
end
context "when setting_name is invalid" do
let(:setting_name) { "wrong_value" }
it { is_expected.to fail_a_policy(:setting_is_available) }
end
context "when a non-admin user tries to change a setting" do
let(:guardian) { Guardian.new }
it { is_expected.to fail_a_policy(:current_user_is_admin) }
end
context "when everything's ok" do
it { is_expected.to run_successfully }
context "when enable_upcoming_changes is disabled" do
let(:setting_name) { :display_local_time_in_user_card }
context "when log_change is true" do
let(:options) { { log_change: true } }
context "when enabling the setting" do
let(:enabled) { true }
before { SiteSetting.display_local_time_in_user_card = false }
it "enables the specified setting" do
expect { result }.to change { SiteSetting.display_local_time_in_user_card }.to(true)
end
it "creates an entry in the staff action logs" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting],
subject: "display_local_time_in_user_card",
).count
}.by(1)
end
it "logs the correct previous value" do
result
history =
UserHistory.find_by(
action: UserHistory.actions[:change_site_setting],
subject: "display_local_time_in_user_card",
)
expect(history.previous_value).to eq("false")
expect(history.new_value).to eq("true")
end
it "does not create an UpcomingChangeEvent" do
expect { result }.not_to change { UpcomingChangeEvent.count }
end
it "triggers the upcoming_change_enabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_enabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
context "when disabling the setting" do
let(:enabled) { false }
before { SiteSetting.display_local_time_in_user_card = true }
it "disables the specified setting" do
expect { result }.to change { SiteSetting.display_local_time_in_user_card }.to(false)
end
it "creates an entry in the staff action logs" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting],
subject: "display_local_time_in_user_card",
).count
}.by(1)
end
it "does not create an UpcomingChangeEvent" do
expect { result }.not_to change { UpcomingChangeEvent.count }
end
it "triggers the upcoming_change_disabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_disabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
end
context "when log_change is false" do
let(:options) { { log_change: false } }
context "when enabling the setting" do
let(:enabled) { true }
before { SiteSetting.display_local_time_in_user_card = false }
it "enables the specified setting" do
expect { result }.to change { SiteSetting.display_local_time_in_user_card }.to(true)
end
it "does not create an entry in the staff action logs" do
expect { result }.not_to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting],
subject: "display_local_time_in_user_card",
).count
}
end
it "does not create an UpcomingChangeEvent" do
expect { result }.not_to change { UpcomingChangeEvent.count }
end
end
context "when disabling the setting" do
let(:enabled) { false }
before { SiteSetting.display_local_time_in_user_card = true }
it "disables the specified setting" do
expect { result }.to change { SiteSetting.display_local_time_in_user_card }.to(false)
end
it "does not create an entry in the staff action logs" do
expect { result }.not_to change {
UserHistory.where(
action: UserHistory.actions[:change_site_setting],
subject: "display_local_time_in_user_card",
).count
}
end
it "does not create an UpcomingChangeEvent" do
expect { result }.not_to change { UpcomingChangeEvent.count }
end
it "triggers the upcoming_change_disabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_disabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
end
end
context "when disallow_enabled_for_groups is true" do
before do
SiteSetting.enable_upcoming_changes = true
mock_upcoming_change_metadata(
enable_form_templates: {
impact: "feature,all_members",
status: :experimental,
impact_type: "feature",
impact_role: "all_members",
disallow_enabled_for_groups: true,
},
)
end
context "when toggling on with existing groups" do
let(:enabled) { true }
fab!(:site_setting_group) do
Fabricate(:site_setting_group, name: "enable_form_templates", group_ids: "1|2")
end
before { SiteSetting.enable_form_templates = false }
it "clears the SiteSettingGroup record" do
expect { result }.to change {
SiteSettingGroup.where(name: "enable_form_templates").count
}.from(1).to(0)
end
end
context "when toggling off with existing groups" do
let(:enabled) { false }
fab!(:site_setting_group) do
Fabricate(:site_setting_group, name: "enable_form_templates", group_ids: "1|2")
end
before { SiteSetting.enable_form_templates = true }
it "clears the SiteSettingGroup record" do
expect { result }.to change {
SiteSettingGroup.where(name: "enable_form_templates").count
}.from(1).to(0)
end
end
context "when toggling with no existing groups" do
let(:enabled) { true }
before { SiteSetting.enable_form_templates = false }
it { is_expected.to run_successfully }
end
end
context "when enable_upcoming_changes is enabled" do
before { SiteSetting.enable_upcoming_changes = true }
context "when log_change is true" do
let(:options) { { log_change: true } }
context "when enabling the setting" do
let(:enabled) { true }
before { SiteSetting.enable_form_templates = false }
it "enables the specified setting" do
expect { result }.to change { SiteSetting.enable_form_templates }.to(true)
end
it "creates an entry in the staff action logs with correct context" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:upcoming_change_toggled],
subject: "enable_form_templates",
).count
}.by(1)
expect(UserHistory.last.context).to eq(
I18n.t("staff_action_logs.upcoming_changes.log_manually_toggled"),
)
end
it "creates an UpcomingChangeEvent with manual_opt_in event_type" do
expect { result }.to change {
UpcomingChangeEvent.where(
event_type: :manual_opt_in,
upcoming_change_name: "enable_form_templates",
).count
}.by(1)
end
it "triggers the upcoming_change_enabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_enabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
context "when disabling the setting" do
let(:enabled) { false }
before { SiteSetting.enable_form_templates = true }
it "disables the specified setting" do
expect { result }.to change { SiteSetting.enable_form_templates }.to(false)
end
it "creates an entry in the staff action logs with correct context" do
expect { result }.to change {
UserHistory.where(
action: UserHistory.actions[:upcoming_change_toggled],
subject: "enable_form_templates",
).count
}.by(1)
expect(UserHistory.last.context).to eq(
I18n.t("staff_action_logs.upcoming_changes.log_manually_toggled"),
)
end
it "creates an UpcomingChangeEvent with manual_opt_out event_type" do
expect { result }.to change {
UpcomingChangeEvent.where(
event_type: :manual_opt_out,
upcoming_change_name: "enable_form_templates",
).count
}.by(1)
end
it "triggers the upcoming_change_disabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_disabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
end
context "when log_change is false" do
let(:options) { { log_change: false } }
context "when enabling the setting" do
let(:enabled) { true }
before { SiteSetting.enable_form_templates = false }
it "enables the specified setting" do
expect { result }.to change { SiteSetting.enable_form_templates }.to(true)
end
it "does not create an entry in the staff action logs" do
expect { result }.not_to change {
UserHistory.where(
action: UserHistory.actions[:upcoming_change_toggled],
subject: "enable_form_templates",
).count
}
end
it "does not create an UpcomingChangeEvent" do
expect { result }.not_to change { UpcomingChangeEvent.count }
end
it "triggers the upcoming_change_enabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_enabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
context "when disabling the setting" do
let(:enabled) { false }
before { SiteSetting.enable_form_templates = true }
it "disables the specified setting" do
expect { result }.to change { SiteSetting.enable_form_templates }.to(false)
end
it "does not create an entry in the staff action logs" do
expect { result }.not_to change {
UserHistory.where(
action: UserHistory.actions[:upcoming_change_toggled],
subject: "enable_form_templates",
).count
}
end
it "does not create an UpcomingChangeEvent" do
expect { result }.not_to change { UpcomingChangeEvent.count }
end
it "triggers the upcoming_change_disabled event" do
events =
DiscourseEvent
.track_events { result }
.select { |e| e[:event_name] == :upcoming_change_disabled }
expect(events.first[:params]).to eq([setting_name.to_s])
end
end
end
end
end
end
end