Skip to content
18 changes: 18 additions & 0 deletions app/controllers/concerns/idv/document_capture_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,24 @@ def fetch_test_verification_data
)
end

def track_document_request_event(document_request:, document_response:, timer:)
document_request_body = JSON.parse(document_request.body, symbolize_names: true)[:config]
response_hash = document_response.to_h
log_extras = {
reference_id: response_hash[:referenceId],
vendor: 'Socure',
vendor_request_time_in_ms: timer.results['vendor_request'],
success: @url.present?,
document_type: document_request_body[:documentType],
docv_transaction_token: response_hash.dig(:data, :docvTransactionToken),
}
analytics_hash = log_extras.merge(analytics_arguments).
merge(document_request_body).except(
:documentType, # requested document type
).merge(response_body: document_response.to_h)
analytics.idv_socure_document_request_submitted(**analytics_hash)
end

private

def track_document_issuing_state(user, state)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ def show
redirect_url: idv_hybrid_mobile_socure_document_capture_update_url,
language: I18n.locale,
)
document_response = document_request.fetch
timer = JobHelpers::Timer.new
document_response = timer.time('vendor_request') do
document_request.fetch
end

@document_request = document_request
@document_response = document_response
@url = document_response.dig(:data, :url)

track_document_request_event(document_request:, document_response:, timer:)

# placeholder until we get an error page for url not being present
if @url.nil?
redirect_to idv_hybrid_mobile_socure_document_capture_errors_url
return
Expand All @@ -48,9 +52,6 @@ def show
:url,
)
document_capture_session.save
# useful for analytics
@msg = document_response[:msg]
@reference_id = document_response[:referenceId]
end

def update
Expand Down
14 changes: 6 additions & 8 deletions app/controllers/idv/socure/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ def show
redirect_url: idv_socure_document_capture_update_url,
language: I18n.locale,
)
timer = JobHelpers::Timer.new
document_response = timer.time('vendor_request') do
document_request.fetch
end

document_response = document_request.fetch

@document_request = document_request
@document_response = document_response
@url = document_response.dig(:data, :url)

track_document_request_event(document_request:, document_response:, timer:)

# placeholder until we get an error page for url not being present
if @url.nil?
redirect_to idv_socure_document_capture_errors_url
Expand All @@ -61,10 +63,6 @@ def show
:url,
)
document_capture_session.save

# useful for analytics
@msg = document_response[:msg]
@reference_id = document_response[:referenceId]
end

def update
Expand Down
70 changes: 70 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4729,6 +4729,76 @@ def idv_session_error_visited(
)
end

# @param [Boolean] success Whether form validation was successful
# @param [Hash] errors Errors resulting from form validation
# @param [String] exception any exceptions thrown during request
# @param [String] docv_transaction_token socure transaction token
# @param [String] reference_id socure interal id for transaction
# @param [String] language lagnuage presented to user
# @param [String] step current step of idv to user
# @param [String] analytics_id id of analytics
# @param [Boolean] redo_document_capture if user is redoing doc capture
# @param [Boolean] skip_hybrid_handoff if user is skipping handoff
# @param [Boolean] selfie_check_required is selfie check required
# @param [Boolean] opted_in_to_in_person_proofing user opts in to IPP
# @param [Hash] redirect hash for redirect (url and method)
# @param [Hash] response_body hash received from socure
# @param ["hybrid","standard"] flow_path Document capture user flow
# @param [Float] vendor_request_time_in_ms Time it took to upload images & get a response.
# @param [Boolean] liveness_checking_required Whether or not the selfie is required
# @param [Boolean] liveness_enabled Whether or not the selfie result is included in response
# @param [String] vendor which 2rd party we are using for doc auth
# @param [Hash] document_type type of socument submitted (Drivers Licenese, etc.)
# The request for socure verification was sent
def idv_socure_document_request_submitted(
success:,
redirect:,
liveness_checking_required:,
vendor_request_time_in_ms:,
vendor:,
language:,
step:,
analytics_id:,
response_body:,
redo_document_capture: nil,
skip_hybrid_handoff: nil,
selfie_check_required: nil,
opted_in_to_in_person_proofing: nil,
errors: nil,
exception: nil,
reference_id: nil,
liveness_enabled: nil,
document_type: nil,
docv_transaction_token: nil,
flow_path: nil,
**extra
)
track_event(
:idv_socure_document_request_submitted,
success:,
redirect:,
liveness_checking_required:,
vendor_request_time_in_ms:,
vendor:,
language:,
step:,
analytics_id:,
redo_document_capture:,
skip_hybrid_handoff:,
selfie_check_required:,
opted_in_to_in_person_proofing:,
errors:,
exception:,
reference_id:,
response_body:,
liveness_enabled:,
document_type:,
docv_transaction_token:,
flow_path:,
**extra,
)
end

# Socure Reason Codes were downloaded and synced against persisted codes in the database
# @param [Boolean] success Result from Socure KYC API call
# @param [Hash] errors Result from resolution proofing
Expand Down
14 changes: 7 additions & 7 deletions app/services/doc_auth/socure/requests/document_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@ def initialize(
@language = language
end

private

def lang(language)
return 'zh-cn' if language == :zh
language
end

def body
redirect = {
method: 'GET',
Expand All @@ -40,6 +33,13 @@ def body
}.to_json
end

private

def lang(language)
return 'zh-cn' if language == :zh
language
end

def handle_http_response(http_response)
JSON.parse(http_response.body, symbolize_names: true)
end
Expand Down
3 changes: 2 additions & 1 deletion app/services/idv/analytics_events_enhancer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ module AnalyticsEventsEnhancer
idv_doc_auth_ssn_visited
idv_doc_auth_submitted_image_upload_form
idv_doc_auth_submitted_image_upload_vendor
idv_socure_verification_data_requested
idv_doc_auth_submitted_pii_validation
idv_doc_auth_verify_proofing_results
idv_doc_auth_verify_submitted
Expand Down Expand Up @@ -97,6 +96,8 @@ module AnalyticsEventsEnhancer
idv_sdk_selfie_image_capture_opened
idv_selfie_image_added
idv_session_error_visited
idv_socure_document_request_submitted
idv_socure_verification_data_requested
idv_threatmetrix_response_body
idv_usps_auth_token_refresh_job_completed
idv_usps_auth_token_refresh_job_network_error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@
)
end

it 'logs correct info' do
expect(@analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end

it 'sets DocumentCaptureSession socure_docv_capture_app_url value' do
document_capture_session.reload
expect(document_capture_session.socure_docv_capture_app_url).to eq(socure_capture_app_url)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@
)
end

it 'logs correct info' do
expect(@analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end

it 'sets DocumentCaptureSession socure_docv_capture_app_url value' do
document_capture_session.reload
expect(document_capture_session.socure_docv_capture_app_url).to eq(socure_capture_app_url)
Expand Down
32 changes: 30 additions & 2 deletions spec/features/idv/doc_auth/socure_document_capture_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
and_return(socure_docv_verification_data_test_mode)
end

context 'happy path' do
context 'happy path', allow_browser_log: true do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

in an existing standard and hybrid flow spec can we add a expect check using fake_analytics for the happy path, network error, and invalid request? 🙏🏿 the invalid request might be the only spec that doesn't exist

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we still add a check to the network error spec?
can we create a spec for an invalid request ... for example, if we pass the wrong api secret key?

can we add fake analytics checks to the hybrid flow specs?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks for adding the analytics check to the hybrid spec. Can you add also add the checks in the hybrid spec for the same scenarios as you did for the standard flow (ie: network error, invalid response(401), ...) ?

before do
@pass_stub = stub_docv_verification_data_pass(docv_transaction_token: @docv_transaction_token)
end
Expand Down Expand Up @@ -63,6 +63,9 @@
'Rate Limit Reached',
limiter_type: :idv_doc_auth,
)
expect(fake_analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end

context 'successfully processes image on last attempt' do
Expand All @@ -88,7 +91,7 @@
end
end

context 'network connection errors' do
context 'network connection errors', allow_browser_log: true do
context 'getting the capture path' do
before do
allow_any_instance_of(Faraday::Connection).to receive(:post).
Expand All @@ -103,6 +106,9 @@

expect(page).to have_content(t('doc_auth.headers.general.network_error'))
expect(page).to have_content(t('doc_auth.errors.general.new_network_error'))
expect(fake_analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end
end

Expand All @@ -113,6 +119,22 @@
end
end

context 'invalid request', allow_browser_log: true do
context 'getting the capture path w wrong api key' do
before do
DocAuth::Mock::DocAuthMockClient.reset!
stub_docv_document_request(status: 401)
end

it 'correctly logs event', js: true do
visit idv_socure_document_capture_path
expect(fake_analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end
end
end

it 'does not track state if state tracking is disabled' do
allow(IdentityConfig.store).to receive(:state_tracking_enabled).and_return(false)
socure_docv_upload_documents(
Expand Down Expand Up @@ -203,6 +225,9 @@
expect(page).to have_current_path(idv_ssn_url)

expect(DocAuthLog.find_by(user_id: @user.id).state).to eq('NY')
expect(fake_analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)

fill_out_ssn_form_ok
click_idv_continue
Expand Down Expand Up @@ -234,6 +259,9 @@

it 'shows the correct error page' do
expect(page).to have_content(t(expected_header_key))
expect(fake_analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end
end

Expand Down
29 changes: 26 additions & 3 deletions spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
let(:fake_socure_document_capture_app_url) { 'https://verify.fake-socure.test/something' }
let(:fake_socure_docv_document_request_endpoint) { 'https://fake-socure.test/document-request' }
let(:socure_docv_verification_data_test_mode) { false }
let(:fake_analytics) { FakeAnalytics.new }

before do
allow(FeatureManagement).to receive(:doc_capture_polling_enabled?).and_return(true)
Expand All @@ -27,9 +28,10 @@
allow(IdentityConfig.store).to receive(:socure_docv_verification_data_test_mode).
and_return(socure_docv_verification_data_test_mode)
@docv_transaction_token = stub_docv_document_request
stub_analytics
end

context 'happy path' do
context 'happy path', allow_browser_log: true do
before do
@pass_stub = stub_docv_verification_data_pass(docv_transaction_token: @docv_transaction_token)
end
Expand Down Expand Up @@ -81,7 +83,6 @@
visit idv_hybrid_mobile_socure_document_capture_url

expect(page).to have_current_path(idv_hybrid_mobile_socure_document_capture_url)

click_idv_continue
expect(page).to have_current_path(fake_socure_document_capture_app_url)
socure_docv_upload_documents(docv_transaction_token: @docv_transaction_token)
Expand All @@ -101,7 +102,7 @@
perform_in_browser(:desktop) do
expect(page).to_not have_content(t('doc_auth.headings.text_message'), wait: 10)
expect(page).to have_current_path(idv_ssn_path)

expect(@analytics).to have_logged_event(:idv_socure_document_request_submitted)
fill_out_ssn_form_ok
click_idv_continue

Expand Down Expand Up @@ -441,11 +442,33 @@

expect(page).to have_text(t('doc_auth.headers.general.network_error'))
expect(page).to have_text(t('doc_auth.errors.general.new_network_error'))
expect(@analytics).to have_logged_event(:idv_socure_document_request_submitted)
end

perform_in_browser(:desktop) do
expect(page).to have_current_path(idv_link_sent_path)
end
end
end

context 'invalid request', allow_browser_log: true do
context 'getting the capture path w wrong api key' do
before do
user = user_with_2fa
visit_idp_from_oidc_sp_with_ial2
sign_in_and_2fa_user(user)
complete_doc_auth_steps_before_document_capture_step
click_idv_continue
DocAuth::Mock::DocAuthMockClient.reset!
stub_docv_document_request(status: 401)
end

it 'correctly logs event', js: true do
visit idv_socure_document_capture_path
expect(@analytics).to have_logged_event(
:idv_socure_document_request_submitted,
)
end
end
end
end