require 'rails_helper' RSpec.describe 'Locale activation', type: :model do let!(:language) { Language.create!(code: 'ain', name: 'ain') } let!(:script) { Script.create!(code: 'Kana', name: 'Kana') } let!(:first) { create(:tag, primary_name: 'activation_first') } let!(:second) { create(:tag, primary_name: 'activation_second') } def build_locale deprecated_at: nil Locale.new(code: 'ain-Kana', language_code: language.code, script_code: script.code, region_code: 392, variants: '', name: 'ain-Kana', deprecated_at:) end def generated_names TagName.where(language_code: 'ain', primary_flg: true) end def fail_second_generation! allow(TagName).to receive(:generate_name).and_call_original allow(TagName).to receive(:generate_name) .with(kind_of(Locale), second, second.tag_name('ja')) .and_raise('backfill failed') end it 'groups all tag histories from locale creation into one event' do previous_ids = TagVersion.pluck(:id) expect { build_locale.save! }.to change { event_rows.length }.by(1) event = event_rows.last expect(event).to include('event_type' => 'locales.create', 'created_by_user_id' => nil) versions = TagVersion.where.not(id: previous_ids) expect(versions.pluck(:tag_id)).to include(first.id, second.id) expect(versions.pluck(:event_id).uniq).to eq([event.fetch('id')]) end it 'rolls back a newly created locale and the preceding generated names' do locale = build_locale fail_second_generation! events = event_rows expect { locale.save! }.to raise_error('backfill failed') expect(Locale.exists?(code: 'ain-Kana')).to be(false) expect(generated_names).to be_empty expect(first.reload.name('ja')).to eq('activation_first') expect(second.reload.name('ja')).to eq('activation_second') expect(event_rows).to eq(events) end it 'does not backfill while the locale is inactive' do build_locale(deprecated_at: Time.current).save! expect(generated_names).to be_empty end it 'backfills missing primary names when the locale becomes active' do locale = build_locale(deprecated_at: Time.current) locale.save! previous_ids = TagVersion.pluck(:id) expect { locale.update!(deprecated_at: nil) }.to change { event_rows.length }.by(1) event = event_rows.last expect(event).to include('event_type' => 'locales.restore', 'created_by_user_id' => nil) versions = TagVersion.where.not(id: previous_ids) expect(versions.pluck(:tag_id)).to include(first.id, second.id) expect(versions.pluck(:event_id).uniq).to eq([event.fetch('id')]) expect(generated_names.pluck(:tag_id)).to contain_exactly(first.id, second.id) expect(generated_names).to all(have_attributes( script_code: 'Kana', primary_flg: true, auto_generated: true)) end it 'rolls back activation and all generated names when backfill fails' do locale = build_locale(deprecated_at: Time.current) locale.save! previous_deprecated_at = locale.reload.deprecated_at fail_second_generation! events = event_rows expect { locale.update!(deprecated_at: nil) }.to raise_error('backfill failed') expect(locale.reload.deprecated_at).to eq(previous_deprecated_at) expect(generated_names).to be_empty expect(event_rows).to eq(events) end it 'preserves a human primary through deactivation and repeated activation' do locale = build_locale locale.save! primary = generated_names.find_by!(tag: first) primary.update!(name: 'human_confirmed', auto_generated: false) snapshot = generated_names.order(:id).map(&:attributes) 2.times do locale.update!(deprecated_at: Time.current) locale.update!(deprecated_at: nil) end expect(generated_names.order(:id).map(&:attributes)).to eq(snapshot) expect(primary.reload).to have_attributes(name: 'human_confirmed', auto_generated: false) end end