diff --git a/app/controllers/concerns/idv/step_indicator_concern.rb b/app/controllers/concerns/idv/step_indicator_concern.rb index 613fc43ef1f..31a170597df 100644 --- a/app/controllers/concerns/idv/step_indicator_concern.rb +++ b/app/controllers/concerns/idv/step_indicator_concern.rb @@ -39,7 +39,7 @@ def step_indicator_steps private def in_person_proofing? - proofing_components_as_hash['document_check'] == Idp::Constants::Vendors::USPS + current_user&.has_in_person_enrollment? end def gpo_address_verification? @@ -49,22 +49,5 @@ def gpo_address_verification? return idv_session&.address_verification_mechanism == 'gpo' if defined?(idv_session) end - - def proofing_components - return {} if !current_user - - if current_user.pending_profile - current_user.pending_profile.proofing_components - else - ProofingComponent.find_by(user: current_user).as_json - end - end - - def proofing_components_as_hash - # A proofing component record exists as a zero-or-one-to-one relation with a user, and values - # are set during identity verification. These values are recorded to the profile at creation, - # including for a pending profile. - @proofing_components_as_hash ||= proofing_components.to_h - end end end diff --git a/app/controllers/concerns/idv_step_concern.rb b/app/controllers/concerns/idv_step_concern.rb index f6a6e4a1bc0..3770cff1419 100644 --- a/app/controllers/concerns/idv_step_concern.rb +++ b/app/controllers/concerns/idv_step_concern.rb @@ -71,7 +71,7 @@ def confirm_document_capture_complete def confirm_verify_info_step_complete return if idv_session.verify_info_step_complete? - if idv_session.pending_in_person_enrollment? + if current_user.has_in_person_enrollment? redirect_to idv_in_person_verify_info_url else redirect_to idv_verify_info_url diff --git a/app/forms/gpo_verify_form.rb b/app/forms/gpo_verify_form.rb index df85c6c2f0b..cb19d512430 100644 --- a/app/forms/gpo_verify_form.rb +++ b/app/forms/gpo_verify_form.rb @@ -22,7 +22,7 @@ def submit if result pending_profile&.remove_gpo_deactivation_reason - if profile_has_pending_in_person_enrollment? + if user.has_establishing_in_person_enrollment_safe? schedule_in_person_enrollment_and_deactivate_profile elsif fraud_check_failed && threatmetrix_enabled? pending_profile&.deactivate_for_fraud_review @@ -43,7 +43,7 @@ def submit letter_count: letter_count, attempts: attempts, pii_like_keypaths: [[:errors, :otp], [:error_details, :otp]], - pending_in_person_enrollment: pending_profile&.pending_in_person_enrollment?, + pending_in_person_enrollment: !!pending_profile&.in_person_enrollment&.pending?, fraud_check_failed: fraud_check_failed, }, ) @@ -61,10 +61,6 @@ def gpo_confirmation_code pending_profile.gpo_confirmation_codes.first_with_otp(otp) end - def profile_has_pending_in_person_enrollment? - pending_profile&.pending_in_person_enrollment? - end - def schedule_in_person_enrollment_and_deactivate_profile UspsInPersonProofing::EnrollmentHelper.schedule_in_person_enrollment(user, pii) pending_profile&.deactivate_for_in_person_verification diff --git a/app/models/profile.rb b/app/models/profile.rb index 3f9d45e6508..acc6a2b84f4 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -254,10 +254,6 @@ def self.build_compound_pii(pii) values.join(':') end - def pending_in_person_enrollment? - proofing_components&.[]('document_check') == Idp::Constants::Vendors::USPS - end - def includes_phone_check? return false if proofing_components.blank? proofing_components['address_check'] == 'lexis_nexis_address' diff --git a/app/models/user.rb b/app/models/user.rb index 5a69f8ef074..07ee98c87a0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -198,6 +198,15 @@ def in_person_pending_profile pending_profile if pending_profile&.in_person_verification_pending? end + def has_in_person_enrollment? + pending_in_person_enrollment.present? || establishing_in_person_enrollment.present? + end + + # Trust `pending_profile` rather than enrollment associations + def has_establishing_in_person_enrollment_safe? + !!pending_profile&.in_person_enrollment&.establishing? + end + def personal_key_generated_at encrypted_recovery_code_digest_generated_at || active_profile&.verified_at || diff --git a/app/services/idv/session.rb b/app/services/idv/session.rb index 9aeb9702b0f..bb57f9e1e31 100644 --- a/app/services/idv/session.rb +++ b/app/services/idv/session.rb @@ -60,7 +60,7 @@ def create_profile_from_applicant_with_password(user_password) profile = profile_maker.save_profile( fraud_pending_reason: threatmetrix_fraud_pending_reason, gpo_verification_needed: gpo_verification_needed?, - in_person_verification_needed: pending_in_person_enrollment?, + in_person_verification_needed: current_user.has_in_person_enrollment?, ) profile.activate unless profile.reason_not_to_activate @@ -76,7 +76,7 @@ def create_profile_from_applicant_with_password(user_password) move_pii_to_user_session elsif address_verification_mechanism == 'gpo' create_gpo_entry - elsif pending_in_person_enrollment? + elsif current_user.has_in_person_enrollment? UspsInPersonProofing::EnrollmentHelper.schedule_in_person_enrollment( current_user, pii, @@ -106,7 +106,8 @@ def clear end def associate_in_person_enrollment_with_profile - return unless pending_in_person_enrollment? && current_user.establishing_in_person_enrollment + return unless current_user.has_in_person_enrollment? + current_user.establishing_in_person_enrollment.update(profile: profile) end @@ -142,10 +143,6 @@ def add_failed_phone_step_number(phone) failed_phone_step_numbers << phone_e164 if !failed_phone_step_numbers.include?(phone_e164) end - def pending_in_person_enrollment? - current_user.proofing_component&.document_check == Idp::Constants::Vendors::USPS - end - def verify_info_step_complete? resolution_successful end diff --git a/spec/controllers/concerns/idv/step_indicator_concern_spec.rb b/spec/controllers/concerns/idv/step_indicator_concern_spec.rb index 167cbaadfb0..65c472d744e 100644 --- a/spec/controllers/concerns/idv/step_indicator_concern_spec.rb +++ b/spec/controllers/concerns/idv/step_indicator_concern_spec.rb @@ -97,6 +97,8 @@ def force_gpo end it 'returns in person gpo steps' do + ProofingComponent.create(user: user, document_check: Idp::Constants::Vendors::USPS) + create(:in_person_enrollment, :establishing, user: user) expect(steps).to eq in_person_step_indicator_steps_gpo end end @@ -104,6 +106,7 @@ def force_gpo context 'via current idv session' do before do ProofingComponent.create(user: user, document_check: Idp::Constants::Vendors::USPS) + create(:in_person_enrollment, :establishing, user: user) end it 'returns in person steps' do diff --git a/spec/controllers/concerns/idv_step_concern_spec.rb b/spec/controllers/concerns/idv_step_concern_spec.rb index 839cecedc33..6868fd455c2 100644 --- a/spec/controllers/concerns/idv_step_concern_spec.rb +++ b/spec/controllers/concerns/idv_step_concern_spec.rb @@ -171,13 +171,17 @@ def show end context 'the user has not completed the verify info step with an in-person enrollment' do + let(:selected_location_details) do + JSON.parse(UspsInPersonProofing::Mock::Fixtures.enrollment_selected_location_details) + end + it 'redirects to the in-person verify info step' do idv_session.resolution_successful = nil - ProofingComponent.find_or_create_by( + InPersonEnrollment.find_or_create_by( user: user, ).update!( - document_check: Idp::Constants::Vendors::USPS, + selected_location_details: selected_location_details, ) get :show diff --git a/spec/forms/gpo_verify_form_spec.rb b/spec/forms/gpo_verify_form_spec.rb index 9cf641f3b77..b162195924f 100644 --- a/spec/forms/gpo_verify_form_spec.rb +++ b/spec/forms/gpo_verify_form_spec.rb @@ -124,13 +124,20 @@ expect(result.to_h[:enqueued_at]).to eq(confirmation_code.code_sent_at) end - context 'pending in person enrollment' do - let!(:enrollment) do - create(:in_person_enrollment, :establishing, profile: pending_profile, user: user) + context 'establishing in person enrollment' do + let!(:establishing_enrollment) do + create( + :in_person_enrollment, + :establishing, + profile: pending_profile, + user: user, + ) end + let(:proofing_components) do ProofingComponent.create(user: user, document_check: Idp::Constants::Vendors::USPS) end + before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) end @@ -148,11 +155,40 @@ it 'updates establishing in-person enrollment to pending' do subject.submit - enrollment.reload + establishing_enrollment.reload + + expect(establishing_enrollment.status).to eq(InPersonEnrollment::STATUS_PENDING) + expect(establishing_enrollment.user_id).to eq(user.id) + expect(establishing_enrollment.enrollment_code).to be_a(String) + end + end - expect(enrollment.status).to eq(InPersonEnrollment::STATUS_PENDING) - expect(enrollment.user_id).to eq(user.id) - expect(enrollment.enrollment_code).to be_a(String) + context 'pending in person enrollment' do + let!(:pending_enrollment) do + create( + :in_person_enrollment, + :pending, + profile: pending_profile, + user: user, + ) + end + + let(:proofing_components) do + ProofingComponent.create(user: user, document_check: Idp::Constants::Vendors::USPS) + end + + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) + end + + it 'changes profile from pending to active' do + subject.submit + pending_profile.reload + + expect(pending_profile).to be_active + expect(pending_profile.deactivation_reason).to be_nil + expect(pending_profile.in_person_verification_pending_at).to be_nil + expect(pending_profile.gpo_verification_pending?).to eq(false) end end diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb index 6115623b71f..2d8fd00a7b3 100644 --- a/spec/models/profile_spec.rb +++ b/spec/models/profile_spec.rb @@ -46,26 +46,6 @@ end end - describe '#pending_in_person_enrollment?' do - it 'returns true if the document_check component is usps' do - profile = create(:profile, proofing_components: { document_check: 'usps' }) - - expect(profile.pending_in_person_enrollment?).to eq(true) - end - - it 'returns false if the document_check component is something else' do - profile = create(:profile, proofing_components: { document_check: 'something_else' }) - - expect(profile.pending_in_person_enrollment?).to eq(false) - end - - it 'returns false if proofing_components is blank' do - profile = create(:profile, proofing_components: '') - - expect(profile.pending_in_person_enrollment?).to eq(false) - end - end - describe '#includes_phone_check?' do it 'returns true if the address_check component is lexis_nexis_address' do profile = create(:profile, proofing_components: { address_check: 'lexis_nexis_address' }) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 2ac84c3e9e9..88a125c61f2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -314,6 +314,43 @@ expect(user.establishing_in_person_enrollment).to eq establishing_enrollment end end + + describe '#has_in_person_enrollment?' do + it 'returns the establishing IPP enrollment that has an address' do + ProofingComponent.find_or_create_by(user: user). + update!(document_check: Idp::Constants::Vendors::USPS) + + expect(user.has_in_person_enrollment?).to eq(true) + end + end + + # We don't know yet if #establishing_in_person_enrollment is, in fact, `establishing` + # so we trust the pending profile in the meantime + describe '#has_establishing_in_person_enrollment_safe?' do + let(:new_user) { create(:user, :fully_registered) } + let(:proofing_components) { nil } + let(:new_pending_profile) do + create( + :profile, + :verify_by_mail_pending, + user: new_user, + proofing_components: proofing_components, + ) + end + let!(:establishing_enrollment) do + create( + :in_person_enrollment, + :establishing, + profile: new_pending_profile, + user: new_user, + ) + end + + it 'returns the establishing IPP enrollment through the pending profile' do + # trust pending_profile + expect(new_user.has_establishing_in_person_enrollment_safe?).to eq(true) + end + end end describe 'deleting identities' do