From ec352a19697b26a9042bb236180963ed5af627ca Mon Sep 17 00:00:00 2001 From: Osama Sayegh Date: Thu, 19 Aug 2021 14:43:58 +0300 Subject: [PATCH] FEATURE: Order pinned topics by their `pinned_at` column (#14090) Currently, pinned topics are ordered by the `bumped_at` column. This behavior is not desired because it gives admins no control over the order of pinned topics. This PR makes pinned topics ordered by the `pinned_at` column. A topic that is pinned last appears first in topic lists. If an admin wants an already pinned topic to appear first in the list of pinned topics, they'll have to unpin that topic and pin it again. Meta topic: https://meta.discourse.org/t/how-do-i-set-the-order-of-pinned-topics/16935/23?u=osama. --- lib/topic_query.rb | 2 +- spec/components/topic_query_spec.rb | 57 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/lib/topic_query.rb b/lib/topic_query.rb index b2e2b0c9b9d..25362ab862f 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -390,7 +390,7 @@ class TopicQuery end unpinned_topics = topics.where("NOT ( #{pinned_clause} )") - pinned_topics = topics.dup.offset(nil).where(pinned_clause) + pinned_topics = topics.dup.offset(nil).where(pinned_clause).reorder(pinned_at: :desc) per_page = options[:per_page] || per_page_setting limit = per_page unless options[:limit] == false diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb index fd879b5f203..cd6595733ea 100644 --- a/spec/components/topic_query_spec.rb +++ b/spec/components/topic_query_spec.rb @@ -97,6 +97,63 @@ describe TopicQuery do page: 1) ).to eq(topics[per_page...num_topics]) end + + it "orders globally pinned topics by pinned_at rather than bumped_at" do + pinned1 = Fabricate( + :topic, + bumped_at: 3.hour.ago, + pinned_at: 1.hours.ago, + pinned_until: 10.days.from_now, + pinned_globally: true + ) + pinned2 = Fabricate( + :topic, + bumped_at: 2.hour.ago, + pinned_at: 4.hours.ago, + pinned_until: 10.days.from_now, + pinned_globally: true + ) + unpinned1 = Fabricate(:topic, bumped_at: 2.hour.ago) + unpinned2 = Fabricate(:topic, bumped_at: 3.hour.ago) + + topic_query = TopicQuery.new(user) + results = topic_query.send(:default_results) + + expected_order = [pinned1, pinned2, unpinned1, unpinned2].map(&:id) + expect(topic_query + .prioritize_pinned_topics(results, per_page: 10, page: 0) + .pluck(:id) + ).to eq(expected_order) + end + + it "orders pinned topics within a category by pinned_at rather than bumped_at" do + cat = Fabricate(:category) + pinned1 = Fabricate( + :topic, + category: cat, + bumped_at: 3.hour.ago, + pinned_at: 1.hours.ago, + pinned_until: 10.days.from_now, + ) + pinned2 = Fabricate( + :topic, + category: cat, + bumped_at: 2.hour.ago, + pinned_at: 4.hours.ago, + pinned_until: 10.days.from_now, + ) + unpinned1 = Fabricate(:topic, category: cat, bumped_at: 2.hour.ago) + unpinned2 = Fabricate(:topic, category: cat, bumped_at: 3.hour.ago) + + topic_query = TopicQuery.new(user) + results = topic_query.send(:default_results) + + expected_order = [pinned1, pinned2, unpinned1, unpinned2].map(&:id) + expect(topic_query + .prioritize_pinned_topics(results, per_page: 10, page: 0, category_id: cat.id) + .pluck(:id) + ).to eq(expected_order) + end end context 'bookmarks' do