このコミットが含まれているのは:
@@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe MaterialSyncImporter do
|
||||
let(:user) { create(:user, :member) }
|
||||
let(:tag) { Tag.create!(tag_name: TagName.create!(name: 'sync_tag'), category: :material) }
|
||||
let(:tag) { create(:tag, name: 'sync_tag', category: :material) }
|
||||
|
||||
def tempfile_for body
|
||||
Tempfile.new(['material-sync-importer', '.png']).tap do |file|
|
||||
|
||||
@@ -65,7 +65,7 @@ RSpec.describe NicoTagVersionRecorder do
|
||||
end
|
||||
|
||||
it 'records sorted linked internal names and later link removal' do
|
||||
tags = ['z_link', 'a_link'].map { |name| Tag.create!(name:, category: :general) }
|
||||
tags = ['z_link', 'a_link'].map { |name| create(:tag, name:, category: :general) }
|
||||
tags.each { |tag| NicoTagRelation.create!(nico_tag: external_tag, tag:) }
|
||||
|
||||
expect(record(:create).linked_tags).to eq('a_link z_link')
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe PostBulkCreator do
|
||||
include_context 'English locale'
|
||||
|
||||
it 'limits workers to two and keeps failures in their request slots' do
|
||||
actor = instance_double(User, id: 123)
|
||||
allow(User).to receive(:find).with(123) {
|
||||
@@ -9,6 +11,7 @@ RSpec.describe PostBulkCreator do
|
||||
mutex = Mutex.new
|
||||
active = 0
|
||||
maximum_active = 0
|
||||
creators = []
|
||||
|
||||
allow(PostCreatePreflight).to receive(:new) do |attributes:, **|
|
||||
preflight = instance_double(PostCreatePreflight)
|
||||
@@ -28,6 +31,7 @@ RSpec.describe PostBulkCreator do
|
||||
end
|
||||
allow(PostCreator).to receive(:new) do |attributes:, **|
|
||||
creator = instance_double(PostCreator)
|
||||
mutex.synchronize { creators << creator }
|
||||
if attributes[:title] == 'broken'
|
||||
allow(creator).to receive(:create!).and_raise(StandardError, 'broken')
|
||||
else
|
||||
@@ -45,7 +49,12 @@ RSpec.describe PostBulkCreator do
|
||||
results = described_class.new(
|
||||
actor:,
|
||||
posts:,
|
||||
thumbnails: { }).run.fetch(:results)
|
||||
thumbnails: { }).run(locale).fetch(:results)
|
||||
|
||||
expect(creators.length).to eq(posts.length)
|
||||
creators.each do |creator|
|
||||
expect(creator).to have_received(:create!).with(locale).once
|
||||
end
|
||||
|
||||
expect(maximum_active).to eq(2)
|
||||
expect(results.length).to eq(posts.length)
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe PostCreatePlan do
|
||||
def create_tag! name, category
|
||||
Tag.create!(name:, category:)
|
||||
create(:tag, name:, category:)
|
||||
end
|
||||
|
||||
before do
|
||||
@@ -10,6 +10,56 @@ RSpec.describe PostCreatePlan do
|
||||
create_tag!('ニジラー情報不詳', :meta)
|
||||
end
|
||||
|
||||
context 'with an explicit locale' do
|
||||
include_context 'English locale'
|
||||
|
||||
it 'resolves the matching language identity and its parents' do
|
||||
english_name = create(:tag_name, name: 'shared_name',
|
||||
language_code: 'en', script_code: 'Latn')
|
||||
english = create(:tag, tag_name: english_name, category: :character)
|
||||
japanese = create(:tag, name: 'temporary_japanese', category: :general)
|
||||
# The DB permits this identity; validation has its own contract spec.
|
||||
japanese.tag_name.update_columns(name: 'shared_name')
|
||||
english_parent = create(:tag, name: 'english_parent', category: :material)
|
||||
japanese_parent = create(:tag, name: 'japanese_parent', category: :general)
|
||||
TagImplication.create!(tag: english, parent_tag: english_parent)
|
||||
TagImplication.create!(tag: japanese, parent_tag: japanese_parent)
|
||||
|
||||
plan = described_class.new(attributes: { tags: 'shared_name' }).build!(locale)
|
||||
|
||||
expect(plan[:direct_tag_specs]).to eq(
|
||||
[{ name: 'shared_name', category: :character }])
|
||||
expect(plan[:post_tag_specs]).to include(
|
||||
{ name: english_parent.name, category: :material })
|
||||
expect(plan[:post_tag_specs].pluck(:name)).not_to include(japanese_parent.name)
|
||||
end
|
||||
|
||||
it 'resolves aliases within the requested language' do
|
||||
japanese = create(:tag, name: 'japanese_canonical')
|
||||
english_name = create(:tag_name, name: 'english_canonical',
|
||||
language_code: 'en', script_code: 'Latn')
|
||||
english = create(:tag, tag_name: english_name, category: :character)
|
||||
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
||||
canonical: japanese.tag_name)
|
||||
english_alias = create(:tag_name, :alias, name: 'temporary_alias',
|
||||
canonical: english_name,
|
||||
language_code: 'en', script_code: 'Latn')
|
||||
english_alias.update_columns(name: 'shared_alias')
|
||||
|
||||
expect(japanese_alias.reload).to have_attributes(
|
||||
canonical_id: japanese.tag_name_id, tag_id: japanese.id,
|
||||
primary_flg: false, language_code: 'ja')
|
||||
expect(english_alias.reload).to have_attributes(
|
||||
canonical_id: english_name.id, tag_id: english.id,
|
||||
primary_flg: false, language_code: 'en')
|
||||
|
||||
plan = described_class.new(attributes: { tags: 'shared_alias' }).build!(locale)
|
||||
|
||||
expect(plan[:direct_tag_specs]).to eq(
|
||||
[{ name: english.name, category: :character }])
|
||||
end
|
||||
end
|
||||
|
||||
it 'plans direct and existing default tags without persisting records' do
|
||||
counts = [TagName.count, Tag.count]
|
||||
|
||||
@@ -18,7 +68,7 @@ RSpec.describe PostCreatePlan do
|
||||
url: 'https://example.com/post',
|
||||
title: 'title',
|
||||
tags: 'character:new_character',
|
||||
parent_post_ids: '' }).build!
|
||||
parent_post_ids: '' }).build!(Locale.nipponese)
|
||||
|
||||
expect(plan[:tags]).to eq('new_character')
|
||||
expect(plan[:direct_tag_specs]).to eq(
|
||||
@@ -31,7 +81,7 @@ RSpec.describe PostCreatePlan do
|
||||
|
||||
it 'resolves aliases and keeps tag sections separate from canonical names' do
|
||||
canonical = create_tag!('虹夏', :character)
|
||||
TagName.create!(name: 'にじか', canonical: canonical.tag_name)
|
||||
create(:tag_name, :alias, name: 'にじか', canonical: canonical.tag_name)
|
||||
create_tag!('動画', :meta)
|
||||
|
||||
plan = described_class.new(
|
||||
@@ -40,7 +90,7 @@ RSpec.describe PostCreatePlan do
|
||||
title: 'video',
|
||||
tags: '動画 にじか[0:10-0:20]',
|
||||
duration: '1:00',
|
||||
parent_post_ids: '' }).build!
|
||||
parent_post_ids: '' }).build!(Locale.nipponese)
|
||||
|
||||
expect(plan[:tags].split).to include('動画', '虹夏[0:10-0:20]')
|
||||
expect(plan[:display_tags]).to include(
|
||||
@@ -55,7 +105,7 @@ RSpec.describe PostCreatePlan do
|
||||
counts = [Tag.count, TagName.count, ExternalTag.count]
|
||||
|
||||
expect {
|
||||
described_class.new(attributes: { tags: 'NiCo:reserved' }).build!
|
||||
described_class.new(attributes: { tags: 'NiCo:reserved' }).build!(Locale.nipponese)
|
||||
}.to raise_error(ActiveRecord::RecordInvalid) { |error|
|
||||
expect(error.record.errors[:tags]).to be_present
|
||||
}
|
||||
@@ -73,7 +123,7 @@ RSpec.describe PostCreatePlan do
|
||||
url: 'https://example.com/post',
|
||||
title: 'title',
|
||||
tags: long_name,
|
||||
parent_post_ids: '' }).build!
|
||||
parent_post_ids: '' }).build!(Locale.nipponese)
|
||||
}.to raise_error(ActiveRecord::RecordInvalid) { |error|
|
||||
expect(error.record.errors[:tags]).not_to be_empty
|
||||
}
|
||||
@@ -87,7 +137,7 @@ RSpec.describe PostCreatePlan do
|
||||
title: 'title',
|
||||
tags: 'ordinary_tag',
|
||||
duration: 'invalid',
|
||||
parent_post_ids: '' }).build!
|
||||
parent_post_ids: '' }).build!(Locale.nipponese)
|
||||
|
||||
expect(plan[:duration]).to eq('invalid')
|
||||
expect(plan[:video_ms]).to be_nil
|
||||
|
||||
@@ -14,7 +14,6 @@ RSpec.describe PostCreator do
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Tag).to receive(:normalise_tags!).and_return({ tags: [], sections: {} })
|
||||
allow(TagVersioning).to receive(:record_tag_snapshots!)
|
||||
allow(Tag).to receive(:expand_parent_tags).and_return([])
|
||||
allow(PostVersionRecorder).to receive(:record!)
|
||||
@@ -34,7 +33,7 @@ RSpec.describe PostCreator do
|
||||
url: 'https://example.com/post',
|
||||
thumbnail: real_thumbnail_upload,
|
||||
thumbnail_base: 'https://example.com/thumb.jpg',
|
||||
tags: '' }).create!
|
||||
tags: '' }).create!(Locale.nipponese)
|
||||
|
||||
expect(post.thumbnail).to be_attached
|
||||
expect(post.thumbnail_base).to eq('https://example.com/thumb.jpg')
|
||||
@@ -54,7 +53,7 @@ RSpec.describe PostCreator do
|
||||
title: 'title',
|
||||
url: 'https://example.com/post',
|
||||
thumbnail_base: 'https://example.com/thumb.jpg',
|
||||
tags: '' }).create!
|
||||
tags: '' }).create!(Locale.nipponese)
|
||||
|
||||
expect(post.thumbnail_base).to eq('https://example.com/thumb.jpg')
|
||||
expect(post.thumbnail).to be_attached
|
||||
@@ -72,7 +71,34 @@ RSpec.describe PostCreator do
|
||||
tags: '' })
|
||||
|
||||
post_count = Post.count
|
||||
expect { creator.create! }.to raise_error(Post::RemoteThumbnailFetchFailed)
|
||||
expect { creator.create!(Locale.nipponese) }
|
||||
.to raise_error(Post::RemoteThumbnailFetchFailed)
|
||||
expect(Post.count).to eq(post_count)
|
||||
end
|
||||
|
||||
context 'with an explicit locale' do
|
||||
include_context 'English locale'
|
||||
|
||||
[false, true].each do |planned|
|
||||
it "passes locale to tag creation with planned attributes: #{ planned }" do
|
||||
attributes = {
|
||||
title: 'Locale propagation',
|
||||
url: 'https://example.com/locale-post',
|
||||
tags: 'character:locale_character' }
|
||||
if planned
|
||||
specs = [{ name: 'locale_character', category: :character }]
|
||||
attributes.merge!(snapshot_tag_specs: specs, post_tag_specs: specs)
|
||||
end
|
||||
allow(Tag).to receive(:find_or_create_by_tag_name!).and_call_original
|
||||
|
||||
post = described_class.new(actor:, attributes:).create!(locale)
|
||||
|
||||
expect(Tag).to have_received(:find_or_create_by_tag_name!)
|
||||
.with(locale, 'locale_character', category: :character).at_least(:once)
|
||||
tag_name = TagName.find_by!(language_code: 'en', name: 'locale_character')
|
||||
expect(tag_name).to have_attributes(script_code: 'Latn', primary_flg: true)
|
||||
expect(post.tags).to include(tag_name.tag)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,7 +64,7 @@ RSpec.describe PostImportPreviewer do
|
||||
end
|
||||
|
||||
it 'applies metadata to automatic fields and recognises metadata tags' do
|
||||
Tag.create!(name: 'known-tag', category: :general)
|
||||
create(:tag, name: 'known-tag', category: :general)
|
||||
allow(PostMetadataFetcher).to receive(:fetch).and_return(
|
||||
title: 'metadata title',
|
||||
thumbnail_base: 'https://example.com/thumb.jpg',
|
||||
|
||||
@@ -6,7 +6,7 @@ RSpec.describe Wiki::Commit do
|
||||
|
||||
def create_page title:, body: 'initial body'
|
||||
described_class.create_content!(
|
||||
tag_name: TagName.create!(name: title),
|
||||
tag_name: create(:tag_name, name: title),
|
||||
body:,
|
||||
created_by_user: user,
|
||||
message: 'init')
|
||||
@@ -16,7 +16,7 @@ RSpec.describe Wiki::Commit do
|
||||
it 'creates page, revision, and version with normalised body' do
|
||||
expect {
|
||||
described_class.create_content!(
|
||||
tag_name: TagName.create!(name: 'commit_integrity_create'),
|
||||
tag_name: create(:tag_name, name: 'commit_integrity_create'),
|
||||
body: "a\r\nb\r\n\r\n",
|
||||
created_by_user: user,
|
||||
message: 'init')
|
||||
@@ -36,7 +36,7 @@ RSpec.describe Wiki::Commit do
|
||||
end
|
||||
|
||||
it 'rejects body that becomes blank after normalisation' do
|
||||
tag_name = TagName.create!(name: 'commit_integrity_blank')
|
||||
tag_name = create(:tag_name, name: 'commit_integrity_blank')
|
||||
|
||||
expect {
|
||||
described_class.create_content!(
|
||||
@@ -76,8 +76,8 @@ RSpec.describe Wiki::Commit do
|
||||
end
|
||||
|
||||
it 'does not record tag_version on body-only wiki update' do
|
||||
tag_name = TagName.create!(name: 'commit_integrity_linked_tag')
|
||||
tag = Tag.create!(tag_name:, category: :general)
|
||||
tag_name = create(:tag_name, name: 'commit_integrity_linked_tag')
|
||||
tag = create(:tag, tag_name:, category: :general)
|
||||
|
||||
page =
|
||||
described_class.create_content!(
|
||||
|
||||
@@ -4,7 +4,7 @@ RSpec.describe Wiki::Commit do
|
||||
let(:user) { create_member_user! }
|
||||
|
||||
def create_page(title: 'commit_spec_page', body: 'initial body')
|
||||
tag_name = TagName.create!(name: title)
|
||||
tag_name = create(:tag_name, name: title)
|
||||
|
||||
Wiki::Commit.create_content!(
|
||||
tag_name:,
|
||||
@@ -80,8 +80,8 @@ RSpec.describe Wiki::Commit do
|
||||
end
|
||||
|
||||
it 'does not record tag version when corresponding tag has no versions' do
|
||||
tag_name = TagName.create!(name: 'commit_linked_tag_without_versions')
|
||||
tag = Tag.create!(tag_name:, category: :general)
|
||||
tag_name = create(:tag_name, name: 'commit_linked_tag_without_versions')
|
||||
tag = create(:tag, tag_name:, category: :general)
|
||||
|
||||
page =
|
||||
described_class.create_content!(
|
||||
@@ -107,8 +107,8 @@ RSpec.describe Wiki::Commit do
|
||||
end
|
||||
|
||||
it 'does not record tag version when corresponding tag has no versions' do
|
||||
tag_name = TagName.create!(name: 'commit_linked_tag_without_versions')
|
||||
tag = Tag.create!(tag_name:, category: :general)
|
||||
tag_name = create(:tag_name, name: 'commit_linked_tag_without_versions')
|
||||
tag = create(:tag, tag_name:, category: :general)
|
||||
|
||||
page =
|
||||
described_class.create_content!(
|
||||
|
||||
@@ -5,7 +5,7 @@ RSpec.describe WikiVersionRecorder do
|
||||
|
||||
def create_page title:, body: 'body'
|
||||
Wiki::Commit.create_content!(
|
||||
tag_name: TagName.create!(name: title),
|
||||
tag_name: create(:tag_name, name: title),
|
||||
body:,
|
||||
created_by_user: user,
|
||||
message: 'init')
|
||||
|
||||
@@ -172,7 +172,8 @@ RSpec.describe Youtube::Sync do
|
||||
Tag.video
|
||||
Tag.no_deerjikist
|
||||
|
||||
deerjikist_tag = Tag.find_or_create_by_tag_name!('テスト投稿者', category: :deerjikist)
|
||||
deerjikist_tag = Tag.find_or_create_by_tag_name!(
|
||||
Locale.nipponese, 'テスト投稿者', category: :deerjikist)
|
||||
Deerjikist.create!(
|
||||
platform: 'youtube',
|
||||
code: 'UC_MAPPED',
|
||||
@@ -226,7 +227,8 @@ RSpec.describe Youtube::Sync do
|
||||
)
|
||||
PostTag.create!(post:, tag: Tag.no_deerjikist)
|
||||
|
||||
deerjikist_tag = Tag.find_or_create_by_tag_name!('後から判明した投稿者', category: :deerjikist)
|
||||
deerjikist_tag = Tag.find_or_create_by_tag_name!(
|
||||
Locale.nipponese, '後から判明した投稿者', category: :deerjikist)
|
||||
Deerjikist.create!(
|
||||
platform: 'youtube',
|
||||
code: 'UC_MAPPED_LATER',
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする