FIX: Move notification level only when user posted

FIX: Move notification level only when user posted

Moving posts also moves the read state (topic_users table) to the destination topic. This changes that behavior so that only users who posted in the destination topic will have the original notification level (probably “watching”) of the original topic. The notification level for all other users will be set to “regular”.

diff --git a/app/models/post_mover.rb b/app/models/post_mover.rb
index 7094f317a5..2cd39b80ae 100644
--- a/app/models/post_mover.rb
+++ b/app/models/post_mover.rb
@@ -318,7 +318,8 @@ class PostMover
       old_topic_id: original_topic.id,
       new_topic_id: destination_topic.id,
       old_highest_post_number: destination_topic.highest_post_number,
-      old_highest_staff_post_number: destination_topic.highest_staff_post_number
+      old_highest_staff_post_number: destination_topic.highest_staff_post_number,
+      default_notification_level: NotificationLevels.topic_levels[:regular]
     }
 
     DB.exec(<<~SQL, params)
@@ -327,12 +328,9 @@ class PostMover
                               notifications_changed_at, notifications_reason_id)
       SELECT tu.user_id,
              :new_topic_id                               AS topic_id,
-             EXISTS(
-                 SELECT 1
-                 FROM posts p
-                 WHERE p.topic_id = tu.topic_id
-                   AND p.user_id = tu.user_id
-               )                                         AS posted,
+             CASE
+               WHEN p.user_id IS NULL THEN FALSE
+               ELSE TRUE END                             AS posted,
              (
                SELECT MAX(lr.new_post_number)
                FROM moved_posts lr
@@ -353,11 +351,19 @@ class PostMover
              )                                           AS last_emailed_post_number,
              GREATEST(tu.first_visited_at, t.created_at) AS first_visited_at,
              GREATEST(tu.last_visited_at, t.created_at)  AS last_visited_at,
-             tu.notification_level,
+             CASE
+               WHEN p.user_id IS NOT NULL THEN tu.notification_level
+               ELSE :default_notification_level END      AS notification_level,
              tu.notifications_changed_at,
              tu.notifications_reason_id
       FROM topic_users tu
            JOIN topics t ON (t.id = :new_topic_id)
+           LEFT OUTER JOIN
+           (
+             SELECT DISTINCT user_id
+             FROM posts
+             WHERE topic_id = :new_topic_id
+           ) p ON (p.user_id = tu.user_id)
       WHERE tu.topic_id = :old_topic_id
         AND GREATEST(
                 tu.last_read_post_number,
diff --git a/spec/models/post_mover_spec.rb b/spec/models/post_mover_spec.rb
index 604fcc4154..78c1cc72ad 100644
--- a/spec/models/post_mover_spec.rb
+++ b/spec/models/post_mover_spec.rb
@@ -387,6 +387,13 @@ describe PostMover do
                 last_emailed_post_number: 3,
                 notification_level: :tracking
               )
+              create_topic_user(
+                user2,
+                last_read_post_number: 2,
+                highest_seen_post_number: 2,
+                last_emailed_post_number: 2,
+                notification_level: :tracking
+              )
               create_topic_user(
                 user3,
                 last_read_post_number: 1,
@@ -395,9 +402,10 @@ describe PostMover do
                 notification_level: :watching
               )
 
+              p2.update!(user_id: user2.id)
               new_topic = topic.move_posts(user, [p1.id, p2.id], title: "new testing topic name")
 
-              expect(TopicUser.where(topic_id: topic.id).count).to eq(3)
+              expect(TopicUser.where(topic_id: topic.id).count).to eq(4)
               expect(TopicUser.find_by(topic: topic, user: user))
                 .to have_attributes(
                       last_read_post_number: 4,
@@ -412,6 +420,13 @@ describe PostMover do
                       last_emailed_post_number: 3,
                       notification_level: TopicUser.notification_levels[:tracking]
                     )
+              expect(TopicUser.find_by(topic: topic, user: user2))
+                .to have_attributes(
+                      last_read_post_number: 2,
+                      highest_seen_post_number: 2,
+                      last_emailed_post_number: 2,
+                      notification_level: TopicUser.notification_levels[:tracking]
+                    )
               expect(TopicUser.find_by(topic: topic, user: user3))
                 .to have_attributes(
                       last_read_post_number: 1,
@@ -420,7 +435,7 @@ describe PostMover do
                       notification_level: TopicUser.notification_levels[:watching]
                     )
 
-              expect(TopicUser.where(topic_id: new_topic.id).count).to eq(3)
+              expect(TopicUser.where(topic_id: new_topic.id).count).to eq(4)
               expect(TopicUser.find_by(topic: new_topic, user: user))
                 .to have_attributes(
                       last_read_post_number: 1,
@@ -434,15 +449,23 @@ describe PostMover do
                       last_read_post_number: 2,
                       highest_seen_post_number: 2,
                       last_emailed_post_number: 2,
-                      notification_level: TopicUser.notification_levels[:tracking],
+                      notification_level: TopicUser.notification_levels[:regular],
                       posted: false
                     )
+              expect(TopicUser.find_by(topic: new_topic, user: user2))
+                .to have_attributes(
+                      last_read_post_number: 2,
+                      highest_seen_post_number: 2,
+                      last_emailed_post_number: 2,
+                      notification_level: TopicUser.notification_levels[:tracking],
+                      posted: true
+                    )
               expect(TopicUser.find_by(topic: new_topic, user: user3))
                 .to have_attributes(
                       last_read_post_number: 1,
                       highest_seen_post_number: 2,
                       last_emailed_post_number: 2,
-                      notification_level: TopicUser.notification_levels[:watching],
+                      notification_level: TopicUser.notification_levels[:regular],
                       posted: false
                     )
             end

GitHub sha: 2c011252

1 Like

This commit has been mentioned on Discourse Meta. There might be relevant details there: