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
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ GEM
debug_inspector (>= 0.0.1)
bootsnap (1.15.0)
msgpack (~> 1.2)
brakeman (5.4.1)
brakeman (5.4.0)
browser (5.3.1)
builder (3.2.4)
bullet (7.0.7)
Expand Down
6 changes: 6 additions & 0 deletions app/components/phone_input_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
:phone,
class: 'usa-label',
) { t('two_factor_authentication.phone_label') } %>
<div class="js">
<%= f.hint(capture do %>
<%= t('forms.example') %>
<span class="phone-input__example"></span>
<% end) %>
</div>
<%= render ValidatedFieldComponent.new(
form: f,
name: :phone,
Expand Down
1 change: 0 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ def analytics
sp: current_sp&.issuer,
session: session,
ahoy: ahoy,
irs_session_id: irs_attempts_api_session_id,
)
end

Expand Down
30 changes: 22 additions & 8 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,23 @@ def async_state_done(current_async_state)
extra: {
address_edited: !!flow_session['address_edited'],
address_line2_present: !pii[:address2].blank?,
pii_like_keypaths: [[:errors, :ssn], [:response_body, :first_name],
[:state_id, :state_id_jurisdiction]],
pii_like_keypaths: [[:errors, :ssn], [:response_body, :first_name]],
},
)
log_idv_verification_submitted_event(
success: form_response.success?,
failure_reason: irs_attempts_api_tracker.parse_failure_reason(form_response),
)

form_response = form_response.merge(check_ssn) if form_response.success?
if form_response.success?
response = check_ssn
form_response = form_response.merge(response)
end
summarize_result_and_throttle_failures(form_response)
delete_async

if form_response.success?
move_applicant_to_idv_session
idv_session.mark_verify_info_step_complete!
idv_session.invalidate_steps_after_verify_info!
redirect_to idv_phone_url
else
idv_session.invalidate_verify_info_step!
Expand Down Expand Up @@ -196,13 +196,27 @@ def log_idv_verification_submitted_event(success: false, failure_reason: nil)
end

def check_ssn
Idv::SsnForm.new(current_user).submit(ssn: pii[:ssn])
result = Idv::SsnForm.new(current_user).submit(ssn: pii[:ssn])

if result.success?
save_legacy_state
delete_pii
end

result
end

def move_applicant_to_idv_session
def save_legacy_state
skip_legacy_steps
idv_session.applicant = pii
idv_session.applicant['uuid'] = current_user.uuid
delete_pii
end

def skip_legacy_steps
idv_session.mark_verify_info_step_complete!
idv_session.vendor_phone_confirmation = false
idv_session.user_phone_confirmation = false
idv_session.address_verification_mechanism = 'phone'
end

def add_proofing_costs(results)
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/idv/in_person/address_search_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
module Idv
module InPerson
class AddressSearchController < ApplicationController
include RenderConditionConcern

check_or_render_not_found -> { IdentityConfig.store.arcgis_search_enabled }

def index
response = addresses(params[:address])
render(**response)
Expand Down
31 changes: 18 additions & 13 deletions app/controllers/idv/in_person/usps_locations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,26 @@ class UspsLocationsController < ApplicationController

# retrieve the list of nearby IPP Post Office locations with a POST request
def index
candidate = UspsInPersonProofing::Applicant.new(
address: search_params['street_address'],
city: search_params['city'], state: search_params['state'],
zip_code: search_params['zip_code']
)
response = proofer.request_facilities(candidate)
if response.length > 0
analytics.idv_in_person_locations_searched(
success: true,
result_total: response.length,
response = []
if IdentityConfig.store.arcgis_search_enabled
candidate = UspsInPersonProofing::Applicant.new(
address: search_params['street_address'],
city: search_params['city'], state: search_params['state'],
zip_code: search_params['zip_code']
)
response = proofer.request_facilities(candidate)
if response.length > 0
analytics.idv_in_person_locations_searched(
success: true,
result_total: response.length,
)
else
analytics.idv_in_person_locations_searched(
success: false, errors: 'No USPS locations found',
)
end
else
analytics.idv_in_person_locations_searched(
success: false, errors: 'No USPS locations found',
)
response = proofer.request_pilot_facilities
end
render json: response.to_json
end
Expand Down
10 changes: 0 additions & 10 deletions app/controllers/redirect/policy_controller.rb

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getConfigValue } from '@18f/identity-config';
import { UploadFormEntriesError } from '../services/upload';
import DocumentsStep from './documents-step';
import InPersonPrepareStep from './in-person-prepare-step';
import InPersonLocationStep from './in-person-location-step';
import InPersonLocationPostOfficeSearchStep from './in-person-location-post-office-search-step';
import InPersonSwitchBackStep from './in-person-switch-back-step';
import ReviewIssuesStep from './review-issues-step';
Expand Down Expand Up @@ -59,7 +60,7 @@ function DocumentCapture({ isAsyncForm = false, onStepChange = () => {} }: Docum
const { t } = useI18n();
const { flowPath } = useContext(UploadContext);
const { trackSubmitEvent, trackVisitEvent } = useContext(AnalyticsContext);
const { inPersonURL } = useContext(InPersonContext);
const { inPersonURL, arcgisSearchEnabled } = useContext(InPersonContext);
const appName = getConfigValue('appName');

useDidUpdateEffect(onStepChange, [stepName]);
Expand Down Expand Up @@ -113,7 +114,7 @@ function DocumentCapture({ isAsyncForm = false, onStepChange = () => {} }: Docum
: ([
{
name: 'location',
form: InPersonLocationPostOfficeSearchStep,
form: arcgisSearchEnabled ? InPersonLocationPostOfficeSearchStep : InPersonLocationStep,
title: t('in_person_proofing.headings.po_search.location'),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import type { SetupServerApi } from 'msw/node';
import { SWRConfig } from 'swr';
import { I18nContext } from '@18f/identity-react-i18n';
import { ComponentType } from 'react';
import { ADDRESS_SEARCH_URL, LOCATIONS_URL } from './address-search';
import { LOCATIONS_URL } from './in-person-location-step';
import { ADDRESS_SEARCH_URL } from './address-search';
import InPersonContext from '../context/in-person';
import InPersonLocationPostOfficeSearchStep from './in-person-location-post-office-search-step';

const DEFAULT_RESPONSE = [
Expand Down Expand Up @@ -56,9 +58,11 @@ const DEFAULT_PROPS = {
registerField() {},
};

describe('InPersonPostOfficeSearchStep', () => {
describe('InPersonLocationStep', () => {
const wrapper: ComponentType = ({ children }) => (
<SWRConfig value={{ provider: () => new Map() }}>{children}</SWRConfig>
<InPersonContext.Provider value={{ arcgisSearchEnabled: true }}>
<SWRConfig value={{ provider: () => new Map() }}>{children}</SWRConfig>
</InPersonContext.Provider>
);

let server: SetupServerApi;
Expand Down Expand Up @@ -86,7 +90,9 @@ describe('InPersonPostOfficeSearchStep', () => {
it('displays a try again error message', async () => {
const { findByText, findByLabelText } = render(
<SWRConfig value={{ provider: () => new Map() }}>
<InPersonLocationPostOfficeSearchStep {...DEFAULT_PROPS} />
<InPersonContext.Provider value={{ arcgisSearchEnabled: true }}>
<InPersonLocationPostOfficeSearchStep {...DEFAULT_PROPS} />
</InPersonContext.Provider>
</SWRConfig>,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import sinon from 'sinon';
import { useContext } from 'react';
import { render } from '@testing-library/react';
import { getAllByRole } from '@testing-library/dom';
import userEvent from '@testing-library/user-event';
import { setupServer } from 'msw/node';
import { rest } from 'msw';
import type { SetupServerApi } from 'msw/node';
import AnalyticsContext, { AnalyticsContextProvider } from '../context/analytics';
import InPersonLocationStep, { LOCATIONS_URL } from './in-person-location-step';
import { ADDRESS_SEARCH_URL } from './address-search';

const DEFAULT_RESPONSE = [
{
address: '100 Main St E, Bronwood, Georgia, 39826',
location: {
latitude: 31.831686000000005,
longitude: -84.363768,
},
street_address: '100 Main St E',
city: 'Bronwood',
state: 'GA',
zip_code: '39826',
},
];

const DEFAULT_PROPS = {
toPreviousStep() {},
onChange() {},
value: {},
registerField() {},
};

describe('InPersonLocationStep', () => {
let server: SetupServerApi;
before(() => {
server = setupServer(
rest.post(LOCATIONS_URL, (_req, res, ctx) => res(ctx.json([{ name: 'Baltimore' }]))),
rest.post(ADDRESS_SEARCH_URL, (_req, res, ctx) => res(ctx.json(DEFAULT_RESPONSE))),
rest.put(LOCATIONS_URL, (_req, res, ctx) => res(ctx.json([{ success: true }]))),
);
server.listen();
});

after(() => {
server.close();
});

it('logs step submission with selected location', async () => {
const trackEvent = sinon.stub();
function MetadataValue() {
return <>{JSON.stringify(useContext(AnalyticsContext).submitEventMetadata)}</>;
}
const { findByText } = render(
<AnalyticsContextProvider trackEvent={trackEvent}>
<MetadataValue />
<InPersonLocationStep {...DEFAULT_PROPS} />
</AnalyticsContextProvider>,
);

const item = await findByText('Baltimore — in_person_proofing.body.location.post_office');
const button = getAllByRole(item.closest('.location-collection-item')!, 'button')[0];

await userEvent.click(button);

await findByText('{"selected_location":"Baltimore","in_person_cta_variant":""}');
});
});
Loading