FIX: Publish web hooks when topic archetype is converted.

FIX: Publish web hooks when topic archetype is converted.

diff --git a/app/models/topic.rb b/app/models/topic.rb
index 317b9c1..f7ee82e 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -1402,6 +1402,14 @@ class Topic < ActiveRecord::Base
     scores[0] >= SiteSetting.num_flaggers_to_close_topic && scores[1] >= SiteSetting.score_to_auto_close_topic
   end
 
+  def update_category_topic_count_by(num)
+    if category_id.present?
+      Category
+        .where(['id = ?', category_id])
+        .update_all("topic_count = topic_count " + (num > 0 ? '+' : '') + "#{num}")
+    end
+  end
+
   private
 
   def invite_to_private_message(invited_by, target_user, guardian)
@@ -1453,12 +1461,6 @@ class Topic < ActiveRecord::Base
     end
   end
 
-  def update_category_topic_count_by(num)
-    if category_id.present?
-      Category.where(['id = ?', category_id]).update_all("topic_count = topic_count " + (num > 0 ? '+' : '') + "#{num}")
-    end
-  end
-
   def limit_first_day_topics_per_day
     apply_per_day_rate_limit_for("first-day-topics", :max_topics_in_first_day)
   end
diff --git a/app/models/topic_converter.rb b/app/models/topic_converter.rb
index 038f50c..8862d29 100644
--- a/app/models/topic_converter.rb
+++ b/app/models/topic_converter.rb
@@ -9,7 +9,7 @@ class TopicConverter
 
   def convert_to_public_topic(category_id = nil)
     Topic.transaction do
-      @topic.category_id =
+      category_id =
         if category_id
           category_id
         elsif SiteSetting.allow_uncategorized_topics
@@ -21,10 +21,15 @@ class TopicConverter
             .pluck(:id).first
         end
 
-      @topic.archetype = Archetype.default
-      @topic.save
+      PostRevisor.new(@topic.first_post, @topic).revise!(
+        @user,
+        {
+          category_id: category_id,
+          archetype: Archetype.default
+        }
+      )
+
       update_user_stats
-      update_category_topic_count_by(1)
       Jobs.enqueue(:topic_action_converter, topic_id: @topic.id)
 
       watch_topic(topic)
@@ -34,11 +39,18 @@ class TopicConverter
 
   def convert_to_private_message
     Topic.transaction do
-      update_category_topic_count_by(-1)
-      @topic.category_id = nil
-      @topic.archetype = Archetype.private_message
+      @topic.update_category_topic_count_by(-1)
+
+      PostRevisor.new(@topic.first_post, @topic).revise!(
+        @user,
+        {
+          category_id: nil,
+          archetype: Archetype.private_message
+        }
+      )
+
       add_allowed_users
-      @topic.save!
+
       Jobs.enqueue(:topic_action_converter, topic_id: @topic.id)
       watch_topic(topic)
     end
@@ -71,6 +83,7 @@ class TopicConverter
     # update topics count
     @topic.user.user_stat.topic_count -= 1
     @topic.user.user_stat.save!
+    @topic.save!
   end
 
   def watch_topic(topic)
@@ -82,10 +95,4 @@ class TopicConverter
     end
   end
 
-  def update_category_topic_count_by(num)
-    if @topic.category_id.present?
-      Category.where(['id = ?', @topic.category_id]).update_all("topic_count = topic_count " + (num > 0 ? '+' : '') + "#{num}")
-    end
-  end
-
 end
diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb
index adb9382..a904158 100644
--- a/lib/post_revisor.rb
+++ b/lib/post_revisor.rb
@@ -63,13 +63,18 @@ class PostRevisor
   end
 
   # Fields we want to record revisions for by default
-  track_topic_field(:title) do |tc, title|
-    tc.record_change('title', tc.topic.title, title)
-    tc.topic.title = title
+  %i{title archetype}.each do |field|
+    track_topic_field(field) do |tc, attribute|
+      tc.record_change(field, tc.topic.public_send(field), attribute)
+      tc.topic.public_send("#{field}=", attribute)
+    end
   end
 
   track_topic_field(:category_id) do |tc, category_id|
-    if category_id == 0 || tc.guardian.can_move_topic_to_category?(category_id)
+    if category_id == 0 && tc.topic.private_message?
+      tc.record_change('category_id', tc.topic.category_id, nil)
+      tc.topic.category_id = nil
+    elsif category_id == 0 || tc.guardian.can_move_topic_to_category?(category_id)
       tc.record_change('category_id', tc.topic.category_id, category_id)
       tc.check_result(tc.topic.change_category_to_id(category_id))
     end
diff --git a/spec/models/topic_converter_spec.rb b/spec/models/topic_converter_spec.rb
index 2421b23..f25b26a 100644
--- a/spec/models/topic_converter_spec.rb
+++ b/spec/models/topic_converter_spec.rb
@@ -10,16 +10,23 @@ describe TopicConverter do
     let(:first_post) { create_post(user: author, topic: private_message) }
     let(:other_user) { private_message.topic_allowed_users.find { |u| u.user != author }.user }
 
+    let(:uncategorized_category) do
+      Category.find(SiteSetting.uncategorized_category_id)
+    end
+
     context 'success' do
       it "converts private message to regular topic" do
         SiteSetting.allow_uncategorized_topics = true
-        topic = TopicConverter.new(private_message, admin).convert_to_public_topic
-        topic.reload
+        topic = nil
+
+        expect do
+          topic = TopicConverter.new(first_post.topic, admin).convert_to_public_topic
+          topic.reload
+        end.to change { uncategorized_category.reload.topic_count }.by(1)
 
         expect(topic).to be_valid
         expect(topic.archetype).to eq("regular")
         expect(topic.category_id).to eq(SiteSetting.uncategorized_category_id)
-        expect(topic.category.topic_count).to eq(1)
       end
 
       describe 'when uncategorized category is not allowed' do
@@ -29,7 +36,7 @@ describe TopicConverter do
         end
 
         it 'should convert private message into the right category' do
-          topic = TopicConverter.new(private_message, admin).convert_to_public_topic
+          topic = TopicConverter.new(first_post.topic, admin).convert_to_public_topic
           topic.reload
 
           expect(topic).to be_valid
@@ -45,7 +52,7 @@ describe TopicConverter do
 
       describe 'when a custom category_id is given' do
         it 'should convert private message into the right category' do
-          topic = TopicConverter.new(private_message, admin).convert_to_public_topic(category.id)
+          topic = TopicConverter.new(first_post.topic, admin).convert_to_public_topic(category.id)
 
           expect(topic.reload.category).to eq(category)
           expect(topic.category.topic_count).to eq(2)
@@ -89,6 +96,7 @@ describe TopicConverter do
     let(:author) { Fabricate(:user) }
     let(:category) { Fabricate(:category) }
     let(:topic) { Fabricate(:topic, user: author, category_id: category.id) }
+    let!(:post) { Fabricate(:post, topic: topic) }
 
     context 'success' do
       it "converts regular topic to private message" do
@@ -142,9 +150,9 @@ describe TopicConverter do
       end
 
       it "works" do
-        private_message = topic.convert_to_private_message(admin)
-        expect(private_message).to be_valid
-        expect(topic.archetype).to eq("private_message")
+        topic.convert_to_private_message(admin)
+
+        expect(topic.reload.archetype).to eq("private_message")
       end
     end
   end

GitHub sha: 1056dd16

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