FIX: Apply category priority for empty query (#9516)

FIX: Apply category priority for empty query (#9516)

diff --git a/lib/search.rb b/lib/search.rb
index ead773d..e1c6509 100644
--- a/lib/search.rb
+++ b/lib/search.rb
@@ -904,13 +904,37 @@ class Search
         posts = categories_ignored(posts) unless @category_filter_matched
         posts
       end
-
-    if @order == :latest || (@term.blank? && !@order)
+    if @order == :latest
       if opts[:aggregate_search]
         posts = posts.order("MAX(posts.created_at) DESC")
       else
         posts = posts.reorder("posts.created_at DESC")
       end
+    elsif @term.blank? && !@order
+      data_ranking = <<~SQL
+      (
+        CASE categories.search_priority
+        WHEN #{Searchable::PRIORITIES[:very_low]}
+        THEN #{SiteSetting.category_search_priority_very_low_weight}
+        WHEN #{Searchable::PRIORITIES[:low]}
+        THEN #{SiteSetting.category_search_priority_low_weight}
+        WHEN #{Searchable::PRIORITIES[:high]}
+        THEN #{SiteSetting.category_search_priority_high_weight}
+        WHEN #{Searchable::PRIORITIES[:very_high]}
+        THEN #{SiteSetting.category_search_priority_very_high_weight}
+        ELSE
+          CASE WHEN topics.closed
+          THEN 0.9
+          ELSE 1
+          END
+        END
+      )
+      SQL
+      if opts[:aggregate_search]
+        posts = posts.order("MAX(#{data_ranking}) DESC").order("MAX(posts.created_at) DESC")
+      else
+        posts = posts.order("#{data_ranking} DESC").order("posts.created_at DESC")
+      end
     elsif @order == :latest_topic
       if opts[:aggregate_search]
         posts = posts.order("MAX(topics.created_at) DESC")
diff --git a/spec/requests/search_controller_spec.rb b/spec/requests/search_controller_spec.rb
index 822ede7..d1d8fff 100644
--- a/spec/requests/search_controller_spec.rb
+++ b/spec/requests/search_controller_spec.rb
@@ -219,6 +219,70 @@ describe SearchController do
     end
   end
 
+  context "search priority" do
+    fab!(:low_priority_category) do
+      Fabricate(
+        :category,
+        search_priority: Searchable::PRIORITIES[:very_low]
+      )
+    end
+    fab!(:high_priority_category) do
+      Fabricate(
+        :category,
+        search_priority: Searchable::PRIORITIES[:high]
+      )
+    end
+    fab!(:very_high_priority_category) do
+      Fabricate(
+        :category,
+        search_priority: Searchable::PRIORITIES[:very_high]
+      )
+    end
+    fab!(:low_priority_topic) { Fabricate(:topic, category: low_priority_category) }
+    fab!(:high_priority_topic) { Fabricate(:topic, category: high_priority_category) }
+    fab!(:very_high_priority_topic) { Fabricate(:topic, category: very_high_priority_category) }
+    fab!(:low_priority_post) do
+      SearchIndexer.enable
+      Fabricate(:post, topic: low_priority_topic, raw: "This is a Low Priority Post")
+    end
+    fab!(:hight_priority_post) do
+      SearchIndexer.enable
+      Fabricate(:post, topic: high_priority_topic, raw: "This is a High Priority Post")
+    end
+    fab!(:old_very_hight_priority_post) do
+      SearchIndexer.enable
+      Fabricate(:old_post, topic: very_high_priority_topic, raw: "This is a Old but Very High Priority Post")
+    end
+
+    it "sort posts with search priority when search term is empty" do
+      get "/search.json", params: { q: 'status:open' }
+      expect(response.status).to eq(200)
+      data = JSON.parse(response.body)
+      post1 = data["posts"].find { |e| e["id"] == old_very_hight_priority_post.id }
+      post2 = data["posts"].find { |e| e["id"] == low_priority_post.id }
+      expect(data["posts"][0]["id"]).to eq(old_very_hight_priority_post.id)
+      expect(post1["id"]).to be > post2["id"]
+    end
+
+    it "sort posts with search priority when no order query" do
+      get "/search.json", params: { q: 'status:open Priority Post' }
+      expect(response.status).to eq(200)
+      data = JSON.parse(response.body)
+      expect(data["posts"][0]["id"]).to eq(old_very_hight_priority_post.id)
+      expect(data["posts"][1]["id"]).to eq(hight_priority_post.id)
+      expect(data["posts"][2]["id"]).to eq(low_priority_post.id)
+    end
+
+    it "doesn't sort posts with search piority when query with order" do
+      get "/search.json", params: { q: 'status:open order:latest Priority Post' }
+      expect(response.status).to eq(200)
+      data = JSON.parse(response.body)
+      expect(data["posts"][0]["id"]).to eq(hight_priority_post.id)
+      expect(data["posts"][1]["id"]).to eq(low_priority_post.id)
+      expect(data["posts"][2]["id"]).to eq(old_very_hight_priority_post.id)
+    end
+  end
+
   context "search context" do
     it "raises an error with an invalid context type" do
       get "/search/query.json", params: {

GitHub sha: 6e01acb3

This commit appears in #9516 which was merged by eviltrout.