このコミットが含まれているのは:
@@ -7,6 +7,8 @@ class PostsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
url = params[:url].presence
|
url = params[:url].presence
|
||||||
title = params[:title].presence
|
title = params[:title].presence
|
||||||
original_created_from = params[:original_created_from].presence
|
original_created_from = params[:original_created_from].presence
|
||||||
@@ -46,7 +48,7 @@ class PostsController < ApplicationController
|
|||||||
'COALESCE(pt_max.max_updated_at, posts.updated_at))'
|
'COALESCE(pt_max.max_updated_at, posts.updated_at))'
|
||||||
|
|
||||||
q =
|
q =
|
||||||
filtered_posts
|
filtered_posts(locale)
|
||||||
.joins("LEFT JOIN (#{ pt_max_sql }) pt_max ON pt_max.post_id = posts.id")
|
.joins("LEFT JOIN (#{ pt_max_sql }) pt_max ON pt_max.post_id = posts.id")
|
||||||
.reselect('posts.*', Arel.sql("#{ updated_at_all_sql } AS updated_at_all"))
|
.reselect('posts.*', Arel.sql("#{ updated_at_all_sql } AS updated_at_all"))
|
||||||
.preload(:external_tags, :uploaded_user, :parents, :children,
|
.preload(:external_tags, :uploaded_user, :parents, :children,
|
||||||
@@ -102,8 +104,10 @@ class PostsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def random
|
def random
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
post =
|
post =
|
||||||
filtered_posts
|
filtered_posts(locale)
|
||||||
.preload(:uploaded_user, :parents, :children,
|
.preload(:uploaded_user, :parents, :children,
|
||||||
post_tags: [:sections, { tag: [:deerjikists, :materials,
|
post_tags: [:sections, { tag: [:deerjikists, :materials,
|
||||||
{ tag_name: :wiki_page }] }])
|
{ tag_name: :wiki_page }] }])
|
||||||
@@ -394,19 +398,19 @@ class PostsController < ApplicationController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def filtered_posts
|
def filtered_posts locale
|
||||||
tag_names = params[:tags].to_s.split
|
tag_names = params[:tags].to_s.split
|
||||||
match_type = params[:match]
|
match_type = params[:match]
|
||||||
if tag_names.present?
|
if tag_names.present?
|
||||||
filter_posts_by_tags(tag_names, match_type)
|
filter_posts_by_tags(locale, tag_names, match_type)
|
||||||
else
|
else
|
||||||
Post.all
|
Post.all
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_posts_by_tags tag_names, match_type
|
def filter_posts_by_tags locale, tag_names, match_type
|
||||||
literals = tag_names.map do |raw_name|
|
literals = tag_names.map do |raw_name|
|
||||||
{ name: TagName.canonicalise(raw_name.sub(/\Anot:/i, '')).first,
|
{ name: TagName.canonicalise(locale, raw_name.sub(/\Anot:/i, '')).first,
|
||||||
negative: raw_name.downcase.start_with?('not:') }
|
negative: raw_name.downcase.start_with?('not:') }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ class TagsController < ApplicationController
|
|||||||
else
|
else
|
||||||
tag.update!(category:, deprecated_at: deprecated ? Time.current : nil)
|
tag.update!(category:, deprecated_at: deprecated ? Time.current : nil)
|
||||||
end
|
end
|
||||||
rename_tag_name!(tag, name) if name_changed
|
rename_tag_name!(locale, tag, name) if name_changed
|
||||||
|
|
||||||
alias_names << old_name if name_changed
|
alias_names << old_name if name_changed
|
||||||
alias_names.delete(name)
|
alias_names.delete(name)
|
||||||
@@ -701,13 +701,13 @@ class TagsController < ApplicationController
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def rename_tag_name! tag, name
|
def rename_tag_name! locale, tag, name
|
||||||
return if name == tag.name
|
return if name == tag.name(locale.language_code)
|
||||||
|
|
||||||
current_tag_name = tag.tag_name
|
current_tag_name = tag.tag_name(locale.language_code)
|
||||||
target_tag_name = TagName.find_by(name:)
|
target_tag_name = TagName.find_by(language_code: locale.language_code, name:)
|
||||||
|
|
||||||
if target_tag_name.nil?
|
unless target_tag_name
|
||||||
current_tag_name.update!(name:)
|
current_tag_name.update!(name:)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -722,19 +722,21 @@ class TagsController < ApplicationController
|
|||||||
TagVersioning.ensure_snapshot!(old_owner_tag, created_by_user: current_user)
|
TagVersioning.ensure_snapshot!(old_owner_tag, created_by_user: current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
promoted_tag_name.update!(canonical: nil)
|
promoted_tag_name.update!(canonical_id: nil, primary_flg: true)
|
||||||
|
|
||||||
TagName.where(canonical_id: current_tag_name.id)
|
TagName.where(tag:,
|
||||||
|
language_code: current_tag_name.language.language_code,
|
||||||
|
primary_flg: false)
|
||||||
.where.not(id: promoted_tag_name.id)
|
.where.not(id: promoted_tag_name.id)
|
||||||
.find_each do |alias_tag_name|
|
.find_each do |alias_tag_name|
|
||||||
alias_tag_name.update!(canonical: promoted_tag_name)
|
alias_tag_name.update!(canonical_id: promoted_tag_name, primary_flg: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
current_tag_name.wiki_page&.update!(tag_name: promoted_tag_name)
|
current_tag_name.wiki_page&.update!(tag_name_id: promoted_tag_name.id)
|
||||||
tag.update!(tag_name: promoted_tag_name)
|
tag.update!(tag_name_id: promoted_tag_name.id)
|
||||||
current_tag_name.association(:wiki_page).reset
|
current_tag_name.association(:wiki_page).reset
|
||||||
current_tag_name.association(:tag).reset
|
current_tag_name.association(:tag).reset
|
||||||
current_tag_name.reload.update!(canonical: promoted_tag_name)
|
current_tag_name.reload.update!(canonical_id: promoted_tag_name, primary_flg: false)
|
||||||
|
|
||||||
return unless old_owner_tag && old_owner_tag != tag
|
return unless old_owner_tag && old_owner_tag != tag
|
||||||
|
|
||||||
@@ -766,12 +768,12 @@ class TagsController < ApplicationController
|
|||||||
current_aliases.each do |alias_tag_name|
|
current_aliases.each do |alias_tag_name|
|
||||||
next if alias_names.include?(alias_tag_name.name)
|
next if alias_names.include?(alias_tag_name.name)
|
||||||
|
|
||||||
alias_tag_name.update!(canonical: nil)
|
alias_tag_name.update!(canonical_id: nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_names.each do |alias_name|
|
alias_names.each do |alias_name|
|
||||||
alias_tag_name = TagName.find_or_create_by!(name: alias_name)
|
alias_tag_name = TagName.find_or_create_by!(name: alias_name)
|
||||||
alias_tag_name.update!(canonical: tag.tag_name)
|
alias_tag_name.update!(canonical_id: tag.tag_name.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
affected_tags.compact.uniq.each do |affected_tag|
|
affected_tags.compact.uniq.each do |affected_tag|
|
||||||
|
|||||||
@@ -51,12 +51,10 @@ class Tag < ApplicationRecord
|
|||||||
has_many :tag_versions
|
has_many :tag_versions
|
||||||
|
|
||||||
has_many :tag_names
|
has_many :tag_names
|
||||||
belongs_to :tag_name
|
|
||||||
delegate :wiki_page, to: :tag_name
|
delegate :wiki_page, to: :tag_name
|
||||||
|
|
||||||
attribute :version_no, :integer, default: 1
|
attribute :version_no, :integer, default: 1
|
||||||
|
|
||||||
delegate :name, to: :tag_name, allow_nil: true
|
|
||||||
validates :tag_name, presence: true
|
validates :tag_name, presence: true
|
||||||
|
|
||||||
enum :category, deerjikist: 'deerjikist',
|
enum :category, deerjikist: 'deerjikist',
|
||||||
@@ -84,9 +82,8 @@ class Tag < ApplicationRecord
|
|||||||
'mtr:' => :material,
|
'mtr:' => :material,
|
||||||
'meta:' => :meta }.freeze
|
'meta:' => :meta }.freeze
|
||||||
|
|
||||||
def name= val
|
def tag_name(language_code) = tag_names.find_by(language_code:, primary_flg: true)
|
||||||
(self.tag_name ||= build_tag_name).name = val
|
def name(language_code) = tag_name(language_code)&.name
|
||||||
end
|
|
||||||
|
|
||||||
def deprecated? = deprecated_at?
|
def deprecated? = deprecated_at?
|
||||||
|
|
||||||
@@ -276,7 +273,7 @@ class Tag < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
TagVersioning.record!(source_tag, event_type: :discard, created_by_user:)
|
TagVersioning.record!(source_tag, event_type: :discard, created_by_user:)
|
||||||
source_tag.tag_names.update_all(tag_id: source_tag.id, primary_key: false,
|
source_tag.tag_names.update_all(tag_id: target_tag.id, primary_flg: false,
|
||||||
updated_at: Time.current)
|
updated_at: Time.current)
|
||||||
source_tag.destroy!
|
source_tag.destroy!
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ class TagName < ApplicationRecord
|
|||||||
|
|
||||||
def primary? = primary_flg
|
def primary? = primary_flg
|
||||||
|
|
||||||
def canonical = TagName.find_by(language:, tag:, primary_flg: true)
|
def canonical = TagName.find_by(language_code:, tag_id:, primary_flg: true)
|
||||||
def aliases = TagName.where(language:, tag:, primary_flg: false)
|
def aliases = TagName.where(language_code:, tag_id:, primary_flg: false)
|
||||||
|
|
||||||
def self.canonicalise locale, names
|
def self.canonicalise locale, names
|
||||||
names = Array(names).map { |n| n.to_s.strip }.reject(&:blank?)
|
names = Array(names).map { |n| n.to_s.strip }.reject(&:blank?)
|
||||||
@@ -23,7 +23,7 @@ class TagName < ApplicationRecord
|
|||||||
tns = TagName.where(language_code: locale.language_code, name: names).index_by(&:name)
|
tns = TagName.where(language_code: locale.language_code, name: names).index_by(&:name)
|
||||||
|
|
||||||
names.map { |name|
|
names.map { |name|
|
||||||
if tns[name].primary_flg
|
if !(tns[name]) || tns[name].primary?
|
||||||
name
|
name
|
||||||
else
|
else
|
||||||
TagName.find_by(language_code: locale.language_code,
|
TagName.find_by(language_code: locale.language_code,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class PostCreatePlan
|
|||||||
|
|
||||||
def build! locale
|
def build! locale
|
||||||
direct_tag_specs, tag_sections = parse_direct_tag_specs(locale)
|
direct_tag_specs, tag_sections = parse_direct_tag_specs(locale)
|
||||||
default_tag_specs = build_default_tag_specs(direct_tag_specs)
|
default_tag_specs = build_default_tag_specs(locale, direct_tag_specs)
|
||||||
snapshot_tag_specs = merge_tag_specs(direct_tag_specs + default_tag_specs)
|
snapshot_tag_specs = merge_tag_specs(direct_tag_specs + default_tag_specs)
|
||||||
preload_existing_tags_by_name!(snapshot_tag_specs.map { _1[:name] })
|
preload_existing_tags_by_name!(snapshot_tag_specs.map { _1[:name] })
|
||||||
validate_new_tag_specs!(snapshot_tag_specs)
|
validate_new_tag_specs!(snapshot_tag_specs)
|
||||||
@@ -263,12 +263,11 @@ class PostCreatePlan
|
|||||||
end
|
end
|
||||||
|
|
||||||
def resolved_tag_name locale, name
|
def resolved_tag_name locale, name
|
||||||
tag_name = TagName.find_by!(language_code: locale.language_code, name:)
|
tag_name = TagName.find_by(language_code: locale.language_code, name:)
|
||||||
unless tag_name.primary_flg
|
return name if !(tag_name) || tag_name.primary?
|
||||||
tag_name = TagName.find_by!(language_code: locale.language_code,
|
|
||||||
tag_id: tag_name.tag_id,
|
TagName.find_by!(language_code: locale.language_code,
|
||||||
primary_flg: true)
|
tag_id: tag_name.tag_id,
|
||||||
end
|
primary_flg: true).name
|
||||||
tag_name.name
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ class PostCreator
|
|||||||
normalised_parent_post_ids: @attributes[:normalised_parent_post_ids] || [],
|
normalised_parent_post_ids: @attributes[:normalised_parent_post_ids] || [],
|
||||||
video_ms: @attributes[:video_ms] }
|
video_ms: @attributes[:video_ms] }
|
||||||
else
|
else
|
||||||
build_materialised_plan
|
build_materialised_plan(locale)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_materialised_plan
|
def build_materialised_plan locale
|
||||||
plan = PostCreatePlan.new(attributes: @attributes).build!
|
plan = PostCreatePlan.new(attributes: @attributes).build!(locale)
|
||||||
snapshot_tags = materialise_tags(plan[:snapshot_tag_specs] || [])
|
snapshot_tags = materialise_tags(plan[:snapshot_tag_specs] || [])
|
||||||
post_tags = materialise_tags(plan[:post_tag_specs] || [])
|
post_tags = materialise_tags(plan[:post_tag_specs] || [])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,29 @@
|
|||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :tag do
|
factory :tag do
|
||||||
transient do
|
transient do
|
||||||
name { nil }
|
primary_name { nil }
|
||||||
|
primary_tag_name do
|
||||||
|
attributes = primary_name.nil? ? { } : { name: primary_name }
|
||||||
|
build(:tag_name, **attributes)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
category { :general }
|
category { :general }
|
||||||
post_count { 0 }
|
post_count { 0 }
|
||||||
|
|
||||||
association :tag_name
|
|
||||||
|
|
||||||
after(:build) do |tag, evaluator|
|
after(:build) do |tag, evaluator|
|
||||||
tag.name = evaluator.name if evaluator.name.present?
|
evaluator.primary_tag_name.primary_flg = true
|
||||||
|
tag.tag_names.target << evaluator.primary_tag_name
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:create) do |tag|
|
before(:create) do |tag, evaluator|
|
||||||
tag.tag_name.update!(tag:) if tag.tag_name.tag_id != tag.id
|
evaluator.primary_tag_name.save!
|
||||||
|
# Compatibility write only; ownership is established through tag_id below.
|
||||||
|
tag.tag_name_id = evaluator.primary_tag_name.id
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:create) do |tag, evaluator|
|
||||||
|
evaluator.primary_tag_name.update!(tag:, primary_flg: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,17 +13,19 @@ RSpec.describe Locale, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'generates a primary name for every existing tag using the name generator' do
|
it 'generates a primary name for every existing tag using the name generator' do
|
||||||
first = create(:tag, name: 'first_existing_tag')
|
first = create(:tag, primary_name: 'first_existing_tag')
|
||||||
second = create(:tag, name: 'second_existing_tag')
|
second = create(:tag, primary_name: 'second_existing_tag')
|
||||||
allow(TagName).to receive(:generate_name).and_call_original
|
allow(TagName).to receive(:generate_name).and_call_original
|
||||||
allow(TagName).to receive(:generate_name)
|
allow(TagName).to receive(:generate_name)
|
||||||
.with(kind_of(described_class), first, first.name)
|
.with(kind_of(described_class), first, primary_tag_name_for(first, 'ja').name)
|
||||||
.and_return('name_from_generator')
|
.and_return('name_from_generator')
|
||||||
|
|
||||||
locale = create_french_locale!
|
locale = create_french_locale!
|
||||||
|
|
||||||
expect(TagName).to have_received(:generate_name).with(locale, first, first.name)
|
expect(TagName).to have_received(:generate_name)
|
||||||
expect(TagName).to have_received(:generate_name).with(locale, second, second.name)
|
.with(locale, first, primary_tag_name_for(first, 'ja').name)
|
||||||
|
expect(TagName).to have_received(:generate_name)
|
||||||
|
.with(locale, second, primary_tag_name_for(second, 'ja').name)
|
||||||
expect(first.tag_names.find_by!(language_code: 'fr', primary_flg: true))
|
expect(first.tag_names.find_by!(language_code: 'fr', primary_flg: true))
|
||||||
.to have_attributes(name: 'name_from_generator', tag_id: first.id,
|
.to have_attributes(name: 'name_from_generator', tag_id: first.id,
|
||||||
language_code: 'fr', script_code: 'Latn',
|
language_code: 'fr', script_code: 'Latn',
|
||||||
@@ -37,7 +39,7 @@ RSpec.describe Locale, type: :model do
|
|||||||
|
|
||||||
it 'does not duplicate an existing primary name in the new language' do
|
it 'does not duplicate an existing primary name in the new language' do
|
||||||
prepare_french_reference!
|
prepare_french_reference!
|
||||||
tag = create(:tag, name: 'already_named')
|
tag = create(:tag, primary_name: 'already_named')
|
||||||
existing = create(:tag_name, name: 'nom_existant', tag:,
|
existing = create(:tag_name, name: 'nom_existant', tag:,
|
||||||
language_code: 'fr', script_code: 'Latn')
|
language_code: 'fr', script_code: 'Latn')
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ RSpec.describe Locale, type: :model do
|
|||||||
|
|
||||||
it 'creates a primary name when the language has only an alias' do
|
it 'creates a primary name when the language has only an alias' do
|
||||||
prepare_french_reference!
|
prepare_french_reference!
|
||||||
tag = create(:tag, name: 'alias_only_tag')
|
tag = create(:tag, primary_name: 'alias_only_tag')
|
||||||
alias_name = create(:tag_name, :alias, name: 'alias_fr',
|
alias_name = create(:tag_name, :alias, name: 'alias_fr',
|
||||||
tag:,
|
tag:,
|
||||||
language_code: 'fr', script_code: 'Latn')
|
language_code: 'fr', script_code: 'Latn')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe MaterialExportItem, type: :model do
|
RSpec.describe MaterialExportItem, type: :model do
|
||||||
let(:user) { create(:user, :member) }
|
let(:user) { create(:user, :member) }
|
||||||
let(:tag) { create(:tag, name: 'export_item', category: :material) }
|
let(:tag) { create(:tag, primary_name: 'export_item', category: :material) }
|
||||||
let(:material) do
|
let(:material) do
|
||||||
Material.create!(tag:, url: 'https://example.com/material',
|
Material.create!(tag:, url: 'https://example.com/material',
|
||||||
created_by_user: user, updated_by_user: user)
|
created_by_user: user, updated_by_user: user)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ RSpec.describe Post, type: :model do
|
|||||||
expect(post.snapshot_tags_json).to eq([
|
expect(post.snapshot_tags_json).to eq([
|
||||||
{ 'tag_id' => tag.id,
|
{ 'tag_id' => tag.id,
|
||||||
'version_no' => tag.version_no,
|
'version_no' => tag.version_no,
|
||||||
'name' => tag.name,
|
'name' => primary_tag_name_for(tag, 'ja').name,
|
||||||
'category' => tag.category,
|
'category' => tag.category,
|
||||||
'sections' => [{ 'begin_ms' => 2000, 'end_ms' => nil }] },
|
'sections' => [{ 'begin_ms' => 2000, 'end_ms' => nil }] },
|
||||||
{ 'external_tag_id' => external.id }])
|
{ 'external_tag_id' => external.id }])
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe PostVersion, type: :model do
|
RSpec.describe PostVersion, type: :model do
|
||||||
let!(:tag_name) { create(:tag_name, name: 'post_version_spec_tag') }
|
let!(:tag_name) { create(:tag_name, name: 'post_version_spec_tag') }
|
||||||
let!(:tag) { create(:tag, tag_name: tag_name, category: :general) }
|
let!(:tag) { create(:tag, primary_tag_name: tag_name, category: :general) }
|
||||||
|
|
||||||
let!(:post_record) do
|
let!(:post_record) do
|
||||||
Post.create!(title: 'spec post', url: 'https://example.com/post-version-spec').tap do |post|
|
Post.create!(title: 'spec post', url: 'https://example.com/post-version-spec').tap do |post|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe TagImplication, type: :model do
|
RSpec.describe TagImplication, type: :model do
|
||||||
it 'rejects a parent tag that would create a cycle' do
|
it 'rejects a parent tag that would create a cycle' do
|
||||||
child = create(:tag, name: 'tag_implication_cycle_child')
|
child = create(:tag, primary_name: 'tag_implication_cycle_child')
|
||||||
parent = create(:tag, name: 'tag_implication_cycle_parent')
|
parent = create(:tag, primary_name: 'tag_implication_cycle_parent')
|
||||||
|
|
||||||
described_class.create!(tag: child, parent_tag: parent)
|
described_class.create!(tag: child, parent_tag: parent)
|
||||||
|
|
||||||
@@ -17,9 +17,9 @@ RSpec.describe TagImplication, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'terminates even when existing data already contains a cycle' do
|
it 'terminates even when existing data already contains a cycle' do
|
||||||
child = create(:tag, name: 'tag_implication_existing_cycle_child')
|
child = create(:tag, primary_name: 'tag_implication_existing_cycle_child')
|
||||||
parent = create(:tag, name: 'tag_implication_existing_cycle_parent')
|
parent = create(:tag, primary_name: 'tag_implication_existing_cycle_parent')
|
||||||
ancestor = create(:tag, name: 'tag_implication_existing_cycle_ancestor')
|
ancestor = create(:tag, primary_name: 'tag_implication_existing_cycle_ancestor')
|
||||||
|
|
||||||
described_class.create!(tag: parent, parent_tag: ancestor)
|
described_class.create!(tag: parent, parent_tag: ancestor)
|
||||||
described_class.insert_all!(
|
described_class.insert_all!(
|
||||||
|
|||||||
@@ -50,17 +50,17 @@ RSpec.describe TagNameSanitisationRule, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'renames without merging tags or deleting either language identity' do
|
it 'renames without merging tags or deleting either language identity' do
|
||||||
japanese = create(:tag, name: 'foobar')
|
japanese = create(:tag, primary_name: 'foobar')
|
||||||
english_name = create(:tag_name, name: 'temporary',
|
english_name = create(:tag_name, name: 'temporary',
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
english = create(:tag, tag_name: english_name)
|
english = create(:tag, primary_tag_name: english_name)
|
||||||
english_name.update_columns(name: 'foo_bar')
|
english_name.update_columns(name: 'foo_bar')
|
||||||
|
|
||||||
described_class.apply!
|
described_class.apply!
|
||||||
|
|
||||||
expect(english_name.reload).to have_attributes(
|
expect(english_name.reload).to have_attributes(
|
||||||
name: 'foobar', language_code: 'en', tag_id: english.id)
|
name: 'foobar', language_code: 'en', tag_id: english.id)
|
||||||
expect(japanese.reload.tag_name).to have_attributes(
|
expect(primary_tag_name_for(japanese.reload, 'ja')).to have_attributes(
|
||||||
name: 'foobar', language_code: 'ja', tag_id: japanese.id)
|
name: 'foobar', language_code: 'ja', tag_id: japanese.id)
|
||||||
expect(english.reload.tag_name_id).to eq(english_name.id)
|
expect(english.reload.tag_name_id).to eq(english_name.id)
|
||||||
end
|
end
|
||||||
@@ -96,15 +96,19 @@ RSpec.describe TagNameSanitisationRule, type: :model do
|
|||||||
|
|
||||||
context 'when the source tag_name has a tag and the existing one has no tag' do
|
context 'when the source tag_name has a tag and the existing one has no tag' do
|
||||||
let!(:existing) { create(:tag_name, name: 'foobar') }
|
let!(:existing) { create(:tag_name, name: 'foobar') }
|
||||||
let!(:source_tag) { create(:tag, name: 'tmp', category: :general) }
|
let!(:source_tag) { create(:tag, primary_name: 'tmp', category: :general) }
|
||||||
let!(:source_tag_name_id) { source_tag.tag_name_id }
|
let!(:source_tag_name_id) { primary_tag_name_for(source_tag, 'ja').id }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
source_tag.tag_name.update_columns(name: 'foo_bar', updated_at: Time.current)
|
primary_tag_name_for(source_tag, 'ja').update_columns(
|
||||||
|
name: 'foo_bar', updated_at: Time.current)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'moves the tag to the existing tag_name' do
|
it 'moves the tag to the existing tag_name' do
|
||||||
described_class.apply!
|
described_class.apply!
|
||||||
|
expect(existing.reload).to have_attributes(
|
||||||
|
tag_id: source_tag.id, language_code: 'ja', primary_flg: true)
|
||||||
|
expect(primary_tag_name_for(source_tag, 'ja')).to eq(existing)
|
||||||
expect(source_tag.reload.tag_name_id).to eq(existing.id)
|
expect(source_tag.reload.tag_name_id).to eq(existing.id)
|
||||||
expect(TagName.unscoped.exists?(source_tag_name_id)).to be(false)
|
expect(TagName.unscoped.exists?(source_tag_name_id)).to be(false)
|
||||||
end
|
end
|
||||||
@@ -112,6 +116,7 @@ RSpec.describe TagNameSanitisationRule, type: :model do
|
|||||||
|
|
||||||
context 'when the sanitised name is an alias of an existing tag' do
|
context 'when the sanitised name is an alias of an existing tag' do
|
||||||
let!(:existing_tag) { create(:tag) }
|
let!(:existing_tag) { create(:tag) }
|
||||||
|
let!(:existing_primary) { primary_tag_name_for(existing_tag, 'ja') }
|
||||||
let!(:alias_name) do
|
let!(:alias_name) do
|
||||||
create(:tag_name, :alias, name: 'foobar', tag: existing_tag)
|
create(:tag_name, :alias, name: 'foobar', tag: existing_tag)
|
||||||
end
|
end
|
||||||
@@ -129,17 +134,17 @@ RSpec.describe TagNameSanitisationRule, type: :model do
|
|||||||
tag_id: existing_tag.id, language_code: 'ja', primary_flg: false)
|
tag_id: existing_tag.id, language_code: 'ja', primary_flg: false)
|
||||||
expect(TagName.find_by!(tag_id: existing_tag.id,
|
expect(TagName.find_by!(tag_id: existing_tag.id,
|
||||||
language_code: 'ja', primary_flg: true))
|
language_code: 'ja', primary_flg: true))
|
||||||
.to eq(existing_tag.tag_name)
|
.to eq(existing_primary)
|
||||||
expect(Tag.find(existing_tag.id)).to eq(existing_tag)
|
expect(Tag.find(existing_tag.id)).to eq(existing_tag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when both source and existing tag_names have tags' do
|
context 'when both source and existing tag_names have tags' do
|
||||||
let!(:existing_tn) { create(:tag_name, name: 'foobar') }
|
let!(:existing_tn) { create(:tag_name, name: 'foobar') }
|
||||||
let!(:existing_tag) { create(:tag, tag_name: existing_tn, category: :general) }
|
let!(:existing_tag) { create(:tag, primary_tag_name: existing_tn, category: :general) }
|
||||||
|
|
||||||
let!(:source_tn) { create(:tag_name, name: 'tmp') }
|
let!(:source_tn) { create(:tag_name, name: 'tmp') }
|
||||||
let!(:source_tag) { create(:tag, tag_name: source_tn, category: :general) }
|
let!(:source_tag) { create(:tag, primary_tag_name: source_tn, category: :general) }
|
||||||
let!(:source_tag_name_id) { source_tn.id }
|
let!(:source_tag_name_id) { source_tn.id }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@@ -155,7 +160,7 @@ RSpec.describe TagNameSanitisationRule, type: :model do
|
|||||||
expect(Tag.unscoped.exists?(source_tag.id)).to be(false)
|
expect(Tag.unscoped.exists?(source_tag.id)).to be(false)
|
||||||
expect(TagName.unscoped.exists?(source_tag_name_id)).to be(false)
|
expect(TagName.unscoped.exists?(source_tag_name_id)).to be(false)
|
||||||
expect(post.reload.tags).to contain_exactly(existing_tag)
|
expect(post.reload.tags).to contain_exactly(existing_tag)
|
||||||
expect(existing_tag.reload.name).to eq('foobar')
|
expect(primary_tag_name_for(existing_tag.reload, 'ja').name).to eq('foobar')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,16 +28,33 @@ RSpec.describe TagName, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'persists both sides of the representative tag factory association' do
|
it 'persists both sides of the representative tag factory association' do
|
||||||
tag = create(:tag)
|
name = create(:tag_name)
|
||||||
|
tag = create(:tag, primary_tag_name: name)
|
||||||
|
|
||||||
expect(tag.reload.tag_name.reload.tag_id).to eq(tag.id)
|
expect(name.reload).to have_attributes(
|
||||||
expect(tag.tag_name.tag).to eq(tag)
|
tag_id: tag.id, language_code: 'ja', script_code: 'Jpan', primary_flg: true)
|
||||||
|
expect(name.tag).to eq(tag)
|
||||||
expect(described_class.find_by!(tag_id: tag.id, language_code: 'ja', primary_flg: true))
|
expect(described_class.find_by!(tag_id: tag.id, language_code: 'ja', primary_flg: true))
|
||||||
.to eq(tag.tag_name)
|
.to eq(name)
|
||||||
|
expect(tag.reload.tag_name_id).to eq(name.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'builds a primary name without persisting the tag or its name' do
|
||||||
|
tag = nil
|
||||||
|
|
||||||
|
expect {
|
||||||
|
tag = build(:tag, primary_name: 'built_primary')
|
||||||
|
}.to change(Tag, :count).by(0).and change(described_class, :count).by(0)
|
||||||
|
|
||||||
|
expect(tag).to be_new_record
|
||||||
|
expect(tag.tag_names.target).to contain_exactly(have_attributes(
|
||||||
|
name: 'built_primary', language_code: 'ja', script_code: 'Jpan',
|
||||||
|
primary_flg: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'persists an alias owned by the same tag as its primary name' do
|
it 'persists an alias owned by the same tag as its primary name' do
|
||||||
tag = create(:tag)
|
primary_name = create(:tag_name)
|
||||||
|
tag = create(:tag, primary_tag_name: primary_name)
|
||||||
alias_name = create(:tag_name, :alias, name: 'valid_alias', tag:)
|
alias_name = create(:tag_name, :alias, name: 'valid_alias', tag:)
|
||||||
|
|
||||||
expect(alias_name.reload).to have_attributes(
|
expect(alias_name.reload).to have_attributes(
|
||||||
@@ -46,12 +63,12 @@ RSpec.describe TagName, type: :model do
|
|||||||
primary = described_class.find_by!(tag_id: alias_name.tag_id,
|
primary = described_class.find_by!(tag_id: alias_name.tag_id,
|
||||||
language_code: alias_name.language_code,
|
language_code: alias_name.language_code,
|
||||||
primary_flg: true)
|
primary_flg: true)
|
||||||
expect(primary).to eq(tag.tag_name)
|
expect(primary).to eq(primary_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.canonicalise' do
|
describe '.canonicalise' do
|
||||||
it 'resolves the primary name of the alias language on the same tag' do
|
it 'resolves the primary name of the alias language on the same tag' do
|
||||||
tag = create(:tag, name: '日本語正本')
|
tag = create(:tag, primary_name: '日本語正本')
|
||||||
english_primary = create(:tag_name, tag:, name: 'english_primary',
|
english_primary = create(:tag_name, tag:, name: 'english_primary',
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
english_alias = create(:tag_name, :alias, tag:, name: 'english_alias',
|
english_alias = create(:tag_name, :alias, tag:, name: 'english_alias',
|
||||||
@@ -69,10 +86,10 @@ RSpec.describe TagName, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'resolves only aliases in the requested language' do
|
it 'resolves only aliases in the requested language' do
|
||||||
japanese = create(:tag, name: 'japanese_canonical')
|
japanese = create(:tag, primary_name: 'japanese_canonical')
|
||||||
english_name = create(:tag_name, name: 'english_canonical',
|
english_name = create(:tag_name, name: 'english_canonical',
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
english = create(:tag, tag_name: english_name)
|
english = create(:tag, primary_tag_name: english_name)
|
||||||
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
tag: japanese)
|
tag: japanese)
|
||||||
english_alias = create(:tag_name, :alias, name: 'shared_alias',
|
english_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
describe 'external tag separation' do
|
describe 'external tag separation' do
|
||||||
['nico:reserved', 'NiCo:reserved'].each do |name|
|
['nico:reserved', 'NiCo:reserved'].each do |name|
|
||||||
it "rejects the reserved prefix #{ name } for internal tags" do
|
it "rejects the reserved prefix #{ name } for internal tags" do
|
||||||
tag = build(:tag, name:)
|
tag = build(:tag, primary_name: name)
|
||||||
|
|
||||||
expect(tag).to be_invalid
|
expect(tag).to be_invalid
|
||||||
expect(tag.errors[:name]).to be_present
|
expect(tag.errors[:name]).to be_present
|
||||||
@@ -32,10 +32,10 @@ RSpec.describe Tag, type: :model do
|
|||||||
{ code: 'en', language_code: 'en', script_code: 'Latn',
|
{ code: 'en', language_code: 'en', script_code: 'Latn',
|
||||||
name: 'English', created_at: Time.current }]) unless Locale.exists?(code: 'en')
|
name: 'English', created_at: Time.current }]) unless Locale.exists?(code: 'en')
|
||||||
english_locale = Locale.find('en')
|
english_locale = Locale.find('en')
|
||||||
japanese = create(:tag, name: 'japanese_canonical')
|
japanese = create(:tag, primary_name: 'japanese_canonical')
|
||||||
english_name = create(:tag_name, name: 'english_canonical',
|
english_name = create(:tag_name, name: 'english_canonical',
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
english = create(:tag, tag_name: english_name)
|
english = create(:tag, primary_tag_name: english_name)
|
||||||
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
tag: japanese)
|
tag: japanese)
|
||||||
english_alias = create(:tag_name, :alias, name: 'shared_alias',
|
english_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
@@ -59,16 +59,16 @@ RSpec.describe Tag, type: :model do
|
|||||||
it 'rejects deprecated tags when deny_deprecated is enabled' do
|
it 'rejects deprecated tags when deny_deprecated is enabled' do
|
||||||
tag_name = create(:tag_name, name: 'normalise deprecated tag')
|
tag_name = create(:tag_name, name: 'normalise deprecated tag')
|
||||||
deprecated_tag = create(:tag,
|
deprecated_tag = create(:tag,
|
||||||
tag_name:,
|
primary_tag_name: tag_name,
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: 1.day.from_now)
|
deprecated_at: 1.day.from_now)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
described_class.normalise_tags!(Locale.nipponese,
|
described_class.normalise_tags!(Locale.nipponese,
|
||||||
[deprecated_tag.name],
|
[primary_tag_name_for(deprecated_tag, 'ja').name],
|
||||||
deny_deprecated: true)
|
deny_deprecated: true)
|
||||||
}.to raise_error(Tag::DeprecatedTagNormalisationError) { |error|
|
}.to raise_error(Tag::DeprecatedTagNormalisationError) { |error|
|
||||||
expect(error.tag_names).to eq([deprecated_tag.name])
|
expect(error.tag_names).to eq([primary_tag_name_for(deprecated_tag, 'ja').name])
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -85,7 +85,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[1:00-]'],
|
['伊地知ニジカ[1:00-]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, nil]])
|
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, nil]])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -94,7 +96,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[-1:00]'],
|
['伊地知ニジカ[-1:00]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections).fetch(tag.id)).to eq([[0, 60_000]])
|
expect(result.fetch(:sections).fetch(tag.id)).to eq([[0, 60_000]])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -103,7 +107,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[-]'],
|
['伊地知ニジカ[-]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections)[tag.id]).to be_nil
|
expect(result.fetch(:sections)[tag.id]).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -112,7 +118,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[0:00-]'],
|
['伊地知ニジカ[0:00-]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections)[tag.id]).to be_nil
|
expect(result.fetch(:sections)[tag.id]).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -121,7 +129,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[1:00-1:00]'],
|
['伊地知ニジカ[1:00-1:00]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, 60_001]])
|
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, 60_001]])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -130,7 +140,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[2:00-1:00]'],
|
['伊地知ニジカ[2:00-1:00]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, 120_000]])
|
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, 120_000]])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -139,7 +151,9 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[1:00-][2:00-3:00]'],
|
['伊地知ニジカ[1:00-][2:00-3:00]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, nil]])
|
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, nil]])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -148,25 +162,23 @@ RSpec.describe Tag, type: :model do
|
|||||||
['伊地知ニジカ[1:00-3:00][3:00-]'],
|
['伊地知ニジカ[1:00-3:00][3:00-]'],
|
||||||
with_sections: true)
|
with_sections: true)
|
||||||
|
|
||||||
tag = result.fetch(:tags).find { _1.name == '伊地知ニジカ' }
|
tag = result.fetch(:tags).find do |candidate|
|
||||||
|
primary_tag_name_for(candidate, 'ja').name == '伊地知ニジカ'
|
||||||
|
end
|
||||||
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, nil]])
|
expect(result.fetch(:sections).fetch(tag.id)).to eq([[60_000, nil]])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.expand_parent_tags' do
|
describe '.expand_parent_tags' do
|
||||||
it 'expands through multiple deprecated parents to an active ancestor' do
|
it 'expands through multiple deprecated parents to an active ancestor' do
|
||||||
child = create(:tag, name: 'expand_child')
|
child = create(:tag, primary_name: 'expand_child')
|
||||||
deprecated_parent = create(
|
deprecated_parent = create(:tag,
|
||||||
:tag,
|
primary_name: 'expand_deprecated_parent',
|
||||||
name: 'expand_deprecated_parent',
|
deprecated_at: Time.current)
|
||||||
deprecated_at: Time.current
|
deprecated_grandparent = create(:tag,
|
||||||
)
|
primary_name: 'expand_deprecated_grandparent',
|
||||||
deprecated_grandparent = create(
|
deprecated_at: Time.current)
|
||||||
:tag,
|
active_ancestor = create(:tag, primary_name: 'expand_active_ancestor')
|
||||||
name: 'expand_deprecated_grandparent',
|
|
||||||
deprecated_at: Time.current
|
|
||||||
)
|
|
||||||
active_ancestor = create(:tag, name: 'expand_active_ancestor')
|
|
||||||
TagImplication.create!(tag: child, parent_tag: deprecated_parent)
|
TagImplication.create!(tag: child, parent_tag: deprecated_parent)
|
||||||
TagImplication.create!(tag: deprecated_parent, parent_tag: deprecated_grandparent)
|
TagImplication.create!(tag: deprecated_parent, parent_tag: deprecated_grandparent)
|
||||||
TagImplication.create!(tag: deprecated_grandparent, parent_tag: active_ancestor)
|
TagImplication.create!(tag: deprecated_grandparent, parent_tag: active_ancestor)
|
||||||
@@ -183,8 +195,8 @@ RSpec.describe Tag, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'terminates when implications contain a cycle' do
|
it 'terminates when implications contain a cycle' do
|
||||||
first = create(:tag, name: 'expand_cycle_first')
|
first = create(:tag, primary_name: 'expand_cycle_first')
|
||||||
second = create(:tag, name: 'expand_cycle_second')
|
second = create(:tag, primary_name: 'expand_cycle_second')
|
||||||
TagImplication.create!(tag: first, parent_tag: second)
|
TagImplication.create!(tag: first, parent_tag: second)
|
||||||
now = Time.current
|
now = Time.current
|
||||||
TagImplication.insert_all!(
|
TagImplication.insert_all!(
|
||||||
@@ -210,7 +222,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
tag = described_class.find_or_create_by_tag_name!(
|
tag = described_class.find_or_create_by_tag_name!(
|
||||||
locale, 'english_name', category: :character)
|
locale, 'english_name', category: :character)
|
||||||
|
|
||||||
expect(tag.tag_name.reload).to have_attributes(
|
expect(primary_tag_name_for(tag, 'en')).to have_attributes(
|
||||||
language_code: 'en', script_code: 'Latn',
|
language_code: 'en', script_code: 'Latn',
|
||||||
primary_flg: true, tag_id: tag.id)
|
primary_flg: true, tag_id: tag.id)
|
||||||
expect(tag.category).to eq('character')
|
expect(tag.category).to eq('character')
|
||||||
@@ -223,8 +235,10 @@ RSpec.describe Tag, type: :model do
|
|||||||
locale, 'same_name', category: :character)
|
locale, 'same_name', category: :character)
|
||||||
|
|
||||||
expect(english).not_to eq(japanese)
|
expect(english).not_to eq(japanese)
|
||||||
expect(english.tag_name.language_code).to eq('en')
|
expect(primary_tag_name_for(english, 'en')).to have_attributes(
|
||||||
expect(japanese.tag_name.language_code).to eq('ja')
|
name: 'same_name', tag_id: english.id, language_code: 'en', primary_flg: true)
|
||||||
|
expect(primary_tag_name_for(japanese, 'ja')).to have_attributes(
|
||||||
|
name: 'same_name', tag_id: japanese.id, language_code: 'ja', primary_flg: true)
|
||||||
expect(described_class.find_or_create_by_tag_name!(
|
expect(described_class.find_or_create_by_tag_name!(
|
||||||
locale, 'same_name', category: :general)).to eq(english)
|
locale, 'same_name', category: :general)).to eq(english)
|
||||||
expect(described_class.find_or_create_by_tag_name!(
|
expect(described_class.find_or_create_by_tag_name!(
|
||||||
@@ -232,7 +246,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'preserves the V1 representative when looking up another primary language' do
|
it 'preserves the V1 representative when looking up another primary language' do
|
||||||
tag = create(:tag, name: '日本語代表名')
|
tag = create(:tag, primary_name: '日本語代表名')
|
||||||
representative_id = tag.tag_name_id
|
representative_id = tag.tag_name_id
|
||||||
english = create(:tag_name, name: 'english_primary', tag:,
|
english = create(:tag_name, name: 'english_primary', tag:,
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
@@ -251,7 +265,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
with_tagme: false, with_no_deerjikist: false)
|
with_tagme: false, with_no_deerjikist: false)
|
||||||
|
|
||||||
expect(tags.length).to eq(1)
|
expect(tags.length).to eq(1)
|
||||||
expect(tags.first.tag_name).to have_attributes(
|
expect(primary_tag_name_for(tags.first, 'en')).to have_attributes(
|
||||||
name: 'normalised_english', language_code: 'en', script_code: 'Latn',
|
name: 'normalised_english', language_code: 'en', script_code: 'Latn',
|
||||||
primary_flg: true, tag_id: tags.first.id)
|
primary_flg: true, tag_id: tags.first.id)
|
||||||
end
|
end
|
||||||
@@ -265,7 +279,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
' lookup_new ', category: :character)
|
' lookup_new ', category: :character)
|
||||||
}.to change(Tag, :count).by(1).and change(TagName, :count).by(1)
|
}.to change(Tag, :count).by(1).and change(TagName, :count).by(1)
|
||||||
|
|
||||||
expect(tag.name).to eq('lookup_new')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('lookup_new')
|
||||||
expect(tag.category).to eq('character')
|
expect(tag.category).to eq('character')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -290,7 +304,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
|
|
||||||
it 'reuses the owning tag through another alias' do
|
it 'reuses the owning tag through another alias' do
|
||||||
tag = create(:tag)
|
tag = create(:tag)
|
||||||
primary = tag.tag_name
|
primary = primary_tag_name_for(tag, 'ja')
|
||||||
alias_name = create(:tag_name, :alias, name: 'lookup_alias', tag:)
|
alias_name = create(:tag_name, :alias, name: 'lookup_alias', tag:)
|
||||||
other_alias = create(:tag_name, :alias, name: 'lookup_other_alias', tag:)
|
other_alias = create(:tag_name, :alias, name: 'lookup_other_alias', tag:)
|
||||||
|
|
||||||
@@ -304,14 +318,14 @@ RSpec.describe Tag, type: :model do
|
|||||||
expect(found).to eq(tag)
|
expect(found).to eq(tag)
|
||||||
}.to change(Tag, :count).by(0).and change(TagName, :count).by(0)
|
}.to change(Tag, :count).by(0).and change(TagName, :count).by(0)
|
||||||
|
|
||||||
expect(tag.reload.tag_name).to eq(primary)
|
expect(primary_tag_name_for(tag.reload, 'ja')).to eq(primary)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.merge_tags!' do
|
describe '.merge_tags!' do
|
||||||
let!(:target_tag) { create(:tag, category: :general) }
|
let!(:target_tag) { create(:tag, category: :general) }
|
||||||
let!(:source_tag) { create(:tag, category: :general) }
|
let!(:source_tag) { create(:tag, category: :general) }
|
||||||
let!(:source_tag_name) { source_tag.tag_name }
|
let!(:source_tag_name) { primary_tag_name_for(source_tag, 'ja') }
|
||||||
|
|
||||||
let!(:post_record) do
|
let!(:post_record) do
|
||||||
Post.create!(url: 'https://example.com/posts/1', title: 'test post')
|
Post.create!(url: 'https://example.com/posts/1', title: 'test post')
|
||||||
@@ -363,7 +377,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
|
|
||||||
it 'keeps source history and records the new target alias after deleting the source' do
|
it 'keeps source history and records the new target alias after deleting the source' do
|
||||||
user = create_member_user!
|
user = create_member_user!
|
||||||
source_name = source_tag.name
|
source_name = primary_tag_name_for(source_tag, 'ja').name
|
||||||
source_alias = create(:tag_name, :alias, name: 'merge_alias', tag: source_tag)
|
source_alias = create(:tag_name, :alias, name: 'merge_alias', tag: source_tag)
|
||||||
TagVersioning.ensure_snapshot!(source_tag, created_by_user: user)
|
TagVersioning.ensure_snapshot!(source_tag, created_by_user: user)
|
||||||
original_version = source_tag.tag_versions.first
|
original_version = source_tag.tag_versions.first
|
||||||
@@ -380,7 +394,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
|
|
||||||
target_versions = target_tag.tag_versions.order(:version_no)
|
target_versions = target_tag.tag_versions.order(:version_no)
|
||||||
expect(target_versions.pluck(:event_type)).to eq(['create', 'update'])
|
expect(target_versions.pluck(:event_type)).to eq(['create', 'update'])
|
||||||
expect(target_versions.last.aliases.split).to eq([source_name])
|
expect(target_versions.last.aliases.split).to contain_exactly('merge_alias', source_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'deletes source relationships while preserving unrelated relationships' do
|
it 'deletes source relationships while preserving unrelated relationships' do
|
||||||
@@ -486,7 +500,7 @@ RSpec.describe Tag, type: :model do
|
|||||||
|
|
||||||
it 'rolls back earlier deletions, links, and history when a later source has a wiki' do
|
it 'rolls back earlier deletions, links, and history when a later source has a wiki' do
|
||||||
earlier_source = create(:tag)
|
earlier_source = create(:tag)
|
||||||
earlier_name = earlier_source.tag_name
|
earlier_name = primary_tag_name_for(earlier_source, 'ja')
|
||||||
source_section = create(:post_tag_section, post: post_record,
|
source_section = create(:post_tag_section, post: post_record,
|
||||||
tag: source_tag,
|
tag: source_tag,
|
||||||
begin_ms: 1000, end_ms: 2000)
|
begin_ms: 1000, end_ms: 2000)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe VersionRecord, type: :model do
|
RSpec.describe VersionRecord, type: :model do
|
||||||
let!(:tag) { create(:tag, name: 'version_record_tag') }
|
let!(:tag) { create(:tag, primary_name: 'version_record_tag') }
|
||||||
let!(:nico_tag) { create(:external_tag, name: 'version_record_tag') }
|
let!(:nico_tag) { create(:external_tag, name: 'version_record_tag') }
|
||||||
|
|
||||||
it 'makes TagVersion read only after create' do
|
it 'makes TagVersion read only after create' do
|
||||||
@@ -9,7 +9,7 @@ RSpec.describe VersionRecord, type: :model do
|
|||||||
tag: tag,
|
tag: tag,
|
||||||
version_no: 1,
|
version_no: 1,
|
||||||
event_type: 'create',
|
event_type: 'create',
|
||||||
name: tag.name,
|
name: primary_tag_name_for(tag, 'ja').name,
|
||||||
category: tag.category,
|
category: tag.category,
|
||||||
aliases: '',
|
aliases: '',
|
||||||
parent_tag_ids: '',
|
parent_tag_ids: '',
|
||||||
@@ -27,7 +27,7 @@ RSpec.describe VersionRecord, type: :model do
|
|||||||
tag: tag,
|
tag: tag,
|
||||||
version_no: 1,
|
version_no: 1,
|
||||||
event_type: 'create',
|
event_type: 'create',
|
||||||
name: tag.name,
|
name: primary_tag_name_for(tag, 'ja').name,
|
||||||
category: tag.category,
|
category: tag.category,
|
||||||
aliases: '',
|
aliases: '',
|
||||||
parent_tag_ids: '',
|
parent_tag_ids: '',
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ RSpec.describe 'Deerjikists API', type: :request do
|
|||||||
|
|
||||||
expect(json['tag']).to be_a(Hash)
|
expect(json['tag']).to be_a(Hash)
|
||||||
expect(json['tag']['id']).to eq(tag1.id)
|
expect(json['tag']['id']).to eq(tag1.id)
|
||||||
expect(json['tag']['name']).to eq(tag1.name)
|
expect(json['tag']['name']).to eq(primary_tag_name_for(tag1, 'ja').name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ RSpec.describe 'error responses', type: :request do
|
|||||||
|
|
||||||
it 'returns a stable field-error payload for unprocessable requests' do
|
it 'returns a stable field-error payload for unprocessable requests' do
|
||||||
member = create(:user, :member)
|
member = create(:user, :member)
|
||||||
tag = create(:tag, :general, name: 'error_response_tag')
|
tag = create(:tag, category: :general, primary_name: 'error_response_tag')
|
||||||
sign_in_as(member)
|
sign_in_as(member)
|
||||||
|
|
||||||
patch "/tags/#{ tag.id }", params: { category: 'nico' }
|
patch "/tags/#{ tag.id }", params: { category: 'nico' }
|
||||||
|
|||||||
@@ -898,22 +898,22 @@ RSpec.describe 'Gekanator learning API', type: :request do
|
|||||||
|
|
||||||
describe 'GET /gekanator/questions' do
|
describe 'GET /gekanator/questions' do
|
||||||
it 'omits questions for deprecated tags' do
|
it 'omits questions for deprecated tags' do
|
||||||
active_tag = create(:tag, name: 'active_question_tag', category: :general)
|
active_tag = create(:tag, primary_name: 'active_question_tag', category: :general)
|
||||||
deprecated_tag = create(:tag,
|
deprecated_tag = create(:tag,
|
||||||
name: 'deprecated_question_tag',
|
primary_name: 'deprecated_question_tag',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
|
|
||||||
[active_tag, deprecated_tag].each do |question_tag|
|
[active_tag, deprecated_tag].each do |question_tag|
|
||||||
GekanatorQuestion.create!(
|
GekanatorQuestion.create!(
|
||||||
text: "#{ question_tag.name }?",
|
text: "#{ primary_tag_name_for(question_tag, 'ja').name }?",
|
||||||
kind: 'tag',
|
kind: 'tag',
|
||||||
source: 'admin_curated',
|
source: 'admin_curated',
|
||||||
status: 'accepted',
|
status: 'accepted',
|
||||||
priority_weight: 1.0,
|
priority_weight: 1.0,
|
||||||
condition: {
|
condition: {
|
||||||
type: 'tag',
|
type: 'tag',
|
||||||
key: "#{ question_tag.category }:#{ question_tag.name }"
|
key: "#{ question_tag.category }:#{ primary_tag_name_for(question_tag, 'ja').name }"
|
||||||
},
|
},
|
||||||
created_by: admin
|
created_by: admin
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ require 'rails_helper'
|
|||||||
RSpec.describe 'Gekanator posts API', type: :request do
|
RSpec.describe 'Gekanator posts API', type: :request do
|
||||||
describe 'GET /gekanator/posts' do
|
describe 'GET /gekanator/posts' do
|
||||||
it 'omits deprecated tags and returns the stored similarity cosine' do
|
it 'omits deprecated tags and returns the stored similarity cosine' do
|
||||||
active_tag = create(:tag, name: 'active tag', category: :general)
|
active_tag = create(:tag, primary_name: 'active tag', category: :general)
|
||||||
deprecated_tag = create(:tag,
|
deprecated_tag = create(:tag,
|
||||||
name: 'deprecated tag',
|
primary_name: 'deprecated tag',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
post_record = Post.create!(title: 'source', url: 'https://example.com/source')
|
post_record = Post.create!(title: 'source', url: 'https://example.com/source')
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
|
|||||||
tag = create(:tag)
|
tag = create(:tag)
|
||||||
|
|
||||||
put "/tags/#{ tag.id }", params: locale_params.merge(
|
put "/tags/#{ tag.id }", params: locale_params.merge(
|
||||||
name: tag.name, category: tag.category, deprecated: false,
|
name: primary_tag_name_for(tag, 'ja').name, category: tag.category, deprecated: false,
|
||||||
aliases: '', parent_tags: 'locale_parent')
|
aliases: '', parent_tags: 'locale_parent')
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok), response.body
|
expect(response).to have_http_status(:ok), response.body
|
||||||
@@ -110,11 +110,11 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
|
|||||||
let!(:english_name) do
|
let!(:english_name) do
|
||||||
create(:tag_name, name: 'shared_name', language_code: 'en', script_code: 'Latn')
|
create(:tag_name, name: 'shared_name', language_code: 'en', script_code: 'Latn')
|
||||||
end
|
end
|
||||||
let!(:english_tag) { create(:tag, tag_name: english_name, category: :material) }
|
let!(:english_tag) { create(:tag, primary_tag_name: english_name, category: :material) }
|
||||||
let!(:japanese_tag) do
|
let!(:japanese_tag) do
|
||||||
create(:tag, name: 'temporary_japanese', category: :general).tap do |tag|
|
create(:tag, primary_name: 'temporary_japanese', category: :general).tap do |tag|
|
||||||
# Isolate lookup from the separately tested uniqueness validation.
|
# Isolate lookup from the separately tested uniqueness validation.
|
||||||
tag.tag_name.update_columns(name: 'shared_name')
|
primary_tag_name_for(tag, 'ja').update_columns(name: 'shared_name')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -157,7 +157,8 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
|
|||||||
child = create(:tag)
|
child = create(:tag)
|
||||||
|
|
||||||
put "/tags/#{ child.id }", params: {
|
put "/tags/#{ child.id }", params: {
|
||||||
locale: 'en', name: child.name, category: child.category, deprecated: false,
|
locale: 'en', name: primary_tag_name_for(child, 'ja').name,
|
||||||
|
category: child.category, deprecated: false,
|
||||||
aliases: '', parent_tags: 'shared_name' }
|
aliases: '', parent_tags: 'shared_name' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok), response.body
|
expect(response).to have_http_status(:ok), response.body
|
||||||
@@ -180,23 +181,24 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
|
|||||||
let!(:english_name) do
|
let!(:english_name) do
|
||||||
create(:tag_name, name: 'english_original', language_code: 'en', script_code: 'Latn')
|
create(:tag_name, name: 'english_original', language_code: 'en', script_code: 'Latn')
|
||||||
end
|
end
|
||||||
let!(:tag) { create(:tag, tag_name: english_name) }
|
let!(:tag) { create(:tag, primary_tag_name: english_name) }
|
||||||
|
|
||||||
it 'allows a rename to a name already used in Japanese' do
|
it 'allows a rename to a name already used in Japanese' do
|
||||||
japanese = create(:tag, name: 'rename_target')
|
japanese = create(:tag, primary_name: 'rename_target')
|
||||||
|
|
||||||
patch "/tags/#{ tag.id }", params: { locale: 'en', name: 'rename_target' }
|
patch "/tags/#{ tag.id }", params: { locale: 'en', name: 'rename_target' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok), response.body
|
expect(response).to have_http_status(:ok), response.body
|
||||||
expect(tag.reload.tag_name).to have_attributes(
|
expect(primary_tag_name_for(tag.reload, 'en')).to have_attributes(
|
||||||
name: 'rename_target', language_code: 'en', tag_id: tag.id)
|
name: 'rename_target', language_code: 'en', tag_id: tag.id)
|
||||||
expect(japanese.reload.tag_name).to have_attributes(
|
expect(primary_tag_name_for(japanese.reload, 'ja')).to have_attributes(
|
||||||
name: 'rename_target', language_code: 'ja', tag_id: japanese.id)
|
name: 'rename_target', language_code: 'ja', tag_id: japanese.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates aliases in the requested language' do
|
it 'creates aliases in the requested language' do
|
||||||
put "/tags/#{ tag.id }", params: {
|
put "/tags/#{ tag.id }", params: {
|
||||||
locale: 'en', name: tag.name, category: tag.category, deprecated: false,
|
locale: 'en', name: english_name.name,
|
||||||
|
category: tag.category, deprecated: false,
|
||||||
aliases: 'english_alias', parent_tags: '' }
|
aliases: 'english_alias', parent_tags: '' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok), response.body
|
expect(response).to have_http_status(:ok), response.body
|
||||||
@@ -210,7 +212,7 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'does not take an alias from another language' do
|
it 'does not take an alias from another language' do
|
||||||
japanese = create(:tag, name: 'japanese_owner')
|
japanese = create(:tag, primary_name: 'japanese_owner')
|
||||||
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
tag: japanese)
|
tag: japanese)
|
||||||
expect(japanese_alias.reload).to have_attributes(
|
expect(japanese_alias.reload).to have_attributes(
|
||||||
@@ -218,7 +220,8 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
|
|||||||
primary_flg: false, language_code: 'ja')
|
primary_flg: false, language_code: 'ja')
|
||||||
|
|
||||||
put "/tags/#{ tag.id }", params: {
|
put "/tags/#{ tag.id }", params: {
|
||||||
locale: 'en', name: tag.name, category: tag.category, deprecated: false,
|
locale: 'en', name: english_name.name,
|
||||||
|
category: tag.category, deprecated: false,
|
||||||
aliases: 'shared_alias', parent_tags: '' }
|
aliases: 'shared_alias', parent_tags: '' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok), response.body
|
expect(response).to have_http_status(:ok), response.body
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
describe 'GET /materials' do
|
describe 'GET /materials' do
|
||||||
let!(:tag_a) do
|
let!(:tag_a) do
|
||||||
create(:tag, name: 'material_index_a', category: :material)
|
create(:tag, primary_name: 'material_index_a', category: :material)
|
||||||
end
|
end
|
||||||
let!(:tag_b) do
|
let!(:tag_b) do
|
||||||
create(:tag, name: 'material_index_b', category: :material)
|
create(:tag, primary_name: 'material_index_b', category: :material)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:material_a) do
|
let!(:material_a) do
|
||||||
@@ -116,20 +116,20 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
it 'filters by descendant tags and returns stable parent tag groups' do
|
it 'filters by descendant tags and returns stable parent tag groups' do
|
||||||
root =
|
root =
|
||||||
create(:tag, name: 'material_scope_root',
|
create(:tag, primary_name: 'material_scope_root',
|
||||||
category: :material)
|
category: :material)
|
||||||
child_b =
|
child_b =
|
||||||
create(:tag, name: 'material_scope_b',
|
create(:tag, primary_name: 'material_scope_b',
|
||||||
category: :material)
|
category: :material)
|
||||||
child_a =
|
child_a =
|
||||||
create(:tag, name: 'material_scope_a',
|
create(:tag, primary_name: 'material_scope_a',
|
||||||
category: :material)
|
category: :material)
|
||||||
deprecated =
|
deprecated =
|
||||||
create(:tag, name: 'material_scope_old',
|
create(:tag, primary_name: 'material_scope_old',
|
||||||
category: :material,
|
category: :material,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
grandchild =
|
grandchild =
|
||||||
create(:tag, name: 'material_scope_grandchild',
|
create(:tag, primary_name: 'material_scope_grandchild',
|
||||||
category: :material)
|
category: :material)
|
||||||
root_material =
|
root_material =
|
||||||
build_material(tag: root, user: member_user,
|
build_material(tag: root, user: member_user,
|
||||||
@@ -179,7 +179,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
describe 'GET /materials/:id' do
|
describe 'GET /materials/:id' do
|
||||||
let!(:tag) do
|
let!(:tag) do
|
||||||
create(:tag, name: 'material_show', category: :material)
|
create(:tag, primary_name: 'material_show', category: :material)
|
||||||
end
|
end
|
||||||
let!(:material) do
|
let!(:material) do
|
||||||
build_material(tag:, user: member_user, file: dummy_upload(filename: 'show.png'))
|
build_material(tag:, user: member_user, file: dummy_upload(filename: 'show.png'))
|
||||||
@@ -269,7 +269,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
|
|
||||||
material = Material.order(:id).last
|
material = Material.order(:id).last
|
||||||
expect(material.tag.name).to eq('material_create_new')
|
expect(primary_tag_name_for(material.tag, 'ja').name).to eq('material_create_new')
|
||||||
expect(material.tag.category).to eq('material')
|
expect(material.tag.category).to eq('material')
|
||||||
expect(material.created_by_user).to eq(member_user)
|
expect(material.created_by_user).to eq(member_user)
|
||||||
expect(material.updated_by_user).to eq(member_user)
|
expect(material.updated_by_user).to eq(member_user)
|
||||||
@@ -297,7 +297,8 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
|
|
||||||
tag = Tag.joins(:tag_name).find_by!(tag_names: { name: 'material_create_versioned_tag' })
|
tag = TagName.find_by!(name: 'material_create_versioned_tag',
|
||||||
|
language_code: 'ja', primary_flg: true).tag
|
||||||
version = tag.tag_versions.order(:version_no).last
|
version = tag.tag_versions.order(:version_no).last
|
||||||
|
|
||||||
expect(version.event_type).to eq('create')
|
expect(version.event_type).to eq('create')
|
||||||
@@ -324,7 +325,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
it 'returns 422 when the existing tag is not material/character' do
|
it 'returns 422 when the existing tag is not material/character' do
|
||||||
general_tag_name = create(:tag_name, name: 'material_create_general_tag')
|
general_tag_name = create(:tag_name, name: 'material_create_general_tag')
|
||||||
create(:tag, tag_name: general_tag_name, category: :general)
|
create(:tag, primary_tag_name: general_tag_name, category: :general)
|
||||||
|
|
||||||
post '/materials', params: {
|
post '/materials', params: {
|
||||||
tag: 'material_create_general_tag',
|
tag: 'material_create_general_tag',
|
||||||
@@ -345,7 +346,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
|
|
||||||
material = Material.order(:id).last
|
material = Material.order(:id).last
|
||||||
expect(material.tag.name).to eq('material_create_url_only')
|
expect(primary_tag_name_for(material.tag, 'ja').name).to eq('material_create_url_only')
|
||||||
expect(material.url).to eq('https://example.com/material-source')
|
expect(material.url).to eq('https://example.com/material-source')
|
||||||
expect(material.file.attached?).to be(false)
|
expect(material.file.attached?).to be(false)
|
||||||
end
|
end
|
||||||
@@ -384,7 +385,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
describe 'PUT /materials/:id' do
|
describe 'PUT /materials/:id' do
|
||||||
let!(:tag) do
|
let!(:tag) do
|
||||||
create(:tag, name: 'material_update_old', category: :material)
|
create(:tag, primary_name: 'material_update_old', category: :material)
|
||||||
end
|
end
|
||||||
let!(:material) do
|
let!(:material) do
|
||||||
build_material(tag:, user: member_user, file: dummy_upload(filename: 'old.png'))
|
build_material(tag:, user: member_user, file: dummy_upload(filename: 'old.png'))
|
||||||
@@ -463,7 +464,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
material.reload
|
material.reload
|
||||||
expect(material.tag.name).to eq('material_update_new')
|
expect(primary_tag_name_for(material.tag, 'ja').name).to eq('material_update_new')
|
||||||
expect(material.tag.category).to eq('material')
|
expect(material.tag.category).to eq('material')
|
||||||
expect(material.url).to eq('https://example.com/updated-source')
|
expect(material.url).to eq('https://example.com/updated-source')
|
||||||
expect(material.updated_by_user).to eq(member_user)
|
expect(material.updated_by_user).to eq(member_user)
|
||||||
@@ -497,7 +498,8 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
tag = Tag.joins(:tag_name).find_by!(tag_names: { name: 'material_update_versioned_tag' })
|
tag = TagName.find_by!(name: 'material_update_versioned_tag',
|
||||||
|
language_code: 'ja', primary_flg: true).tag
|
||||||
version = tag.tag_versions.order(:version_no).last
|
version = tag.tag_versions.order(:version_no).last
|
||||||
|
|
||||||
expect(version.event_type).to eq('create')
|
expect(version.event_type).to eq('create')
|
||||||
@@ -508,7 +510,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
it 'backfills a create tag_version for an existing material tag without history' do
|
it 'backfills a create tag_version for an existing material tag without history' do
|
||||||
existing_tag =
|
existing_tag =
|
||||||
create(:tag, name: 'material_update_existing_no_history',
|
create(:tag, primary_name: 'material_update_existing_no_history',
|
||||||
category: :material)
|
category: :material)
|
||||||
|
|
||||||
expect(existing_tag.tag_versions).to be_empty
|
expect(existing_tag.tag_versions).to be_empty
|
||||||
@@ -531,7 +533,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
it 'backfills a create tag_version for an existing character tag without history' do
|
it 'backfills a create tag_version for an existing character tag without history' do
|
||||||
existing_tag =
|
existing_tag =
|
||||||
create(:tag, name: 'material_update_character_no_history',
|
create(:tag, primary_name: 'material_update_character_no_history',
|
||||||
category: :character)
|
category: :character)
|
||||||
|
|
||||||
expect(existing_tag.tag_versions).to be_empty
|
expect(existing_tag.tag_versions).to be_empty
|
||||||
@@ -563,7 +565,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
material.reload
|
material.reload
|
||||||
expect(material.tag.name).to eq('material_update_remove_file')
|
expect(primary_tag_name_for(material.tag, 'ja').name).to eq('material_update_remove_file')
|
||||||
expect(material.url).to eq('https://example.com/updated-source')
|
expect(material.url).to eq('https://example.com/updated-source')
|
||||||
expect(material.updated_by_user).to eq(member_user)
|
expect(material.updated_by_user).to eq(member_user)
|
||||||
expect(material.file.attached?).to be(false)
|
expect(material.file.attached?).to be(false)
|
||||||
@@ -651,8 +653,8 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /materials/download.zip' do
|
describe 'GET /materials/download.zip' do
|
||||||
let!(:tag_a) { create(:tag, name: 'zip_a', category: :material) }
|
let!(:tag_a) { create(:tag, primary_name: 'zip_a', category: :material) }
|
||||||
let!(:tag_b) { create(:tag, name: 'zip_b', category: :material) }
|
let!(:tag_b) { create(:tag, primary_name: 'zip_b', category: :material) }
|
||||||
let!(:material_a) do
|
let!(:material_a) do
|
||||||
build_material(tag: tag_a, user: member_user,
|
build_material(tag: tag_a, user: member_user,
|
||||||
file: dummy_upload(filename: 'a.png', body: 'zip-a'))
|
file: dummy_upload(filename: 'a.png', body: 'zip-a'))
|
||||||
@@ -701,7 +703,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
describe 'GET /materials/versions' do
|
describe 'GET /materials/versions' do
|
||||||
let!(:tag) do
|
let!(:tag) do
|
||||||
create(:tag, name: 'material_history', category: :material)
|
create(:tag, primary_name: 'material_history', category: :material)
|
||||||
end
|
end
|
||||||
let!(:material) do
|
let!(:material) do
|
||||||
build_material(tag:, user: member_user, file: dummy_upload(filename: 'history.png'))
|
build_material(tag:, user: member_user, file: dummy_upload(filename: 'history.png'))
|
||||||
@@ -776,7 +778,7 @@ RSpec.describe 'Materials API', type: :request do
|
|||||||
|
|
||||||
describe 'DELETE /materials/:id' do
|
describe 'DELETE /materials/:id' do
|
||||||
let!(:tag) do
|
let!(:tag) do
|
||||||
create(:tag, name: 'material_destroy', category: :material)
|
create(:tag, primary_name: 'material_destroy', category: :material)
|
||||||
end
|
end
|
||||||
let!(:material) do
|
let!(:material) do
|
||||||
build_material(tag:, user: member_user, file: dummy_upload(filename: 'destroy.png'))
|
build_material(tag:, user: member_user, file: dummy_upload(filename: 'destroy.png'))
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ RSpec.describe 'NicoTags', type: :request do
|
|||||||
unlinked.update!(name: 'search_unlinked')
|
unlinked.update!(name: 'search_unlinked')
|
||||||
other = create(:external_tag)
|
other = create(:external_tag)
|
||||||
other.update!(name: 'other')
|
other.update!(name: 'other')
|
||||||
destination = create(:tag, :general)
|
destination = create(:tag, category: :general)
|
||||||
destination.tag_name.update!(name: 'destination_search')
|
primary_tag_name_for(destination, 'ja').update!(name: 'destination_search')
|
||||||
NicoTagRelation.create!(nico_tag: linked, tag: destination)
|
NicoTagRelation.create!(nico_tag: linked, tag: destination)
|
||||||
NicoTagRelation.create!(nico_tag: other, tag: create(:tag, :general))
|
NicoTagRelation.create!(nico_tag: other, tag: create(:tag, category: :general))
|
||||||
|
|
||||||
get '/tags/nico', params: {
|
get '/tags/nico', params: {
|
||||||
name: 'search_',
|
name: 'search_',
|
||||||
@@ -151,7 +151,7 @@ RSpec.describe 'NicoTags', type: :request do
|
|||||||
|
|
||||||
it '404 when only an internal tag exists for the target id' do
|
it '404 when only an internal tag exists for the target id' do
|
||||||
sign_in_as(member)
|
sign_in_as(member)
|
||||||
non_nico = create(:tag, :general)
|
non_nico = create(:tag, category: :general)
|
||||||
expect(ExternalTag.exists?(non_nico.id)).to be(false)
|
expect(ExternalTag.exists?(non_nico.id)).to be(false)
|
||||||
patch "/tags/nico/#{non_nico.id}", params: { tags: 'a b' }
|
patch "/tags/nico/#{non_nico.id}", params: { tags: 'a b' }
|
||||||
expect(response).to have_http_status(:not_found)
|
expect(response).to have_http_status(:not_found)
|
||||||
@@ -163,17 +163,17 @@ RSpec.describe 'NicoTags', type: :request do
|
|||||||
nico_tag = create(:external_tag, name: 'nico_tags_spec_source')
|
nico_tag = create(:external_tag, name: 'nico_tags_spec_source')
|
||||||
|
|
||||||
linked_a_name = create(:tag_name, name: 'nico_linked_a')
|
linked_a_name = create(:tag_name, name: 'nico_linked_a')
|
||||||
linked_a = create(:tag, tag_name: linked_a_name, category: :general)
|
linked_a = create(:tag, primary_tag_name: linked_a_name, category: :general)
|
||||||
|
|
||||||
linked_b_name = create(:tag_name, name: 'nico_linked_b')
|
linked_b_name = create(:tag_name, name: 'nico_linked_b')
|
||||||
linked_b = create(:tag, tag_name: linked_b_name, category: :general)
|
linked_b = create(:tag, primary_tag_name: linked_b_name, category: :general)
|
||||||
|
|
||||||
NicoTagVersionRecorder.record!(external_tag: nico_tag,
|
NicoTagVersionRecorder.record!(external_tag: nico_tag,
|
||||||
event_type: :create, created_by_user: admin)
|
event_type: :create, created_by_user: admin)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
patch "/tags/nico/#{nico_tag.id}", params: {
|
patch "/tags/nico/#{nico_tag.id}", params: {
|
||||||
tags: " #{linked_a.name}\n#{linked_b.name} "
|
tags: " #{ linked_a_name.name }\n#{ linked_b_name.name } "
|
||||||
}
|
}
|
||||||
}.to change(TagVersion, :count).by(2)
|
}.to change(TagVersion, :count).by(2)
|
||||||
.and change(NicoTagVersion, :count).by(1)
|
.and change(NicoTagVersion, :count).by(1)
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
let!(:tag_name) { create(:tag_name, name: 'spec_tag') }
|
let!(:tag_name) { create(:tag_name, name: 'spec_tag') }
|
||||||
let!(:tag) { create(:tag, tag_name: tag_name, category: :general) }
|
let!(:tag) { create(:tag, primary_tag_name: tag_name, category: :general) }
|
||||||
|
|
||||||
let!(:post_record) do
|
let!(:post_record) do
|
||||||
Post.create!(title: 'spec post', url: 'https://example.com/spec').tap do |p|
|
Post.create!(title: 'spec post', url: 'https://example.com/spec').tap do |p|
|
||||||
@@ -126,9 +126,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
let!(:user) { create_member_user! }
|
let!(:user) { create_member_user! }
|
||||||
|
|
||||||
let!(:tag_name) { create(:tag_name, name: 'spec_tag') }
|
let!(:tag_name) { create(:tag_name, name: 'spec_tag') }
|
||||||
let!(:tag) { create(:tag, tag_name:, category: :general) }
|
let!(:tag) { create(:tag, primary_tag_name: tag_name, category: :general) }
|
||||||
let!(:tag_name2) { create(:tag_name, name: 'unko') }
|
let!(:tag_name2) { create(:tag_name, name: 'unko') }
|
||||||
let!(:tag2) { create(:tag, tag_name: tag_name2, category: :deerjikist) }
|
let!(:tag2) { create(:tag, primary_tag_name: tag_name2, category: :deerjikist) }
|
||||||
let!(:alias_tag_name) { create(:tag_name, :alias, name: 'manko', tag:) }
|
let!(:alias_tag_name) { create(:tag_name, :alias, name: 'manko', tag:) }
|
||||||
|
|
||||||
let!(:hit_post) do
|
let!(:hit_post) do
|
||||||
@@ -267,7 +267,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'keeps internal name searches independent of colliding external ids' do
|
it 'keeps internal name searches independent of colliding external ids' do
|
||||||
get '/posts', params: { tags: tag.name }
|
get '/posts', params: { tags: primary_tag_name_for(tag, 'ja').name }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json.fetch('count')).to eq(3)
|
expect(json.fetch('count')).to eq(3)
|
||||||
@@ -286,7 +286,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
[nil, 'all'].each do |match|
|
[nil, 'all'].each do |match|
|
||||||
it "intersects internal and external matches with match=#{ match || 'omitted' }" do
|
it "intersects internal and external matches with match=#{ match || 'omitted' }" do
|
||||||
params = { tags: "#{ tag.name } nico:search_external" }
|
params = { tags: "#{ primary_tag_name_for(tag, 'ja').name } nico:search_external" }
|
||||||
params[:match] = match if match
|
params[:match] = match if match
|
||||||
|
|
||||||
get '/posts', params: params
|
get '/posts', params: params
|
||||||
@@ -307,7 +307,8 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'excludes external matches from an internal tag search' do
|
it 'excludes external matches from an internal tag search' do
|
||||||
get '/posts', params: { tags: "#{ tag.name } not:nico:search_external" }
|
get '/posts', params: {
|
||||||
|
tags: "#{ primary_tag_name_for(tag, 'ja').name } not:nico:search_external" }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json.fetch('count')).to eq(2)
|
expect(json.fetch('count')).to eq(2)
|
||||||
@@ -316,7 +317,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'unions an external match with a negated internal match' do
|
it 'unions an external match with a negated internal match' do
|
||||||
get '/posts', params: { tags: "nico:search_external not:#{ tag.name }", match: 'any' }
|
get '/posts', params: {
|
||||||
|
tags: "nico:search_external not:#{ primary_tag_name_for(tag, 'ja').name }",
|
||||||
|
match: 'any' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json.fetch('count')).to eq(2)
|
expect(json.fetch('count')).to eq(2)
|
||||||
@@ -333,7 +336,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'applies the same mixed name search to the existing random endpoint' do
|
it 'applies the same mixed name search to the existing random endpoint' do
|
||||||
get '/posts/random', params: { tags: "#{ tag.name } nico:search_external", match: 'all' }
|
get '/posts/random', params: {
|
||||||
|
tags: "#{ primary_tag_name_for(tag, 'ja').name } nico:search_external",
|
||||||
|
match: 'all' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json.fetch('id')).to eq(both_post.id)
|
expect(json.fetch('id')).to eq(both_post.id)
|
||||||
@@ -342,13 +347,13 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
context 'when tags contain not:' do
|
context 'when tags contain not:' do
|
||||||
let!(:foo_tag_name) { create(:tag_name, name: 'not_spec_foo') }
|
let!(:foo_tag_name) { create(:tag_name, name: 'not_spec_foo') }
|
||||||
let!(:foo_tag) { create(:tag, tag_name: foo_tag_name, category: :general) }
|
let!(:foo_tag) { create(:tag, primary_tag_name: foo_tag_name, category: :general) }
|
||||||
|
|
||||||
let!(:bar_tag_name) { create(:tag_name, name: 'not_spec_bar') }
|
let!(:bar_tag_name) { create(:tag_name, name: 'not_spec_bar') }
|
||||||
let!(:bar_tag) { create(:tag, tag_name: bar_tag_name, category: :general) }
|
let!(:bar_tag) { create(:tag, primary_tag_name: bar_tag_name, category: :general) }
|
||||||
|
|
||||||
let!(:baz_tag_name) { create(:tag_name, name: 'not_spec_baz') }
|
let!(:baz_tag_name) { create(:tag_name, name: 'not_spec_baz') }
|
||||||
let!(:baz_tag) { create(:tag, tag_name: baz_tag_name, category: :general) }
|
let!(:baz_tag) { create(:tag, primary_tag_name: baz_tag_name, category: :general) }
|
||||||
|
|
||||||
let!(:foo_alias_tag_name) do
|
let!(:foo_alias_tag_name) do
|
||||||
create(:tag_name, :alias, name: 'not_spec_foo_alias', tag: foo_tag)
|
create(:tag_name, :alias, name: 'not_spec_foo_alias', tag: foo_tag)
|
||||||
@@ -739,7 +744,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
.find { _1['name'] == 'nico:post_index_external' }
|
.find { _1['name'] == 'nico:post_index_external' }
|
||||||
|
|
||||||
expect(post_json.fetch('tags')).to include(
|
expect(post_json.fetch('tags')).to include(
|
||||||
a_hash_including('id' => tag.id, 'name' => tag.name, 'category' => 'general'))
|
a_hash_including('id' => tag.id,
|
||||||
|
'name' => primary_tag_name_for(tag, 'ja').name,
|
||||||
|
'category' => 'general'))
|
||||||
expect(external_json).not_to be_nil
|
expect(external_json).not_to be_nil
|
||||||
expect_external_tag_json(external_json, external_tag)
|
expect_external_tag_json(external_json, external_tag)
|
||||||
end
|
end
|
||||||
@@ -773,7 +780,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
it 'omits deprecated tags' do
|
it 'omits deprecated tags' do
|
||||||
deprecated_tag = create(:tag,
|
deprecated_tag = create(:tag,
|
||||||
name: 'deprecated_post_tag',
|
primary_name: 'deprecated_post_tag',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
PostTag.create!(post: post_record, tag: deprecated_tag)
|
PostTag.create!(post: post_record, tag: deprecated_tag)
|
||||||
@@ -853,7 +860,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
tags =
|
tags =
|
||||||
15.times.map do |i|
|
15.times.map do |i|
|
||||||
tag_name = create(:tag_name, name: "show_query_tag_#{ i }")
|
tag_name = create(:tag_name, name: "show_query_tag_#{ i }")
|
||||||
tag = create(:tag, tag_name:, category: :general)
|
tag = create(:tag, primary_tag_name: tag_name, category: :general)
|
||||||
create(:tag_name, :alias, name: "show_query_alias_#{ i }", tag:)
|
create(:tag_name, :alias, name: "show_query_alias_#{ i }", tag:)
|
||||||
PostTag.create!(post: post_record, tag:)
|
PostTag.create!(post: post_record, tag:)
|
||||||
tag
|
tag
|
||||||
@@ -909,7 +916,9 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
expect(json.fetch('tags')).to include(
|
expect(json.fetch('tags')).to include(
|
||||||
a_hash_including('id' => tag.id, 'name' => tag.name, 'category' => 'general'))
|
a_hash_including('id' => tag.id,
|
||||||
|
'name' => primary_tag_name_for(tag, 'ja').name,
|
||||||
|
'category' => 'general'))
|
||||||
external_json =
|
external_json =
|
||||||
json
|
json
|
||||||
.fetch('tags')
|
.fetch('tags')
|
||||||
@@ -1157,7 +1166,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
it 'rejects a deprecated tag specified directly' do
|
it 'rejects a deprecated tag specified directly' do
|
||||||
create(:tag,
|
create(:tag,
|
||||||
name: 'deprecated_direct_tag',
|
primary_name: 'deprecated_direct_tag',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
sign_in_as(member)
|
sign_in_as(member)
|
||||||
@@ -1176,16 +1185,16 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'expands through multiple deprecated parent tags and saves active ancestors' do
|
it 'expands through multiple deprecated parent tags and saves active ancestors' do
|
||||||
child = create(:tag, name: 'active_child', category: :general)
|
child = create(:tag, primary_name: 'active_child', category: :general)
|
||||||
deprecated_parent = create(:tag,
|
deprecated_parent = create(:tag,
|
||||||
name: 'deprecated_parent',
|
primary_name: 'deprecated_parent',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
deprecated_grandparent = create(:tag,
|
deprecated_grandparent = create(:tag,
|
||||||
name: 'deprecated_grandparent',
|
primary_name: 'deprecated_grandparent',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
active_grandparent = create(:tag, name: 'active_grandparent', category: :general)
|
active_grandparent = create(:tag, primary_name: 'active_grandparent', category: :general)
|
||||||
TagImplication.create!(tag: child, parent_tag: deprecated_parent)
|
TagImplication.create!(tag: child, parent_tag: deprecated_parent)
|
||||||
TagImplication.create!(tag: deprecated_parent, parent_tag: deprecated_grandparent)
|
TagImplication.create!(tag: deprecated_parent, parent_tag: deprecated_grandparent)
|
||||||
TagImplication.create!(tag: deprecated_grandparent, parent_tag: active_grandparent)
|
TagImplication.create!(tag: deprecated_grandparent, parent_tag: active_grandparent)
|
||||||
@@ -1199,7 +1208,8 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
)
|
)
|
||||||
|
|
||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
saved_names = Post.find(json.fetch('id')).tags.map(&:name)
|
saved_names = TagName.where(tag_id: Post.find(json.fetch('id')).tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name)
|
||||||
expect(saved_names).to include('active_child', 'active_grandparent')
|
expect(saved_names).to include('active_child', 'active_grandparent')
|
||||||
expect(saved_names).not_to include('deprecated_parent', 'deprecated_grandparent')
|
expect(saved_names).not_to include('deprecated_parent', 'deprecated_grandparent')
|
||||||
end
|
end
|
||||||
@@ -1302,7 +1312,8 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
|
|
||||||
created_post = Post.find(json.fetch('id'))
|
created_post = Post.find(json.fetch('id'))
|
||||||
tag = Tag.joins(:tag_name).find_by!(tag_names: { name: '伊地知ニジカ' })
|
tag = TagName.find_by!(name: '伊地知ニジカ',
|
||||||
|
language_code: 'ja', primary_flg: true).tag
|
||||||
section = PostTagSection.find_by!(post: created_post, tag:)
|
section = PostTagSection.find_by!(post: created_post, tag:)
|
||||||
|
|
||||||
expect(section.begin_ms).to eq(60_000)
|
expect(section.begin_ms).to eq(60_000)
|
||||||
@@ -1322,7 +1333,8 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
|
|
||||||
created_post = Post.find(json.fetch('id'))
|
created_post = Post.find(json.fetch('id'))
|
||||||
tag = Tag.joins(:tag_name).find_by!(tag_names: { name: '伊地知ニジカ' })
|
tag = TagName.find_by!(name: '伊地知ニジカ',
|
||||||
|
language_code: 'ja', primary_flg: true).tag
|
||||||
expect(PostTagSection.find_by(post: created_post, tag:)).to be_nil
|
expect(PostTagSection.find_by(post: created_post, tag:)).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1339,7 +1351,8 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
|
|
||||||
created_post = Post.find(json.fetch('id'))
|
created_post = Post.find(json.fetch('id'))
|
||||||
tag = Tag.joins(:tag_name).find_by!(tag_names: { name: '伊地知ニジカ' })
|
tag = TagName.find_by!(name: '伊地知ニジカ',
|
||||||
|
language_code: 'ja', primary_flg: true).tag
|
||||||
expect(PostTagSection.find_by(post: created_post, tag:)).to be_nil
|
expect(PostTagSection.find_by(post: created_post, tag:)).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1656,7 +1669,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
begin_ms: 1000, end_ms: 2000)
|
begin_ms: 1000, end_ms: 2000)
|
||||||
|
|
||||||
tn2 = create(:tag_name, name: 'spec_tag_2')
|
tn2 = create(:tag_name, name: 'spec_tag_2')
|
||||||
replacement_tag = create(:tag, tag_name: tn2, category: :general)
|
replacement_tag = create(:tag, primary_tag_name: tn2, category: :general)
|
||||||
|
|
||||||
put "/posts/#{post_record.id}", params: post_update_params(
|
put "/posts/#{post_record.id}", params: post_update_params(
|
||||||
post_record,
|
post_record,
|
||||||
@@ -1705,7 +1718,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
it 'rejects a deprecated tag specified directly' do
|
it 'rejects a deprecated tag specified directly' do
|
||||||
create(:tag,
|
create(:tag,
|
||||||
name: 'deprecated_update_tag',
|
primary_name: 'deprecated_update_tag',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
sign_in_as(member)
|
sign_in_as(member)
|
||||||
@@ -1962,7 +1975,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
base_version_no: base_version.version_no,
|
base_version_no: base_version.version_no,
|
||||||
title: 'updated by me',
|
title: 'updated by me',
|
||||||
tags: "spec_tag #{Tag.no_deerjikist.name}")
|
tags: "spec_tag #{primary_tag_name_for(Tag.no_deerjikist, 'ja').name}")
|
||||||
|
|
||||||
expect(response).to have_http_status(:conflict)
|
expect(response).to have_http_status(:conflict)
|
||||||
|
|
||||||
@@ -1994,7 +2007,8 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
base_version_no: base_version.version_no,
|
base_version_no: base_version.version_no,
|
||||||
title: post_record.title,
|
title: post_record.title,
|
||||||
tags: "spec_tag #{Tag.no_deerjikist.name} incoming_added_tag")
|
tags: ['spec_tag', primary_tag_name_for(Tag.no_deerjikist, 'ja').name,
|
||||||
|
'incoming_added_tag'].join(' '))
|
||||||
|
|
||||||
expect(response).to have_http_status(:conflict)
|
expect(response).to have_http_status(:conflict)
|
||||||
|
|
||||||
@@ -2024,15 +2038,17 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
base_version_no: base_version.version_no,
|
base_version_no: base_version.version_no,
|
||||||
title: post_record.title,
|
title: post_record.title,
|
||||||
tags: "spec_tag #{Tag.no_deerjikist.name} incoming_merge_tag",
|
tags: ['spec_tag', primary_tag_name_for(Tag.no_deerjikist, 'ja').name,
|
||||||
|
'incoming_merge_tag'].join(' '),
|
||||||
merge: '1')
|
merge: '1')
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
names = post_record.reload.tags.map(&:name)
|
names = TagName.where(tag_id: post_record.reload.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name)
|
||||||
|
|
||||||
expect(names).to include('spec_tag')
|
expect(names).to include('spec_tag')
|
||||||
expect(names).to include(Tag.no_deerjikist.name)
|
expect(names).to include(primary_tag_name_for(Tag.no_deerjikist, 'ja').name)
|
||||||
expect(names).to include('current_merge_tag')
|
expect(names).to include('current_merge_tag')
|
||||||
expect(names).to include('incoming_merge_tag')
|
expect(names).to include('incoming_merge_tag')
|
||||||
end
|
end
|
||||||
@@ -2055,14 +2071,15 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
base_version_no: base_version.version_no,
|
base_version_no: base_version.version_no,
|
||||||
title: post_record.title,
|
title: post_record.title,
|
||||||
tags: "spec_tag #{ Tag.no_deerjikist.name }")
|
tags: "spec_tag #{ primary_tag_name_for(Tag.no_deerjikist, 'ja').name }")
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
names = post_record.reload.tags.map(&:name)
|
names = TagName.where(tag_id: post_record.reload.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name)
|
||||||
|
|
||||||
expect(names).to include('spec_tag')
|
expect(names).to include('spec_tag')
|
||||||
expect(names).to include(Tag.no_deerjikist.name)
|
expect(names).to include(primary_tag_name_for(Tag.no_deerjikist, 'ja').name)
|
||||||
expect(post_record.external_tags).to contain_exactly(nico_tag)
|
expect(post_record.external_tags).to contain_exactly(nico_tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2077,14 +2094,15 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
base_version_no: base_version.version_no,
|
base_version_no: base_version.version_no,
|
||||||
title: 'updated title',
|
title: 'updated title',
|
||||||
tags: "spec_tag #{ Tag.no_deerjikist.name }")
|
tags: "spec_tag #{ primary_tag_name_for(Tag.no_deerjikist, 'ja').name }")
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
names = post_record.reload.tags.map(&:name)
|
names = TagName.where(tag_id: post_record.reload.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name)
|
||||||
|
|
||||||
expect(names).to include('spec_tag')
|
expect(names).to include('spec_tag')
|
||||||
expect(names).to include(Tag.no_deerjikist.name)
|
expect(names).to include(primary_tag_name_for(Tag.no_deerjikist, 'ja').name)
|
||||||
expect(post_record.external_tags).to contain_exactly(nico_tag)
|
expect(post_record.external_tags).to contain_exactly(nico_tag)
|
||||||
|
|
||||||
external_json =
|
external_json =
|
||||||
@@ -2112,16 +2130,17 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
base_version_no: base_version.version_no,
|
base_version_no: base_version.version_no,
|
||||||
title: post_record.title,
|
title: post_record.title,
|
||||||
tags: "spec_tag #{ Tag.no_deerjikist.name }")
|
tags: "spec_tag #{ primary_tag_name_for(Tag.no_deerjikist, 'ja').name }")
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
names = post_record.reload.tags.map(&:name)
|
names = TagName.where(tag_id: post_record.reload.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name)
|
||||||
|
|
||||||
expect(post_record.external_tags).to contain_exactly(nico_tag)
|
expect(post_record.external_tags).to contain_exactly(nico_tag)
|
||||||
expect(names).to include('spec_tag')
|
expect(names).to include('spec_tag')
|
||||||
expect(names).to include(Tag.no_deerjikist.name)
|
expect(names).to include(primary_tag_name_for(Tag.no_deerjikist, 'ja').name)
|
||||||
expect(names).not_to include(linked_tag.name)
|
expect(names).not_to include(primary_tag_name_for(linked_tag, 'ja').name)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'force-updates stale posts without base_version_no' do
|
it 'force-updates stale posts without base_version_no' do
|
||||||
@@ -2137,7 +2156,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
|
|
||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
title: 'forced title',
|
title: 'forced title',
|
||||||
tags: "spec_tag #{Tag.no_deerjikist.name}",
|
tags: "spec_tag #{primary_tag_name_for(Tag.no_deerjikist, 'ja').name}",
|
||||||
force: '1')
|
force: '1')
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
@@ -2191,7 +2210,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
let(:oc_before) { Time.zone.local(2020, 1, 1, 0, 0, 0) }
|
let(:oc_before) { Time.zone.local(2020, 1, 1, 0, 0, 0) }
|
||||||
|
|
||||||
let!(:tag_name2) { create(:tag_name, name: 'spec_tag_2') }
|
let!(:tag_name2) { create(:tag_name, name: 'spec_tag_2') }
|
||||||
let!(:tag2) { create(:tag, tag_name: tag_name2, category: :general) }
|
let!(:tag2) { create(:tag, primary_tag_name: tag_name2, category: :general) }
|
||||||
|
|
||||||
def snapshot_tags(post)
|
def snapshot_tags(post)
|
||||||
post.snapshot_tag_names.join(' ')
|
post.snapshot_tag_names.join(' ')
|
||||||
@@ -2416,7 +2435,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json.fetch('count')).to eq(3)
|
expect(json.fetch('count')).to eq(3)
|
||||||
expect(json.fetch('versions').first.fetch('tags')).to include(
|
expect(json.fetch('versions').first.fetch('tags')).to include(
|
||||||
'name' => tag2.name, 'type' => 'context')
|
'name' => primary_tag_name_for(tag2, 'ja').name, 'type' => 'context')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters versions by tag when the current snapshot includes the tag' do
|
it 'filters versions by tag when the current snapshot includes the tag' do
|
||||||
@@ -2550,7 +2569,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
base_version = create_post_version_for!(post_record)
|
base_version = create_post_version_for!(post_record)
|
||||||
|
|
||||||
tag_name2 = create(:tag_name, name: 'spec_tag_2')
|
tag_name2 = create(:tag_name, name: 'spec_tag_2')
|
||||||
create(:tag, tag_name: tag_name2, category: :general)
|
create(:tag, primary_tag_name: tag_name2, category: :general)
|
||||||
|
|
||||||
expect do
|
expect do
|
||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
@@ -2715,7 +2734,7 @@ RSpec.describe 'Posts API', type: :request do
|
|||||||
base_version = create_post_version_for!(post_record.reload)
|
base_version = create_post_version_for!(post_record.reload)
|
||||||
|
|
||||||
tag_name2 = create(:tag_name, name: 'spec_tag_2')
|
tag_name2 = create(:tag_name, name: 'spec_tag_2')
|
||||||
tag2 = create(:tag, tag_name: tag_name2, category: :general)
|
tag2 = create(:tag, primary_tag_name: tag_name2, category: :general)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
put "/posts/#{post_record.id}", params: post_write_params(
|
put "/posts/#{post_record.id}", params: post_write_params(
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ require 'rails_helper'
|
|||||||
RSpec.describe 'TagVersions API', type: :request do
|
RSpec.describe 'TagVersions API', type: :request do
|
||||||
let(:member) { create(:user, :member, name: 'version member') }
|
let(:member) { create(:user, :member, name: 'version member') }
|
||||||
|
|
||||||
let!(:tag) { create(:tag, name: 'tag_versions_target', category: :general) }
|
let!(:tag) { create(:tag, primary_name: 'tag_versions_target', category: :general) }
|
||||||
let!(:other_tag) { create(:tag, name: 'tag_versions_other', category: :general) }
|
let!(:other_tag) { create(:tag, primary_name: 'tag_versions_other', category: :general) }
|
||||||
|
|
||||||
let!(:parent_shared) { create(:tag, name: 'parent_shared', category: :general) }
|
let!(:parent_shared) { create(:tag, primary_name: 'parent_shared', category: :general) }
|
||||||
let!(:parent_old) { create(:tag, name: 'parent_old', category: :general) }
|
let!(:parent_old) { create(:tag, primary_name: 'parent_old', category: :general) }
|
||||||
let!(:parent_new) { create(:tag, name: 'parent_new', category: :general) }
|
let!(:parent_new) { create(:tag, primary_name: 'parent_new', category: :general) }
|
||||||
let!(:other_parent) { create(:tag, name: 'other_parent', category: :general) }
|
let!(:other_parent) { create(:tag, primary_name: 'other_parent', category: :general) }
|
||||||
|
|
||||||
let(:t_v1) { Time.zone.local(2020, 1, 1, 12, 0, 0) }
|
let(:t_v1) { Time.zone.local(2020, 1, 1, 12, 0, 0) }
|
||||||
let(:t_v2) { Time.zone.local(2020, 1, 2, 12, 0, 0) }
|
let(:t_v2) { Time.zone.local(2020, 1, 2, 12, 0, 0) }
|
||||||
@@ -211,7 +211,7 @@ RSpec.describe 'TagVersions API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'returns empty when the specified tag has no versions' do
|
it 'returns empty when the specified tag has no versions' do
|
||||||
fresh_tag = create(:tag, name: 'no_versions_tag', category: :general)
|
fresh_tag = create(:tag, primary_name: 'no_versions_tag', category: :general)
|
||||||
|
|
||||||
get '/tags/versions', params: { id: fresh_tag.id }
|
get '/tags/versions', params: { id: fresh_tag.id }
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ RSpec.describe 'TagVersions API', type: :request do
|
|||||||
|
|
||||||
it 'does not create tag versions by wiki updates when tag has no versions yet' do
|
it 'does not create tag versions by wiki updates when tag has no versions yet' do
|
||||||
wiki_tag_name = create(:tag_name, name: 'tag_versions_from_wiki')
|
wiki_tag_name = create(:tag_name, name: 'tag_versions_from_wiki')
|
||||||
wiki_tag = create(:tag, tag_name: wiki_tag_name, category: :general)
|
wiki_tag = create(:tag, primary_tag_name: wiki_tag_name, category: :general)
|
||||||
|
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
|
|||||||
|
|
||||||
def create_tag! name:, category: :general
|
def create_tag! name:, category: :general
|
||||||
tag_name = create(:tag_name, name:)
|
tag_name = create(:tag_name, name:)
|
||||||
create(:tag, tag_name:, category:)
|
create(:tag, primary_tag_name: tag_name, category:)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_wiki_for_tag! tag:, body: 'wiki body', user: member_user
|
def create_wiki_for_tag! tag:, body: 'wiki body', user: member_user
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body:,
|
body:,
|
||||||
created_by_user: user,
|
created_by_user: user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -43,7 +43,7 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
|
|||||||
wiki_page.reload
|
wiki_page.reload
|
||||||
version = wiki_page.wiki_versions.order(:version_no).last
|
version = wiki_page.wiki_versions.order(:version_no).last
|
||||||
|
|
||||||
expect(tag.name).to eq('patch_tag_wiki_after')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('patch_tag_wiki_after')
|
||||||
expect(wiki_page.title).to eq('patch_tag_wiki_after')
|
expect(wiki_page.title).to eq('patch_tag_wiki_after')
|
||||||
|
|
||||||
expect(version).to have_attributes(
|
expect(version).to have_attributes(
|
||||||
@@ -72,7 +72,7 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
|
|||||||
tag.reload
|
tag.reload
|
||||||
wiki_page.reload
|
wiki_page.reload
|
||||||
|
|
||||||
expect(tag.name).to eq('patch_tag_category_only')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('patch_tag_category_only')
|
||||||
expect(tag.category).to eq('meme')
|
expect(tag.category).to eq('meme')
|
||||||
expect(wiki_page.wiki_versions.count).to eq(before_wiki_versions)
|
expect(wiki_page.wiki_versions.count).to eq(before_wiki_versions)
|
||||||
end
|
end
|
||||||
@@ -101,7 +101,7 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
|
|||||||
wiki_page.reload
|
wiki_page.reload
|
||||||
version = wiki_page.wiki_versions.order(:version_no).last
|
version = wiki_page.wiki_versions.order(:version_no).last
|
||||||
|
|
||||||
expect(tag.name).to eq('put_tag_wiki_after')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('put_tag_wiki_after')
|
||||||
expect(wiki_page.title).to eq('put_tag_wiki_after')
|
expect(wiki_page.title).to eq('put_tag_wiki_after')
|
||||||
|
|
||||||
expect(version).to have_attributes(
|
expect(version).to have_attributes(
|
||||||
@@ -134,7 +134,7 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
|
|||||||
tag.reload
|
tag.reload
|
||||||
wiki_page.reload
|
wiki_page.reload
|
||||||
|
|
||||||
expect(tag.name).to eq('put_tag_category_only')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('put_tag_category_only')
|
||||||
expect(tag.category).to eq('meme')
|
expect(tag.category).to eq('meme')
|
||||||
expect(wiki_page.wiki_versions.count).to eq(before_wiki_versions)
|
expect(wiki_page.wiki_versions.count).to eq(before_wiki_versions)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do
|
|||||||
let(:guest) { create(:user, role: :guest) }
|
let(:guest) { create(:user, role: :guest) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
tag.tag_name.update!(name: 'deerjika')
|
primary_tag_name_for(tag, 'ja').update!(name: 'deerjika')
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /tags/:id/deerjikists' do
|
describe 'GET /tags/:id/deerjikists' do
|
||||||
@@ -344,7 +344,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
other_tag.tag_name.update!(name: 'existing-deerjikist')
|
primary_tag_name_for(other_tag, 'ja').update!(name: 'existing-deerjikist')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an indexed 422 error and rolls back the complete replacement' do
|
it 'returns an indexed 422 error and rolls back the complete replacement' do
|
||||||
|
|||||||
+112
-107
@@ -3,12 +3,12 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe 'Tags API', type: :request do
|
RSpec.describe 'Tags API', type: :request do
|
||||||
let!(:tn) { create(:tag_name, name: 'spec_tag') }
|
let!(:tn) { create(:tag_name, name: 'spec_tag') }
|
||||||
let!(:tag) { create(:tag, tag_name: tn, category: :general) }
|
let!(:tag) { create(:tag, primary_tag_name: tn, category: :general) }
|
||||||
let!(:alias_tn) { create(:tag_name, :alias, name: 'unko', tag:) }
|
let!(:alias_tn) { create(:tag_name, :alias, name: 'unko', tag:) }
|
||||||
let!(:post) { Post.create!(url: 'https://example.com/unkounkounko') }
|
let!(:post) { Post.create!(url: 'https://example.com/unkounkounko') }
|
||||||
let!(:post_tag) { PostTag.create!(post:, tag:) }
|
let!(:post_tag) { PostTag.create!(post:, tag:) }
|
||||||
let!(:tn2) { create(:tag_name, name: 'unknown') }
|
let!(:tn2) { create(:tag_name, name: 'unknown') }
|
||||||
let!(:tag2) { create(:tag, tag_name: tn2, category: :general) }
|
let!(:tag2) { create(:tag, primary_tag_name: tn2, category: :general) }
|
||||||
|
|
||||||
def response_tags
|
def response_tags
|
||||||
json.fetch('tags')
|
json.fetch('tags')
|
||||||
@@ -38,7 +38,9 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json.fetch('count')).to eq(2)
|
expect(json.fetch('count')).to eq(2)
|
||||||
expect(response_tags).to contain_exactly(
|
expect(response_tags).to contain_exactly(
|
||||||
a_hash_including('id' => tag.id, 'name' => tag.name, 'category' => 'general'),
|
a_hash_including('id' => tag.id,
|
||||||
|
'name' => primary_tag_name_for(tag, 'ja').name,
|
||||||
|
'category' => 'general'),
|
||||||
a_hash_including(
|
a_hash_including(
|
||||||
'id' => external.id,
|
'id' => external.id,
|
||||||
'name' => 'nico:spec_external',
|
'name' => 'nico:spec_external',
|
||||||
@@ -91,7 +93,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'filters tags by category' do
|
it 'filters tags by category' do
|
||||||
meme = create(:tag, name: 'meme_only', category: :meme)
|
meme = create(:tag, primary_name: 'meme_only', category: :meme)
|
||||||
|
|
||||||
get '/tags', params: { category: 'meme' }
|
get '/tags', params: { category: 'meme' }
|
||||||
|
|
||||||
@@ -102,28 +104,28 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'filters tags by deprecated state' do
|
it 'filters tags by deprecated state' do
|
||||||
deprecated_tag = create(:tag,
|
deprecated_tag = create(:tag,
|
||||||
name: 'deprecated_filter',
|
primary_name: 'deprecated_filter',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: 1.day.from_now)
|
deprecated_at: 1.day.from_now)
|
||||||
active_tag = create(:tag, name: 'active_filter', category: :general)
|
active_tag = create(:tag, primary_name: 'active_filter', category: :general)
|
||||||
|
|
||||||
get '/tags', params: { name: '_filter', deprecated: '1' }
|
get '/tags', params: { name: '_filter', deprecated: '1' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(response_names).to include(deprecated_tag.name)
|
expect(response_names).to include(primary_tag_name_for(deprecated_tag, 'ja').name)
|
||||||
expect(response_names).not_to include(active_tag.name)
|
expect(response_names).not_to include(primary_tag_name_for(active_tag, 'ja').name)
|
||||||
|
|
||||||
get '/tags', params: { name: '_filter', deprecated: '0' }
|
get '/tags', params: { name: '_filter', deprecated: '0' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(response_names).to include(active_tag.name)
|
expect(response_names).to include(primary_tag_name_for(active_tag, 'ja').name)
|
||||||
expect(response_names).not_to include(deprecated_tag.name)
|
expect(response_names).not_to include(primary_tag_name_for(deprecated_tag, 'ja').name)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters tags by post_count range' do
|
it 'filters tags by post_count range' do
|
||||||
low = create(:tag, name: 'pc_low', category: :general)
|
low = create(:tag, primary_name: 'pc_low', category: :general)
|
||||||
mid = create(:tag, name: 'pc_mid', category: :general)
|
mid = create(:tag, primary_name: 'pc_mid', category: :general)
|
||||||
high = create(:tag, name: 'pc_high', category: :general)
|
high = create(:tag, primary_name: 'pc_high', category: :general)
|
||||||
|
|
||||||
low.update_columns(post_count: 1)
|
low.update_columns(post_count: 1)
|
||||||
mid.update_columns(post_count: 3)
|
mid.update_columns(post_count: 3)
|
||||||
@@ -141,8 +143,8 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'filters tags by created_at range' do
|
it 'filters tags by created_at range' do
|
||||||
old_tag = create(:tag, name: 'created_old', category: :general)
|
old_tag = create(:tag, primary_name: 'created_old', category: :general)
|
||||||
new_tag = create(:tag, name: 'created_new', category: :general)
|
new_tag = create(:tag, primary_name: 'created_new', category: :general)
|
||||||
|
|
||||||
old_time = Time.zone.local(2024, 1, 1, 0, 0, 0)
|
old_time = Time.zone.local(2024, 1, 1, 0, 0, 0)
|
||||||
new_time = Time.zone.local(2024, 2, 1, 0, 0, 0)
|
new_time = Time.zone.local(2024, 2, 1, 0, 0, 0)
|
||||||
@@ -161,8 +163,8 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'filters tags by updated_at range' do
|
it 'filters tags by updated_at range' do
|
||||||
old_tag = create(:tag, name: 'updated_old', category: :general)
|
old_tag = create(:tag, primary_name: 'updated_old', category: :general)
|
||||||
new_tag = create(:tag, name: 'updated_new', category: :general)
|
new_tag = create(:tag, primary_name: 'updated_new', category: :general)
|
||||||
|
|
||||||
old_time = Time.zone.local(2024, 3, 1, 0, 0, 0)
|
old_time = Time.zone.local(2024, 3, 1, 0, 0, 0)
|
||||||
new_time = Time.zone.local(2024, 4, 1, 0, 0, 0)
|
new_time = Time.zone.local(2024, 4, 1, 0, 0, 0)
|
||||||
@@ -181,12 +183,12 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'orders tags by custom category order' do
|
it 'orders tags by custom category order' do
|
||||||
create(:tag, name: 'cat_deerjikist', category: :deerjikist)
|
create(:tag, primary_name: 'cat_deerjikist', category: :deerjikist)
|
||||||
create(:tag, name: 'cat_meme', category: :meme)
|
create(:tag, primary_name: 'cat_meme', category: :meme)
|
||||||
create(:tag, name: 'cat_character', category: :character)
|
create(:tag, primary_name: 'cat_character', category: :character)
|
||||||
create(:tag, name: 'cat_general', category: :general)
|
create(:tag, primary_name: 'cat_general', category: :general)
|
||||||
create(:tag, name: 'cat_material', category: :material)
|
create(:tag, primary_name: 'cat_material', category: :material)
|
||||||
create(:tag, name: 'cat_meta', category: :meta)
|
create(:tag, primary_name: 'cat_meta', category: :meta)
|
||||||
create(:external_tag, name: 'cat_nico')
|
create(:external_tag, name: 'cat_nico')
|
||||||
|
|
||||||
get '/tags', params: { name: 'cat_', order: 'category:asc', limit: 20 }
|
get '/tags', params: { name: 'cat_', order: 'category:asc', limit: 20 }
|
||||||
@@ -201,19 +203,19 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
context 'with mixed legacy pagination' do
|
context 'with mixed legacy pagination' do
|
||||||
let!(:first_tag) do
|
let!(:first_tag) do
|
||||||
create(:tag,
|
create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'a_mixed_page'),
|
primary_tag_name: create(:tag_name, name: 'a_mixed_page'),
|
||||||
category: :meme)
|
category: :meme)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:middle_tag) do
|
let!(:middle_tag) do
|
||||||
create(:tag,
|
create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'm_mixed_page'),
|
primary_tag_name: create(:tag_name, name: 'm_mixed_page'),
|
||||||
category: :meta)
|
category: :meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:last_tag) do
|
let!(:last_tag) do
|
||||||
create(:tag,
|
create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'z_mixed_page'),
|
primary_tag_name: create(:tag_name, name: 'z_mixed_page'),
|
||||||
category: :general)
|
category: :general)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -264,7 +266,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'paginates and keeps total count' do
|
it 'paginates and keeps total count' do
|
||||||
%w[pag_a pag_b pag_c].each do |name|
|
%w[pag_a pag_b pag_c].each do |name|
|
||||||
create(:tag, tag_name: create(:tag_name, name:), category: :general)
|
create(:tag, primary_tag_name: create(:tag_name, name:), category: :general)
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/tags', params: { name: 'pag_', order: 'name:asc', page: 2, limit: 2 }
|
get '/tags', params: { name: 'pag_', order: 'name:asc', page: 2, limit: 2 }
|
||||||
@@ -275,8 +277,8 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'falls back to default ordering when order is invalid' do
|
it 'falls back to default ordering when order is invalid' do
|
||||||
low = create(:tag, name: 'fallback_low', category: :general)
|
low = create(:tag, primary_name: 'fallback_low', category: :general)
|
||||||
high = create(:tag, name: 'fallback_high', category: :general)
|
high = create(:tag, primary_name: 'fallback_high', category: :general)
|
||||||
|
|
||||||
low.update_columns(post_count: 1)
|
low.update_columns(post_count: 1)
|
||||||
high.update_columns(post_count: 9)
|
high.update_columns(post_count: 9)
|
||||||
@@ -289,7 +291,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'normalises invalid page and limit' do
|
it 'normalises invalid page and limit' do
|
||||||
%w[norm_a norm_b].each do |name|
|
%w[norm_a norm_b].each do |name|
|
||||||
create(:tag, tag_name: create(:tag_name, name:), category: :general)
|
create(:tag, primary_tag_name: create(:tag_name, name:), category: :general)
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/tags', params: { name: 'norm_', order: 'name:asc', page: 0, limit: 0 }
|
get '/tags', params: { name: 'norm_', order: 'name:asc', page: 0, limit: 0 }
|
||||||
@@ -302,7 +304,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'returns aliases and parent tags' do
|
it 'returns aliases and parent tags' do
|
||||||
parent_tag = create(:tag,
|
parent_tag = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'index_parent_tag'),
|
primary_tag_name: create(:tag_name, name: 'index_parent_tag'),
|
||||||
category: :meme)
|
category: :meme)
|
||||||
TagImplication.create!(tag:, parent_tag:)
|
TagImplication.create!(tag:, parent_tag:)
|
||||||
|
|
||||||
@@ -348,7 +350,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'returns aliases and parent tags' do
|
it 'returns aliases and parent tags' do
|
||||||
parent_tag = create(:tag,
|
parent_tag = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'show_parent_tag'),
|
primary_tag_name: create(:tag_name, name: 'show_parent_tag'),
|
||||||
category: :character)
|
category: :character)
|
||||||
TagImplication.create!(tag:, parent_tag:)
|
TagImplication.create!(tag:, parent_tag:)
|
||||||
|
|
||||||
@@ -395,7 +397,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it 'prefers Tag when Tag and ExternalTag have the same id' do
|
it 'prefers Tag when Tag and ExternalTag have the same id' do
|
||||||
internal = create(
|
internal = create(
|
||||||
:tag,
|
:tag,
|
||||||
tag_name: create(:tag_name, name: 'internal_collision'))
|
primary_tag_name: create(:tag_name, name: 'internal_collision'))
|
||||||
create(
|
create(
|
||||||
:external_tag,
|
:external_tag,
|
||||||
id: internal.id,
|
id: internal.id,
|
||||||
@@ -413,7 +415,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
describe 'GET /tags/autocomplete' do
|
describe 'GET /tags/autocomplete' do
|
||||||
it 'combines internal and external matches without conflating equal ids' do
|
it 'combines internal and external matches without conflating equal ids' do
|
||||||
internal = create(:tag, category: :general, name: 'mixed_internal', post_count: 2)
|
internal = create(:tag, category: :general, primary_name: 'mixed_internal', post_count: 2)
|
||||||
external = create(:external_tag, id: internal.id,
|
external = create(:external_tag, id: internal.id,
|
||||||
name: 'mixed_external', post_count: 3)
|
name: 'mixed_external', post_count: 3)
|
||||||
|
|
||||||
@@ -452,7 +454,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it 'limits the combined results to 20 and sorts ties by displayed name' do
|
it 'limits the combined results to 20 and sorts ties by displayed name' do
|
||||||
11.times do |i|
|
11.times do |i|
|
||||||
name = "combined_#{ i.to_s.rjust(2, '0') }"
|
name = "combined_#{ i.to_s.rjust(2, '0') }"
|
||||||
create(:tag, category: :general, name:, post_count: 1)
|
create(:tag, category: :general, primary_name: name, post_count: 1)
|
||||||
create(:external_tag, name:, post_count: 1)
|
create(:external_tag, name:, post_count: 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -464,8 +466,8 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'excludes external tags but preserves internal alias matches when nico is false' do
|
it 'excludes external tags but preserves internal alias matches when nico is false' do
|
||||||
internal = create(:tag, category: :general, name: 'switch_internal', post_count: 1)
|
internal = create(:tag, category: :general, primary_name: 'switch_internal', post_count: 1)
|
||||||
alias_target = create(:tag, category: :general, name: 'alias_target', post_count: 1)
|
alias_target = create(:tag, category: :general, primary_name: 'alias_target', post_count: 1)
|
||||||
create(:tag_name, :alias, name: 'switch_alias', tag: alias_target)
|
create(:tag_name, :alias, name: 'switch_alias', tag: alias_target)
|
||||||
create(:external_tag, name: 'switch_external', post_count: 1)
|
create(:external_tag, name: 'switch_external', post_count: 1)
|
||||||
|
|
||||||
@@ -473,27 +475,30 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json).to contain_exactly(
|
expect(json).to contain_exactly(
|
||||||
a_hash_including('id' => internal.id, 'name' => internal.name),
|
a_hash_including('id' => internal.id,
|
||||||
a_hash_including('id' => alias_target.id, 'name' => alias_target.name,
|
'name' => primary_tag_name_for(internal, 'ja').name),
|
||||||
|
a_hash_including('id' => alias_target.id,
|
||||||
|
'name' => primary_tag_name_for(alias_target, 'ja').name,
|
||||||
'matched_alias' => 'switch_alias'))
|
'matched_alias' => 'switch_alias'))
|
||||||
end
|
end
|
||||||
|
|
||||||
['%', '_'].each do |wildcard|
|
['%', '_'].each do |wildcard|
|
||||||
it "treats #{ wildcard } literally for primary, alias, and external names" do
|
it "treats #{ wildcard } literally for primary, alias, and external names" do
|
||||||
literal = "literal#{ wildcard }match"
|
literal = "literal#{ wildcard }match"
|
||||||
create(:tag, category: :general, name: literal, post_count: 1)
|
create(:tag, category: :general, primary_name: literal, post_count: 1)
|
||||||
alias_target = create(
|
alias_target = create(
|
||||||
:tag, category: :general, name: 'literal_alias_target', post_count: 1)
|
:tag, category: :general, primary_name: 'literal_alias_target', post_count: 1)
|
||||||
create(:tag_name, :alias, name: "#{ literal }_alias",
|
create(:tag_name, :alias, name: "#{ literal }_alias",
|
||||||
tag: alias_target)
|
tag: alias_target)
|
||||||
create(:external_tag, name: literal, post_count: 1)
|
create(:external_tag, name: literal, post_count: 1)
|
||||||
create(:tag, category: :general, name: 'literalXmatch', post_count: 2)
|
create(:tag, category: :general, primary_name: 'literalXmatch', post_count: 2)
|
||||||
create(:external_tag, name: 'literalXmatch', post_count: 2)
|
create(:external_tag, name: 'literalXmatch', post_count: 2)
|
||||||
|
|
||||||
get '/tags/autocomplete', params: { q: "literal#{ wildcard }" }
|
get '/tags/autocomplete', params: { q: "literal#{ wildcard }" }
|
||||||
|
|
||||||
expect(json.map { |row| row.fetch('name') })
|
expect(json.map { |row| row.fetch('name') })
|
||||||
.to contain_exactly(literal, alias_target.name, "nico:#{ literal }")
|
.to contain_exactly(
|
||||||
|
literal, primary_tag_name_for(alias_target, 'ja').name, "nico:#{ literal }")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -523,7 +528,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'omits deprecated tags' do
|
it 'omits deprecated tags' do
|
||||||
deprecated_tag = create(:tag,
|
deprecated_tag = create(:tag,
|
||||||
name: 'spec_deprecated',
|
primary_name: 'spec_deprecated',
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
deprecated_tag.update_columns(post_count: 1)
|
deprecated_tag.update_columns(post_count: 1)
|
||||||
@@ -619,7 +624,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
expect(tag.name).to eq('new')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('new')
|
||||||
expect(tag.category).to eq('general')
|
expect(tag.category).to eq('general')
|
||||||
|
|
||||||
body = JSON.parse(response.body)
|
body = JSON.parse(response.body)
|
||||||
@@ -634,7 +639,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
expect(tag.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('spec_tag')
|
||||||
expect(tag.category).to eq('meme')
|
expect(tag.category).to eq('meme')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -644,7 +649,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
expect(tag.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('spec_tag')
|
||||||
expect(tag.category).to eq('general')
|
expect(tag.category).to eq('general')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -654,7 +659,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
expect(tag.name).to eq('n')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('n')
|
||||||
expect(tag.category).to eq('meta')
|
expect(tag.category).to eq('meta')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -667,7 +672,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
patch "/tags/#{tag.id}", params: { name: 'new', category: 'nico' }
|
patch "/tags/#{tag.id}", params: { name: 'new', category: 'nico' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
expect(tag.reload.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag.reload, 'ja').name).to eq('spec_tag')
|
||||||
expect(tag.category).to eq('general')
|
expect(tag.category).to eq('general')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -717,7 +722,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it 'PATCH で tag の name を変更すると対応する wiki version を作成する' do
|
it 'PATCH で tag の name を変更すると対応する wiki version を作成する' do
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'wiki body before',
|
body: 'wiki body before',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -745,7 +750,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it 'tag の category だけを変更しても wiki version は作成しない' do
|
it 'tag の category だけを変更しても wiki version は作成しない' do
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'wiki body before',
|
body: 'wiki body before',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -781,8 +786,8 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
|
|
||||||
expect(tag.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('spec_tag')
|
||||||
expect(tag.tag_name).to have_attributes(
|
expect(primary_tag_name_for(tag, 'ja')).to have_attributes(
|
||||||
tag_id: tag.id, language_code: 'ja', primary_flg: true)
|
tag_id: tag.id, language_code: 'ja', primary_flg: true)
|
||||||
expect(TagName.find_by!(language_code: 'ja', name: 'patch_roundtrip_target'))
|
expect(TagName.find_by!(language_code: 'ja', name: 'patch_roundtrip_target'))
|
||||||
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
||||||
@@ -791,7 +796,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it '別 tag の正規名には変更できない' do
|
it '別 tag の正規名には変更できない' do
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'patch collision wiki',
|
body: 'patch collision wiki',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -803,10 +808,10 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
'name' => ['その名前は既に使はれてゐます.']
|
'name' => ['その名前は既に使はれてゐます.']
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(tag.reload.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag.reload, 'ja').name).to eq('spec_tag')
|
||||||
expect(TagName.where(tag_id: tag.id, language_code: 'ja', primary_flg: false).pluck(:name))
|
expect(TagName.where(tag_id: tag.id, language_code: 'ja', primary_flg: false).pluck(:name))
|
||||||
.to contain_exactly('unko')
|
.to contain_exactly('unko')
|
||||||
expect(wiki_page.reload.tag_name).to eq(tag.tag_name)
|
expect(wiki_page.reload.tag_name).to eq(primary_tag_name_for(tag, 'ja'))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'system tag の name は変更できない' do
|
it 'system tag の name は変更できない' do
|
||||||
@@ -815,34 +820,34 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
patch "/tags/#{ system_tag.id }", params: { name: 'patch_system_tag_renamed' }
|
patch "/tags/#{ system_tag.id }", params: { name: 'patch_system_tag_renamed' }
|
||||||
|
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
expect(system_tag.reload.name).to eq('bot操作')
|
expect(primary_tag_name_for(system_tag.reload, 'ja').name).to eq('bot操作')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /tags/with-depth' do
|
describe 'GET /tags/with-depth' do
|
||||||
let!(:root_meme) do
|
let!(:root_meme) do
|
||||||
create(:tag, name: 'depth_a_root_meme', category: :meme)
|
create(:tag, primary_name: 'depth_a_root_meme', category: :meme)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:root_material) do
|
let!(:root_material) do
|
||||||
create(:tag, name: 'depth_b_root_material', category: :material)
|
create(:tag, primary_name: 'depth_b_root_material', category: :material)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:hidden_general_root) do
|
let!(:hidden_general_root) do
|
||||||
create(:tag, name: 'depth_hidden_general_root', category: :general)
|
create(:tag, primary_name: 'depth_hidden_general_root', category: :general)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:child_character) do
|
let!(:child_character) do
|
||||||
create(:tag, name: 'depth_child_character', category: :character)
|
create(:tag, primary_name: 'depth_child_character', category: :character)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:grandchild_material) do
|
let!(:grandchild_material) do
|
||||||
create(:tag, name: 'depth_grandchild_material', category: :material)
|
create(:tag, primary_name: 'depth_grandchild_material', category: :material)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:child_general) do
|
let!(:child_general) do
|
||||||
create(:tag, name: 'depth_child_general', category: :general)
|
create(:tag, primary_name: 'depth_child_general', category: :general)
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@@ -886,11 +891,11 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'passes through deprecated tags when finding children' do
|
it 'passes through deprecated tags when finding children' do
|
||||||
deprecated_middle = create(:tag,
|
deprecated_middle = create(:tag,
|
||||||
name: 'depth_deprecated_middle',
|
primary_name: 'depth_deprecated_middle',
|
||||||
category: :character,
|
category: :character,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
visible_descendant = create(:tag,
|
visible_descendant = create(:tag,
|
||||||
name: 'depth_visible_descendant',
|
primary_name: 'depth_visible_descendant',
|
||||||
category: :material)
|
category: :material)
|
||||||
TagImplication.create!(parent_tag: root_material, tag: deprecated_middle)
|
TagImplication.create!(parent_tag: root_material, tag: deprecated_middle)
|
||||||
TagImplication.create!(parent_tag: deprecated_middle, tag: visible_descendant)
|
TagImplication.create!(parent_tag: deprecated_middle, tag: visible_descendant)
|
||||||
@@ -904,18 +909,18 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'passes through multiple deprecated tags for roots and has_children' do
|
it 'passes through multiple deprecated tags for roots and has_children' do
|
||||||
active_child = create(:tag,
|
active_child = create(:tag,
|
||||||
name: 'depth_active_child_below_deprecated',
|
primary_name: 'depth_active_child_below_deprecated',
|
||||||
category: :character)
|
category: :character)
|
||||||
deprecated_parent = create(:tag,
|
deprecated_parent = create(:tag,
|
||||||
name: 'depth_deprecated_parent',
|
primary_name: 'depth_deprecated_parent',
|
||||||
category: :character,
|
category: :character,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
deprecated_grandparent = create(:tag,
|
deprecated_grandparent = create(:tag,
|
||||||
name: 'depth_deprecated_grandparent',
|
primary_name: 'depth_deprecated_grandparent',
|
||||||
category: :material,
|
category: :material,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
active_ancestor = create(:tag,
|
active_ancestor = create(:tag,
|
||||||
name: 'depth_active_ancestor',
|
primary_name: 'depth_active_ancestor',
|
||||||
category: :meme)
|
category: :meme)
|
||||||
TagImplication.create!(tag: active_child, parent_tag: deprecated_parent)
|
TagImplication.create!(tag: active_child, parent_tag: deprecated_parent)
|
||||||
TagImplication.create!(tag: deprecated_parent, parent_tag: deprecated_grandparent)
|
TagImplication.create!(tag: deprecated_parent, parent_tag: deprecated_grandparent)
|
||||||
@@ -942,10 +947,10 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'treats an active tag with only deprecated ancestors as a root' do
|
it 'treats an active tag with only deprecated ancestors as a root' do
|
||||||
active_child = create(:tag,
|
active_child = create(:tag,
|
||||||
name: 'depth_root_below_deprecated',
|
primary_name: 'depth_root_below_deprecated',
|
||||||
category: :character)
|
category: :character)
|
||||||
deprecated_parent = create(:tag,
|
deprecated_parent = create(:tag,
|
||||||
name: 'depth_root_deprecated_parent',
|
primary_name: 'depth_root_deprecated_parent',
|
||||||
category: :material,
|
category: :material,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
TagImplication.create!(tag: active_child, parent_tag: deprecated_parent)
|
TagImplication.create!(tag: active_child, parent_tag: deprecated_parent)
|
||||||
@@ -962,11 +967,11 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'terminates when deprecated implications contain a cycle' do
|
it 'terminates when deprecated implications contain a cycle' do
|
||||||
first = create(:tag,
|
first = create(:tag,
|
||||||
name: 'depth_cycle_first',
|
primary_name: 'depth_cycle_first',
|
||||||
category: :character,
|
category: :character,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
second = create(:tag,
|
second = create(:tag,
|
||||||
name: 'depth_cycle_second',
|
primary_name: 'depth_cycle_second',
|
||||||
category: :material,
|
category: :material,
|
||||||
deprecated_at: Time.current)
|
deprecated_at: Time.current)
|
||||||
TagImplication.create!(tag: first, parent_tag: root_material)
|
TagImplication.create!(tag: first, parent_tag: root_material)
|
||||||
@@ -994,19 +999,19 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
let!(:material_user) { create_member_user! }
|
let!(:material_user) { create_member_user! }
|
||||||
|
|
||||||
let!(:root_tag) do
|
let!(:root_tag) do
|
||||||
create(:tag, name: 'materials_root', category: :material)
|
create(:tag, primary_name: 'materials_root', category: :material)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:child_a_tag) do
|
let!(:child_a_tag) do
|
||||||
create(:tag, name: 'materials_child_a', category: :material)
|
create(:tag, primary_name: 'materials_child_a', category: :material)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:child_b_tag) do
|
let!(:child_b_tag) do
|
||||||
create(:tag, name: 'materials_child_b', category: :character)
|
create(:tag, primary_name: 'materials_child_b', category: :character)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:grandchild_tag) do
|
let!(:grandchild_tag) do
|
||||||
create(:tag, name: 'materials_grandchild', category: :material)
|
create(:tag, primary_name: 'materials_grandchild', category: :material)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:root_material) do
|
let!(:root_material) do
|
||||||
@@ -1028,7 +1033,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a tag tree with nested materials sorted by child name' do
|
it 'returns a tag tree with nested materials sorted by child name' do
|
||||||
get "/tags/name/#{ CGI.escape(root_tag.name) }/materials"
|
get "/tags/name/#{ CGI.escape(primary_tag_name_for(root_tag, 'ja').name) }/materials"
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
@@ -1119,7 +1124,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
expect(tag.reload.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag.reload, 'ja').name).to eq('spec_tag')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'category が空なら 422 を返す' do
|
it 'category が空なら 422 を返す' do
|
||||||
@@ -1131,7 +1136,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
expect(tag.reload.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag.reload, 'ja').name).to eq('spec_tag')
|
||||||
expect(tag.category).to eq('general')
|
expect(tag.category).to eq('general')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1151,10 +1156,10 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'name, category, aliases, parent tags をまとめて更新できる' do
|
it 'name, category, aliases, parent tags をまとめて更新できる' do
|
||||||
old_parent = create(:tag,
|
old_parent = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_old_parent'),
|
primary_tag_name: create(:tag_name, name: 'put_old_parent'),
|
||||||
category: :general)
|
category: :general)
|
||||||
kept_parent = create(:tag,
|
kept_parent = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_kept_parent'),
|
primary_tag_name: create(:tag_name, name: 'put_kept_parent'),
|
||||||
category: :general)
|
category: :general)
|
||||||
TagImplication.create!(tag:, parent_tag: old_parent)
|
TagImplication.create!(tag:, parent_tag: old_parent)
|
||||||
TagImplication.create!(tag:, parent_tag: kept_parent)
|
TagImplication.create!(tag:, parent_tag: kept_parent)
|
||||||
@@ -1171,7 +1176,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
|
|
||||||
expect(tag.name).to eq('put_renamed_tag')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('put_renamed_tag')
|
||||||
expect(tag.category).to eq('meme')
|
expect(tag.category).to eq('meme')
|
||||||
|
|
||||||
expect(TagName.find_by!(language_code: 'ja', name: 'put_alias_a'))
|
expect(TagName.find_by!(language_code: 'ja', name: 'put_alias_a'))
|
||||||
@@ -1179,17 +1184,16 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
expect(TagName.find_by!(language_code: 'ja', name: 'put_alias_b'))
|
expect(TagName.find_by!(language_code: 'ja', name: 'put_alias_b'))
|
||||||
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
||||||
|
|
||||||
old_name_alias = TagName.find_by(name: 'spec_tag')
|
old_name_alias = TagName.find_by(language_code: 'ja', name: 'spec_tag')
|
||||||
expect(old_name_alias).to be_present
|
expect(old_name_alias).to be_present
|
||||||
expect(old_name_alias).to have_attributes(
|
expect(old_name_alias).to have_attributes(
|
||||||
tag_id: tag.id, language_code: 'ja', primary_flg: false)
|
tag_id: tag.id, language_code: 'ja', primary_flg: false)
|
||||||
|
|
||||||
expect(alias_tn.reload.tag_id).to be_nil
|
expect(alias_tn.reload.tag_id).to be_nil
|
||||||
|
|
||||||
expect(tag.parents.map(&:name)).to contain_exactly(
|
expect(TagName.where(tag_id: tag.parents.select(:id),
|
||||||
'put_kept_parent',
|
language_code: 'ja', primary_flg: true).pluck(:name))
|
||||||
'put_new_parent'
|
.to contain_exactly('put_kept_parent', 'put_new_parent')
|
||||||
)
|
|
||||||
|
|
||||||
expect(TagImplication.where(tag:, parent_tag: old_parent)).not_to exist
|
expect(TagImplication.where(tag:, parent_tag: old_parent)).not_to exist
|
||||||
|
|
||||||
@@ -1290,7 +1294,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
|
|
||||||
expect(tag.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('spec_tag')
|
||||||
expect(TagName.find_by!(language_code: 'ja', name: 'put_roundtrip_b'))
|
expect(TagName.find_by!(language_code: 'ja', name: 'put_roundtrip_b'))
|
||||||
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
||||||
expect(TagName.where(tag_id: tag.id, language_code: 'ja', primary_flg: false).pluck(:name))
|
expect(TagName.where(tag_id: tag.id, language_code: 'ja', primary_flg: false).pluck(:name))
|
||||||
@@ -1309,10 +1313,10 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it 'parent tag の snapshot も作成する' do
|
it 'parent tag の snapshot も作成する' do
|
||||||
old_parent = create(:tag,
|
old_parent = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_snapshot_old_parent'),
|
primary_tag_name: create(:tag_name, name: 'put_snapshot_old_parent'),
|
||||||
category: :general)
|
category: :general)
|
||||||
new_parent = create(:tag,
|
new_parent = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_snapshot_new_parent'),
|
primary_tag_name: create(:tag_name, name: 'put_snapshot_new_parent'),
|
||||||
category: :general)
|
category: :general)
|
||||||
TagImplication.create!(tag:, parent_tag: old_parent)
|
TagImplication.create!(tag:, parent_tag: old_parent)
|
||||||
|
|
||||||
@@ -1320,7 +1324,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
name: 'spec_tag',
|
name: 'spec_tag',
|
||||||
category: 'general',
|
category: 'general',
|
||||||
aliases: 'unko',
|
aliases: 'unko',
|
||||||
parent_tags: new_parent.name,
|
parent_tags: primary_tag_name_for(new_parent, 'ja').name,
|
||||||
deprecated: '0',
|
deprecated: '0',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1343,13 +1347,13 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
|
||||||
expect(tag.reload.name).to eq('spec_tag')
|
expect(primary_tag_name_for(tag.reload, 'ja').name).to eq('spec_tag')
|
||||||
expect(tag.category).to eq('general')
|
expect(tag.category).to eq('general')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'system tag の name は変更できない' do
|
it 'system tag の name は変更できない' do
|
||||||
system_tag = Tag.tagme
|
system_tag = Tag.tagme
|
||||||
old_name = system_tag.name
|
old_name = primary_tag_name_for(system_tag, 'ja').name
|
||||||
old_category = system_tag.category
|
old_category = system_tag.category
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
@@ -1364,14 +1368,14 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
expect(response).to have_http_status(:unprocessable_entity)
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
|
||||||
expect(system_tag.reload.name).to eq(old_name)
|
expect(primary_tag_name_for(system_tag.reload, 'ja').name).to eq(old_name)
|
||||||
expect(system_tag.category).to eq(old_category)
|
expect(system_tag.category).to eq(old_category)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'wiki を持つ tag を更新すると wiki version も作成する' do
|
it 'wiki を持つ tag を更新すると wiki version も作成する' do
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'wiki body before',
|
body: 'wiki body before',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -1410,7 +1414,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it 'wiki を持つ tag を旧 alias へ戻しても wiki を新しい正本名へ移す' do
|
it 'wiki を持つ tag を旧 alias へ戻しても wiki を新しい正本名へ移す' do
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'wiki body before',
|
body: 'wiki body before',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -1439,8 +1443,9 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
|
|
||||||
expect(wiki_page.reload.tag_name).to eq(tag.tag_name)
|
expect(wiki_page.reload.tag_name).to eq(primary_tag_name_for(tag, 'ja'))
|
||||||
expect(TagName.find_by!(name: 'put_wiki_roundtrip_b').wiki_page).to be_nil
|
expect(TagName.find_by!(language_code: 'ja', name: 'put_wiki_roundtrip_b').wiki_page)
|
||||||
|
.to be_nil
|
||||||
expect(TagName.find_by!(language_code: 'ja', name: 'put_wiki_roundtrip_b'))
|
expect(TagName.find_by!(language_code: 'ja', name: 'put_wiki_roundtrip_b'))
|
||||||
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
.to have_attributes(tag_id: tag.id, primary_flg: false)
|
||||||
|
|
||||||
@@ -1452,7 +1457,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it '別名を他 tag から奪った場合、奪はれた側の tag version も作成する' do
|
it '別名を他 tag から奪った場合、奪はれた側の tag version も作成する' do
|
||||||
old_owner = create(:tag,
|
old_owner = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_alias_old_owner'),
|
primary_tag_name: create(:tag_name, name: 'put_alias_old_owner'),
|
||||||
category: :general)
|
category: :general)
|
||||||
stolen_alias = create(:tag_name, :alias,
|
stolen_alias = create(:tag_name, :alias,
|
||||||
name: 'put_stolen_alias',
|
name: 'put_stolen_alias',
|
||||||
@@ -1493,14 +1498,14 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
it '別 tag の alias 名を rename で奪へる' do
|
it '別 tag の alias 名を rename で奪へる' do
|
||||||
old_owner = create(:tag,
|
old_owner = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_alias_collision_owner'),
|
primary_tag_name: create(:tag_name, name: 'put_alias_collision_owner'),
|
||||||
category: :general)
|
category: :general)
|
||||||
stolen_alias = create(:tag_name, :alias,
|
stolen_alias = create(:tag_name, :alias,
|
||||||
name: 'put_alias_collision_name',
|
name: 'put_alias_collision_name',
|
||||||
tag: old_owner)
|
tag: old_owner)
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'put collision wiki',
|
body: 'put collision wiki',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
@@ -1519,7 +1524,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
old_owner.reload
|
old_owner.reload
|
||||||
stolen_alias.reload
|
stolen_alias.reload
|
||||||
|
|
||||||
expect(tag.name).to eq('put_alias_collision_name')
|
expect(primary_tag_name_for(tag, 'ja').name).to eq('put_alias_collision_name')
|
||||||
expect(stolen_alias).to have_attributes(
|
expect(stolen_alias).to have_attributes(
|
||||||
tag_id: tag.id, language_code: 'ja', primary_flg: true)
|
tag_id: tag.id, language_code: 'ja', primary_flg: true)
|
||||||
expect(TagName.find_by!(language_code: 'ja', name: 'spec_tag'))
|
expect(TagName.find_by!(language_code: 'ja', name: 'spec_tag'))
|
||||||
@@ -1532,12 +1537,12 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
|
|
||||||
expect(old_owner_versions.last.event_type).to eq('update')
|
expect(old_owner_versions.last.event_type).to eq('update')
|
||||||
expect(old_owner_versions.last.aliases.split).not_to include('put_alias_collision_name')
|
expect(old_owner_versions.last.aliases.split).not_to include('put_alias_collision_name')
|
||||||
expect(wiki_page.reload.tag_name).to eq(tag.tag_name)
|
expect(wiki_page.reload.tag_name).to eq(primary_tag_name_for(tag, 'ja'))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'parent_tags に指定すると循環する tag は 422 にする' do
|
it 'parent_tags に指定すると循環する tag は 422 にする' do
|
||||||
child = create(:tag,
|
child = create(:tag,
|
||||||
tag_name: create(:tag_name, name: 'put_cycle_child'),
|
primary_tag_name: create(:tag_name, name: 'put_cycle_child'),
|
||||||
category: :general)
|
category: :general)
|
||||||
|
|
||||||
TagImplication.create!(tag: child, parent_tag: tag)
|
TagImplication.create!(tag: child, parent_tag: tag)
|
||||||
@@ -1546,7 +1551,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
name: 'spec_tag',
|
name: 'spec_tag',
|
||||||
category: 'general',
|
category: 'general',
|
||||||
aliases: 'unko',
|
aliases: 'unko',
|
||||||
parent_tags: child.name,
|
parent_tags: primary_tag_name_for(child, 'ja').name,
|
||||||
deprecated: '0',
|
deprecated: '0',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1558,7 +1563,7 @@ RSpec.describe 'Tags API', type: :request do
|
|||||||
it 'tag の name を変更すると対応する wiki version を作成する' do
|
it 'tag の name を変更すると対応する wiki version を作成する' do
|
||||||
wiki_page =
|
wiki_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
tag_name: tag.tag_name,
|
tag_name: primary_tag_name_for(tag, 'ja'),
|
||||||
body: 'wiki body before',
|
body: 'wiki body before',
|
||||||
created_by_user: member_user,
|
created_by_user: member_user,
|
||||||
message: 'init')
|
message: 'init')
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ RSpec.describe 'Theatres API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'finalizes skip when votes reach majority and stores voters and tag snapshots' do
|
it 'finalizes skip when votes reach majority and stores voters and tag snapshots' do
|
||||||
tag = create(:tag, name: 'skip-target')
|
tag = create(:tag, primary_name: 'skip-target')
|
||||||
PostTag.create!(post: niconico_post, tag:)
|
PostTag.create!(post: niconico_post, tag:)
|
||||||
|
|
||||||
TheatreSkipVote.create!(theatre:, post: niconico_post, user: member)
|
TheatreSkipVote.create!(theatre:, post: niconico_post, user: member)
|
||||||
@@ -503,7 +503,7 @@ RSpec.describe 'Theatres API', type: :request do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'returns tag penalties and candidate weights for the current watchers' do
|
it 'returns tag penalties and candidate weights for the current watchers' do
|
||||||
tag = create(:tag, name: 'heavy-tag')
|
tag = create(:tag, primary_name: 'heavy-tag')
|
||||||
PostTag.create!(post: second_niconico_post, tag:)
|
PostTag.create!(post: second_niconico_post, tag:)
|
||||||
event = TheatreSkipEvent.create!(
|
event = TheatreSkipEvent.create!(
|
||||||
theatre:,
|
theatre:,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ RSpec.describe 'Wiki API', type: :request do
|
|||||||
end
|
end
|
||||||
let!(:tag) do
|
let!(:tag) do
|
||||||
create(:tag,
|
create(:tag,
|
||||||
tag_name: tn,
|
primary_tag_name: tn,
|
||||||
category: :general,
|
category: :general,
|
||||||
deprecated_at: Time.zone.local(2026, 6, 1))
|
deprecated_at: Time.zone.local(2026, 6, 1))
|
||||||
end
|
end
|
||||||
@@ -275,7 +275,7 @@ RSpec.describe 'Wiki API', type: :request do
|
|||||||
|
|
||||||
it 'wiki body だけを変更しても tag version は作成しない' do
|
it 'wiki body だけを変更しても tag version は作成しない' do
|
||||||
linked_tag_name = create(:tag_name, name: 'wiki_body_only_tag')
|
linked_tag_name = create(:tag_name, name: 'wiki_body_only_tag')
|
||||||
linked_tag = create(:tag, tag_name: linked_tag_name, category: :general)
|
linked_tag = create(:tag, primary_tag_name: linked_tag_name, category: :general)
|
||||||
|
|
||||||
TagVersionRecorder.record!(
|
TagVersionRecorder.record!(
|
||||||
tag: linked_tag,
|
tag: linked_tag,
|
||||||
@@ -535,7 +535,7 @@ RSpec.describe 'Wiki API', type: :request do
|
|||||||
|
|
||||||
it 'wiki title を変更すると対応する tag の version を作成する' do
|
it 'wiki title を変更すると対応する tag の version を作成する' do
|
||||||
linked_tag_name = create(:tag_name, name: 'wiki_linked_tag_for_version')
|
linked_tag_name = create(:tag_name, name: 'wiki_linked_tag_for_version')
|
||||||
linked_tag = create(:tag, tag_name: linked_tag_name, category: :general)
|
linked_tag = create(:tag, primary_tag_name: linked_tag_name, category: :general)
|
||||||
|
|
||||||
linked_page =
|
linked_page =
|
||||||
Wiki::Commit.create_content!(
|
Wiki::Commit.create_content!(
|
||||||
@@ -563,7 +563,8 @@ RSpec.describe 'Wiki API', type: :request do
|
|||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
linked_tag.reload
|
linked_tag.reload
|
||||||
expect(linked_tag.name).to eq('wiki_linked_tag_for_version_renamed')
|
expect(primary_tag_name_for(linked_tag, 'ja').name)
|
||||||
|
.to eq('wiki_linked_tag_for_version_renamed')
|
||||||
|
|
||||||
versions = linked_tag.tag_versions.order(:version_no)
|
versions = linked_tag.tag_versions.order(:version_no)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe MaterialSyncImporter do
|
RSpec.describe MaterialSyncImporter do
|
||||||
let(:user) { create(:user, :member) }
|
let(:user) { create(:user, :member) }
|
||||||
let(:tag) { create(:tag, name: 'sync_tag', category: :material) }
|
let(:tag) { create(:tag, primary_name: 'sync_tag', category: :material) }
|
||||||
|
|
||||||
def tempfile_for body
|
def tempfile_for body
|
||||||
Tempfile.new(['material-sync-importer', '.png']).tap do |file|
|
Tempfile.new(['material-sync-importer', '.png']).tap do |file|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ RSpec.describe NicoTagVersionRecorder do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'records sorted linked internal names and later link removal' do
|
it 'records sorted linked internal names and later link removal' do
|
||||||
tags = ['z_link', 'a_link'].map { |name| create(:tag, name:, category: :general) }
|
tags = ['z_link', 'a_link'].map { |name| create(:tag, primary_name: name, category: :general) }
|
||||||
tags.each { |tag| NicoTagRelation.create!(nico_tag: external_tag, tag:) }
|
tags.each { |tag| NicoTagRelation.create!(nico_tag: external_tag, tag:) }
|
||||||
|
|
||||||
expect(record(:create).linked_tags).to eq('a_link z_link')
|
expect(record(:create).linked_tags).to eq('a_link z_link')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe PostCreatePlan do
|
RSpec.describe PostCreatePlan do
|
||||||
def create_tag! name, category
|
def create_tag! name, category
|
||||||
create(:tag, name:, category:)
|
create(:tag, primary_name: name, category:)
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@@ -16,12 +16,15 @@ RSpec.describe PostCreatePlan do
|
|||||||
it 'resolves the matching language identity and its parents' do
|
it 'resolves the matching language identity and its parents' do
|
||||||
english_name = create(:tag_name, name: 'shared_name',
|
english_name = create(:tag_name, name: 'shared_name',
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
english = create(:tag, tag_name: english_name, category: :character)
|
english = create(:tag, primary_tag_name: english_name, category: :character)
|
||||||
japanese = create(:tag, name: 'temporary_japanese', category: :general)
|
japanese = create(:tag, primary_name: 'temporary_japanese', category: :general)
|
||||||
# The DB permits this identity; validation has its own contract spec.
|
# The DB permits this identity; validation has its own contract spec.
|
||||||
japanese.tag_name.update_columns(name: 'shared_name')
|
primary_tag_name_for(japanese, 'ja').update_columns(name: 'shared_name')
|
||||||
english_parent = create(:tag, name: 'english_parent', category: :material)
|
english_parent_name = create(:tag_name, name: 'english_parent',
|
||||||
japanese_parent = create(:tag, name: 'japanese_parent', category: :general)
|
language_code: 'en', script_code: 'Latn')
|
||||||
|
english_parent = create(:tag, primary_tag_name: english_parent_name,
|
||||||
|
category: :material)
|
||||||
|
japanese_parent = create(:tag, primary_name: 'japanese_parent', category: :general)
|
||||||
TagImplication.create!(tag: english, parent_tag: english_parent)
|
TagImplication.create!(tag: english, parent_tag: english_parent)
|
||||||
TagImplication.create!(tag: japanese, parent_tag: japanese_parent)
|
TagImplication.create!(tag: japanese, parent_tag: japanese_parent)
|
||||||
|
|
||||||
@@ -30,15 +33,16 @@ RSpec.describe PostCreatePlan do
|
|||||||
expect(plan[:direct_tag_specs]).to eq(
|
expect(plan[:direct_tag_specs]).to eq(
|
||||||
[{ name: 'shared_name', category: :character }])
|
[{ name: 'shared_name', category: :character }])
|
||||||
expect(plan[:post_tag_specs]).to include(
|
expect(plan[:post_tag_specs]).to include(
|
||||||
{ name: english_parent.name, category: :material })
|
{ name: primary_tag_name_for(english_parent, 'en').name, category: :material })
|
||||||
expect(plan[:post_tag_specs].pluck(:name)).not_to include(japanese_parent.name)
|
expect(plan[:post_tag_specs].pluck(:name))
|
||||||
|
.not_to include(primary_tag_name_for(japanese_parent, 'ja').name)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'resolves aliases within the requested language' do
|
it 'resolves aliases within the requested language' do
|
||||||
japanese = create(:tag, name: 'japanese_canonical')
|
japanese = create(:tag, primary_name: 'japanese_canonical')
|
||||||
english_name = create(:tag_name, name: 'english_canonical',
|
english_name = create(:tag_name, name: 'english_canonical',
|
||||||
language_code: 'en', script_code: 'Latn')
|
language_code: 'en', script_code: 'Latn')
|
||||||
english = create(:tag, tag_name: english_name, category: :character)
|
english = create(:tag, primary_tag_name: english_name, category: :character)
|
||||||
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
tag: japanese)
|
tag: japanese)
|
||||||
english_alias = create(:tag_name, :alias, name: 'shared_alias',
|
english_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||||
@@ -55,7 +59,7 @@ RSpec.describe PostCreatePlan do
|
|||||||
plan = described_class.new(attributes: { tags: 'shared_alias' }).build!(locale)
|
plan = described_class.new(attributes: { tags: 'shared_alias' }).build!(locale)
|
||||||
|
|
||||||
expect(plan[:direct_tag_specs]).to eq(
|
expect(plan[:direct_tag_specs]).to eq(
|
||||||
[{ name: english.name, category: :character }])
|
[{ name: english_name.name, category: :character }])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ RSpec.describe PostImportPreviewer do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'applies metadata to automatic fields and recognises metadata tags' do
|
it 'applies metadata to automatic fields and recognises metadata tags' do
|
||||||
create(:tag, name: 'known-tag', category: :general)
|
create(:tag, primary_name: 'known-tag', category: :general)
|
||||||
allow(PostMetadataFetcher).to receive(:fetch).and_return(
|
allow(PostMetadataFetcher).to receive(:fetch).and_return(
|
||||||
title: 'metadata title',
|
title: 'metadata title',
|
||||||
thumbnail_base: 'https://example.com/thumb.jpg',
|
thumbnail_base: 'https://example.com/thumb.jpg',
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ RSpec.describe Wiki::Commit do
|
|||||||
|
|
||||||
it 'does not record tag_version on body-only wiki update' do
|
it 'does not record tag_version on body-only wiki update' do
|
||||||
tag_name = create(:tag_name, name: 'commit_integrity_linked_tag')
|
tag_name = create(:tag_name, name: 'commit_integrity_linked_tag')
|
||||||
tag = create(:tag, tag_name:, category: :general)
|
tag = create(:tag, primary_tag_name: tag_name, category: :general)
|
||||||
|
|
||||||
page =
|
page =
|
||||||
described_class.create_content!(
|
described_class.create_content!(
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ RSpec.describe Wiki::Commit do
|
|||||||
|
|
||||||
it 'does not record tag version when corresponding tag has no versions' do
|
it 'does not record tag version when corresponding tag has no versions' do
|
||||||
tag_name = create(:tag_name, name: 'commit_linked_tag_without_versions')
|
tag_name = create(:tag_name, name: 'commit_linked_tag_without_versions')
|
||||||
tag = create(:tag, tag_name:, category: :general)
|
tag = create(:tag, primary_tag_name: tag_name, category: :general)
|
||||||
|
|
||||||
page =
|
page =
|
||||||
described_class.create_content!(
|
described_class.create_content!(
|
||||||
@@ -108,7 +108,7 @@ RSpec.describe Wiki::Commit do
|
|||||||
|
|
||||||
it 'does not record tag version when corresponding tag has no versions' do
|
it 'does not record tag version when corresponding tag has no versions' do
|
||||||
tag_name = create(:tag_name, name: 'commit_linked_tag_without_versions')
|
tag_name = create(:tag_name, name: 'commit_linked_tag_without_versions')
|
||||||
tag = create(:tag, tag_name:, category: :general)
|
tag = create(:tag, primary_tag_name: tag_name, category: :general)
|
||||||
|
|
||||||
page =
|
page =
|
||||||
described_class.create_content!(
|
described_class.create_content!(
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
module TestRecords
|
module TestRecords
|
||||||
|
def primary_tag_name_for(tag, language_code)
|
||||||
|
TagName.find_by!(tag_id: tag.id, language_code:, primary_flg: true)
|
||||||
|
end
|
||||||
|
|
||||||
def create_member_user!
|
def create_member_user!
|
||||||
User.create!(name: 'spec user',
|
User.create!(name: 'spec user',
|
||||||
inheritance_code: SecureRandom.hex(16),
|
inheritance_code: SecureRandom.hex(16),
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ RSpec.describe 'nico:sync' do
|
|||||||
run_rake_task('nico:sync')
|
run_rake_task('nico:sync')
|
||||||
|
|
||||||
post.reload
|
post.reload
|
||||||
active_tag_names = post.tags.joins(:tag_name).pluck('tag_names.name')
|
active_tag_names = TagName.where(tag_id: post.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name)
|
||||||
|
|
||||||
expect(active_tag_names).to include('spec_kept')
|
expect(active_tag_names).to include('spec_kept')
|
||||||
expect(post.external_tags).to contain_exactly(nico)
|
expect(post.external_tags).to contain_exactly(nico)
|
||||||
@@ -434,7 +435,9 @@ RSpec.describe 'nico:sync' do
|
|||||||
|
|
||||||
external = post.external_tags.sole
|
external = post.external_tags.sole
|
||||||
expect(external.name).to eq('raw tag[]')
|
expect(external.name).to eq('raw tag[]')
|
||||||
expect(post.tags.map(&:name)).not_to include('bot操作')
|
expect(TagName.where(tag_id: post.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name))
|
||||||
|
.not_to include('bot操作')
|
||||||
expect(post.post_versions.order(:version_no).last.tags_json)
|
expect(post.post_versions.order(:version_no).last.tags_json)
|
||||||
.to include('external_tag_id' => external.id)
|
.to include('external_tag_id' => external.id)
|
||||||
|
|
||||||
@@ -446,7 +449,9 @@ RSpec.describe 'nico:sync' do
|
|||||||
run_nico_sync_with_tags!([])
|
run_nico_sync_with_tags!([])
|
||||||
}.to change(PostVersion, :count).by(1)
|
}.to change(PostVersion, :count).by(1)
|
||||||
expect(post.reload.external_tags).to be_empty
|
expect(post.reload.external_tags).to be_empty
|
||||||
expect(post.tags.map(&:name)).not_to include('bot操作')
|
expect(TagName.where(tag_id: post.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name))
|
||||||
|
.not_to include('bot操作')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'サニタイズ後の既存外部タグを再利用し、その連携タグを記載する' do
|
it 'サニタイズ後の既存外部タグを再利用し、その連携タグを記載する' do
|
||||||
@@ -563,7 +568,9 @@ RSpec.describe 'nico:sync' do
|
|||||||
name: 'AAA')
|
name: 'AAA')
|
||||||
expect(ExternalTag.exists?(platform: :nico, name: 'AAA?')).to be(false)
|
expect(ExternalTag.exists?(platform: :nico, name: 'AAA?')).to be(false)
|
||||||
|
|
||||||
expect(post.tags.map(&:name)).not_to include('bot操作')
|
expect(TagName.where(tag_id: post.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name))
|
||||||
|
.not_to include('bot操作')
|
||||||
expect(post.post_versions.order(:version_no).last.tags_json)
|
expect(post.post_versions.order(:version_no).last.tags_json)
|
||||||
.to include('external_tag_id' => external.id)
|
.to include('external_tag_id' => external.id)
|
||||||
|
|
||||||
@@ -577,7 +584,9 @@ RSpec.describe 'nico:sync' do
|
|||||||
}.to change(PostVersion, :count).by(1)
|
}.to change(PostVersion, :count).by(1)
|
||||||
|
|
||||||
expect(post.reload.external_tags).to be_empty
|
expect(post.reload.external_tags).to be_empty
|
||||||
expect(post.tags.map(&:name)).not_to include('bot操作')
|
expect(TagName.where(tag_id: post.tags.select(:id),
|
||||||
|
language_code: 'ja', primary_flg: true).pluck(:name))
|
||||||
|
.not_to include('bot操作')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'nico: prefix を含む従来の規則で外部タグ名をサニタイズする' do
|
it 'nico: prefix を含む従来の規則で外部タグ名をサニタイズする' do
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ RSpec.describe 'post_similarity:calc' do
|
|||||||
|
|
||||||
it 'calculates similarities from active tags only' do
|
it 'calculates similarities from active tags only' do
|
||||||
# 必要最低限のデータ
|
# 必要最低限のデータ
|
||||||
t1 = create(:tag, name: 't1')
|
t1 = create(:tag, primary_name: 't1')
|
||||||
t2 = create(:tag, name: 't2')
|
t2 = create(:tag, primary_name: 't2')
|
||||||
t3 = create(:tag, name: 't3')
|
t3 = create(:tag, primary_name: 't3')
|
||||||
deprecated_tag = create(:tag, name: 'deprecated', deprecated_at: Time.current)
|
deprecated_tag = create(:tag, primary_name: 'deprecated', deprecated_at: Time.current)
|
||||||
|
|
||||||
p1 = Post.create!(url: "https://example.com/1")
|
p1 = Post.create!(url: "https://example.com/1")
|
||||||
p2 = Post.create!(url: "https://example.com/2")
|
p2 = Post.create!(url: "https://example.com/2")
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ RSpec.describe 'tag_similarity:calc' do
|
|||||||
|
|
||||||
it 'calculates similarities for active tags only' do
|
it 'calculates similarities for active tags only' do
|
||||||
# 必要最低限のデータ
|
# 必要最低限のデータ
|
||||||
t1 = create(:tag, name: 't1')
|
t1 = create(:tag, primary_name: 't1')
|
||||||
t2 = create(:tag, name: 't2')
|
t2 = create(:tag, primary_name: 't2')
|
||||||
t3 = create(:tag, name: 't3')
|
t3 = create(:tag, primary_name: 't3')
|
||||||
deprecated_tag = create(:tag, name: 'deprecated', deprecated_at: Time.current)
|
deprecated_tag = create(:tag, primary_name: 'deprecated', deprecated_at: Time.current)
|
||||||
|
|
||||||
p1 = Post.create!(url: "https://example.com/1")
|
p1 = Post.create!(url: "https://example.com/1")
|
||||||
p2 = Post.create!(url: "https://example.com/2")
|
p2 = Post.create!(url: "https://example.com/2")
|
||||||
|
|||||||
新しいイシューから参照
ユーザーをブロックする