From 3d3f9ce46cc89c97db4f1916a5c84f7c2489cbc3 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 30 Apr 2020 18:17:02 -0500 Subject: [PATCH] Fix #4343: Presence of metatags shouldn't prevent rendering of the excerpt. On the post index page, show the wiki excerpt if the search includes a single tag, even if the tag is negated or the search includes other metatags. If the search includes a single pool: or ordpool: metatag, show the pool excerpt even if the search includes other metatags. --- app/logical/post_query_builder.rb | 8 ++- app/logical/post_sets/post.rb | 12 ++-- test/functional/posts_controller_test.rb | 91 +++++++++++++++++++++++- 3 files changed, 101 insertions(+), 10 deletions(-) diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 85f2ef008..4455e2dc7 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -823,8 +823,8 @@ class PostQueryBuilder scan_query.select { |term| term.type == :metatag } end - def select_metatags(metatag) - metatags.select { |term| term.name == metatag.to_s.downcase } + def select_metatags(*names) + metatags.select { |term| term.name.in?(names.map(&:to_s)) } end def find_metatag(metatag) @@ -835,6 +835,10 @@ class PostQueryBuilder metatags.any? { |term| term.name.in?(metatag_names.map(&:to_s).map(&:downcase)) } end + def has_single_tag? + tags.size == 1 && !tags.first.wildcard + end + def is_metatag?(name, value = nil) if value.nil? is_single_term? && has_metatag?(name) diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb index d757c9bf4..3fe2d2760 100644 --- a/app/logical/post_sets/post.rb +++ b/app/logical/post_sets/post.rb @@ -27,7 +27,7 @@ module PostSets end def tag - return nil unless query.is_simple_tag? + return nil unless query.has_single_tag? @tag ||= Tag.find_by(name: query.tags.first.name) end @@ -38,15 +38,17 @@ module PostSets end def pool - return nil unless query.is_metatag?(:pool) || query.is_metatag?(:ordpool) - name = query.find_metatag(:pool) || query.find_metatag(:ordpool) + pool_names = query.select_metatags(:pool, :ordpool).map(&:value) + name = pool_names.first + return nil unless pool_names.size == 1 @pool ||= Pool.find_by_name(name) end def favgroup - return nil unless query.is_metatag?(:favgroup) - name = query.find_metatag(:favgroup) + favgroup_names = query.select_metatags(:favgroup, :ordfavgroup).map(&:value) + name = favgroup_names.first + return nil unless favgroup_names.size == 1 @favgroup ||= FavoriteGroup.visible(CurrentUser.user).find_by_name_or_id(name, CurrentUser.user) end diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb index 1a0e28668..f45cbcf57 100644 --- a/test/functional/posts_controller_test.rb +++ b/test/functional/posts_controller_test.rb @@ -21,48 +21,58 @@ class PostsControllerTest < ActionDispatch::IntegrationTest should "render for an empty tag" do get posts_path, params: { tags: "does_not_exist" } assert_response :success + assert_select "#show-excerpt-link", count: 0 end should "render for an artist tag" do - create(:post, tag_string: "artist:bkub") + create(:post, tag_string: "artist:bkub", rating: "s") get posts_path, params: { tags: "bkub" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" artist = create(:artist, name: "bkub") get posts_path, params: { tags: "bkub" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Artist" artist.update(is_banned: true) get posts_path, params: { tags: "bkub" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Artist" artist.update(is_banned: false, is_deleted: true) get posts_path, params: { tags: "bkub" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" as_user { create(:wiki_page, title: "bkub") } get posts_path, params: { tags: "bkub" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" end should "render for a tag with a wiki page" do - create(:post, tag_string: "char:fumimi") + create(:post, tag_string: "char:fumimi", rating: "s") get posts_path, params: { tags: "fumimi" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" as_user { @wiki = create(:wiki_page, title: "fumimi") } get posts_path, params: { tags: "fumimi" } assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" as_user { @wiki.update(is_deleted: true) } get posts_path, params: { tags: "bkub" } assert_response :success + assert_select "#show-excerpt-link", count: 0 end should "render for a wildcard tag search" do create(:post, tag_string: "1girl solo") get posts_path(tags: "*girl*") assert_response :success + assert_select "#show-excerpt-link", count: 0 end should "render for a search:all search" do @@ -80,9 +90,14 @@ class PostsControllerTest < ActionDispatch::IntegrationTest context "with a multi-tag search" do should "render" do - create(:post, tag_string: "1girl solo") + as(create(:user)) do + create(:post, tag_string: "1girl solo") + create(:wiki_page, title: "1girl") + end + get posts_path, params: {:tags => "1girl solo"} assert_response :success + assert_select "#show-excerpt-link", count: 0 end should "render an error when searching for too many tags" do @@ -100,6 +115,76 @@ class PostsControllerTest < ActionDispatch::IntegrationTest end end + context "with a pool: search" do + setup do + CurrentUser.user = create(:user) + CurrentUser.ip_addr = "127.0.0.1" + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + should "render for a pool: search" do + pool1 = create(:pool) + pool2 = create(:pool) + create(:post, tag_string: "solo pool:#{pool1.id}", rating: "s") + create(:wiki_page, title: "solo") + + get posts_path(tags: "pool:#{pool1.id}") + assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Pool" + + get posts_path(tags: "pool:#{pool1.id} rating:s") + assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Pool" + + get posts_path(tags: "pool:#{pool1.id} solo") + assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" + + get posts_path(tags: "pool:#{pool1.id} -pool:#{pool2.id}") + assert_response :success + assert_select "#show-excerpt-link", count: 0 + end + end + + context "with a favgroup: search" do + setup do + CurrentUser.user = create(:user) + CurrentUser.ip_addr = "127.0.0.1" + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + should "render for a favgroup: search" do + wiki = create(:wiki_page, title: "solo") + post1 = create(:post, tag_string: "solo", rating: "s") + favgroup1 = create(:favorite_group, post_ids: [post1.id]) + favgroup2 = create(:favorite_group) + + get posts_path(tags: "favgroup:#{favgroup1.id}") + assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Favorite Group" + + get posts_path(tags: "favgroup:#{favgroup1.id} rating:s") + assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Favorite Group" + + get posts_path(tags: "favgroup:#{favgroup1.id} solo") + assert_response :success + assert_select "#show-excerpt-link", count: 1, text: "Wiki" + + get posts_path(tags: "favgroup:#{favgroup1.id} -favgroup:#{favgroup2.id}") + assert_response :success + assert_select "#show-excerpt-link", count: 0 + end + end + context "with an md5 param" do should "render" do get posts_path, params: { md5: @post.md5 }