FIX: Staff users can accept posts in deleted topics. (#75)

FIX: Staff users can accept posts in deleted topics. (#75)

diff --git a/plugin.rb b/plugin.rb
index 4f76f18..27eaae3 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -73,8 +73,8 @@ SQL
 
     AUTO_CLOSE_TOPIC_TIMER_CUSTOM_FIELD = "solved_auto_close_topic_timer_id".freeze
 
-    def self.accept_answer!(post, acting_user)
-      topic = post.topic
+    def self.accept_answer!(post, acting_user, topic: nil)
+      topic ||= post.topic
       accepted_id = topic.custom_fields["accepted_answer_post_id"].to_i
 
       if accepted_id > 0
@@ -140,10 +140,10 @@ SQL
       DiscourseEvent.trigger(:accepted_solution, post)
     end
 
-    def self.unaccept_answer!(post)
+    def self.unaccept_answer!(post, topic: nil)
+      topic ||= post.topic
       post.custom_fields["is_accepted_answer"] = nil
-      post.topic.custom_fields["accepted_answer_post_id"] = nil
-      topic = post.topic
+      topic.custom_fields["accepted_answer_post_id"] = nil
 
       if timer_id = topic.custom_fields[AUTO_CLOSE_TOPIC_TIMER_CUSTOM_FIELD]
         topic_timer = TopicTimer.find_by(id: timer_id)
@@ -183,9 +183,13 @@ SQL
       limit_accepts
 
       post = Post.find(params[:id].to_i)
-      guardian.ensure_can_accept_answer!(post.topic)
 
-      DiscourseSolved.accept_answer!(post, current_user)
+      topic = post.topic
+      topic ||= Topic.with_deleted.find(post.topic_id) if guardian.is_staff?
+
+      guardian.ensure_can_accept_answer!(topic)
+
+      DiscourseSolved.accept_answer!(post, current_user, topic: topic)
 
       render json: success_json
     end
@@ -195,9 +199,13 @@ SQL
       limit_accepts
 
       post = Post.find(params[:id].to_i)
-      guardian.ensure_can_accept_answer!(post.topic)
 
-      DiscourseSolved.unaccept_answer!(post)
+      topic = post.topic
+      topic ||= Topic.with_deleted.find(post.topic_id) if guardian.is_staff?
+
+      guardian.ensure_can_accept_answer!(topic)
+
+      DiscourseSolved.unaccept_answer!(post, topic: topic)
       render json: success_json
     end
 
@@ -399,7 +407,7 @@ SQL
     end
 
     def can_accept_answer?(topic)
-      allow_accepted_answers_on_category?(topic.category_id) && (
+      topic && allow_accepted_answers_on_category?(topic.category_id) && (
         is_staff? || (
           authenticated? && ((!topic.closed? && topic.user_id == current_user.id) ||
                             (current_user.trust_level >= SiteSetting.accept_all_solutions_trust_level))
diff --git a/spec/integration/solved_spec.rb b/spec/integration/solved_spec.rb
index d6a829b..856bce0 100644
--- a/spec/integration/solved_spec.rb
+++ b/spec/integration/solved_spec.rb
@@ -74,6 +74,20 @@ RSpec.describe "Managing Posts solved status" do
       expect(topic.public_topic_timer).to eq(nil)
       expect(topic.closed).to eq(true)
     end
+
+    it 'works with staff and trashed topics' do
+      topic.trash!(Discourse.system_user)
+
+      post "/solution/accept.json", params: { id: p1.id }
+      expect(response.status).to eq(403)
+
+      sign_in(Fabricate(:admin))
+      post "/solution/accept.json", params: { id: p1.id }
+      expect(response.status).to eq(200)
+
+      p1.reload
+      expect(p1.custom_fields["is_accepted_answer"]).to eq("true")
+    end
   end
 
   describe '#unaccept' do
diff --git a/spec/serializers/topic_answer_mixin_spec.rb b/spec/serializers/topic_answer_mixin_spec.rb
index f0c785a..ec92b98 100644
--- a/spec/serializers/topic_answer_mixin_spec.rb
+++ b/spec/serializers/topic_answer_mixin_spec.rb
@@ -20,5 +20,5 @@ describe TopicAnswerMixin do
       json = serializer.new(topic, scope: guardian, root: false).as_json
       expect(json[:has_accepted_answer]).to be_truthy
     end
-  end  
+  end
 end

GitHub sha: 3297d152

1 Like