diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 280440ba7..7ae704637 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -485,12 +485,14 @@ class PostQueryBuilder relation = relation.joins("JOIN (#{pool_posts.to_sql}) pool_posts ON pool_posts.post_id = posts.id").order("pool_posts.pool_index ASC") end - q[:favgroups_neg].to_a.each do |favgroup| - relation = relation.where.not(id: FavoriteGroup.where(id: favgroup.id).select("unnest(post_ids)")) + q[:favgroup_neg].to_a.each do |favgroup_name| + favgroup = FavoriteGroup.visible(CurrentUser.user).name_or_id_matches(favgroup_name, CurrentUser.user) + relation = relation.where.not(id: favgroup.select("unnest(post_ids)")) end - q[:favgroups].to_a.each do |favgroup| - relation = relation.where(id: FavoriteGroup.where(id: favgroup.id).select("unnest(post_ids)")) + q[:favgroup].to_a.each do |favgroup_name| + favgroup = FavoriteGroup.visible(CurrentUser.user).name_or_id_matches(favgroup_name, CurrentUser.user) + relation = relation.where(id: favgroup.select("unnest(post_ids)")) end q[:upvoter].to_a.each do |upvoter| @@ -782,18 +784,12 @@ class PostQueryBuilder q[:ordpool] = g2 when "-favgroup" - favgroup = FavoriteGroup.find_by_name_or_id!(g2, CurrentUser.user) - raise User::PrivilegeError unless Pundit.policy!([CurrentUser.user, nil], favgroup).show? - - q[:favgroups_neg] ||= [] - q[:favgroups_neg] << favgroup + q[:favgroup_neg] ||= [] + q[:favgroup_neg] << g2 when "favgroup" - favgroup = FavoriteGroup.find_by_name_or_id!(g2, CurrentUser.user) - raise User::PrivilegeError unless Pundit.policy!([CurrentUser.user, nil], favgroup).show? - - q[:favgroups] ||= [] - q[:favgroups] << favgroup + q[:favgroup] ||= [] + q[:favgroup] << g2 when "-fav" favuser = User.find_by_name(g2) diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb index 0470fba84..a34bb0170 100644 --- a/app/logical/post_sets/post.rb +++ b/app/logical/post_sets/post.rb @@ -52,7 +52,7 @@ module PostSets name = Tag.has_metatag?(tag_array, :favgroup) return nil unless is_single_tag? && name.present? - @favgroup ||= FavoriteGroup.find_by_name_or_id(name, CurrentUser.user) + @favgroup ||= FavoriteGroup.visible(CurrentUser.user).find_by_name_or_id(name, CurrentUser.user) end def has_explicit? diff --git a/app/models/favorite_group.rb b/app/models/favorite_group.rb index 1ccc7a4d8..d90e0e04a 100644 --- a/app/models/favorite_group.rb +++ b/app/models/favorite_group.rb @@ -89,14 +89,18 @@ class FavoriteGroup < ApplicationRecord self.name = FavoriteGroup.normalize_name(name) end - def self.find_by_name_or_id(name, user) + def self.name_or_id_matches(name, user) if name =~ /\A\d+\z/ - find_by(id: name) + where(id: name) else - user.favorite_groups.where_iequals(:name, normalize_name(name)).first + where(creator: user).where_iequals(:name, normalize_name(name)) end end + def self.find_by_name_or_id(name, user) + name_or_id_matches(name, user).first + end + def self.find_by_name_or_id!(name, user) find_by_name_or_id(name, user) or raise ActiveRecord::RecordNotFound end diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb index ced1732a9..90929ae73 100644 --- a/test/unit/post_test.rb +++ b/test/unit/post_test.rb @@ -2092,12 +2092,35 @@ class PostTest < ActiveSupport::TestCase end should "return posts for the favgroup: metatag" do - favgroups = FactoryBot.create_list(:favorite_group, 2, creator: CurrentUser.user) - posts = favgroups.map { |g| FactoryBot.create(:post, tag_string: "favgroup:#{g.name}") } + post1 = create(:post) + post2 = create(:post) + post3 = create(:post) - assert_tag_match([posts[0]], "favgroup:#{favgroups[0].name}") - assert_tag_match([posts[1]], "-favgroup:#{favgroups[0].name}") - assert_tag_match([], "-favgroup:#{favgroups[0].name} -favgroup:#{favgroups[1].name}") + favgroup1 = create(:favorite_group, creator: CurrentUser.user, post_ids: [post1.id]) + favgroup2 = create(:favorite_group, creator: CurrentUser.user, post_ids: [post2.id]) + favgroup3 = create(:favorite_group, creator: create(:user), post_ids: [post3.id], is_public: false) + + assert_tag_match([post1], "favgroup:#{favgroup1.id}") + assert_tag_match([post2], "favgroup:#{favgroup2.name}") + assert_tag_match([], "favgroup:#{favgroup3.name}") + assert_tag_match([], "favgroup:dne") + + assert_tag_match([post3, post2], "-favgroup:#{favgroup1.id}") + assert_tag_match([post3, post1], "-favgroup:#{favgroup2.name}") + assert_tag_match([post3, post2, post1], "-favgroup:#{favgroup3.name}") + assert_tag_match([post3, post2, post1], "-favgroup:dne") + + assert_tag_match([post3], "-favgroup:#{favgroup1.name} -favgroup:#{favgroup2.name}") + + as(favgroup3.creator) do + assert_tag_match([post1], "favgroup:#{favgroup1.id}") + assert_tag_match([post2], "favgroup:#{favgroup2.id}") + assert_tag_match([post3], "favgroup:#{favgroup3.id}") + + assert_tag_match([], "favgroup:#{favgroup1.name}") + assert_tag_match([], "favgroup:#{favgroup2.name}") + assert_tag_match([post3], "favgroup:#{favgroup3.name}") + end end should "return posts for the user: metatag" do