diff --git a/app/models/profile.rb b/app/models/profile.rb index 87cad4cdba4..b83cec0e45c 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -81,28 +81,35 @@ def remove_gpo_deactivation_reason end def activate_after_passing_review - update!( - fraud_review_pending_at: nil, - fraud_rejection_at: nil, - ) - track_fraud_review_adjudication(decision: 'pass') - activate + transaction do + update!( + fraud_review_pending_at: nil, + fraud_rejection_at: nil, + ) + activate + end + + track_fraud_review_adjudication(decision: 'pass') if active? end def activate_after_passing_in_person - update!( - deactivation_reason: nil, - fraud_review_pending_at: nil, - ) - activate + transaction do + update!( + deactivation_reason: nil, + fraud_review_pending_at: nil, + ) + activate + end end def activate_after_password_reset if password_reset? - update!( - deactivation_reason: nil, - ) - activate(reason_deactivated: :password_reset) + transaction do + update!( + deactivation_reason: nil, + ) + activate(reason_deactivated: :password_reset) + end end end diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb index a3c678b6fe2..8a66d58f413 100644 --- a/spec/models/profile_spec.rb +++ b/spec/models/profile_spec.rb @@ -389,6 +389,7 @@ RuntimeError, 'Attempting to activate profile with pending reasons: fraud_check_pending', ) + expect(profile).to_not be_active end it 'does not activate a profile with non password_reset deactivation_reason' do @@ -416,6 +417,25 @@ expect(profile.initiating_service_provider).to be_nil expect(profile.verified_at).to be_nil end + + it 'does not activate a profile if it encounters a transaction error' do + profile = create( + :profile, + user: user, + active: false, + deactivation_reason: :password_reset, + verified_at: 1.day.ago, + ) + + allow(profile).to receive(:update!).and_raise(RuntimeError) + + suppress(RuntimeError) do + profile.activate_after_password_reset + end + + expect(profile.deactivation_reason).to eq('password_reset') + expect(profile).to_not be_active + end end describe '#activate_after_passing_in_person' do @@ -432,6 +452,25 @@ expect(profile.deactivation_reason).to be_nil expect(profile).to be_active end + + it 'does not activate a profile if transaction raises an error' do + profile = create( + :profile, + user: user, + active: false, + deactivation_reason: :in_person_verification_pending, + fraud_review_pending_at: 1.day.ago, + ) + + allow(profile).to receive(:update!).and_raise(RuntimeError) + + suppress(RuntimeError) do + profile.activate_after_passing_in_person + end + + expect(profile.deactivation_reason).to eq('in_person_verification_pending') + expect(profile).to_not be_active + end end describe '#activate_after_passing_review' do @@ -445,6 +484,24 @@ expect(profile).to be_active end + it 'does not activate a profile if transaction raises an error' do + profile = create( + :profile, + user: user, + active: false, + fraud_review_pending_at: 1.day.ago, + ) + + allow(profile).to receive(:update!).and_raise(RuntimeError) + + suppress(RuntimeError) do + profile.activate_after_passing_review + end + + expect(profile.fraud_review_pending_at).to_not eq nil + expect(profile).to_not be_active + end + context 'when the initiating_sp is the IRS' do let(:sp) { create(:service_provider, :irs) } let(:profile) do