DEV: Extend /filter's ability to order (#28242)

This commit is contained in:
Natalie Tay 2024-08-07 16:37:00 +08:00 committed by GitHub
parent 5dbf812d32
commit a49a6941c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 1 deletions

View File

@ -549,14 +549,21 @@ class TopicsFilter
def order_by(values:)
values.each do |value|
# If the order by value is not recognized, check if it is a custom filter.
match_data = value.match(ORDER_BY_REGEXP)
if match_data && column_name = ORDER_BY_MAPPINGS.dig(match_data[:order_by], :column)
if scope = ORDER_BY_MAPPINGS.dig(match_data[:order_by], :scope)
@scope = instance_exec(&scope)
end
@scope = @scope.order("#{column_name} #{match_data[:asc] ? "ASC" : "DESC"}")
else
match_data = value.match /^(?<column>.*?)(?:-(?<asc>asc))?$/
key = "order:#{match_data[:column]}"
if custom_match =
DiscoursePluginRegistry.custom_filter_mappings.find { |hash| hash.key?(key) }
@scope = custom_match[key].call(@scope, match_data[:asc].nil? ? "DESC" : "ASC")
end
end
end
end

View File

@ -1349,6 +1349,13 @@ RSpec.describe TopicsFilter do
end
describe "ordering topics filter" do
before do
Plugin::Instance.new.add_filter_custom_filter(
"order:wrongly",
&->(scope) { scope.order("wrongly") }
)
end
# Requires the fabrication of `topic`, `topic2` and `topic3` such that the order of the topics is `topic2`, `topic1`, `topic3`
# when ordered by the given filter in descending order.
shared_examples "ordering topics filters" do |order, order_description|
@ -1500,6 +1507,38 @@ RSpec.describe TopicsFilter do
end
end
end
context "for DiscoursePluginRegistry.custom_filter_mappings" do
describe "when extending order:{col}" do
fab!(:earlier_topic) { Fabricate(:topic, bumped_at: 2.hours.ago) }
fab!(:now_topic) { Fabricate(:topic, bumped_at: Time.now) }
before_all do
Plugin::Instance.new.add_filter_custom_filter(
"order:bumped",
&->(scope, value) { scope.order("bumped_at #{value}") }
)
end
it "applies ASC order correctly" do
expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("order:bumped-asc")
.pluck(:id),
).to eq([earlier_topic.id, now_topic.id])
end
it "applies default order correctly" do
expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("order:bumped")
.pluck(:id),
).to eq([now_topic.id, earlier_topic.id])
end
end
end
end
end
end