mirror of
https://github.com/discourse/discourse.git
synced 2025-02-17 07:42:45 +08:00
DEV: Support posts-min:<count>
and posts-max:<count>
on /filter
(#21090)
This commit adds support for the `posts-min:<count>` and `posts-max:<count>` filters for the topics filtering query language. `posts-min:1` will filter for topics with at least a one post while `posts-max:3` will filter foor topics with a maximum of 3 posts. If the filter has an invalid value, i.e string that cannot be converted into an integer, the filter will be ignored. If either of each filter is specify multiple times, only the last occurence of each filter will be taken into consideration.
This commit is contained in:
parent
9b3408223b
commit
bc4a9c50f2
|
@ -40,6 +40,10 @@ class TopicsFilter
|
|||
filter_created_by_user(usernames: values.flat_map { |value| value.split(",") })
|
||||
when "in"
|
||||
filter_in(values: values)
|
||||
when "posts-min"
|
||||
filter_by_number_of_posts(min: values.last)
|
||||
when "posts-max"
|
||||
filter_by_number_of_posts(max: values.last)
|
||||
when "status"
|
||||
values.each { |status| @scope = filter_status(status: status) }
|
||||
when "tags"
|
||||
|
@ -77,6 +81,13 @@ class TopicsFilter
|
|||
|
||||
private
|
||||
|
||||
def filter_by_number_of_posts(min: nil, max: nil)
|
||||
{ min => ">=", max => "<=" }.each do |value, operator|
|
||||
next if !value || value !~ /^\d+$/
|
||||
@scope = @scope.where("topics.posts_count #{operator} ?", value)
|
||||
end
|
||||
end
|
||||
|
||||
def filter_categories(values:)
|
||||
exclude_subcategories_category_slugs = []
|
||||
include_subcategories_category_slugs = []
|
||||
|
|
|
@ -846,5 +846,88 @@ RSpec.describe TopicsFilter do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when filtering by number of posts in a topic" do
|
||||
fab!(:topic_with_1_post) { Fabricate(:topic, posts_count: 1) }
|
||||
fab!(:topic_with_2_posts) { Fabricate(:topic, posts_count: 2) }
|
||||
fab!(:topic_with_3_posts) { Fabricate(:topic, posts_count: 3) }
|
||||
|
||||
describe "when query string is `posts-min:1`" do
|
||||
it "should only return topics with at least 1 post" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-min:1")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_1_post.id, topic_with_2_posts.id, topic_with_3_posts.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `posts-min:3`" do
|
||||
it "should only return topics with at least 3 posts" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-min:3")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_3_posts.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `posts-max:1`" do
|
||||
it "should only return topics with at most 1 post" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-max:1")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_1_post.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `posts-max:3`" do
|
||||
it "should only return topics with at most 3 posts" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-max:3")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_1_post.id, topic_with_2_posts.id, topic_with_3_posts.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `posts-min:1 posts-max:2`" do
|
||||
it "should only return topics with at least a post and at most 2 posts" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-min:1 posts-max:2")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_1_post.id, topic_with_2_posts.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `posts-min:3 posts-min:2 posts-max:1 posts-max:3`" do
|
||||
it "should only return topics with at least 2 posts and at most 3 posts as it ignores earlier filters which are duplicated" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-min:3 posts-min:2 posts-max:1 posts-max:3")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_2_posts.id, topic_with_3_posts.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `posts-min:invalid posts-max:invalid`" do
|
||||
it "should ignore the filters with invalid values" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("posts-min:invalid posts-max:invalid")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(topic_with_1_post.id, topic_with_2_posts.id, topic_with_3_posts.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user