discourse/spec/lib/group_manager_spec.rb
Bannon Tanner 0acfe07701
PERF: Add Users to Group Improvements Pt. 2 (#38901)
Pt. 2 of the performance update to group add/remove users, building on
#38737

This PR moves the bulk_add/remove logic from the `Group` model into
`GroupManager`, making `GroupManager` the single owner of membership
mutation logic. `Group#bulk_add` and `Group#bulk_remove` become thin
delegators.

The controller's per-user `add_user_to_group` loop is replaced with a
single bulk `add_users_to_group` call. `GroupActionLogger` gets
`bulk_log_add_users_to_group` / `bulk_log_remove_users_from_group`
backed by `insert_all`. `DiscourseConnect` routes through `GroupManager`
instead of raw `GroupUser.create!/destroy_all`

Also moves notifications for adding users to a group to a background
job, as that was running synchronously and causing performance issues
when `notify_users: true`

There will be a Pt. 3 (#39091) that updates all callers using some
variation of `GroupUser.create` and removes callbacks from `GroupUser`
2026-04-06 09:31:50 -05:00

39 lines
1 KiB
Ruby

# frozen_string_literal: true
RSpec.describe GroupManager do
fab!(:group)
fab!(:user)
fab!(:user2, :user)
subject(:manager) { GroupManager.new(group) }
describe "#add" do
it "adds users to group and returns added user IDs" do
result = manager.add([user.id, user2.id])
expect(result).to contain_exactly(user.id, user2.id)
expect(group.group_users.map(&:user_id)).to contain_exactly(user.id, user2.id)
end
it "returns empty array for blank input" do
expect(manager.add([])).to eq([])
expect(manager.add(nil)).to eq([])
end
end
describe "#remove" do
before { manager.add([user.id, user2.id]) }
it "removes users from group and returns removed user IDs" do
result = manager.remove([user.id, user2.id])
expect(result).to contain_exactly(user.id, user2.id)
expect(group.group_users.count).to eq(0)
end
it "returns empty array for blank input" do
expect(manager.remove([])).to eq([])
expect(manager.remove(nil)).to eq([])
end
end
end