diff --git a/lib/assigner.rb b/lib/assigner.rb index eecf536a..f18b5867 100644 --- a/lib/assigner.rb +++ b/lib/assigner.rb @@ -195,7 +195,7 @@ def first_post topic.posts.where(post_number: 1).first end - def forbidden_reasons(assign_to:, type:, note:, status:) + def forbidden_reasons(assign_to:, type:, note:, status:, allow_self_reassign:) case when assign_to.is_a?(User) && !can_assignee_see_target?(assign_to) if topic.private_message? @@ -211,7 +211,7 @@ def forbidden_reasons(assign_to:, type:, note:, status:) end when !can_be_assigned?(assign_to) assign_to.is_a?(User) ? :forbidden_assign_to : :forbidden_group_assign_to - when already_assigned?(assign_to, type, note, status) + when !allow_self_reassign && already_assigned?(assign_to, type, note, status) assign_to.is_a?(User) ? :already_assigned : :group_already_assigned when Assignment.where(topic: topic, active: true).count >= ASSIGNMENTS_PER_TOPIC_LIMIT && !reassign? @@ -252,7 +252,13 @@ def update_details(assign_to, note, status, skip_small_action_post: false) { success: true } end - def assign(assign_to, note: nil, skip_small_action_post: false, status: nil) + def assign( + assign_to, + note: nil, + skip_small_action_post: false, + status: nil, + allow_self_reassign: false + ) assigned_to_type = assign_to.is_a?(User) ? "User" : "Group" if topic.private_message? && SiteSetting.invite_on_assign @@ -260,7 +266,13 @@ def assign(assign_to, note: nil, skip_small_action_post: false, status: nil) end forbidden_reason = - forbidden_reasons(assign_to: assign_to, type: assigned_to_type, note: note, status: status) + forbidden_reasons( + assign_to: assign_to, + type: assigned_to_type, + note: note, + status: status, + allow_self_reassign: allow_self_reassign, + ) return { success: false, reason: forbidden_reason } if forbidden_reason if no_assignee_change?(assign_to) && details_change?(note, status) @@ -271,7 +283,8 @@ def assign(assign_to, note: nil, skip_small_action_post: false, status: nil) action_code[:user] = topic.assignment.present? ? "reassigned" : "assigned" action_code[:group] = topic.assignment.present? ? "reassigned_group" : "assigned_group" - skip_small_action_post = skip_small_action_post || no_assignee_change?(assign_to) + skip_small_action_post = + skip_small_action_post || (!allow_self_reassign && no_assignee_change?(assign_to)) if @target.assignment Jobs.enqueue( diff --git a/lib/random_assign_utils.rb b/lib/random_assign_utils.rb index badfacd4..470f96af 100644 --- a/lib/random_assign_utils.rb +++ b/lib/random_assign_utils.rb @@ -87,7 +87,7 @@ def assign_user! return create_post_template if post_template Assigner .new(topic, Discourse.system_user) - .assign(assigned_user) + .assign(assigned_user, allow_self_reassign: true) .then do |result| next if result[:success] no_one! @@ -104,7 +104,7 @@ def create_post_template ).create! Assigner .new(post, Discourse.system_user) - .assign(assigned_user) + .assign(assigned_user, allow_self_reassign: true) .then do |result| next if result[:success] PostDestroyer.new(Discourse.system_user, post).destroy diff --git a/spec/lib/assigner_spec.rb b/spec/lib/assigner_spec.rb index 265661ef..fb2b8f58 100644 --- a/spec/lib/assigner_spec.rb +++ b/spec/lib/assigner_spec.rb @@ -264,33 +264,47 @@ def assigned_to?(assignee) expect(second_assign[:success]).to eq(true) end - it "fails to assign when the assigned user and note is the same" do - assigner = described_class.new(topic, moderator_2) - assigner.assign(moderator, note: "note me down") + context "when 'allow_self_reassign' is false" do + subject(:assign) do + assigner.assign(moderator, note: other_note, allow_self_reassign: self_reassign) + end - assign = assigner.assign(moderator, note: "note me down") + let(:self_reassign) { false } + let(:assigner) { described_class.new(topic, moderator_2) } + let(:note) { "note me down" } - expect(assign[:success]).to eq(false) - expect(assign[:reason]).to eq(:already_assigned) - end + before { assigner.assign(moderator, note: note) } - it "fails to assign when the assigned user and note is the same" do - assigner = described_class.new(post, moderator_2) - assigner.assign(moderator, note: "note me down") + context "when the assigned user and the note is the same" do + let(:other_note) { note } - assign = assigner.assign(moderator, note: "note me down") + it "fails to assign" do + expect(assign).to match(success: false, reason: :already_assigned) + end + end - expect(assign[:success]).to eq(false) - expect(assign[:reason]).to eq(:already_assigned) + context "when the assigned user is the same but the note is different" do + let(:other_note) { "note me down again" } + + it "allows assignment" do + expect(assign).to match(success: true) + end + end end - it "allows assign when the assigned user is same but note is different" do - assigner = described_class.new(topic, moderator_2) - assigner.assign(moderator, note: "note me down") + context "when 'allow_self_reassign' is true" do + subject(:assign) { assigner.assign(moderator, allow_self_reassign: self_reassign) } - assign = assigner.assign(moderator, note: "note me down again") + let(:self_reassign) { true } + let(:assigner) { described_class.new(topic, moderator_2) } - expect(assign[:success]).to eq(true) + context "when the assigned user is the same" do + before { assigner.assign(moderator) } + + it "allows assignment" do + expect(assign).to match(success: true) + end + end end it "fails to assign when the assigned user cannot view the pm" do diff --git a/spec/lib/random_assign_utils_spec.rb b/spec/lib/random_assign_utils_spec.rb index 5e70ed49..6c99d168 100644 --- a/spec/lib/random_assign_utils_spec.rb +++ b/spec/lib/random_assign_utils_spec.rb @@ -182,6 +182,28 @@ end end + context "when in a group of one person" do + let(:fields) do + { + "assignees_group" => { + "value" => group_1.id, + }, + "assigned_topic" => { + "value" => topic_1.id, + }, + } + end + + context "when user is already assigned" do + before { described_class.automation_script!(ctx, fields, automation) } + + it "reassigns them" do + expect { auto_assign }.to change { topic_1.reload.assignment.id } + expect(topic_1.assignment.assigned_to).to eq(user_1) + end + end + end + context "when assignees_group is not provided" do let(:fields) { { "assigned_topic" => { "value" => topic_1.id } } }