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 'rolls back a newly created locale and the preceding generated names' do locale = build_locale fail_second_generation! 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') 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! locale.update!(deprecated_at: nil) 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! 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 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