diff --git a/Gemfile.lock b/Gemfile.lock
index 63391bcf577..3ad249f6264 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -20,10 +20,11 @@ GIT
GIT
remote: https://github.com/18F/identity-idp-functions.git
- revision: 1ffdce9da7fd2d69de2b51a04873bc8bbd9c3f4b
- ref: 1ffdce9da7fd2d69de2b51a04873bc8bbd9c3f4b
+ revision: d32d49bc27c62a510695c6fe498c6d9b8942f6be
+ ref: d32d49bc27c62a510695c6fe498c6d9b8942f6be
specs:
- identity-idp-functions (0.3.0)
+ identity-idp-functions (0.3.2)
+ retries (>= 0.0.5)
GIT
remote: https://github.com/18F/identity-lexisnexis-api-client-gem.git
diff --git a/app/controllers/idv/phone_controller.rb b/app/controllers/idv/phone_controller.rb
index 8e7bbd1824e..82323ac6eeb 100644
--- a/app/controllers/idv/phone_controller.rb
+++ b/app/controllers/idv/phone_controller.rb
@@ -9,7 +9,19 @@ class PhoneController < ApplicationController
before_action :set_idv_form
def new
- analytics.track_event(Analytics::IDV_PHONE_RECORD_VISIT)
+ async_state = step.async_state
+
+ case async_state.status
+ when :none
+ analytics.track_event(Analytics::IDV_PHONE_RECORD_VISIT)
+ render :new
+ when :in_progress
+ render :wait
+ when :timed_out
+ render :new
+ when :done
+ async_state_done(async_state)
+ end
end
def create
@@ -17,6 +29,7 @@ def create
analytics.track_event(Analytics::IDV_PHONE_CONFIRMATION_FORM, result.to_h)
return render(:new) unless result.success?
submit_proofing_attempt
+ redirect_to idv_phone_path
end
private
@@ -34,14 +47,11 @@ def phone_confirmation_required?
end
def submit_proofing_attempt
- idv_result = step.submit(step_params.to_h)
- analytics.track_event(Analytics::IDV_PHONE_CONFIRMATION_VENDOR, idv_result.to_h)
- redirect_to_next_step and return if idv_result.success?
- handle_proofing_failure
+ step.submit(step_params.to_h)
end
- def handle_proofing_failure
- idv_session.previous_phone_step_params = step_params.to_h
+ def handle_proofing_failure(pii)
+ idv_session.previous_phone_step_params = { 'phone' => pii[:phone] }
redirect_to failure_url(step.failure_reason)
end
@@ -80,5 +90,12 @@ def failure_url(reason)
idv_phone_errors_failure_url
end
end
+
+ def async_state_done(async_state)
+ form_result = step.async_state_done(async_state)
+ analytics.track_event(Analytics::IDV_PHONE_CONFIRMATION_VENDOR, form_result.to_h)
+ redirect_to_next_step and return if async_state.result[:success]
+ handle_proofing_failure(async_state.pii)
+ end
end
end
diff --git a/app/controllers/lambda_callback/address_proof_result_controller.rb b/app/controllers/lambda_callback/address_proof_result_controller.rb
index e014feadf0a..01a8f40f8b7 100644
--- a/app/controllers/lambda_callback/address_proof_result_controller.rb
+++ b/app/controllers/lambda_callback/address_proof_result_controller.rb
@@ -3,7 +3,7 @@ class AddressProofResultController < AuthTokenController
def create
dcs = DocumentCaptureSession.new
dcs.result_id = result_id_parameter
- dcs.store_proofing_result(address_result_parameter)
+ dcs.store_proofing_result(address_result_parameter.to_h)
end
private
@@ -13,7 +13,8 @@ def result_id_parameter
end
def address_result_parameter
- params.require(:address_result)
+ params.require(:address_result).permit(:exception, :success, :timed_out,
+ errors: {}, context: {})
end
def config_auth_token
diff --git a/app/services/idv/agent.rb b/app/services/idv/agent.rb
index 01b73acb4e9..f200fd74150 100644
--- a/app/services/idv/agent.rb
+++ b/app/services/idv/agent.rb
@@ -14,9 +14,19 @@ def proof_resolution(should_proof_state_id:)
submit_applicant(vendor: vendor, results: results)
end
- def proof_address
- vendor = Idv::Proofer.address_vendor.new
- submit_applicant(vendor: vendor, results: init_results)
+ def proof_address(document_capture_session)
+ callback_url = Rails.application.routes.url_helpers.address_proof_result_url(
+ document_capture_session.result_id,
+ )
+
+ LambdaJobs::Runner.new(
+ job_name: nil, job_class: Idv::Proofer.address_job_class,
+ args: { applicant_pii: @applicant, callback_url: callback_url }
+ ).run do |idv_result|
+ document_capture_session.store_proofing_result(idv_result[:address_result])
+
+ nil
+ end
end
private
diff --git a/app/services/idv/phone_step.rb b/app/services/idv/phone_step.rb
index 3b73b76edac..75d3d02a407 100644
--- a/app/services/idv/phone_step.rb
+++ b/app/services/idv/phone_step.rb
@@ -7,13 +7,6 @@ def initialize(idv_session:)
def submit(step_params)
self.step_params = step_params
proof_address
- increment_attempts_count unless failed_due_to_timeout_or_exception?
- success = idv_result[:success]
- handle_successful_proofing_attempt if success
- FormResponse.new(
- success: success, errors: idv_result[:errors],
- extra: extra_analytics_attributes
- )
end
def failure_reason
@@ -23,6 +16,36 @@ def failure_reason
return :warning if idv_result[:success] != true
end
+ def async_state
+ dcs_uuid = idv_session.idv_phone_step_document_capture_session_uuid
+ dcs = DocumentCaptureSession.find_by(uuid: dcs_uuid)
+ return ProofingDocumentCaptureSessionResult.none if dcs_uuid.nil?
+ return ProofingDocumentCaptureSessionResult.timed_out if dcs.nil?
+
+ proofing_job_result = dcs.load_proofing_result
+ return ProofingDocumentCaptureSessionResult.timed_out if proofing_job_result.nil?
+
+ if proofing_job_result.result
+ proofing_job_result.done
+ elsif proofing_job_result.pii
+ ProofingDocumentCaptureSessionResult.in_progress
+ end
+ end
+
+ def async_state_done(async_state)
+ @idv_result = async_state.result
+ pii = async_state.pii
+
+ increment_attempts_count unless failed_due_to_timeout_or_exception?
+ success = idv_result[:success]
+ handle_successful_proofing_attempt(pii) if success
+ idv_session.idv_phone_step_document_capture_session_uuid = nil
+ FormResponse.new(
+ success: success, errors: idv_result[:errors],
+ extra: extra_analytics_attributes
+ )
+ end
+
private
attr_accessor :idv_session, :step_params, :idv_result
@@ -32,13 +55,19 @@ def idv_max_attempts
end
def proof_address
- self.idv_result = Idv::Agent.new(applicant).proof_address
+ document_capture_session = DocumentCaptureSession.create(user_id: idv_session.current_user.id,
+ requested_at: Time.zone.now)
+
+ document_capture_session.store_proofing_pii_from_doc(applicant)
+ idv_session.idv_phone_step_document_capture_session_uuid = document_capture_session.uuid
+
+ run_job(document_capture_session)
add_proofing_cost
end
- def handle_successful_proofing_attempt
- update_idv_session
- start_phone_confirmation_session
+ def handle_successful_proofing_attempt(successful_applicant)
+ update_idv_session(successful_applicant)
+ start_phone_confirmation_session(successful_applicant)
end
def add_proofing_cost
@@ -81,24 +110,24 @@ def failed_due_to_timeout_or_exception?
idv_result[:timed_out] || idv_result[:exception]
end
- def update_idv_session
+ def update_idv_session(successful_applicant)
idv_session.address_verification_mechanism = :phone
- idv_session.applicant = applicant
+ idv_session.applicant = successful_applicant
idv_session.vendor_phone_confirmation = true
- idv_session.user_phone_confirmation = phone_matches_user_phone?
+ idv_session.user_phone_confirmation = phone_matches_user_phone?(successful_applicant[:phone])
Db::ProofingComponent::Add.call(idv_session.current_user.id, :address_check,
'lexis_nexis_address')
end
- def start_phone_confirmation_session
+ def start_phone_confirmation_session(successful_applicant)
idv_session.user_phone_confirmation_session = PhoneConfirmation::ConfirmationSession.start(
- phone: PhoneFormatter.format(applicant[:phone]),
+ phone: PhoneFormatter.format(successful_applicant[:phone]),
delivery_method: :sms,
)
end
- def phone_matches_user_phone?
- applicant_phone = PhoneFormatter.format(applicant[:phone])
+ def phone_matches_user_phone?(phone)
+ applicant_phone = PhoneFormatter.format(phone)
return false if applicant_phone.blank?
user_phones.include?(applicant_phone)
end
@@ -116,5 +145,9 @@ def extra_analytics_attributes
vendor: idv_result.except(:errors, :success),
}
end
+
+ def run_job(document_capture_session)
+ Idv::Agent.new(applicant).proof_address(document_capture_session)
+ end
end
end
diff --git a/app/services/idv/proofer.rb b/app/services/idv/proofer.rb
index d3ee3814b75..deffd327b46 100644
--- a/app/services/idv/proofer.rb
+++ b/app/services/idv/proofer.rb
@@ -4,9 +4,14 @@ module Proofer
class << self
def validate_vendors!
+ if mock_fallback_enabled?
+ require 'identity-idp-functions/proof_address_mock'
+ else
+ require 'identity-idp-functions/proof_address'
+ end
+
resolution_vendor.new
state_id_vendor.new
- address_vendor.new
end
def resolution_vendor
@@ -25,16 +30,14 @@ def state_id_vendor
end
end
- def address_vendor
+ def address_job_class
if mock_fallback_enabled?
- AddressMock
+ IdentityIdpFunctions::ProofAddressMock
else
- LexisNexis::PhoneFinder::Proofer
+ IdentityIdpFunctions::ProofAddress
end
end
- private
-
def mock_fallback_enabled?
Figaro.env.proofer_mock_fallback == 'true'
end
diff --git a/app/services/idv/session.rb b/app/services/idv/session.rb
index e3ecee3bd00..3d876638614 100644
--- a/app/services/idv/session.rb
+++ b/app/services/idv/session.rb
@@ -3,6 +3,7 @@ class Session
VALID_SESSION_ATTRIBUTES = %i[
address_verification_mechanism
applicant
+ idv_phone_step_document_capture_session_uuid
vendor_phone_confirmation
user_phone_confirmation
pii
diff --git a/app/services/idv/steps/verify_wait_step_show.rb b/app/services/idv/steps/verify_wait_step_show.rb
index b8671306257..f7290b45366 100644
--- a/app/services/idv/steps/verify_wait_step_show.rb
+++ b/app/services/idv/steps/verify_wait_step_show.rb
@@ -1,26 +1,6 @@
module Idv
module Steps
class VerifyWaitStepShow < VerifyBaseStep
- State = Struct.new(:status, :pii, :result, keyword_init: true) do
- def self.none
- new(status: :none)
- end
-
- def self.timed_out
- new(status: :timed_out)
- end
-
- def self.in_progress
- new(status: :in_progress)
- end
-
- def self.done(pii:, result:)
- new(status: :done, pii: pii, result: result)
- end
-
- private_class_method :new
- end
-
def call
poll_with_meta_refresh(Figaro.env.poll_rate_for_verify_in_seconds.to_i)
@@ -59,18 +39,16 @@ def async_state_done(current_async_state)
def async_state
dcs_uuid = flow_session[:idv_verify_step_document_capture_session_uuid]
dcs = DocumentCaptureSession.find_by(uuid: dcs_uuid)
- return State.none if dcs_uuid.nil?
- return State.timed_out if dcs.nil?
+ return ProofingDocumentCaptureSessionResult.none if dcs_uuid.nil?
+ return ProofingDocumentCaptureSessionResult.timed_out if dcs.nil?
proofing_job_result = dcs.load_proofing_result
- return State.timed_out if proofing_job_result.nil?
+ return ProofingDocumentCaptureSessionResult.timed_out if proofing_job_result.nil?
if proofing_job_result.result
- proofing_job_result.result.deep_symbolize_keys!
- proofing_job_result.pii.deep_symbolize_keys!
- State.done(pii: proofing_job_result.pii, result: proofing_job_result.result)
+ proofing_job_result.done
elsif proofing_job_result.pii
- State.in_progress
+ ProofingDocumentCaptureSessionResult.in_progress
end
end
diff --git a/app/services/lambda_jobs/git_ref.rb b/app/services/lambda_jobs/git_ref.rb
index aee3bc752da..2be1cb99c01 100644
--- a/app/services/lambda_jobs/git_ref.rb
+++ b/app/services/lambda_jobs/git_ref.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module LambdaJobs
- GIT_REF = '1ffdce9da7fd2d69de2b51a04873bc8bbd9c3f4b'
+ GIT_REF = 'd32d49bc27c62a510695c6fe498c6d9b8942f6be'
end
diff --git a/app/services/lambda_jobs/runner.rb b/app/services/lambda_jobs/runner.rb
index 46a0a6390ba..4cf5ad4ae2b 100644
--- a/app/services/lambda_jobs/runner.rb
+++ b/app/services/lambda_jobs/runner.rb
@@ -18,7 +18,7 @@ def run(&local_callback)
)
else
job_class.handle(
- event: { body: args.to_json },
+ event: { 'body' => args.to_json },
context: nil,
&local_callback
)
diff --git a/app/services/proofing_document_capture_session_result.rb b/app/services/proofing_document_capture_session_result.rb
index 461e8740733..19e71feaa19 100644
--- a/app/services/proofing_document_capture_session_result.rb
+++ b/app/services/proofing_document_capture_session_result.rb
@@ -1,7 +1,28 @@
# frozen_string_literal: true
-ProofingDocumentCaptureSessionResult = Struct.new(:id, :pii, :result, keyword_init: true) do
+ProofingDocumentCaptureSessionResult = Struct.new(:id, :pii, :result, :status,
+ keyword_init: true) do
def self.redis_key_prefix
'dcs-proofing:result'
end
+
+ def self.none
+ new(status: :none)
+ end
+
+ def self.timed_out
+ new(status: :timed_out)
+ end
+
+ def self.in_progress
+ new(status: :in_progress)
+ end
+
+ def done
+ ProofingDocumentCaptureSessionResult.new(
+ pii: pii.deep_symbolize_keys,
+ result: result.deep_symbolize_keys,
+ status: :done,
+ )
+ end
end
diff --git a/app/views/idv/phone/wait.html.erb b/app/views/idv/phone/wait.html.erb
new file mode 100644
index 00000000000..60a35d3eef1
--- /dev/null
+++ b/app/views/idv/phone/wait.html.erb
@@ -0,0 +1,3 @@
+<% title t('doc_auth.titles.doc_auth') %>
+
+
<%= t('doc_auth.info.interstitial_eta') %>
diff --git a/config/application.yml.default b/config/application.yml.default
index e755331c90c..b1359692559 100644
--- a/config/application.yml.default
+++ b/config/application.yml.default
@@ -108,6 +108,7 @@ pinpoint_voice_longcode_pool:
pinpoint_voice_region:
poll_rate_for_verify_in_seconds: '10'
proofer_mock_fallback: 'true'
+proofing_lambda_http_callback:
push_notifications_enabled:
reauthn_window: '120'
recaptcha_enabled_percent: '0'
@@ -207,6 +208,7 @@ development:
otp_delivery_blocklist_maxretry: '10'
participate_in_dap:
password_pepper: f22d4b2cafac9066fe2f4416f5b7a32c
+ proofing_lambda_http_callback: 'true'
identity_pki_disabled: 'false'
identity_pki_local_dev: 'true'
piv_cac_service_url: https://localhost:8443/
@@ -321,6 +323,7 @@ production:
piv_cac_service_url:
piv_cac_verify_token_secret:
piv_cac_verify_token_url:
+ proofing_lambda_http_callback:
rack_mini_profiler:
recurring_jobs_disabled_names: "[]"
redis_throttle_url: redis://redis.login.gov.internal:6379/1
@@ -430,6 +433,7 @@ test:
piv_cac_service_url: https://localhost:8443/
piv_cac_verify_token_secret: 3ac13bfa23e22adae321194c083e783faf89469f6f85dcc0802b27475c94b5c3891b5657bd87d0c1ad65de459166440512f2311018db90d57b15d8ab6660748f
piv_cac_verify_token_url: https://localhost:8443/
+ proofing_lambda_http_callback: false
rack_mini_profiler:
recurring_jobs_disabled_names: '["disabled job"]'
redis_throttle_url: redis://localhost:6379/1
diff --git a/lib/proofer_mocks/address_mock.rb b/lib/proofer_mocks/address_mock.rb
index d43734bdec5..e69de29bb2d 100644
--- a/lib/proofer_mocks/address_mock.rb
+++ b/lib/proofer_mocks/address_mock.rb
@@ -1,19 +0,0 @@
-class AddressMock < Proofer::Base
- required_attributes :phone
-
- optional_attributes :uuid, :uuid_prefix
-
- stage :address
-
- proof do |applicant, result|
- plain_phone = applicant[:phone].gsub(/\D/, '').gsub(/\A1/, '')
- if plain_phone == '7035555555'
- result.add_error(:phone, 'The phone number could not be verified.')
- elsif plain_phone == '7035555999'
- raise 'Failed to contact proofing vendor'
- elsif plain_phone == '7035555888'
- raise Proofer::TimeoutError, 'address mock timeout'
- end
- result.context[:message] = 'some context for the mock address proofer'
- end
-end
diff --git a/spec/controllers/idv/phone_controller_spec.rb b/spec/controllers/idv/phone_controller_spec.rb
index 816b931190b..0dd9b50c871 100644
--- a/spec/controllers/idv/phone_controller_spec.rb
+++ b/spec/controllers/idv/phone_controller_spec.rb
@@ -5,6 +5,9 @@
let(:max_attempts) { idv_max_attempts }
let(:good_phone) { '+1 (703) 555-0000' }
+ let(:bad_phone) do
+ IdentityIdpFunctions::AddressMockClient::UNVERIFIABLE_PHONE_NUMBER
+ end
let(:normalized_phone) { '7035550000' }
let(:bad_phone) { '+1 (703) 555-5555' }
@@ -61,6 +64,29 @@
expect(response).to redirect_to idv_phone_errors_failure_url
end
+
+ it 'shows phone form if async process times out' do
+ # setting the document capture session to a nonexistent uuid will trigger async
+ # timed_out behavior
+ subject.idv_session.idv_phone_step_document_capture_session_uuid = 'abc123'
+
+ get :new
+ expect(response).to render_template :new
+ end
+
+ it 'shows waiting interstitial if async process is in progress' do
+ # having a document capture session with PII but without results will trigger
+ # in progress behavior
+ document_capture_session = DocumentCaptureSession.create(user_id: user.id,
+ requested_at: Time.zone.now)
+ document_capture_session.store_proofing_pii_from_doc({})
+
+ subject.idv_session.idv_phone_step_document_capture_session_uuid =
+ document_capture_session.uuid
+
+ get :new
+ expect(response).to render_template :wait
+ end
end
describe '#create' do
@@ -133,6 +159,8 @@
put :create, params: { idv_phone_form: { phone: good_phone } }
+ expect(response).to redirect_to idv_phone_path
+ get :new
expect(response).to redirect_to idv_review_path
expected_applicant = {
@@ -140,7 +168,7 @@
last_name: 'One',
phone: normalized_phone,
uuid_prefix: nil,
- }.with_indifferent_access
+ }
expect(subject.idv_session.applicant).to eq expected_applicant
expect(subject.idv_session.vendor_phone_confirmation).to eq true
@@ -157,6 +185,8 @@
put :create, params: { idv_phone_form: { phone: good_phone } }
+ expect(response).to redirect_to idv_phone_path
+ get :new
expect(response).to redirect_to idv_otp_delivery_method_path
expect(subject.idv_session.vendor_phone_confirmation).to eq true
@@ -186,6 +216,8 @@
)
put :create, params: { idv_phone_form: { phone: good_phone } }
+ expect(response).to redirect_to idv_phone_path
+ get :new
end
end
@@ -194,9 +226,11 @@
user = build(:user, with: { phone: '+1 (415) 555-0130', phone_confirmed_at: Time.zone.now })
stub_verify_steps_one_and_two(user)
- put :create, params: { idv_phone_form: { phone: '7035555555' } }
+ put :create, params: { idv_phone_form: { phone: bad_phone } }
- expect(response).to redirect_to idv_phone_errors_warning_url
+ expect(response).to redirect_to idv_phone_path
+ get :new
+ expect(response).to redirect_to idv_phone_errors_warning_path
expect(subject.idv_session.vendor_phone_confirmation).to be_falsy
expect(subject.idv_session.user_phone_confirmation).to be_falsy
@@ -221,11 +255,15 @@
expect(@analytics).to receive(:track_event).ordered.with(
Analytics::IDV_PHONE_CONFIRMATION_FORM, hash_including(:success)
)
+
+ put :create, params: { idv_phone_form: { phone: bad_phone } }
+
expect(@analytics).to receive(:track_event).ordered.with(
Analytics::IDV_PHONE_CONFIRMATION_VENDOR, result
)
+ expect(response).to redirect_to idv_phone_path
- put :create, params: { idv_phone_form: { phone: '7035555555' } }
+ get :new
end
end
end
diff --git a/spec/controllers/lambda_callback/address_proof_result_controller_spec.rb b/spec/controllers/lambda_callback/address_proof_result_controller_spec.rb
index dd25ebde6b8..d5b4fb0ccce 100644
--- a/spec/controllers/lambda_callback/address_proof_result_controller_spec.rb
+++ b/spec/controllers/lambda_callback/address_proof_result_controller_spec.rb
@@ -12,19 +12,24 @@
it 'accepts and stores successful address proofing results' do
applicant = { phone: Faker::PhoneNumber.cell_phone }
document_capture_session.store_proofing_pii_from_doc(applicant)
- proofer_result = AddressMock.new.proof(applicant)
+ Idv::Agent.new(applicant).proof_address(document_capture_session)
+ proofer_result = document_capture_session.load_proofing_result[:result]
post :create, params: { result_id: document_capture_session.result_id,
address_result: proofer_result.to_h }
proofing_result = document_capture_session.load_proofing_result
- expect(proofing_result.result).to eq({ exception: '', success: 'true' })
+ expect(proofing_result.result).to include({ exception: '', success: 'true' })
end
it 'accepts and stores unsuccessful address proofing results' do
- applicant = { phone: '7035555555' }
+ applicant = {
+ phone: IdentityIdpFunctions::AddressMockClient::UNVERIFIABLE_PHONE_NUMBER,
+ }
+
document_capture_session.store_proofing_pii_from_doc(applicant)
- proofer_result = AddressMock.new.proof(applicant)
+ Idv::Agent.new(applicant).proof_address(document_capture_session)
+ proofer_result = document_capture_session.load_proofing_result[:result]
post :create, params: { result_id: document_capture_session.result_id,
address_result: proofer_result.to_h }
diff --git a/spec/services/idv/agent_spec.rb b/spec/services/idv/agent_spec.rb
index f16ea841cb1..48f31878630 100644
--- a/spec/services/idv/agent_spec.rb
+++ b/spec/services/idv/agent_spec.rb
@@ -2,6 +2,9 @@
require 'ostruct'
describe Idv::Agent do
+ let(:bad_phone) do
+ IdentityIdpFunctions::AddressMockClient::UNVERIFIABLE_PHONE_NUMBER
+ end
describe 'instance' do
let(:applicant) { { foo: 'bar' } }
@@ -100,16 +103,20 @@
end
describe '#proof_address' do
+ let(:document_capture_session) { DocumentCaptureSession.new(result_id: 'abc123') }
+
it 'proofs addresses successfully with valid information' do
agent = Idv::Agent.new({ phone: Faker::PhoneNumber.cell_phone })
- result = agent.proof_address
+ agent.proof_address(document_capture_session)
+ result = document_capture_session.load_proofing_result[:result]
expect(result[:context][:stages]).to include({ address: 'AddressMock' })
expect(result[:success]).to eq true
end
it 'fails to proof addresses with invalid information' do
- agent = Idv::Agent.new({ phone: '7035555555' })
- result = agent.proof_address
+ agent = Idv::Agent.new(phone: bad_phone)
+ agent.proof_address(document_capture_session)
+ result = document_capture_session.load_proofing_result[:result]
expect(result[:context][:stages]).to include({ address: 'AddressMock' })
expect(result[:success]).to eq false
end
diff --git a/spec/services/idv/phone_step_spec.rb b/spec/services/idv/phone_step_spec.rb
index 1b3a5316b33..152146de8fa 100644
--- a/spec/services/idv/phone_step_spec.rb
+++ b/spec/services/idv/phone_step_spec.rb
@@ -17,9 +17,15 @@
idvs
end
let(:good_phone) { '2255555000' }
- let(:bad_phone) { '7035555555' }
- let(:fail_phone) { '7035555999' }
- let(:timeout_phone) { '7035555888' }
+ let(:bad_phone) do
+ IdentityIdpFunctions::AddressMockClient::UNVERIFIABLE_PHONE_NUMBER
+ end
+ let(:fail_phone) do
+ IdentityIdpFunctions::AddressMockClient::FAILED_TO_CONTACT_PHONE_NUMBER
+ end
+ let(:timeout_phone) do
+ IdentityIdpFunctions::AddressMockClient::PROOFER_TIMEOUT_PHONE_NUMBER
+ end
subject { described_class.new(idv_session: idv_session) }
@@ -28,8 +34,10 @@
context = { stages: [{ address: 'AddressMock' }] }
extra = { vendor: { messages: [], context: context, exception: nil, timed_out: false } }
- result = subject.submit(phone: good_phone)
+ subject.submit(phone: good_phone)
+ expect(subject.async_state.status).to eq :done
+ result = subject.async_state_done(subject.async_state)
expect(result).to be_kind_of(FormResponse)
expect(result.success?).to eq(true)
expect(result.errors).to be_empty
@@ -44,7 +52,9 @@
context = { stages: [{ address: 'AddressMock' }] }
extra = { vendor: { messages: [], context: context, exception: nil, timed_out: false } }
- result = subject.submit(phone: bad_phone)
+ subject.submit(phone: bad_phone)
+ expect(subject.async_state.status).to eq :done
+ result = subject.async_state_done(subject.async_state)
expect(result).to be_kind_of(FormResponse)
expect(result.success?).to eq(false)
@@ -59,6 +69,8 @@
original_step_attempts = idv_session.step_attempts[:phone]
subject.submit(phone: bad_phone)
+ expect(subject.async_state.status).to eq :done
+ _result = subject.async_state_done(subject.async_state)
expect(idv_session.step_attempts[:phone]).to eq(original_step_attempts + 1)
end
@@ -82,14 +94,19 @@
it 'marks the phone as confirmed if it matches 2FA phone' do
user.phone_configurations = [build(:phone_configuration, user: user, phone: good_phone)]
- result = subject.submit(phone: good_phone)
+ subject.submit(phone: good_phone)
+ expect(subject.async_state.status).to eq :done
+ result = subject.async_state_done(subject.async_state)
+
expect(result.success?).to eq(true)
expect(idv_session.vendor_phone_confirmation).to eq(true)
expect(idv_session.user_phone_confirmation).to eq(true)
end
it 'does not mark the phone as confirmed if it does not match 2FA phone' do
- result = subject.submit(phone: good_phone)
+ subject.submit(phone: good_phone)
+ expect(subject.async_state.status).to eq :done
+ result = subject.async_state_done(subject.async_state)
expect(result.success?).to eq(true)
expect(idv_session.vendor_phone_confirmation).to eq(true)
@@ -101,6 +118,8 @@
context 'when there are idv attempts remaining' do
it 'returns :warning' do
subject.submit(phone: bad_phone)
+ expect(subject.async_state.status).to eq :done
+ _result = subject.async_state_done(subject.async_state)
expect(subject.failure_reason).to eq(:warning)
end
@@ -111,6 +130,8 @@
idv_session.step_attempts[:phone] = idv_max_attempts - 1
subject.submit(phone: bad_phone)
+ expect(subject.async_state.status).to eq :done
+ _result = subject.async_state_done(subject.async_state)
expect(subject.failure_reason).to eq(:fail)
end
@@ -119,6 +140,8 @@
context 'when the vendor raises a timeout exception' do
it 'returns :timeout' do
subject.submit(phone: timeout_phone)
+ expect(subject.async_state.status).to eq :done
+ _result = subject.async_state_done(subject.async_state)
expect(subject.failure_reason).to eq(:timeout)
end
@@ -127,6 +150,8 @@
context 'when the vendor raises an exception' do
it 'returns :jobfail' do
subject.submit(phone: fail_phone)
+ expect(subject.async_state.status).to eq :done
+ _result = subject.async_state_done(subject.async_state)
expect(subject.failure_reason).to eq(:jobfail)
end
diff --git a/spec/services/idv/proofer_spec.rb b/spec/services/idv/proofer_spec.rb
index a03f07bf34f..2cb299e9770 100644
--- a/spec/services/idv/proofer_spec.rb
+++ b/spec/services/idv/proofer_spec.rb
@@ -50,44 +50,13 @@
end
end
- describe '.address_vendor' do
- context 'with mock proofers enabled' do
- let(:proofer_mock_fallback) { 'true' }
-
- it 'returns the mock vendor' do
- expect(subject.address_vendor).to eq(AddressMock)
- end
- end
-
- context 'with mock proofers disabled' do
- before do
- class_double('LexisNexis::PhoneFinder::Proofer', new: {}).as_stubbed_const
- end
- it 'returns the live vendor' do
- expect(subject.address_vendor).to eq(LexisNexis::PhoneFinder::Proofer)
- end
- end
- end
-
describe '.validate_vendors!' do
let(:proofer_mock_fallback) { 'false' }
- context 'with vendors configured for each stage' do
- before do
- class_double('LexisNexis::InstantVerify::Proofer', new: {}).as_stubbed_const
- class_double('LexisNexis::PhoneFinder::Proofer', new: {}).as_stubbed_const
- class_double('Aamva::Proofer', new: {}).as_stubbed_const
- end
-
- it 'does not raise' do
- expect { described_class.validate_vendors! }.to_not raise_error
- end
- end
-
context 'without vendors configured for each stage' do
it 'does raise' do
expect { described_class.validate_vendors! }.to raise_error(
- NameError,
+ LoadError,
)
end
end
diff --git a/spec/services/lambda_jobs/runner_spec.rb b/spec/services/lambda_jobs/runner_spec.rb
index ce50fff8b91..0028eb11f20 100644
--- a/spec/services/lambda_jobs/runner_spec.rb
+++ b/spec/services/lambda_jobs/runner_spec.rb
@@ -56,7 +56,7 @@
it 'calls JobClass.handle' do
expect(job_class).to receive(:handle).with(
- event: { body: args.to_json },
+ event: { 'body' => args.to_json },
context: nil,
)
@@ -70,7 +70,7 @@
it 'calls JobClass.handle' do
expect(job_class).to receive(:handle).with(
- event: { body: args.to_json },
+ event: { 'body' => args.to_json },
context: nil,
)
@@ -82,7 +82,7 @@
result = Object.new
expect(job_class).to receive(:handle).with(
- event: { body: args.to_json },
+ event: { 'body' => args.to_json },
context: nil,
).and_yield(result)
diff --git a/spec/support/idv_examples/failed_idv_job.rb b/spec/support/idv_examples/failed_idv_job.rb
index d813faa5bcf..e0f9e5037a4 100644
--- a/spec/support/idv_examples/failed_idv_job.rb
+++ b/spec/support/idv_examples/failed_idv_job.rb
@@ -46,7 +46,8 @@ def fill_out_idv_form_error
end
def fill_out_phone_form_error
- fill_in :idv_phone_form_phone, with: '7035555999'
+ fill_in :idv_phone_form_phone, with:
+ IdentityIdpFunctions::AddressMockClient::FAILED_TO_CONTACT_PHONE_NUMBER
end
def fill_out_idv_form_timeout
@@ -55,7 +56,8 @@ def fill_out_idv_form_timeout
end
def fill_out_phone_form_timeout
- fill_in :idv_phone_form_phone, with: '7035555888'
+ fill_in :idv_phone_form_phone, with:
+ IdentityIdpFunctions::AddressMockClient::PROOFER_TIMEOUT_PHONE_NUMBER
end
def session_timeout_path