aliases/implications: remove 'pending' state.
Remove the pending status from tag aliases and implications. Previously aliases would be created first in the pending state then changed to active when the alias was later processed in a delayed job. This meant that BURs weren't processed completely sequentially; first all the aliases in a BUR would be created in one go, then later they would be processed and set to active sequentially. This was problematic in complex BURs that tried to reverse or swap around aliases, since new pending aliases could be created before old conflicting aliases were removed.
This commit is contained in:
@@ -1,7 +0,0 @@
|
|||||||
class ProcessTagAliasJob < ApplicationJob
|
|
||||||
queue_as :bulk_update
|
|
||||||
|
|
||||||
def perform(tag_alias, approver)
|
|
||||||
tag_alias.process!(approver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
class ProcessTagImplicationJob < ApplicationJob
|
|
||||||
queue_as :bulk_update
|
|
||||||
|
|
||||||
def perform(tag_implication, approver)
|
|
||||||
tag_implication.process!(approver)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
9
app/jobs/process_tag_relationship_job.rb
Normal file
9
app/jobs/process_tag_relationship_job.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class ProcessTagRelationshipJob < ApplicationJob
|
||||||
|
queue_as :bulk_update
|
||||||
|
|
||||||
|
def perform(class_name:, approver:, antecedent_name:, consequent_name:, forum_topic: nil)
|
||||||
|
relation_class = Kernel.const_get(class_name)
|
||||||
|
tag_relationship = relation_class.create!(creator: approver, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
|
||||||
|
tag_relationship.process!
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,7 +4,7 @@ class BulkUpdateRequestProcessor
|
|||||||
class Error < StandardError; end
|
class Error < StandardError; end
|
||||||
|
|
||||||
attr_reader :bulk_update_request
|
attr_reader :bulk_update_request
|
||||||
delegate :script, :forum_topic_id, to: :bulk_update_request
|
delegate :script, :forum_topic, to: :bulk_update_request
|
||||||
validate :validate_script
|
validate :validate_script
|
||||||
|
|
||||||
def initialize(bulk_update_request)
|
def initialize(bulk_update_request)
|
||||||
@@ -105,12 +105,10 @@ class BulkUpdateRequestProcessor
|
|||||||
commands.map do |command, *args|
|
commands.map do |command, *args|
|
||||||
case command
|
case command
|
||||||
when :create_alias
|
when :create_alias
|
||||||
tag_alias = TagAlias.create!(creator: approver, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: args[0], consequent_name: args[1])
|
TagAlias.approve!(antecedent_name: args[0], consequent_name: args[1], approver: approver, forum_topic: forum_topic)
|
||||||
tag_alias.approve!(approver)
|
|
||||||
|
|
||||||
when :create_implication
|
when :create_implication
|
||||||
tag_implication = TagImplication.create!(creator: approver, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: args[0], consequent_name: args[1])
|
TagImplication.approve!(antecedent_name: args[0], consequent_name: args[1], approver: approver, forum_topic: forum_topic)
|
||||||
tag_implication.approve!(approver)
|
|
||||||
|
|
||||||
when :remove_alias
|
when :remove_alias
|
||||||
tag_alias = TagAlias.active.find_by!(antecedent_name: args[0], consequent_name: args[1])
|
tag_alias = TagAlias.active.find_by!(antecedent_name: args[0], consequent_name: args[1])
|
||||||
|
|||||||
@@ -192,8 +192,7 @@ class Artist < ApplicationRecord
|
|||||||
|
|
||||||
# potential race condition but unlikely
|
# potential race condition but unlikely
|
||||||
unless TagImplication.where(:antecedent_name => name, :consequent_name => "banned_artist").exists?
|
unless TagImplication.where(:antecedent_name => name, :consequent_name => "banned_artist").exists?
|
||||||
tag_implication = TagImplication.create!(antecedent_name: name, consequent_name: "banned_artist", creator: banner)
|
TagImplication.approve!(antecedent_name: name, consequent_name: "banned_artist", approver: banner)
|
||||||
tag_implication.approve!(banner)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
update!(is_banned: true)
|
update!(is_banned: true)
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ class TagAlias < TagRelationship
|
|||||||
validates_uniqueness_of :antecedent_name, scope: :status, conditions: -> { active }
|
validates_uniqueness_of :antecedent_name, scope: :status, conditions: -> { active }
|
||||||
validate :absence_of_transitive_relation
|
validate :absence_of_transitive_relation
|
||||||
|
|
||||||
def approve!(approver)
|
|
||||||
ProcessTagAliasJob.perform_later(self, approver)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.to_aliased(names)
|
def self.to_aliased(names)
|
||||||
names = Array(names).map(&:to_s)
|
names = Array(names).map(&:to_s)
|
||||||
return [] if names.empty?
|
return [] if names.empty?
|
||||||
@@ -14,8 +10,7 @@ class TagAlias < TagRelationship
|
|||||||
names.map { |name| aliases[name] || name }
|
names.map { |name| aliases[name] || name }
|
||||||
end
|
end
|
||||||
|
|
||||||
def process!(approver)
|
def process!
|
||||||
update!(approver: approver, status: "active")
|
|
||||||
TagMover.new(antecedent_name, consequent_name, user: User.system).move!
|
TagMover.new(antecedent_name, consequent_name, user: User.system).move!
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
update!(status: "error: #{e}")
|
update!(status: "error: #{e}")
|
||||||
|
|||||||
@@ -109,13 +109,8 @@ class TagImplication < TagRelationship
|
|||||||
end
|
end
|
||||||
|
|
||||||
module ApprovalMethods
|
module ApprovalMethods
|
||||||
def process!(approver)
|
def process!
|
||||||
unless valid?
|
|
||||||
raise errors.full_messages.join("; ")
|
|
||||||
end
|
|
||||||
|
|
||||||
CurrentUser.scoped(User.system) do
|
CurrentUser.scoped(User.system) do
|
||||||
update!(approver: approver, status: "active")
|
|
||||||
update_posts
|
update_posts
|
||||||
end
|
end
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
@@ -123,10 +118,6 @@ class TagImplication < TagRelationship
|
|||||||
DanbooruLogger.log(e, tag_implication_id: id, antecedent_name: antecedent_name, consequent_name: consequent_name)
|
DanbooruLogger.log(e, tag_implication_id: id, antecedent_name: antecedent_name, consequent_name: consequent_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def approve!(approver)
|
|
||||||
ProcessTagImplicationJob.perform_later(self, approver)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_mod_action
|
def create_mod_action
|
||||||
implication = %("tag implication ##{id}":[#{Rails.application.routes.url_helpers.tag_implication_path(self)}]: [[#{antecedent_name}]] -> [[#{consequent_name}]])
|
implication = %("tag implication ##{id}":[#{Rails.application.routes.url_helpers.tag_implication_path(self)}]: [[#{antecedent_name}]] -> [[#{consequent_name}]])
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,10 @@ class TagRelationship < ApplicationRecord
|
|||||||
scope :deleted, -> {where(status: "deleted")}
|
scope :deleted, -> {where(status: "deleted")}
|
||||||
scope :expired, -> {where("created_at < ?", EXPIRY.days.ago)}
|
scope :expired, -> {where("created_at < ?", EXPIRY.days.ago)}
|
||||||
scope :old, -> {where("created_at >= ? and created_at < ?", EXPIRY.days.ago, EXPIRY_WARNING.days.ago)}
|
scope :old, -> {where("created_at >= ? and created_at < ?", EXPIRY.days.ago, EXPIRY_WARNING.days.ago)}
|
||||||
scope :pending, -> {where(status: "pending")}
|
|
||||||
scope :retired, -> {where(status: "retired")}
|
scope :retired, -> {where(status: "retired")}
|
||||||
|
|
||||||
before_validation :normalize_names
|
before_validation :normalize_names
|
||||||
validates_format_of :status, :with => /\A(active|deleted|pending|retired|error: .*)\Z/
|
validates_format_of :status, :with => /\A(active|deleted|retired|error: .*)\Z/
|
||||||
validates_presence_of :antecedent_name, :consequent_name
|
validates_presence_of :antecedent_name, :consequent_name
|
||||||
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
|
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
|
||||||
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
|
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
|
||||||
@@ -44,10 +43,6 @@ class TagRelationship < ApplicationRecord
|
|||||||
status == "deleted"
|
status == "deleted"
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_pending?
|
|
||||||
status == "pending"
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_active?
|
def is_active?
|
||||||
status == "active"
|
status == "active"
|
||||||
end
|
end
|
||||||
@@ -74,11 +69,6 @@ class TagRelationship < ApplicationRecord
|
|||||||
where(field => Tag.search(params).reorder(nil).select(:name))
|
where(field => Tag.search(params).reorder(nil).select(:name))
|
||||||
end
|
end
|
||||||
|
|
||||||
def pending_first
|
|
||||||
# unknown statuses return null and are sorted first
|
|
||||||
order(Arel.sql("array_position(array['pending', 'active', 'deleted', 'retired'], status::text) NULLS FIRST, id DESC"))
|
|
||||||
end
|
|
||||||
|
|
||||||
def search(params)
|
def search(params)
|
||||||
q = super
|
q = super
|
||||||
q = q.search_attributes(params, :antecedent_name, :consequent_name)
|
q = q.search_attributes(params, :antecedent_name, :consequent_name)
|
||||||
@@ -107,8 +97,6 @@ class TagRelationship < ApplicationRecord
|
|||||||
q = q.order("antecedent_name asc, consequent_name asc")
|
q = q.order("antecedent_name asc, consequent_name asc")
|
||||||
when "tag_count"
|
when "tag_count"
|
||||||
q = q.joins(:consequent_tag).order("tags.post_count desc, antecedent_name asc, consequent_name asc")
|
q = q.joins(:consequent_tag).order("tags.post_count desc, antecedent_name asc, consequent_name asc")
|
||||||
when "status"
|
|
||||||
q = q.pending_first
|
|
||||||
else
|
else
|
||||||
q = q.apply_default_order(params)
|
q = q.apply_default_order(params)
|
||||||
end
|
end
|
||||||
@@ -144,6 +132,10 @@ class TagRelationship < ApplicationRecord
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.approve!(antecedent_name:, consequent_name:, approver:, forum_topic: nil)
|
||||||
|
ProcessTagRelationshipJob.perform_later(class_name: self.name, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
|
||||||
|
end
|
||||||
|
|
||||||
def self.model_restriction(table)
|
def self.model_restriction(table)
|
||||||
super.where(table[:status].eq("active"))
|
super.where(table[:status].eq("active"))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<%= f.simple_fields_for :consequent_tag do |fa| %>
|
<%= f.simple_fields_for :consequent_tag do |fa| %>
|
||||||
<%= fa.input :category, label: "To Category", collection: TagCategory.canonical_mapping.to_a, include_blank: true, selected: params.dig(:search, :consequent_tag, :category) %>
|
<%= fa.input :category, label: "To Category", collection: TagCategory.canonical_mapping.to_a, include_blank: true, selected: params.dig(:search, :consequent_tag, :category) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= f.input :status, label: "Status", collection: %w[Active Pending Deleted Retired], include_blank: true, selected: params[:search][:status] %>
|
<%= f.input :status, label: "Status", collection: %w[Active Deleted Retired], include_blank: true, selected: params[:search][:status] %>
|
||||||
<%= f.input :order, label: "Order", collection: [%w[Created created_at], %w[Updated updated_at], %w[Name name], %w[Tag\ count tag_count], %w[Status status]], include_blank: true, selected: params[:search][:order] %>
|
<%= f.input :order, label: "Order", collection: [%w[Created created_at], %w[Updated updated_at], %w[Name name], %w[Tag\ count tag_count]], include_blank: true, selected: params[:search][:order] %>
|
||||||
<%= f.submit "Search" %>
|
<%= f.submit "Search" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class ChangeDefaultStatusOnTagRelationships < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
change_column_default(:tag_aliases, :status, from: "pending", to: "active")
|
||||||
|
change_column_default(:tag_implications, :status, from: "pending", to: "active")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2857,7 +2857,7 @@ CREATE TABLE public.tag_aliases (
|
|||||||
consequent_name character varying NOT NULL,
|
consequent_name character varying NOT NULL,
|
||||||
creator_id integer NOT NULL,
|
creator_id integer NOT NULL,
|
||||||
forum_topic_id integer,
|
forum_topic_id integer,
|
||||||
status text DEFAULT 'pending'::text NOT NULL,
|
status text DEFAULT 'active'::text NOT NULL,
|
||||||
created_at timestamp without time zone NOT NULL,
|
created_at timestamp without time zone NOT NULL,
|
||||||
updated_at timestamp without time zone NOT NULL,
|
updated_at timestamp without time zone NOT NULL,
|
||||||
approver_id integer,
|
approver_id integer,
|
||||||
@@ -2894,7 +2894,7 @@ CREATE TABLE public.tag_implications (
|
|||||||
consequent_name character varying NOT NULL,
|
consequent_name character varying NOT NULL,
|
||||||
creator_id integer NOT NULL,
|
creator_id integer NOT NULL,
|
||||||
forum_topic_id integer,
|
forum_topic_id integer,
|
||||||
status text DEFAULT 'pending'::text NOT NULL,
|
status text DEFAULT 'active'::text NOT NULL,
|
||||||
created_at timestamp without time zone NOT NULL,
|
created_at timestamp without time zone NOT NULL,
|
||||||
updated_at timestamp without time zone NOT NULL,
|
updated_at timestamp without time zone NOT NULL,
|
||||||
approver_id integer,
|
approver_id integer,
|
||||||
@@ -7419,6 +7419,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20200427190519'),
|
('20200427190519'),
|
||||||
('20200520060951'),
|
('20200520060951'),
|
||||||
('20200803022359'),
|
('20200803022359'),
|
||||||
('20200816175151');
|
('20200816175151'),
|
||||||
|
('20201201211748');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -107,10 +107,13 @@ class ArtistsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
|
|
||||||
context "ban action" do
|
context "ban action" do
|
||||||
should "ban an artist" do
|
should "ban an artist" do
|
||||||
put_auth ban_artist_path(@artist.id), @admin
|
perform_enqueued_jobs do
|
||||||
|
put_auth ban_artist_path(@artist.id), @admin
|
||||||
|
end
|
||||||
|
|
||||||
assert_redirected_to(@artist)
|
assert_redirected_to(@artist)
|
||||||
assert_equal(true, @artist.reload.is_banned?)
|
assert_equal(true, @artist.reload.is_banned?)
|
||||||
assert_equal(true, TagImplication.exists?(antecedent_name: @artist.name, consequent_name: "banned_artist"))
|
assert_equal(true, TagImplication.exists?(antecedent_name: @artist.name, consequent_name: "banned_artist", status: "active"))
|
||||||
end
|
end
|
||||||
|
|
||||||
should "not allow non-admins to ban artists" do
|
should "not allow non-admins to ban artists" do
|
||||||
|
|||||||
@@ -156,12 +156,14 @@ class BulkUpdateRequestsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
create(:tag, name: "artist2a", category: Tag.categories.artist, post_count: 20)
|
create(:tag, name: "artist2a", category: Tag.categories.artist, post_count: 20)
|
||||||
@bulk_update_request = create(:bulk_update_request, script: "mass update artist1a -> artist1b\ncreate alias artist2a -> artist2b")
|
@bulk_update_request = create(:bulk_update_request, script: "mass update artist1a -> artist1b\ncreate alias artist2a -> artist2b")
|
||||||
|
|
||||||
post_auth approve_bulk_update_request_path(@bulk_update_request), @builder
|
perform_enqueued_jobs do
|
||||||
|
post_auth approve_bulk_update_request_path(@bulk_update_request), @builder
|
||||||
|
end
|
||||||
|
|
||||||
assert_redirected_to(bulk_update_requests_path)
|
assert_redirected_to(bulk_update_requests_path)
|
||||||
assert_equal("approved", @bulk_update_request.reload.status)
|
assert_equal("approved", @bulk_update_request.reload.status)
|
||||||
assert_equal(@builder, @bulk_update_request.approver)
|
assert_equal(@builder, @bulk_update_request.approver)
|
||||||
assert_equal(true, TagAlias.where(antecedent_name: "artist2a", consequent_name: "artist2b").exists?)
|
assert_equal(true, TagAlias.exists?(antecedent_name: "artist2a", consequent_name: "artist2b", status: "active"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "show a notice for a single tag search with a pending BUR" do
|
should "show a notice for a single tag search with a pending BUR" do
|
||||||
|
create(:tag, name: "foo")
|
||||||
create(:bulk_update_request, script: "create alias foo -> bar")
|
create(:bulk_update_request, script: "create alias foo -> bar")
|
||||||
get_auth posts_path(tags: "foo"), @user
|
get_auth posts_path(tags: "foo"), @user
|
||||||
assert_select ".tag-change-notice"
|
assert_select ".tag-change-notice"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class TagAliasesControllerTest < ActionDispatch::IntegrationTest
|
|||||||
@antecedent_wiki = create(:wiki_page, title: "touhou", body: "zun project")
|
@antecedent_wiki = create(:wiki_page, title: "touhou", body: "zun project")
|
||||||
@consequent_wiki = create(:wiki_page, title: "touhou_project")
|
@consequent_wiki = create(:wiki_page, title: "touhou_project")
|
||||||
|
|
||||||
@other_alias = create(:tag_alias, antecedent_name: "touhou", consequent_name: "touhou_project", creator: @user, status: "pending", forum_topic: @forum_topic, forum_post: @forum_post)
|
@other_alias = create(:tag_alias, antecedent_name: "touhou", consequent_name: "touhou_project", creator: @user, status: "deleted", forum_topic: @forum_topic, forum_post: @forum_post)
|
||||||
@unrelated_alias = create(:tag_alias)
|
@unrelated_alias = create(:tag_alias)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ class TagAliasesControllerTest < ActionDispatch::IntegrationTest
|
|||||||
should respond_to_search({}).with { [@unrelated_alias, @other_alias, @tag_alias] }
|
should respond_to_search({}).with { [@unrelated_alias, @other_alias, @tag_alias] }
|
||||||
should respond_to_search(antecedent_name: "aaa").with { @tag_alias }
|
should respond_to_search(antecedent_name: "aaa").with { @tag_alias }
|
||||||
should respond_to_search(consequent_name: "bbb").with { @tag_alias }
|
should respond_to_search(consequent_name: "bbb").with { @tag_alias }
|
||||||
should respond_to_search(status: "pending").with { @other_alias }
|
should respond_to_search(status: "deleted").with { @other_alias }
|
||||||
|
|
||||||
context "using includes" do
|
context "using includes" do
|
||||||
should respond_to_search(antecedent_tag: {post_count: 1000}).with { @other_alias }
|
should respond_to_search(antecedent_tag: {post_count: 1000}).with { @other_alias }
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class TagImplicationsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
@antecedent_wiki = create(:wiki_page, title: "cannon", body: "made of fun")
|
@antecedent_wiki = create(:wiki_page, title: "cannon", body: "made of fun")
|
||||||
@consequent_wiki = create(:wiki_page, title: "weapon")
|
@consequent_wiki = create(:wiki_page, title: "weapon")
|
||||||
|
|
||||||
@other_implication = create(:tag_implication, antecedent_name: "cannon", consequent_name: "weapon", creator: @user, status: "pending", forum_topic: @forum_topic, forum_post: @forum_post)
|
@other_implication = create(:tag_implication, antecedent_name: "cannon", consequent_name: "weapon", creator: @user, status: "deleted", forum_topic: @forum_topic, forum_post: @forum_post)
|
||||||
@unrelated_implication = create(:tag_implication)
|
@unrelated_implication = create(:tag_implication)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ class TagImplicationsControllerTest < ActionDispatch::IntegrationTest
|
|||||||
should respond_to_search({}).with { [@unrelated_implication, @other_implication, @tag_implication] }
|
should respond_to_search({}).with { [@unrelated_implication, @other_implication, @tag_implication] }
|
||||||
should respond_to_search(antecedent_name: "aaa").with { @tag_implication }
|
should respond_to_search(antecedent_name: "aaa").with { @tag_implication }
|
||||||
should respond_to_search(consequent_name: "bbb").with { @tag_implication }
|
should respond_to_search(consequent_name: "bbb").with { @tag_implication }
|
||||||
should respond_to_search(status: "pending").with { @other_implication }
|
should respond_to_search(status: "deleted").with { @other_implication }
|
||||||
|
|
||||||
context "using includes" do
|
context "using includes" do
|
||||||
should respond_to_search(antecedent_tag: {post_count: 10}).with { @other_implication }
|
should respond_to_search(antecedent_tag: {post_count: 10}).with { @other_implication }
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ class ArtistTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "create a new tag implication" do
|
should "create a new tag implication" do
|
||||||
perform_enqueued_jobs
|
|
||||||
assert_equal(1, TagImplication.where(:antecedent_name => "aaa", :consequent_name => "banned_artist").count)
|
assert_equal(1, TagImplication.where(:antecedent_name => "aaa", :consequent_name => "banned_artist").count)
|
||||||
assert_equal("aaa banned_artist", @post.reload.tag_string)
|
assert_equal("aaa banned_artist", @post.reload.tag_string)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
should allow_value('active').for(:status)
|
should allow_value('active').for(:status)
|
||||||
should allow_value('deleted').for(:status)
|
should allow_value('deleted').for(:status)
|
||||||
should allow_value('pending').for(:status)
|
|
||||||
should allow_value('error: derp').for(:status)
|
should allow_value('error: derp').for(:status)
|
||||||
|
|
||||||
should_not allow_value('ACTIVE').for(:status)
|
should_not allow_value('ACTIVE').for(:status)
|
||||||
@@ -47,18 +46,17 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
ta2 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "retired")
|
ta2 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "retired")
|
||||||
ta3 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
ta3 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
||||||
ta4 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
ta4 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
||||||
ta5 = FactoryBot.create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
[ta1, ta2, ta3, ta4].each { |ta| assert(ta.valid?) }
|
||||||
[ta1, ta2, ta3, ta4, ta5].each { |ta| assert(ta.valid?) }
|
|
||||||
|
|
||||||
ta5.update(status: "active")
|
ta4.update(status: "active")
|
||||||
assert_includes(ta5.errors[:antecedent_name], "has already been taken")
|
assert_includes(ta4.errors[:antecedent_name], "has already been taken")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "#reject!" do
|
context "#reject!" do
|
||||||
should "not be blocked by validations" do
|
should "not be blocked by validations" do
|
||||||
ta1 = create(:tag_alias, antecedent_name: "kitty", consequent_name: "kitten", status: "active")
|
ta1 = create(:tag_alias, antecedent_name: "kitty", consequent_name: "kitten", status: "active")
|
||||||
ta2 = build(:tag_alias, antecedent_name: "cat", consequent_name: "kitty", status: "pending")
|
ta2 = build(:tag_alias, antecedent_name: "cat", consequent_name: "kitty", status: "active")
|
||||||
|
|
||||||
ta2.reject!
|
ta2.reject!
|
||||||
assert_equal("deleted", ta2.reload.status)
|
assert_equal("deleted", ta2.reload.status)
|
||||||
@@ -89,9 +87,8 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
@ss3 = create(:saved_search, query: "123 ~... 456", user: CurrentUser.user)
|
@ss3 = create(:saved_search, query: "123 ~... 456", user: CurrentUser.user)
|
||||||
@ss4 = create(:saved_search, query: "... 456", user: CurrentUser.user)
|
@ss4 = create(:saved_search, query: "... 456", user: CurrentUser.user)
|
||||||
@ss5 = create(:saved_search, query: "123 ...", user: CurrentUser.user)
|
@ss5 = create(:saved_search, query: "123 ...", user: CurrentUser.user)
|
||||||
@ta = create(:tag_alias, antecedent_name: "...", consequent_name: "bbb")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "...", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal("123 bbb 456", @ss1.reload.query)
|
assert_equal("123 bbb 456", @ss1.reload.query)
|
||||||
@@ -111,9 +108,8 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
@u5 = create(:user, blacklisted_tags: "111 ...")
|
@u5 = create(:user, blacklisted_tags: "111 ...")
|
||||||
@u6 = create(:user, blacklisted_tags: "111 222\n\n... 333\n")
|
@u6 = create(:user, blacklisted_tags: "111 222\n\n... 333\n")
|
||||||
@u7 = create(:user, blacklisted_tags: "111 ...\r\n222 333\n")
|
@u7 = create(:user, blacklisted_tags: "111 ...\r\n222 333\n")
|
||||||
@ta = create(:tag_alias, antecedent_name: "...", consequent_name: "aaa")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "...", consequent_name: "aaa", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal("111 aaa 222", @u1.reload.blacklisted_tags)
|
assert_equal("111 aaa 222", @u1.reload.blacklisted_tags)
|
||||||
@@ -130,8 +126,7 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
post1 = FactoryBot.create(:post, :tag_string => "aaa bbb")
|
post1 = FactoryBot.create(:post, :tag_string => "aaa bbb")
|
||||||
post2 = FactoryBot.create(:post, :tag_string => "ccc ddd")
|
post2 = FactoryBot.create(:post, :tag_string => "ccc ddd")
|
||||||
|
|
||||||
ta = FactoryBot.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "ccc")
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "ccc", approver: @admin)
|
||||||
ta.approve!(@admin)
|
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal("bbb ccc", post1.reload.tag_string)
|
assert_equal("bbb ccc", post1.reload.tag_string)
|
||||||
@@ -151,11 +146,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
context "when the tags have wikis" do
|
context "when the tags have wikis" do
|
||||||
should "rename the old wiki if there is no conflict" do
|
should "rename the old wiki if there is no conflict" do
|
||||||
@wiki = create(:wiki_page, title: "aaa")
|
@wiki = create(:wiki_page, title: "aaa")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal("bbb", @wiki.reload.title)
|
assert_equal("bbb", @wiki.reload.title)
|
||||||
end
|
end
|
||||||
@@ -163,11 +156,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "merge existing wikis if there is a conflict" do
|
should "merge existing wikis if there is a conflict" do
|
||||||
@wiki1 = create(:wiki_page, title: "aaa", other_names: "111 222", body: "first")
|
@wiki1 = create(:wiki_page, title: "aaa", other_names: "111 222", body: "first")
|
||||||
@wiki2 = create(:wiki_page, title: "bbb", other_names: "111 333", body: "second")
|
@wiki2 = create(:wiki_page, title: "bbb", other_names: "111 333", body: "second")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal(true, @wiki1.reload.is_deleted)
|
assert_equal(true, @wiki1.reload.is_deleted)
|
||||||
assert_equal([], @wiki1.other_names)
|
assert_equal([], @wiki1.other_names)
|
||||||
@@ -181,11 +172,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "ignore the old wiki if it has been deleted" do
|
should "ignore the old wiki if it has been deleted" do
|
||||||
@wiki1 = create(:wiki_page, title: "aaa", other_names: "111 222", body: "first", is_deleted: true)
|
@wiki1 = create(:wiki_page, title: "aaa", other_names: "111 222", body: "first", is_deleted: true)
|
||||||
@wiki2 = create(:wiki_page, title: "bbb", other_names: "111 333", body: "second")
|
@wiki2 = create(:wiki_page, title: "bbb", other_names: "111 333", body: "second")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal(true, @wiki1.reload.is_deleted)
|
assert_equal(true, @wiki1.reload.is_deleted)
|
||||||
assert_equal(%w[111 222], @wiki1.other_names)
|
assert_equal(%w[111 222], @wiki1.other_names)
|
||||||
@@ -198,11 +187,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
should "rewrite links in other wikis to use the new tag" do
|
should "rewrite links in other wikis to use the new tag" do
|
||||||
@wiki = create(:wiki_page, body: "foo [[aaa]] bar")
|
@wiki = create(:wiki_page, body: "foo [[aaa]] bar")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal("foo [[bbb]] bar", @wiki.reload.body)
|
assert_equal("foo [[bbb]] bar", @wiki.reload.body)
|
||||||
end
|
end
|
||||||
@@ -211,11 +198,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
context "when the tags have artist entries" do
|
context "when the tags have artist entries" do
|
||||||
should "rename the old artist entry if there is no conflict" do
|
should "rename the old artist entry if there is no conflict" do
|
||||||
@artist = create(:artist, name: "aaa")
|
@artist = create(:artist, name: "aaa")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal("bbb", @artist.reload.name)
|
assert_equal("bbb", @artist.reload.name)
|
||||||
end
|
end
|
||||||
@@ -224,11 +209,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
@tag = create(:tag, name: "aaa", category: Tag.categories.artist)
|
@tag = create(:tag, name: "aaa", category: Tag.categories.artist)
|
||||||
@artist1 = create(:artist, name: "aaa", group_name: "g_aaa", other_names: "111 222", url_string: "https://twitter.com/111\n-https://twitter.com/222")
|
@artist1 = create(:artist, name: "aaa", group_name: "g_aaa", other_names: "111 222", url_string: "https://twitter.com/111\n-https://twitter.com/222")
|
||||||
@artist2 = create(:artist, name: "bbb", other_names: "111 333", url_string: "https://twitter.com/111\n-https://twitter.com/333\nhttps://twitter.com/444")
|
@artist2 = create(:artist, name: "bbb", other_names: "111 333", url_string: "https://twitter.com/111\n-https://twitter.com/333\nhttps://twitter.com/444")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal(true, @artist1.reload.is_deleted)
|
assert_equal(true, @artist1.reload.is_deleted)
|
||||||
assert_equal([@artist2.name], @artist1.other_names)
|
assert_equal([@artist2.name], @artist1.other_names)
|
||||||
@@ -244,11 +227,9 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "ignore the old artist if it has been deleted" do
|
should "ignore the old artist if it has been deleted" do
|
||||||
@artist1 = create(:artist, name: "aaa", group_name: "g_aaa", other_names: "111 222", url_string: "https://twitter.com/111\n-https://twitter.com/222", is_deleted: true)
|
@artist1 = create(:artist, name: "aaa", group_name: "g_aaa", other_names: "111 222", url_string: "https://twitter.com/111\n-https://twitter.com/222", is_deleted: true)
|
||||||
@artist2 = create(:artist, name: "bbb", other_names: "111 333", url_string: "https://twitter.com/111\n-https://twitter.com/333\nhttps://twitter.com/444")
|
@artist2 = create(:artist, name: "bbb", other_names: "111 333", url_string: "https://twitter.com/111\n-https://twitter.com/333\nhttps://twitter.com/444")
|
||||||
@ta = create(:tag_alias, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
|
||||||
|
|
||||||
@ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "aaa", consequent_name: "bbb", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
assert_equal("active", @ta.reload.status)
|
|
||||||
|
|
||||||
assert_equal(true, @artist1.reload.is_deleted)
|
assert_equal(true, @artist1.reload.is_deleted)
|
||||||
assert_equal(%w[111 222], @artist1.other_names)
|
assert_equal(%w[111 222], @artist1.other_names)
|
||||||
@@ -265,9 +246,8 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "push the consequent's category to the antecedent if the antecedent is general" do
|
should "push the consequent's category to the antecedent if the antecedent is general" do
|
||||||
tag1 = create(:tag, name: "general", category: 0)
|
tag1 = create(:tag, name: "general", category: 0)
|
||||||
tag2 = create(:tag, name: "artist", category: 1)
|
tag2 = create(:tag, name: "artist", category: 1)
|
||||||
ta = create(:tag_alias, antecedent_name: "general", consequent_name: "artist")
|
|
||||||
|
|
||||||
ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "general", consequent_name: "artist", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal(1, tag1.reload.category)
|
assert_equal(1, tag1.reload.category)
|
||||||
@@ -277,9 +257,8 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "push the antecedent's category to the consequent if the consequent is general" do
|
should "push the antecedent's category to the consequent if the consequent is general" do
|
||||||
tag1 = create(:tag, name: "artist", category: 1)
|
tag1 = create(:tag, name: "artist", category: 1)
|
||||||
tag2 = create(:tag, name: "general", category: 0)
|
tag2 = create(:tag, name: "general", category: 0)
|
||||||
ta = create(:tag_alias, antecedent_name: "artist", consequent_name: "general")
|
|
||||||
|
|
||||||
ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "artist", consequent_name: "general", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal(1, tag1.reload.category)
|
assert_equal(1, tag1.reload.category)
|
||||||
@@ -289,9 +268,8 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "not change either tag category when neither the antecedent or consequent are general" do
|
should "not change either tag category when neither the antecedent or consequent are general" do
|
||||||
tag1 = create(:tag, name: "character", category: 4)
|
tag1 = create(:tag, name: "character", category: 4)
|
||||||
tag2 = create(:tag, name: "copyright", category: 3)
|
tag2 = create(:tag, name: "copyright", category: 3)
|
||||||
ta = create(:tag_alias, antecedent_name: "character", consequent_name: "copyright")
|
|
||||||
|
|
||||||
ta.approve!(@admin)
|
TagAlias.approve!(antecedent_name: "character", consequent_name: "copyright", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal(4, tag1.reload.category)
|
assert_equal(4, tag1.reload.category)
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
should allow_value('active').for(:status)
|
should allow_value('active').for(:status)
|
||||||
should allow_value('deleted').for(:status)
|
should allow_value('deleted').for(:status)
|
||||||
should allow_value('pending').for(:status)
|
|
||||||
should allow_value('error: derp').for(:status)
|
should allow_value('error: derp').for(:status)
|
||||||
|
|
||||||
should_not allow_value('ACTIVE').for(:status)
|
should_not allow_value('ACTIVE').for(:status)
|
||||||
@@ -43,17 +42,16 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
ti2 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "retired")
|
ti2 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "retired")
|
||||||
ti3 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
ti3 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
||||||
ti4 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
ti4 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "deleted")
|
||||||
ti5 = FactoryBot.create(:tag_implication, antecedent_name: "aaa", consequent_name: "bbb", status: "pending")
|
[ti1, ti2, ti3, ti4].each { |ti| assert(ti.valid?) }
|
||||||
[ti1, ti2, ti3, ti4, ti5].each { |ti| assert(ti.valid?) }
|
|
||||||
|
|
||||||
ti5.update(status: "active")
|
ti4.update(status: "active")
|
||||||
assert_includes(ti5.errors[:antecedent_name], "Implication already exists")
|
assert_includes(ti4.errors[:antecedent_name], "Implication already exists")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "#reject!" do
|
context "#reject!" do
|
||||||
should "not be blocked by alias validations" do
|
should "not be blocked by alias validations" do
|
||||||
ti = create(:tag_implication, antecedent_name: "cat", consequent_name: "animal", status: "pending")
|
ti = create(:tag_implication, antecedent_name: "cat", consequent_name: "animal", status: "active")
|
||||||
ta = create(:tag_alias, antecedent_name: "cat", consequent_name: "kitty", status: "active")
|
ta = create(:tag_alias, antecedent_name: "cat", consequent_name: "kitty", status: "active")
|
||||||
|
|
||||||
ti.reject!
|
ti.reject!
|
||||||
@@ -120,11 +118,9 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
should "update any affected post upon save" do
|
should "update any affected post upon save" do
|
||||||
p1 = FactoryBot.create(:post, :tag_string => "aaa bbb ccc")
|
p1 = FactoryBot.create(:post, :tag_string => "aaa bbb ccc")
|
||||||
ti1 = FactoryBot.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "xxx")
|
|
||||||
ti2 = FactoryBot.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "yyy")
|
|
||||||
|
|
||||||
ti1.approve!(@admin)
|
TagImplication.approve!(antecedent_name: "aaa", consequent_name: "xxx", approver: @admin)
|
||||||
ti2.approve!(@admin)
|
TagImplication.approve!(antecedent_name: "aaa", consequent_name: "yyy", approver: @admin)
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
assert_equal("aaa bbb ccc xxx yyy", p1.reload.tag_string)
|
assert_equal("aaa bbb ccc xxx yyy", p1.reload.tag_string)
|
||||||
@@ -149,7 +145,7 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
should "not include inactive implications" do
|
should "not include inactive implications" do
|
||||||
create(:tag_implication, antecedent_name: "a", consequent_name: "b", status: "active")
|
create(:tag_implication, antecedent_name: "a", consequent_name: "b", status: "active")
|
||||||
create(:tag_implication, antecedent_name: "b", consequent_name: "c", status: "pending")
|
create(:tag_implication, antecedent_name: "b", consequent_name: "c", status: "deleted")
|
||||||
create(:tag_implication, antecedent_name: "c", consequent_name: "d", status: "active")
|
create(:tag_implication, antecedent_name: "c", consequent_name: "d", status: "active")
|
||||||
|
|
||||||
assert_equal(["b"], TagImplication.tags_implied_by("a").map(&:name))
|
assert_equal(["b"], TagImplication.tags_implied_by("a").map(&:name))
|
||||||
|
|||||||
Reference in New Issue
Block a user