240 行
10 KiB
Ruby
240 行
10 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe 'Locale propagation on write paths', type: :request do
|
|
include_context 'English locale'
|
|
|
|
let(:member) { create(:user, :member) }
|
|
|
|
before do
|
|
sign_in_as(member)
|
|
end
|
|
|
|
def expect_localised_tag(name, expected_locale)
|
|
tag_name = TagName.find_by!(name:, language_code: expected_locale.language_code)
|
|
expect(tag_name).to have_attributes(
|
|
script_code: expected_locale.script_code, primary_flg: true)
|
|
expect(tag_name.tag_id).to be_present
|
|
expect(tag_name.tag.tag_name_id).to eq(tag_name.id)
|
|
tag_name.tag
|
|
end
|
|
|
|
['en', nil].each do |requested_locale|
|
|
context "with locale #{ requested_locale.inspect }" do
|
|
let(:locale_params) { requested_locale ? { locale: requested_locale } : { } }
|
|
let(:expected_locale) { requested_locale ? locale : Locale.nipponese }
|
|
|
|
it 'creates post tags in the requested language or Japanese fallback' do
|
|
post '/posts', params: locale_params.merge(
|
|
title: 'Locale post', url: 'https://example.com/locale-post',
|
|
tags: 'locale_post_tag', parent_post_ids: '')
|
|
|
|
expect(response).to have_http_status(:created), response.body
|
|
tag = expect_localised_tag('locale_post_tag', expected_locale)
|
|
expect(Post.find(json.fetch('id')).tags).to include(tag)
|
|
end
|
|
|
|
it 'updates post tags in the requested language or Japanese fallback' do
|
|
record = create(:post)
|
|
PostVersionRecorder.record!(post: record, event_type: :create, created_by_user: member)
|
|
|
|
put "/posts/#{ record.id }", params: locale_params.merge(
|
|
title: record.title, tags: 'locale_updated_tag', parent_post_ids: '',
|
|
base_version_no: record.reload.version_no)
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
tag = expect_localised_tag('locale_updated_tag', expected_locale)
|
|
expect(record.reload.tags).to include(tag)
|
|
end
|
|
|
|
it 'passes the resolved locale to bulk creation' do
|
|
# Worker propagation is exercised in post_bulk_creator_spec.
|
|
expect_any_instance_of(PostBulkCreator).to receive(:run)
|
|
.with(expected_locale).and_return(results: [])
|
|
manifest = [{ title: 'Bulk locale', url: 'https://example.com/bulk-locale',
|
|
tags: 'bulk_locale_tag', parent_post_ids: '' }]
|
|
|
|
post '/posts/bulk', params: locale_params.merge(posts: JSON.generate(manifest)),
|
|
headers: { 'CONTENT_TYPE' => 'multipart/form-data' }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
end
|
|
|
|
it 'creates materials with tags in the resolved locale' do
|
|
post '/materials', params: locale_params.merge(
|
|
tag: 'locale_material', url: 'https://example.com/material')
|
|
|
|
expect(response).to have_http_status(:created), response.body
|
|
tag = expect_localised_tag('locale_material', expected_locale)
|
|
expect(Material.find(json.fetch('id')).tag).to eq(tag)
|
|
end
|
|
|
|
it 'updates materials with tags in the resolved locale' do
|
|
tag = create(:tag, category: :material)
|
|
material = Material.create!(tag:, url: 'https://example.com/material')
|
|
|
|
put "/materials/#{ material.id }", params: locale_params.merge(
|
|
tag: 'locale_material_updated', url: material.url)
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
resolved_tag = expect_localised_tag('locale_material_updated', expected_locale)
|
|
expect(material.reload.tag).to eq(resolved_tag)
|
|
end
|
|
|
|
it 'links Nico external tags to internal tags in the resolved locale' do
|
|
external = create(:external_tag)
|
|
NicoTagVersionRecorder.record!(
|
|
external_tag: external, event_type: :create, created_by_user: member)
|
|
|
|
put "/tags/nico/#{ external.id }", params: locale_params.merge(tags: 'locale_link')
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
tag = expect_localised_tag('locale_link', expected_locale)
|
|
expect(external.reload.linked_tags).to contain_exactly(tag)
|
|
end
|
|
|
|
it 'creates parent tags in the resolved locale' do
|
|
tag = create(:tag)
|
|
|
|
put "/tags/#{ tag.id }", params: locale_params.merge(
|
|
name: primary_tag_name_for(tag, 'ja').name, category: tag.category, deprecated: false,
|
|
aliases: '', parent_tags: 'locale_parent')
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
parent = expect_localised_tag('locale_parent', expected_locale)
|
|
expect(TagImplication.where(tag:).pluck(:parent_tag_id)).to eq([parent.id])
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with existing names in both languages' do
|
|
let!(:english_name) do
|
|
create(:tag_name, name: 'shared_name', language_code: 'en', script_code: 'Latn')
|
|
end
|
|
let!(:english_tag) { create(:tag, primary_tag_name: english_name, category: :material) }
|
|
let!(:japanese_tag) do
|
|
create(:tag, primary_name: 'temporary_japanese', category: :general).tap do |tag|
|
|
# Isolate lookup from the separately tested uniqueness validation.
|
|
primary_tag_name_for(tag, 'ja').update_columns(name: 'shared_name')
|
|
end
|
|
end
|
|
|
|
it 'plans and creates the post using the English identity and category' do
|
|
post '/posts', params: {
|
|
locale: 'en', title: 'English identity',
|
|
url: 'https://example.com/english-identity', tags: 'shared_name', parent_post_ids: '' }
|
|
|
|
expect(response).to have_http_status(:created), response.body
|
|
record = Post.find(json.fetch('id'))
|
|
expect(record.tags).to include(english_tag)
|
|
expect(record.tags).not_to include(japanese_tag)
|
|
expect(english_tag.reload.category).to eq('material')
|
|
expect(japanese_tag.reload.category).to eq('general')
|
|
end
|
|
|
|
it 'updates the post using the English identity' do
|
|
record = create(:post)
|
|
PostVersionRecorder.record!(post: record, event_type: :create, created_by_user: member)
|
|
|
|
put "/posts/#{ record.id }", params: {
|
|
locale: 'en', title: record.title, tags: 'shared_name', parent_post_ids: '',
|
|
base_version_no: record.reload.version_no }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
expect(record.reload.tags).to include(english_tag)
|
|
expect(record.tags).not_to include(japanese_tag)
|
|
end
|
|
|
|
it 'resolves the English material tag' do
|
|
post '/materials', params: {
|
|
locale: 'en', tag: 'shared_name', url: 'https://example.com/english-material' }
|
|
|
|
expect(response).to have_http_status(:created), response.body
|
|
expect(Material.find(json.fetch('id')).tag).to eq(english_tag)
|
|
expect(Material.where(tag: japanese_tag)).to be_empty
|
|
end
|
|
|
|
it 'resolves the English parent tag' do
|
|
child = create(:tag)
|
|
|
|
put "/tags/#{ child.id }", params: {
|
|
locale: 'en', name: primary_tag_name_for(child, 'ja').name,
|
|
category: child.category, deprecated: false,
|
|
aliases: '', parent_tags: 'shared_name' }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
expect(TagImplication.where(tag: child).pluck(:parent_tag_id)).to eq([english_tag.id])
|
|
end
|
|
|
|
it 'resolves the English internal tag for a Nico link' do
|
|
external = create(:external_tag)
|
|
NicoTagVersionRecorder.record!(
|
|
external_tag: external, event_type: :create, created_by_user: member)
|
|
|
|
put "/tags/nico/#{ external.id }", params: { locale: 'en', tags: 'shared_name' }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
expect(external.reload.linked_tags).to contain_exactly(english_tag)
|
|
end
|
|
end
|
|
|
|
context 'when renaming or updating aliases in English' do
|
|
let!(:english_name) do
|
|
create(:tag_name, name: 'english_original', language_code: 'en', script_code: 'Latn')
|
|
end
|
|
let!(:tag) { create(:tag, primary_tag_name: english_name) }
|
|
|
|
it 'allows a rename to a name already used in Japanese' do
|
|
japanese = create(:tag, primary_name: 'rename_target')
|
|
|
|
patch "/tags/#{ tag.id }", params: { locale: 'en', name: 'rename_target' }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
expect(primary_tag_name_for(tag.reload, 'en')).to have_attributes(
|
|
name: 'rename_target', language_code: 'en', tag_id: tag.id)
|
|
expect(primary_tag_name_for(japanese.reload, 'ja')).to have_attributes(
|
|
name: 'rename_target', language_code: 'ja', tag_id: japanese.id)
|
|
end
|
|
|
|
it 'creates aliases in the requested language' do
|
|
put "/tags/#{ tag.id }", params: {
|
|
locale: 'en', name: english_name.name,
|
|
category: tag.category, deprecated: false,
|
|
aliases: 'english_alias', parent_tags: '' }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
expect(TagName.find_by!(language_code: 'en', name: 'english_alias'))
|
|
.to have_attributes(
|
|
script_code: 'Latn',
|
|
tag_id: tag.id, primary_flg: false, language_code: 'en')
|
|
expect(tag.reload.tag_name_id).to eq(english_name.id)
|
|
primary = TagName.find_by!(tag_id: tag.id, language_code: 'en', primary_flg: true)
|
|
expect(primary).to have_attributes(name: 'english_original', script_code: 'Latn')
|
|
end
|
|
|
|
it 'does not take an alias from another language' do
|
|
japanese = create(:tag, primary_name: 'japanese_owner')
|
|
japanese_alias = create(:tag_name, :alias, name: 'shared_alias',
|
|
tag: japanese)
|
|
expect(japanese_alias.reload).to have_attributes(
|
|
tag_id: japanese.id,
|
|
primary_flg: false, language_code: 'ja')
|
|
|
|
put "/tags/#{ tag.id }", params: {
|
|
locale: 'en', name: english_name.name,
|
|
category: tag.category, deprecated: false,
|
|
aliases: 'shared_alias', parent_tags: '' }
|
|
|
|
expect(response).to have_http_status(:ok), response.body
|
|
expect(japanese_alias.reload).to have_attributes(
|
|
tag_id: japanese.id,
|
|
primary_flg: false, language_code: 'ja')
|
|
expect(TagName.find_by!(language_code: 'en', name: 'shared_alias'))
|
|
.to have_attributes(
|
|
tag_id: tag.id, script_code: 'Latn',
|
|
primary_flg: false, language_code: 'en')
|
|
expect(TagName.where(name: 'shared_alias').pluck(:language_code, :tag_id))
|
|
.to contain_exactly(['ja', japanese.id], ['en', tag.id])
|
|
end
|
|
end
|
|
end
|