diff --git a/lib/mastodon/cli/maintenance.rb b/lib/mastodon/cli/maintenance.rb index 2e5243468b..98067c6e34 100644 --- a/lib/mastodon/cli/maintenance.rb +++ b/lib/mastodon/cli/maintenance.rb @@ -546,7 +546,7 @@ module Mastodon::CLI if migrator_version < 2021_04_21_121431 ActiveRecord::Base.connection.add_index :tags, 'lower((name)::text)', name: 'index_tags_on_name_lower', unique: true else - ActiveRecord::Base.connection.execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' + ActiveRecord::Base.connection.execute 'CREATE UNIQUE INDEX index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' end end diff --git a/spec/lib/mastodon/cli/maintenance_spec.rb b/spec/lib/mastodon/cli/maintenance_spec.rb index 02169b7a42..61331e6dba 100644 --- a/spec/lib/mastodon/cli/maintenance_spec.rb +++ b/spec/lib/mastodon/cli/maintenance_spec.rb @@ -52,5 +52,78 @@ describe Mastodon::CLI::Maintenance do .and raise_error(SystemExit) end end + + context 'when requirements are met' do + before do + allow(ActiveRecord::Migrator).to receive(:current_version).and_return(2023_08_22_081029) # The latest migration before the cutoff + agree_to_backup_warning + end + + context 'with duplicate accounts' do + before do + prepare_duplicate_data + end + + let(:duplicate_account_username) { 'username' } + let(:duplicate_account_domain) { 'host.example' } + + it 'runs the deduplication process' do + expect { subject } + .to output_results( + 'Deduplicating accounts', + 'Restoring index_accounts_on_username_and_domain_lower', + 'Reindexing textual indexes on accounts…', + 'Finished!' + ) + .and change(duplicate_accounts, :count).from(2).to(1) + end + + def duplicate_accounts + Account.where(username: duplicate_account_username, domain: duplicate_account_domain) + end + + def prepare_duplicate_data + ActiveRecord::Base.connection.remove_index :accounts, name: :index_accounts_on_username_and_domain_lower + Fabricate(:account, username: duplicate_account_username, domain: duplicate_account_domain) + Fabricate.build(:account, username: duplicate_account_username, domain: duplicate_account_domain).save(validate: false) + end + end + + context 'with duplicate users' do + before do + prepare_duplicate_data + end + + let(:duplicate_email) { 'duplicate@example.host' } + + it 'runs the deduplication process' do + expect { subject } + .to output_results( + 'Deduplicating user records', + 'Restoring users indexes', + 'Finished!' + ) + .and change(duplicate_users, :count).from(2).to(1) + end + + def duplicate_users + User.where(email: duplicate_email) + end + + def prepare_duplicate_data + ActiveRecord::Base.connection.remove_index :users, :email + Fabricate(:user, email: duplicate_email) + Fabricate.build(:user, email: duplicate_email).save(validate: false) + end + end + + def agree_to_backup_warning + allow(cli.shell) + .to receive(:yes?) + .with('Continue? (Yes/No)') + .and_return(true) + .once + end + end end end