From 6cbc5899905b47af82833f19882c4b57b0b4c34b Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 9 Feb 2023 21:01:38 +0100 Subject: [PATCH] Fix `UserCleanupScheduler` crash when an unconfirmed account has a moderation note (#23318) (#23487) * Fix `UserCleanupScheduler` crash when an unconfirmed account has a moderation note * Add tests --- .../scheduler/user_cleanup_scheduler.rb | 2 + .../scheduler/user_cleanup_scheduler_spec.rb | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 spec/workers/scheduler/user_cleanup_scheduler_spec.rb diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb index d1f00c47f..df566a18c 100644 --- a/app/workers/scheduler/user_cleanup_scheduler.rb +++ b/app/workers/scheduler/user_cleanup_scheduler.rb @@ -15,6 +15,8 @@ class Scheduler::UserCleanupScheduler def clean_unconfirmed_accounts! User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch| + # We have to do it separately because of missing database constraints + AccountModerationNote.where(target_account_id: batch.map(&:account_id)).delete_all Account.where(id: batch.map(&:account_id)).delete_all User.where(id: batch.map(&:id)).delete_all end diff --git a/spec/workers/scheduler/user_cleanup_scheduler_spec.rb b/spec/workers/scheduler/user_cleanup_scheduler_spec.rb new file mode 100644 index 000000000..da99f10f9 --- /dev/null +++ b/spec/workers/scheduler/user_cleanup_scheduler_spec.rb @@ -0,0 +1,39 @@ +require 'rails_helper' + +describe Scheduler::UserCleanupScheduler do + subject { described_class.new } + + let!(:new_unconfirmed_user) { Fabricate(:user) } + let!(:old_unconfirmed_user) { Fabricate(:user) } + let!(:confirmed_user) { Fabricate(:user) } + let!(:moderation_note) { Fabricate(:account_moderation_note, account: Fabricate(:account), target_account: old_unconfirmed_user.account) } + + describe '#perform' do + before do + # Need to update the already-existing users because their initialization overrides confirmation_sent_at + new_unconfirmed_user.update!(confirmed_at: nil, confirmation_sent_at: Time.now.utc) + old_unconfirmed_user.update!(confirmed_at: nil, confirmation_sent_at: 1.week.ago) + confirmed_user.update!(confirmed_at: 1.day.ago) + end + + it 'deletes the old unconfirmed user' do + expect { subject.perform }.to change { User.exists?(old_unconfirmed_user.id) }.from(true).to(false) + end + + it "deletes the old unconfirmed user's account" do + expect { subject.perform }.to change { Account.exists?(old_unconfirmed_user.account_id) }.from(true).to(false) + end + + it 'does not delete the new unconfirmed user or their account' do + subject.perform + expect(User.exists?(new_unconfirmed_user.id)).to be true + expect(Account.exists?(new_unconfirmed_user.account_id)).to be true + end + + it 'does not delete the confirmed user or their account' do + subject.perform + expect(User.exists?(confirmed_user.id)).to be true + expect(Account.exists?(confirmed_user.account_id)).to be true + end + end +end