FIX: unassign/assign when group pm is archived (#192)

FIX: unassign/assign when group pm is archived (#192)

Send correct messages and correctly unassign/assign to user/group if group PM is archived or moved back to inbox.

diff --git a/plugin.rb b/plugin.rb
index c2c4dd9..8c0c027 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -66,6 +66,8 @@ after_initialize do
   frequency_field = PendingAssignsReminder::REMINDERS_FREQUENCY
   register_editable_user_custom_field frequency_field
   User.register_custom_field_type frequency_field, :integer
+  Topic.register_custom_field_type "prev_assigned_to_id", :integer
+  Topic.register_custom_field_type "prev_assigned_to_type", :string
   DiscoursePluginRegistry.serialized_current_user_fields << frequency_field
   add_to_serializer(:user, :reminders_frequency) do
     RemindAssignsFrequencySiteSettings.values
@@ -535,13 +537,19 @@ after_initialize do
   )
 
   # TopicTrackingState
-  add_class_method(:topic_tracking_state, :publish_assigned_private_message) do |topic, user_id|
+  add_class_method(:topic_tracking_state, :publish_assigned_private_message) do |topic, assignee|
     return unless topic.private_message?
+    opts =
+      if assignee.is_a?(User)
+        { user_ids: [assignee.id] }
+      else
+        { group_ids: [assignee.id] }
+      end
 
     MessageBus.publish(
       "/private-messages/assigned",
       { topic_id: topic.id },
-      user_ids: [user_id]
+      opts
     )
   end
 
@@ -563,12 +571,8 @@ after_initialize do
 
   on(:move_to_inbox) do |info|
     topic = info[:topic]
-    assigned_to_id = topic.assignment&.assigned_to_id
-    assigned_to_type = topic.assignment&.assigned_to_type
 
-    if info[:user]&.id == assigned_to_id && assigned_to_type == "User"
-      TopicTrackingState.publish_assigned_private_message(topic, assigned_to_id)
-    end
+    TopicTrackingState.publish_assigned_private_message(topic, topic.assignment.assigned_to) if topic.assignment
 
     next if !SiteSetting.unassign_on_group_archive
     next if !info[:group]
@@ -584,30 +588,27 @@ after_initialize do
       assigner = TopicAssigner.new(topic, Discourse.system_user)
       assigner.assign(previous_assigned_to, silent: true)
     end
+
+    topic.custom_fields.delete("prev_assigned_to_id")
+    topic.custom_fields.delete("prev_assigned_to_type")
+    topic.save!
   end
 
   on(:archive_message) do |info|
     topic = info[:topic]
     next if !topic.assignment
 
-    assigned_to_id = topic.assignment.assigned_to_id
-    assigned_to_type = topic.assignment.assigned_to_type
-
-    if info[:user]&.id == assigned_to_id && assigned_to_type == "User"
-      TopicTrackingState.publish_assigned_private_message(topic, assigned_to_id)
-    end
+    TopicTrackingState.publish_assigned_private_message(topic, topic.assignment.assigned_to)
 
     next if !SiteSetting.unassign_on_group_archive
     next if !info[:group]
 
-    if assigned_to = topic.assignment
-      topic.custom_fields["prev_assigned_to_id"] = assigned_to.id
-      topic.custom_fields["prev_assigned_to_type"] = assigned_to.class
-      topic.save!
+    topic.custom_fields["prev_assigned_to_id"] = topic.assignment.assigned_to_id
+    topic.custom_fields["prev_assigned_to_type"] = topic.assignment.assigned_to_type
+    topic.save!
 
-      assigner = TopicAssigner.new(topic, Discourse.system_user)
-      assigner.unassign(silent: true)
-    end
+    assigner = TopicAssigner.new(topic, Discourse.system_user)
+    assigner.unassign(silent: true)
   end
 
   on(:user_removed_from_group) do |user, group|
diff --git a/spec/integration/assign_spec.rb b/spec/integration/assign_spec.rb
index 0a6d417..7cc1218 100644
--- a/spec/integration/assign_spec.rb
+++ b/spec/integration/assign_spec.rb
@@ -23,15 +23,18 @@ describe 'integration tests' do
     let(:user) { pm.allowed_users.first }
     let(:user2) { pm.allowed_users.last }
     let(:channel) { "/private-messages/assigned" }
+    fab!(:group) { Fabricate(:group, assignable_level: Group::ALIAS_LEVELS[:everyone]) }
 
     include_context 'A group that is allowed to assign'
 
     before do
       add_to_assign_allowed_group(user)
       add_to_assign_allowed_group(user2)
+      group.add(user)
+      group.add(user2)
     end
 
-    def assert_publish_topic_state(topic, user)
+    def assert_publish_topic_state(topic, user: nil, group: nil)
       messages = MessageBus.track_publish do
         yield
       end
@@ -39,21 +42,65 @@ describe 'integration tests' do
       message = messages.find { |m| m.channel == channel }
 
       expect(message.data[:topic_id]).to eq(topic.id)
-      expect(message.user_ids).to eq([user.id])
+      expect(message.user_ids).to eq([user.id]) if user
+      expect(message.group_ids).to eq([group.id]) if group
     end
 
     it 'publishes the right message on archive and move to inbox' do
       assigner = TopicAssigner.new(pm, user)
       assigner.assign(user)
 
-      assert_publish_topic_state(pm, user) do
+      assert_publish_topic_state(pm, user: user) do
         UserArchivedMessage.archive!(user.id, pm.reload)
       end
 
-      assert_publish_topic_state(pm, user) do
+      assert_publish_topic_state(pm, user: user) do
         UserArchivedMessage.move_to_inbox!(user.id, pm.reload)
       end
     end
+
+    it 'publishes the right message on archive and move to inbox for groups' do
+      assigner = TopicAssigner.new(pm, user)
+      assigner.assign(group)
+
+      assert_publish_topic_state(pm, group: group) do
+        GroupArchivedMessage.archive!(group.id, pm.reload)
+      end
+
+      assert_publish_topic_state(pm, group: group) do
+        GroupArchivedMessage.move_to_inbox!(group.id, pm.reload)
+      end
+    end
+
+    it "unassign and assign user if unassign_on_group_archive" do
+      SiteSetting.unassign_on_group_archive = true
+      assigner = TopicAssigner.new(pm, user)
+      assigner.assign(user)
+
+      GroupArchivedMessage.archive!(group.id, pm.reload)
+      expect(pm.assignment).to eq(nil)
+      expect(pm.custom_fields["prev_assigned_to_id"]).to eq(user.id)
+      expect(pm.custom_fields["prev_assigned_to_type"]).to eq("User")
+
+      GroupArchivedMessage.move_to_inbox!(group.id, pm.reload)
+      expect(pm.assignment.assigned_to).to eq(user)
+      expect(pm.custom_fields["prev_assigned_to_id"]).to eq(nil)
+      expect(pm.custom_fields["prev_assigned_to_type"]).to eq(nil)
+    end
+
+    it "unassign and assign group if unassign_on_group_archive" do
+      SiteSetting.unassign_on_group_archive = true
+      assigner = TopicAssigner.new(pm, user)
+      assigner.assign(group)
+
+      GroupArchivedMessage.archive!(group.id, pm.reload)
+      expect(pm.assignment).to eq(nil)
+      expect(pm.custom_fields["prev_assigned_to_id"]).to eq(group.id)
+      expect(pm.custom_fields["prev_assigned_to_type"]).to eq("Group")
+
+      GroupArchivedMessage.move_to_inbox!(group.id, pm.reload)
+      expect(pm.assignment.assigned_to).to eq(group)
+    end
   end
 
   describe "on assign_topic event" do

GitHub sha: ab9e6f0684102dbb1e1f68d2c3b8bca332a2c8df

This commit appears in #192 which was approved by martin and tgxworld. It was merged by lis2.