From 9e9ac2862cb73c785a6ac0ba7803558587ebab86 Mon Sep 17 00:00:00 2001 From: Natalie Tay Date: Thu, 27 Mar 2025 01:15:15 +0800 Subject: [PATCH] FIX: Some solved topics have no answers (#350) As part of https://github.com/discourse/discourse-solved/pull/342, some discrepancies in the old implementation resulted in solved topics linking to posts that do not exist (dangling custom field value). Causing us to see the following when there are no `answer_post` ``` NoMethodError (undefined method `user' for nil) ``` This PR prevents the error. --- .../topic_view_serializer_extension.rb | 3 +- .../serializers/topic_view_serializer_spec.rb | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 spec/serializers/topic_view_serializer_spec.rb diff --git a/lib/discourse_solved/topic_view_serializer_extension.rb b/lib/discourse_solved/topic_view_serializer_extension.rb index 9cf41ee..cadfb49 100644 --- a/lib/discourse_solved/topic_view_serializer_extension.rb +++ b/lib/discourse_solved/topic_view_serializer_extension.rb @@ -6,7 +6,8 @@ module DiscourseSolved::TopicViewSerializerExtension prepended { attributes :accepted_answer } def include_accepted_answer? - SiteSetting.solved_enabled? && object.topic.solved.present? + SiteSetting.solved_enabled? && object.topic.solved.present? && + object.topic.solved.answer_post.present? end def accepted_answer diff --git a/spec/serializers/topic_view_serializer_spec.rb b/spec/serializers/topic_view_serializer_spec.rb new file mode 100644 index 0000000..b333214 --- /dev/null +++ b/spec/serializers/topic_view_serializer_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +describe TopicViewSerializer do + fab!(:topic) + fab!(:post1) { Fabricate(:post, topic:) } + fab!(:post2) { Fabricate(:post, topic:) } + fab!(:user) + + before { SiteSetting.solved_enabled = true } + + describe "#accepted_answer" do + it "returns the accepted answer post when the topic has an accepted answer" do + Fabricate(:solved_topic, topic: topic, answer_post: post2) + serializer = TopicViewSerializer.new(TopicView.new(topic), scope: Guardian.new(user)) + serialized = serializer.as_json + expect(serialized[:topic_view][:accepted_answer][:post_number]).to eq(post2.post_number) + end + + it "returns nil when the topic does not have an accepted answer" do + unsolved_topic = Fabricate(:topic) + serializer = TopicViewSerializer.new(TopicView.new(unsolved_topic), scope: Guardian.new(user)) + serialized = serializer.as_json + expect(serialized[:accepted_answer]).to be_nil + end + + it "returns nil when the accepted answer post does not exist" do + weird_topic = Fabricate(:solved_topic) + weird_topic.update!(answer_post_id: 19_238_319) + serializer = + TopicViewSerializer.new(TopicView.new(weird_topic.topic), scope: Guardian.new(user)) + serialized = serializer.as_json + expect(serialized[:accepted_answer]).to be_nil + end + end +end