FEATURE: ability to bulk_remove users from a group (#20876)
This commit is contained in:
parent
7afcb664fb
commit
9518e47204
|
@ -793,22 +793,26 @@ class Group < ActiveRecord::Base
|
||||||
group_user = self.group_users.find_by(user: user)
|
group_user = self.group_users.find_by(user: user)
|
||||||
return false if group_user.blank?
|
return false if group_user.blank?
|
||||||
|
|
||||||
has_webhooks = WebHook.active_web_hooks(:group_user)
|
|
||||||
payload =
|
|
||||||
WebHook.generate_payload(:group_user, group_user, WebHookGroupUserSerializer) if has_webhooks
|
|
||||||
group_user.destroy
|
group_user.destroy
|
||||||
trigger_user_removed_event(user)
|
trigger_user_removed_event(user)
|
||||||
if has_webhooks
|
enqueue_user_removed_from_group_webhook_events(group_user)
|
||||||
WebHook.enqueue_hooks(
|
|
||||||
:group_user,
|
|
||||||
:user_removed_from_group,
|
|
||||||
id: group_user.id,
|
|
||||||
payload: payload,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enqueue_user_removed_from_group_webhook_events(group_user)
|
||||||
|
return if !WebHook.active_web_hooks(:group_user)
|
||||||
|
|
||||||
|
payload = WebHook.generate_payload(:group_user, group_user, WebHookGroupUserSerializer)
|
||||||
|
|
||||||
|
WebHook.enqueue_hooks(
|
||||||
|
:group_user,
|
||||||
|
:user_removed_from_group,
|
||||||
|
id: group_user.id,
|
||||||
|
payload: payload,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def trigger_user_added_event(user, automatic)
|
def trigger_user_added_event(user, automatic)
|
||||||
DiscourseEvent.trigger(:user_added_to_group, user, self, automatic: automatic)
|
DiscourseEvent.trigger(:user_added_to_group, user, self, automatic: automatic)
|
||||||
end
|
end
|
||||||
|
@ -866,14 +870,7 @@ class Group < ActiveRecord::Base
|
||||||
User.where(id: user_ids).update_all(user_attributes) if user_attributes.present?
|
User.where(id: user_ids).update_all(user_attributes) if user_attributes.present?
|
||||||
|
|
||||||
# update group user count
|
# update group user count
|
||||||
DB.exec <<~SQL
|
recalculate_user_count
|
||||||
UPDATE groups g
|
|
||||||
SET user_count =
|
|
||||||
(SELECT COUNT(gu.user_id)
|
|
||||||
FROM group_users gu
|
|
||||||
WHERE gu.group_id = g.id)
|
|
||||||
WHERE g.id = #{self.id};
|
|
||||||
SQL
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.grant_trust_level.present?
|
if self.grant_trust_level.present?
|
||||||
|
@ -883,6 +880,31 @@ class Group < ActiveRecord::Base
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bulk_remove(user_ids)
|
||||||
|
Group.transaction do
|
||||||
|
group_users_to_be_destroyed = group_users.includes(:user).where(user_id: user_ids).destroy_all
|
||||||
|
group_users_to_be_destroyed.each do |group_user|
|
||||||
|
trigger_user_removed_event(group_user.user)
|
||||||
|
enqueue_user_removed_from_group_webhook_events(group_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
recalculate_user_count
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def recalculate_user_count
|
||||||
|
DB.exec <<~SQL
|
||||||
|
UPDATE groups g
|
||||||
|
SET user_count =
|
||||||
|
(SELECT COUNT(gu.user_id)
|
||||||
|
FROM group_users gu
|
||||||
|
WHERE gu.group_id = g.id)
|
||||||
|
WHERE g.id = #{self.id};
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
def add_automatically(user, subject: nil)
|
def add_automatically(user, subject: nil)
|
||||||
if users.exclude?(user) && add(user)
|
if users.exclude?(user) && add(user)
|
||||||
logger = GroupActionLogger.new(Discourse.system_user, self)
|
logger = GroupActionLogger.new(Discourse.system_user, self)
|
||||||
|
|
|
@ -864,6 +864,20 @@ RSpec.describe Group do
|
||||||
events = DiscourseEvent.track_events { group.remove(user) }.map { |e| e[:event_name] }
|
events = DiscourseEvent.track_events { group.remove(user) }.map { |e| e[:event_name] }
|
||||||
expect(events).to include(:user_removed_from_group)
|
expect(events).to include(:user_removed_from_group)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "with webhook" do
|
||||||
|
fab!(:group_user_web_hook) { Fabricate(:group_user_web_hook) }
|
||||||
|
|
||||||
|
it "Enqueues webhook events" do
|
||||||
|
group.remove(user)
|
||||||
|
job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first
|
||||||
|
|
||||||
|
expect(job_args["event_name"]).to eq("user_removed_from_group")
|
||||||
|
payload = JSON.parse(job_args["payload"])
|
||||||
|
expect(payload["group_id"]).to eq(group.id)
|
||||||
|
expect(payload["user_id"]).to eq(user.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#add" do
|
describe "#add" do
|
||||||
|
@ -994,7 +1008,45 @@ RSpec.describe Group do
|
||||||
expect {
|
expect {
|
||||||
group.bulk_add([user.id, admin.id])
|
group.bulk_add([user.id, admin.id])
|
||||||
group.reload
|
group.reload
|
||||||
}.to change { group.user_count }.by(2)
|
}.to change { group.user_count }.from(0).to(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#bulk_remove" do
|
||||||
|
it "removes multiple users from the group and doesn't error with user_ids not present" do
|
||||||
|
group.bulk_add([user.id, admin.id])
|
||||||
|
|
||||||
|
group.bulk_remove([user.id, admin.id, admin.id + 1])
|
||||||
|
|
||||||
|
expect(group.group_users.count).to be_zero
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates group user count" do
|
||||||
|
group.bulk_add([user.id, admin.id])
|
||||||
|
expect(group.reload.user_count).to eq(2)
|
||||||
|
|
||||||
|
group.bulk_remove([user.id, admin.id])
|
||||||
|
expect(group.reload.user_count).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "with webhook" do
|
||||||
|
fab!(:group_user_web_hook) { Fabricate(:group_user_web_hook) }
|
||||||
|
|
||||||
|
it "Enqueues user_removed_from_group webhook events for each group_user" do
|
||||||
|
group.bulk_add([user.id, admin.id])
|
||||||
|
|
||||||
|
group.bulk_remove([user.id, admin.id])
|
||||||
|
Jobs::EmitWebHookEvent
|
||||||
|
.jobs
|
||||||
|
.last(2)
|
||||||
|
.each do |event|
|
||||||
|
job_args = event["args"].first
|
||||||
|
expect(job_args["event_name"]).to eq("user_removed_from_group")
|
||||||
|
payload = JSON.parse(job_args["payload"])
|
||||||
|
expect(payload["group_id"]).to eq(group.id)
|
||||||
|
expect([user.id, admin.id]).to include(payload["user_id"])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue