From c859e41650965abcf8eeaf29015d30656f40b5fb Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 6 Jun 2025 23:32:03 +0800 Subject: [PATCH] FIX: User directory for solutions should update when value changes from positive to zero --- plugin.rb | 35 +++++++++++++++--------------- spec/models/directory_item_spec.rb | 27 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/plugin.rb b/plugin.rb index 13f51a0..c3c7cb5 100644 --- a/plugin.rb +++ b/plugin.rb @@ -291,23 +291,24 @@ after_initialize do query = <<~SQL WITH x AS ( - SELECT p.user_id, COUNT(DISTINCT st.id) AS solutions - FROM discourse_solved_solved_topics AS st - JOIN posts AS p - ON p.id = st.answer_post_id - AND COALESCE(st.created_at, :since) > :since - AND p.deleted_at IS NULL - JOIN topics AS t - ON t.id = st.topic_id - AND t.archetype <> 'private_message' - AND t.deleted_at IS NULL - JOIN users AS u - ON u.id = p.user_id - WHERE u.id > 0 - AND u.active - AND u.silenced_till IS NULL - AND u.suspended_till IS NULL - GROUP BY p.user_id + SELECT users.id AS user_id, + COUNT(DISTINCT CASE WHEN + st.topic_id IS NOT NULL AND + t.id IS NOT NULL AND + t.archetype <> 'private_message' AND + t.deleted_at IS NULL AND + p.deleted_at IS NULL + THEN st.topic_id ELSE NULL END) AS solutions + FROM users + LEFT JOIN posts p ON p.user_id = users.id + LEFT JOIN discourse_solved_solved_topics st + ON st.answer_post_id = p.id + AND st.created_at >= :since + LEFT JOIN topics t ON t.id = st.topic_id + WHERE users.active + AND users.silenced_till IS NULL + AND users.suspended_till IS NULL + GROUP BY users.id ) UPDATE directory_items di SET solutions = x.solutions diff --git a/spec/models/directory_item_spec.rb b/spec/models/directory_item_spec.rb index 7e2034c..7b72585 100644 --- a/spec/models/directory_item_spec.rb +++ b/spec/models/directory_item_spec.rb @@ -101,5 +101,32 @@ describe DirectoryItem, type: :model do ).solutions, ).to eq(1) end + + context "when refreshing across dates" do + it "updates the user's solution count from 1 to 0" do + freeze_time 40.days.ago + DiscourseSolved.accept_answer!(topic_post1, Discourse.system_user) + + DirectoryItem.refresh! + + expect( + DirectoryItem.find_by( + user_id: user.id, + period_type: DirectoryItem.period_types[:monthly], + ).solutions, + ).to eq(1) + + unfreeze_time + + DirectoryItem.refresh! + + expect( + DirectoryItem.find_by( + user_id: user.id, + period_type: DirectoryItem.period_types[:monthly], + ).solutions, + ).to eq(0) + end + end end end