Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions app/controllers/idv/phone_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def set_idv_form
allowed_countries:
PhoneNumberCapabilities::ADDRESS_IDENTITY_PROOFING_SUPPORTED_COUNTRY_CODES,
failed_phone_numbers: idv_session.failed_phone_step_numbers,
hybrid_handoff_phone_number: idv_session.phone_for_mobile_flow,
)
end

Expand All @@ -171,6 +172,7 @@ def async_state_done(async_state)
[:context, :stages, :address],
],
new_phone_added: new_phone_added?,
hybrid_handoff_phone_used: hybrid_handoff_phone_used?,
),
)

Expand Down Expand Up @@ -198,8 +200,18 @@ def new_phone_added?
configured_phones = context.phone_configurations.map(&:phone).map do |number|
PhoneFormatter.format(number)
end
applicant_phone = PhoneFormatter.format(idv_session.applicant['phone'])
!configured_phones.include?(applicant_phone)
!configured_phones.include?(formatted_previous_phone_step_params_phone)
end

def hybrid_handoff_phone_used?
formatted_previous_phone_step_params_phone ==
PhoneFormatter.format(idv_session.phone_for_mobile_flow)
end

def formatted_previous_phone_step_params_phone
PhoneFormatter.format(
idv_session.previous_phone_step_params&.fetch('phone'),
)
end

def gpo_letter_available
Expand Down
8 changes: 5 additions & 3 deletions app/forms/idv/phone_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class PhoneForm
ALL_DELIVERY_METHODS = [:sms, :voice].freeze

attr_reader :user, :phone, :allowed_countries, :delivery_methods, :international_code,
:otp_delivery_preference, :failed_phone_numbers
:otp_delivery_preference, :failed_phone_numbers, :hybrid_handoff_phone_number

validate :validate_valid_phone_for_allowed_countries
validate :validate_phone_delivery_methods
Expand All @@ -20,13 +20,15 @@ def initialize(
previous_params:,
allowed_countries: nil,
delivery_methods: ALL_DELIVERY_METHODS,
failed_phone_numbers: []
failed_phone_numbers: [],
hybrid_handoff_phone_number: nil
)
previous_params ||= {}
@user = user
@allowed_countries = allowed_countries
@delivery_methods = delivery_methods
@failed_phone_numbers = failed_phone_numbers
@hybrid_handoff_phone_number = hybrid_handoff_phone_number

@international_code, @phone = determine_initial_values(
**previous_params.
Expand All @@ -52,7 +54,7 @@ def submit(params)
# @return [Array<string,string>] The international_code and phone values to use.
def determine_initial_values(international_code: nil, phone: nil)
if phone.nil? && international_code.nil?
default_phone = user.default_phone_configuration&.phone
default_phone = user.default_phone_configuration&.phone || hybrid_handoff_phone_number
if valid_phone?(default_phone, phone_confirmed: true)
phone = default_phone
international_code = country_code_for(default_phone)
Expand Down
23 changes: 23 additions & 0 deletions spec/controllers/idv/phone_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@
result = {
success: true,
new_phone_added: true,
hybrid_handoff_phone_used: false,
errors: {},
phone_fingerprint: Pii::Fingerprinter.fingerprint(proofing_phone.e164),
country_code: proofing_phone.country,
Expand Down Expand Up @@ -506,6 +507,27 @@
end
end

it 'tracks that the hybrid handoff phone was used' do
user = build(:user)
stub_verify_steps_one_and_two(user)

stub_analytics
allow(@analytics).to receive(:track_event)

expect(@analytics).to receive(:track_event).ordered.with(
'IdV: phone confirmation form', hash_including(:success)
)
expect(@analytics).to receive(:track_event).ordered.with(
'IdV: phone confirmation vendor', hash_including(hybrid_handoff_phone_used: true)
)

subject.idv_session.phone_for_mobile_flow = good_phone

put :create, params: { idv_phone_form: { phone: good_phone } }
expect(response).to redirect_to idv_phone_path
get :new
end

context 'when verification fails' do
it 'renders failure page and does not set phone confirmation' do
user = build(:user, with: { phone: '+1 (415) 555-0130', phone_confirmed_at: Time.zone.now })
Expand Down Expand Up @@ -548,6 +570,7 @@
result = {
success: false,
new_phone_added: true,
hybrid_handoff_phone_used: false,
phone_fingerprint: Pii::Fingerprinter.fingerprint(proofing_phone.e164),
country_code: proofing_phone.country,
area_code: proofing_phone.area_code,
Expand Down
4 changes: 2 additions & 2 deletions spec/features/idv/analytics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', threatmetrix: threatmetrix, threatmetrix_review_status: 'pass' }
},
'IdV: phone confirmation vendor' => {
success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false, reference: '' }, new_phone_added: false, area_code: '202', country_code: 'US', phone_fingerprint: anything,
success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false, reference: '' }, new_phone_added: false, hybrid_handoff_phone_used: false, area_code: '202', country_code: 'US', phone_fingerprint: anything,
proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', threatmetrix: threatmetrix, threatmetrix_review_status: 'pass', address_check: 'lexis_nexis_address' }
},
'IdV: phone confirmation otp sent' => {
Expand Down Expand Up @@ -312,7 +312,7 @@
proofing_components: { document_check: 'usps', resolution_check: 'lexis_nexis', threatmetrix: threatmetrix, threatmetrix_review_status: 'pass', source_check: 'aamva' }
},
'IdV: phone confirmation vendor' => {
success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false, reference: '' }, new_phone_added: false, area_code: '202', country_code: 'US', phone_fingerprint: anything,
success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false, reference: '' }, new_phone_added: false, hybrid_handoff_phone_used: false, area_code: '202', country_code: 'US', phone_fingerprint: anything,
proofing_components: { address_check: 'lexis_nexis_address', document_check: 'usps', resolution_check: 'lexis_nexis', threatmetrix: threatmetrix, threatmetrix_review_status: 'pass', source_check: 'aamva' }
},
'IdV: phone confirmation otp sent' => {
Expand Down
49 changes: 49 additions & 0 deletions spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@
expect(page).to have_content(t('headings.verify'))
click_idv_continue

prefilled_phone = page.find(id: 'idv_phone_form_phone').value

expect(
PhoneFormatter.format(prefilled_phone),
).to eq(
PhoneFormatter.format(user.default_phone_configuration.phone),
)

fill_out_phone_form_ok
verify_phone_otp

Expand Down Expand Up @@ -304,4 +312,45 @@
end
end
end

it 'prefils the phone number used on the phone step if the user has no MFA phone', :js do
user = create(:user, :with_authentication_app)

perform_in_browser(:desktop) do
start_idv_from_sp
sign_in_and_2fa_user(user)

complete_doc_auth_steps_before_hybrid_handoff_step
clear_and_fill_in(:doc_auth_phone, phone_number)
click_send_link
end

expect(@sms_link).to be_present

perform_in_browser(:mobile) do
visit @sms_link
attach_and_submit_images

expect(page).to have_current_path(idv_hybrid_mobile_capture_complete_url)
expect(page).to have_text(t('doc_auth.instructions.switch_back'))
end

perform_in_browser(:desktop) do
expect(page).to have_current_path(idv_ssn_path, wait: 10)

fill_out_ssn_form_ok
click_idv_continue

expect(page).to have_content(t('headings.verify'))
click_idv_continue

prefilled_phone = page.find(id: 'idv_phone_form_phone').value

expect(
PhoneFormatter.format(prefilled_phone),
).to eq(
PhoneFormatter.format(phone_number),
)
Comment on lines 347 to 353
Copy link
Copy Markdown
Contributor

@amirbey amirbey Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be worth inserting this same check (using MFA # 202-555-1212) on line 83 above 🤔

end
end
end
23 changes: 23 additions & 0 deletions spec/forms/idv/phone_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,29 @@
end
end

context 'with a number submitted on the hybrid handoff step' do
context 'with a phone number on the user record' do
let(:user_phone) { '2025555000' }
let(:hybrid_handoff_phone_number) { '2025551234' }
let(:user) { build_stubbed(:user, :fully_registered, with: { phone: user_phone }) }
let(:optional_params) { { hybrid_handoff_phone_number: hybrid_handoff_phone_number } }

it 'uses the user phone as the initial value' do
expect(subject.phone).to eq(PhoneFormatter.format(user_phone))
end
end

context 'without a phone number on the user record' do
let(:hybrid_handoff_phone_number) { '2025551234' }
let(:user) { build_stubbed(:user) }
let(:optional_params) { { hybrid_handoff_phone_number: hybrid_handoff_phone_number } }

it 'uses the hybrid handoff phone as the initial value' do
expect(subject.phone).to eq(PhoneFormatter.format(hybrid_handoff_phone_number))
end
end
end

context 'with previously submitted value' do
let(:user) { build_stubbed(:user, :fully_registered, with: { phone: '7035551234' }) }
let(:previous_params) { { phone: '2255555000' } }
Expand Down