search: split tag_match into user_tag_match / system_tag_match.

When doing a tag search, we have to be careful about which user we're
running the search as because the results depend on the current user.
Specifically, things like private favorites, private favorite groups,
post votes, saved searches, and flagger names depend on the user's
permissions, and whether non-safe or deleted posts are filtered out
depend on whether the user has safe mode on or the hide deleted posts
setting enabled.

* Refactor internal searches to explicitly state whether they're
  running as the system user (DanbooruBot) or as the current user.
* Explicitly pass in the current user to PostQueryBuilder instead of
  implicitly relying on the CurrentUser global.
* Get rid of CurrentUser.admin_mode? (used to ignore the hide deleted
  post setting) and CurrentUser.without_safe_mode (used to ignore safe
  mode).
* Change the /counts/posts.json endpoint to ignore safe mode and the
  hide deleted posts settings when counting posts.
* Fix searches not correctly overriding the hide deleted posts setting
  when multiple status: metatags were used (e.g. `status:banned status:active`)
* Fix fast_count not respecting the hide deleted posts setting when the
  status:banned metatag was used.
This commit is contained in:
evazion
2020-05-06 22:00:47 -05:00
parent a753ebbea9
commit f38c38f26e
24 changed files with 120 additions and 147 deletions

View File

@@ -2,11 +2,11 @@ require 'test_helper'
class PostQueryBuilderTest < ActiveSupport::TestCase
def assert_tag_match(posts, query)
assert_equal(posts.map(&:id), Post.tag_match(query).pluck(:id))
assert_equal(posts.map(&:id), Post.user_tag_match(query).pluck(:id))
end
def assert_fast_count(count, query, **options)
assert_equal(count, PostQueryBuilder.new(query).fast_count(**options))
assert_equal(count, PostQueryBuilder.new(query, **options).fast_count)
end
setup do
@@ -616,6 +616,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([deleted], "status:deleted")
assert_tag_match([undeleted, deleted], "status:any")
assert_tag_match([undeleted, deleted], "status:all")
assert_tag_match([deleted], "status:banned status:deleted")
assert_tag_match([], "-status:banned")
assert_tag_match([deleted], "-status:active")
@@ -629,6 +630,8 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([deleted], "status:deleted")
assert_tag_match([undeleted, deleted], "status:any")
assert_tag_match([undeleted, deleted], "status:all")
assert_fast_count(2, "status:banned")
end
should "return posts for the filetype:<ext> metatag" do
@@ -988,7 +991,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
post1 = create(:post, rating: "s")
assert_raise(::Post::SearchError) do
Post.tag_match("a b c rating:s width:10 height:10 user:bob")
Post.user_tag_match("a b c rating:s width:10 height:10 user:bob")
end
end
@@ -1143,29 +1146,28 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
context "in safe mode" do
setup do
CurrentUser.stubs(:safe_mode?).returns(true)
create(:post, rating: "s")
end
should "work for a blank search" do
assert_fast_count(1, "")
assert_fast_count(1, "", safe_mode: true)
end
should "work for a nil search" do
assert_fast_count(1, nil)
assert_fast_count(1, nil, safe_mode: true)
end
should "not fail for a two tag search by a member" do
post1 = create(:post, tag_string: "aaa bbb rating:s")
post2 = create(:post, tag_string: "aaa bbb rating:e")
assert_fast_count(1, "aaa bbb")
assert_fast_count(1, "aaa bbb", safe_mode: true)
end
context "with a primed cache" do
should "fetch the value from the cache" do
PostQueryBuilder.new(nil).set_count_in_cache("rating:s", 100)
assert_fast_count(100, "")
assert_fast_count(100, "", safe_mode: true)
end
end
end

View File

@@ -2,14 +2,7 @@ require 'test_helper'
class RelatedTagCalculatorTest < ActiveSupport::TestCase
setup do
user = FactoryBot.create(:user)
CurrentUser.user = user
CurrentUser.ip_addr = "127.0.0.1"
end
teardown do
CurrentUser.user = nil
CurrentUser.ip_addr = nil
@user = create(:user)
end
context "RelatedTagCalculator" do
@@ -18,7 +11,7 @@ class RelatedTagCalculatorTest < ActiveSupport::TestCase
create(:post, tag_string: "aaa bbb ccc ddd")
create(:post, tag_string: "aaa bbb ccc")
create(:post, tag_string: "aaa bbb")
posts = Post.tag_match("aaa")
posts = Post.user_tag_match("aaa", @user)
assert_equal(%w[aaa bbb ccc ddd], RelatedTagCalculator.frequent_tags_for_post_array(posts))
end
@@ -30,7 +23,7 @@ class RelatedTagCalculatorTest < ActiveSupport::TestCase
create(:post, tag_string: "aaa bbb ccc")
create(:post, tag_string: "aaa bbb")
assert_equal(%w[aaa bbb ccc ddd], RelatedTagCalculator.frequent_tags_for_search("aaa").pluck(:name))
assert_equal(%w[aaa bbb ccc ddd], RelatedTagCalculator.frequent_tags_for_search("aaa", @user).pluck(:name))
end
should "calculate the most frequent tags for a multiple tag search" do
@@ -38,16 +31,16 @@ class RelatedTagCalculatorTest < ActiveSupport::TestCase
create(:post, tag_string: "aaa bbb ccc ddd")
create(:post, tag_string: "aaa eee fff")
assert_equal(%w[aaa bbb ccc ddd], RelatedTagCalculator.frequent_tags_for_search("aaa bbb").pluck(:name))
assert_equal(%w[aaa bbb ccc ddd], RelatedTagCalculator.frequent_tags_for_search("aaa bbb", @user).pluck(:name))
end
should "calculate the most frequent tags with a category constraint" do
create(:post, tag_string: "aaa bbb art:ccc copy:ddd")
create(:post, tag_string: "aaa bbb art:ccc")
create(:post, tag_string: "aaa bbb ccc")
create(:post, tag_string: "aaa bbb")
assert_equal(%w[aaa bbb], RelatedTagCalculator.frequent_tags_for_search("aaa", category: Tag.categories.general).pluck(:name))
assert_equal(%w[ccc], RelatedTagCalculator.frequent_tags_for_search("aaa", category: Tag.categories.artist).pluck(:name))
assert_equal(%w[aaa bbb], RelatedTagCalculator.frequent_tags_for_search("aaa", @user, category: Tag.categories.general).pluck(:name))
assert_equal(%w[ccc], RelatedTagCalculator.frequent_tags_for_search("aaa", @user, category: Tag.categories.artist).pluck(:name))
end
end
@@ -57,9 +50,9 @@ class RelatedTagCalculatorTest < ActiveSupport::TestCase
create(:post, tag_string: "1girl solo", rating: "q")
create(:post, tag_string: "1girl 1boy", rating: "q")
assert_equal(%w[1girl solo 1boy], RelatedTagCalculator.similar_tags_for_search("1girl").pluck(:name))
assert_equal(%w[1girl 1boy solo], RelatedTagCalculator.similar_tags_for_search("rating:q").pluck(:name))
assert_equal(%w[solo 1girl], RelatedTagCalculator.similar_tags_for_search("solo").pluck(:name))
assert_equal(%w[1girl solo 1boy], RelatedTagCalculator.similar_tags_for_search("1girl", @user).pluck(:name))
assert_equal(%w[1girl 1boy solo], RelatedTagCalculator.similar_tags_for_search("rating:q", @user).pluck(:name))
assert_equal(%w[solo 1girl], RelatedTagCalculator.similar_tags_for_search("solo", @user).pluck(:name))
end
should "calculate the similar tags for an aliased tag" do
@@ -67,7 +60,7 @@ class RelatedTagCalculatorTest < ActiveSupport::TestCase
create(:post, tag_string: "bunny dog")
create(:post, tag_string: "bunny cat")
assert_equal(%w[bunny cat dog], RelatedTagCalculator.similar_tags_for_search("rabbit").pluck(:name))
assert_equal(%w[bunny cat dog], RelatedTagCalculator.similar_tags_for_search("rabbit", @user).pluck(:name))
end
end
end