0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/plugins/discourse-policy/spec/lib/check_policy_spec.rb
Alan Guo Xiang Tan 6df9b0b357
DEV: Prefer RSpec primitives for test setup (#42122)
RSpec setup becomes harder to follow at either extreme: trivial fixture
wrappers hide lifecycle and intent, while forcing every named operation
inline repeats low-level protocol and configuration details.

This change documents and applies a test-setup hierarchy:

- use `fab!`, `let`, `let!`, `subject`, and inline `Fabricate` according
to lifecycle and role;
- use a small example-group method when parameterized behavior gives one
spec useful vocabulary;
- move helpers into auto-loaded `spec/support` only when they are shared
across spec files;
- use fabricators and page objects for the data shapes and system-test
interfaces they own.

Core and plugin support files are loaded centrally by `rails_helper`, so
plugin-specific support loaders are unnecessary. The migration specs
encountered during the sweep are removed according to repository policy;
production migrations are unchanged.
2026-07-30 11:17:22 +08:00

357 lines
9 KiB
Ruby
Vendored

# frozen_string_literal: true
describe Jobs::DiscoursePolicy::CheckPolicy do
subject(:job) { described_class.new }
fab!(:user1, :user)
fab!(:user2, :user)
fab!(:group) do
group = Fabricate(:group)
group.add(user1)
group.add(user2)
group
end
before do
enable_current_plugin
Jobs.run_immediately!
end
it "correctly renews policies with no renew-start" do
freeze_time Time.utc(2019)
raw = <<~MD
[policy group=#{group.name} renew=400]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
freeze_time Time.utc(2021)
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
freeze_time Time.utc(2022)
job.execute
post.reload
expect(post.post_policy.accepted_by).to contain_exactly(user1, user2)
freeze_time Time.utc(2023)
job.execute
post.reload
expect(post.post_policy.accepted_by).to be_empty
end
it "expires only for user with expired policy" do
freeze_time Time.utc(2019)
raw = <<~MD
[policy group=#{group.name} renew=364]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
freeze_time Time.utc(2021)
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
freeze_time Time.utc(2022)
PolicyUser.where(user_id: user2.id).update(accepted_at: Time.now)
job.execute
post.reload
expect(post.post_policy.accepted_by).to contain_exactly(user2)
end
it "expires just for expired policy" do
freeze_time Time.utc(2019)
raw = <<~MD
[policy group=#{group.name} renew=364]
I always open **doors**!
[/policy]
MD
raw2 = <<~MD
[policy group=#{group.name} renew=1000]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
post2 = create_post(raw: raw2, user: Fabricate(:admin))
freeze_time Time.utc(2021)
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post2.post_policy) }
freeze_time Time.utc(2022)
job.execute
post.reload
expect(post.post_policy.accepted_by).to be_empty
expect(post2.post_policy.accepted_by).to contain_exactly(user1, user2)
end
it "correctly renews policies" do
freeze_time Time.utc(2019)
raw = <<~MD
[policy group=#{group.name} renew=100 renew-start="2020-10-17"]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
freeze_time Time.utc(2020)
job.execute
post.reload
# did not hit renew start
expect(post.post_policy.accepted_by).to contain_exactly(user1, user2)
freeze_time Time.utc(2020, 10, 18)
job.execute
post.reload
expect(post.post_policy.accepted_by).to be_empty
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
freeze_time(Time.utc(2020, 10, 17) + 101.days)
PolicyUser.add!(user2, post.post_policy)
job.execute
post.reload
expect(post.post_policy.accepted_by).to contain_exactly(user2)
end
%w[monthly quarterly yearly].each do |how_often|
it "sets correctly next_renew_at for #{how_often} when renew-start is set" do
period =
case how_often
when "monthly"
1.month
when "quarterly"
3.months
when "yearly"
12.months
end
freeze_time Time.utc(2020, 10, 16)
raw = <<~MD
[policy group=#{group.name} renew=#{how_often} renew-start="2020-10-17"]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
freeze_time Time.utc(2020, 10, 17)
job.execute
post.reload
expect(post.post_policy.accepted_by).to contain_exactly(user1, user2)
freeze_time Time.utc(2020, 10, 18)
job.execute
post.reload
expect(post.post_policy.accepted_by).to be_empty
expect(post.post_policy.next_renew_at.to_s).to eq((Time.utc(2020, 10, 17) + period).to_s)
end
end
%w[monthly quarterly yearly].each do |how_often|
it "expires policies when #{how_often}" do
period =
case how_often
when "monthly"
1.month
when "quarterly"
3.months
when "yearly"
12.months
end
freeze_time Time.utc(2020, 10, 16)
raw = <<~MD
[policy group=#{group.name} renew=#{how_often}]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
[user1, user2].each { |policy_user| PolicyUser.add!(policy_user, post.post_policy) }
freeze_time Time.utc(2020, 10, 30)
job.execute
post.reload
expect(post.post_policy.accepted_by).to contain_exactly(user1, user2)
freeze_time Time.utc(2020, 10, 16) + period + 1.day
job.execute
post.reload
expect(post.post_policy.accepted_by).to be_empty
expect(post.post_policy.renew_start).to eq(nil)
end
end
it "will correctly notify users with high priority notifications" do
Jobs.run_immediately!
freeze_time
raw = <<~MD
[policy group=#{group.name} reminder=weekly]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
job.execute
expect(
user1.notifications.where(notification_type: Notification.types[:topic_reminder]).count,
).to eq(0)
expect(
user2.notifications.where(notification_type: Notification.types[:topic_reminder]).count,
).to eq(0)
freeze_time 2.weeks.from_now
job.execute
job.execute
user1_notifications =
user1.notifications.where(
notification_type: Notification.types[:topic_reminder],
topic_id: post.topic_id,
post_number: 1,
)
expect(user1_notifications.count).to eq(1)
expect(user1_notifications.first.high_priority).to eq(true)
user2_notifications =
user2.notifications.where(
notification_type: Notification.types[:topic_reminder],
topic_id: post.topic_id,
post_number: 1,
)
expect(user2_notifications.count).to eq(1)
expect(user2_notifications.first.high_priority).to eq(true)
end
context "when the policy topic is restricted" do
it "creates reminders only for users who can see it" do
freeze_time
policy_user_with_topic_access = Fabricate(:user)
policy_user_without_topic_access = Fabricate(:user)
policy_target_group = Fabricate(:group)
policy_target_group.add(policy_user_with_topic_access)
policy_target_group.add(policy_user_without_topic_access)
private_category_access_group = Fabricate(:group)
private_category_access_group.add(policy_user_with_topic_access)
private_category = Fabricate(:private_category, group: private_category_access_group)
raw = <<~MD
[policy group=#{policy_target_group.name} reminder=weekly]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin), category: private_category)
freeze_time 2.weeks.from_now
job.execute
expect(
Notification.where(
notification_type: Notification.types[:topic_reminder],
topic_id: post.topic_id,
post_number: 1,
).pluck(:user_id),
).to contain_exactly(policy_user_with_topic_access.id)
end
end
it "will delete the existing policy reminder notification before creating a new one" do
Jobs.run_immediately!
freeze_time
raw = <<~MD
[policy group=#{group.name} reminder=weekly]
I always open **doors**!
[/policy]
MD
post = create_post(raw: raw, user: Fabricate(:admin))
job.execute
expect(
user1.notifications.where(notification_type: Notification.types[:topic_reminder]).count,
).to eq(0)
freeze_time 2.weeks.from_now
job.execute
user1_notification =
user1
.notifications
.where(
notification_type: Notification.types[:topic_reminder],
topic_id: post.topic_id,
post_number: 1,
)
.last
expect(user1_notification).not_to eq(nil)
freeze_time 2.weeks.from_now
job.execute
expect(
user1
.notifications
.where(
notification_type: Notification.types[:topic_reminder],
topic_id: post.topic_id,
post_number: 1,
)
.count,
).to eq(1)
expect(Notification.find_by(id: user1_notification.id)).to eq(nil)
end
it "clears the next_renew_at when renew_start is nil" do
policy = Fabricate(:post_policy, next_renew_at: 3.hours.ago, renew_start: nil, renew_days: 10)
job.execute
expect(policy.reload.next_renew_at).to be_nil
end
end