From 1c9a926eac4512762fb9a3efc512abc107b00261 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 3 Dec 2020 13:58:51 -0600 Subject: [PATCH] BURs: add size requirements for implications. Implications now have the following rules: * The child tag must have at least 10 posts. * The child tag must be at least 0.01% the size of the parent tag. * The child tag can't make up more than 90% of the parent tag. * These rules only apply to general tags. --- app/models/tag_implication.rb | 25 +++++++++++++++++++++++++ test/unit/bulk_update_request_test.rb | 19 +++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/app/models/tag_implication.rb b/app/models/tag_implication.rb index f84320636..16910e96d 100644 --- a/app/models/tag_implication.rb +++ b/app/models/tag_implication.rb @@ -1,4 +1,8 @@ class TagImplication < TagRelationship + MINIMUM_TAG_COUNT = 10 + MINIMUM_TAG_PERCENTAGE = 0.0001 + MAXIMUM_TAG_PERCENTAGE = 0.9 + has_many :child_implications, class_name: "TagImplication", primary_key: :consequent_name, foreign_key: :antecedent_name has_many :parent_implications, class_name: "TagImplication", primary_key: :antecedent_name, foreign_key: :consequent_name @@ -8,6 +12,7 @@ class TagImplication < TagRelationship validate :antecedent_is_not_aliased validate :consequent_is_not_aliased validate :tag_categories_are_compatible + validate :meets_tag_size_requirements, on: :request validate :has_wiki_page, on: :request concerning :HierarchyMethods do @@ -100,6 +105,26 @@ class TagImplication < TagRelationship end end + # Require tags to have at least 10 posts or be at least 0.01% the size of + # the parent tag, and not make up more than 90% of the parent tag. Only + # applies to general tags. Doesn't apply when the parent tag is empty to + # allow creating new umbrella tags. + def meets_tag_size_requirements + return unless antecedent_tag.general? + return if consequent_tag.empty? + + if antecedent_tag.post_count < MINIMUM_TAG_COUNT + errors[:base] << "'#{antecedent_name}' must have at least #{MINIMUM_TAG_COUNT} posts" + elsif antecedent_tag.post_count < (MINIMUM_TAG_PERCENTAGE * consequent_tag.post_count) + errors[:base] << "'#{antecedent_name}' must have at least #{(MINIMUM_TAG_PERCENTAGE * consequent_tag.post_count).to_i} posts" + end + + max_count = MAXIMUM_TAG_PERCENTAGE * PostQueryBuilder.new("~#{antecedent_name} ~#{consequent_name}").fast_count.to_i + if antecedent_tag.post_count > max_count && max_count > 0 + errors[:base] << "'#{antecedent_name}' can't make up than #{(MAXIMUM_TAG_PERCENTAGE * 100).to_i}% of '#{consequent_name}'" + end + end + def has_wiki_page if !antecedent_tag.empty? && antecedent_wiki.blank? errors[:base] << "'#{antecedent_name}' must have a wiki page" diff --git a/test/unit/bulk_update_request_test.rb b/test/unit/bulk_update_request_test.rb index 204fdc048..fd063f875 100644 --- a/test/unit/bulk_update_request_test.rb +++ b/test/unit/bulk_update_request_test.rb @@ -152,6 +152,21 @@ class BulkUpdateRequestTest < ActiveSupport::TestCase assert_equal(false, @bur.valid?) assert_equal(["Can't create implication hatsune_miku -> vocaloid (Can't imply a character tag to a copyright tag)"], @bur.errors.full_messages) end + + should "fail for a child tag that is too small" do + @t1 = create(:tag, name: "white_shirt", post_count: 9) + @t2 = create(:tag, name: "shirt", post_count: 1000000) + create(:wiki_page, title: "white_shirt") + create(:wiki_page, title: "shirt") + @bur = build(:bulk_update_request, script: "imply white_shirt -> shirt") + + assert_equal(false, @bur.valid?) + assert_equal(["Can't create implication white_shirt -> shirt ('white_shirt' must have at least 10 posts)"], @bur.errors.full_messages) + + @t1.update!(post_count: 99) + assert_equal(false, @bur.valid?) + assert_equal(["Can't create implication white_shirt -> shirt ('white_shirt' must have at least 100 posts)"], @bur.errors.full_messages) + end end context "the remove alias command" do @@ -342,8 +357,8 @@ class BulkUpdateRequestTest < ActiveSupport::TestCase context "requesting an implication for a populated tag without a wiki" do should "fail" do - create(:tag, name: "a", post_count: 1) - create(:tag, name: "b", post_count: 1) + create(:tag, name: "a", post_count: 10) + create(:tag, name: "b", post_count: 100) @bur = build(:bulk_update_request, script: "imply a -> b") assert_equal(false, @bur.valid?)