0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/spec/jobs/clean_up_inactive_users_spec.rb
Steven Chang 39f73fb398
DEV: add clean_up_inactive_users_query modifier for plugins to extend query for inactive users (#41372)
This PR adds Bookmarks and PostActions (likes) to the query for
`CleanUpInactiveUsers` to fetch qualified users.

This PR also allows plugins to modify the `CleanUpInactiveUsers` job
query for selecting which users to destroy. The modifier is given the AR
relation as the argument. Plugins should avoid executing the query, as
it expects a builder style pattern.

Implementation:
```ruby
register_modifier(:clean_up_inactive_users_query) do |relation|
  relation.where.missing(:table_name)
end
```
2026-07-06 09:39:11 -07:00

201 lines
5.5 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe Jobs::CleanUpInactiveUsers do
it "should clean up new users that have been inactive" do
SiteSetting.clean_up_inactive_users_after_days = 0
user =
Fabricate(
:user,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
Fabricate(:active_user)
Fabricate(
:post,
user:
Fabricate(
:user,
trust_level: TrustLevel.levels[:newuser],
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
),
).user
Fabricate(
:user,
trust_level: TrustLevel.levels[:newuser],
created_at: 5.days.ago,
last_seen_at: 2.days.ago,
)
Fabricate(:user, trust_level: TrustLevel.levels[:basic], created_at: 5.days.ago)
expect { described_class.new.execute({}) }.to_not change { User.count }
SiteSetting.clean_up_inactive_users_after_days = 4
expect { described_class.new.execute({}) }.to change { User.count }.by(-1)
expect(User.exists?(id: user.id)).to eq(false)
end
it "doesn't delete inactive admins" do
SiteSetting.clean_up_inactive_users_after_days = 4
admin =
Fabricate(
:admin,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
expect { described_class.new.execute({}) }.to_not change { User.count }
expect(User.exists?(admin.id)).to eq(true)
end
it "doesn't delete inactive mods" do
SiteSetting.clean_up_inactive_users_after_days = 4
moderator =
Fabricate(
:moderator,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
expect { described_class.new.execute({}) }.to_not change { User.count }
expect(User.exists?(moderator.id)).to eq(true)
end
it "should clean up a user that has a deleted post" do
SiteSetting.clean_up_inactive_users_after_days = 1
Fabricate(:active_user)
Fabricate(
:post,
user:
Fabricate(
:user,
trust_level: TrustLevel.levels[:newuser],
created_at: 5.days.ago,
last_seen_at: 2.days.ago,
),
# ensuring that topic author is a different user as the topic is non-deleted
topic: Fabricate(:topic, user: Fabricate(:user)),
deleted_at: Time.now,
).user
expect { described_class.new.execute({}) }.to change { User.count }.by(-1)
end
it "should clean up user that has a deleted topic" do
SiteSetting.clean_up_inactive_users_after_days = 1
Fabricate(:active_user)
Fabricate(
:topic,
user:
Fabricate(
:user,
trust_level: TrustLevel.levels[:newuser],
created_at: 2.days.ago,
last_seen_at: 2.days.ago,
),
deleted_at: Time.now,
).user
expect { described_class.new.execute({}) }.to change { User.count }.by(-1)
end
it "doesn't delete a user who has liked a post" do
SiteSetting.clean_up_inactive_users_after_days = 4
user =
Fabricate(
:user,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
Fabricate(:post_action, user: user, post_action_type_id: PostActionType.types[:like])
expect { described_class.new.execute({}) }.not_to change { User.count }
expect(User.exists?(user.id)).to eq(true)
end
it "deletes a user whose only like was on a deleted post" do
SiteSetting.clean_up_inactive_users_after_days = 4
user =
Fabricate(
:user,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
Fabricate(
:post_action,
user: user,
post_action_type_id: PostActionType.types[:like],
post: Fabricate(:post, deleted_at: Time.now),
)
expect { described_class.new.execute({}) }.to change { User.count }.by(-1)
expect(User.exists?(user.id)).to eq(false)
end
it "doesn't delete a user who has a bookmark" do
SiteSetting.clean_up_inactive_users_after_days = 4
user =
Fabricate(
:user,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
Fabricate(:bookmark, user: user)
expect { described_class.new.execute({}) }.not_to change { User.count }
expect(User.exists?(user.id)).to eq(true)
end
it "supports plugins extending eligibility via the clean_up_inactive_users_query modifier" do
SiteSetting.clean_up_inactive_users_after_days = 4
eligible_user =
Fabricate(
:user,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
protected_user =
Fabricate(
:user,
created_at: 5.days.ago,
last_seen_at: 5.days.ago,
trust_level: TrustLevel.levels[:newuser],
)
modifier_proc = Proc.new { |relation| relation.where.not(id: protected_user.id) }
plugin_instance = Plugin::Instance.new
plugin_instance.register_modifier(:clean_up_inactive_users_query, &modifier_proc)
begin
expect { described_class.new.execute({}) }.to change { User.count }.by(-1)
expect(User.exists?(eligible_user.id)).to eq(false)
expect(User.exists?(protected_user.id)).to eq(true)
ensure
DiscoursePluginRegistry.unregister_modifier(
plugin_instance,
:clean_up_inactive_users_query,
&modifier_proc
)
end
end
end