Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
042efd5
Trim leading & trailing white space
gina-yamada Aug 14, 2023
9cad418
create new input handler for zipcode
gina-yamada Aug 15, 2023
5b164b4
move trim method to onSearch vars
gina-yamada Aug 15, 2023
51f0389
Add trimStart to check for only spaces
gina-yamada Aug 15, 2023
4dee0b5
Add zip code error message for pattern mismatch
gina-yamada Aug 16, 2023
e3c8776
fix lint issues
gina-yamada Aug 16, 2023
eec205a
changelog: User-Facing Improvements, In-person proofing, Improve vali…
gina-yamada Aug 16, 2023
d6407b1
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 16, 2023
1675b06
Tests to check for validation errors
gina-yamada Aug 16, 2023
5b43348
fix lint errors
gina-yamada Aug 16, 2023
9d28293
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 17, 2023
235dc4b
Add logic to check for valid zipCode length
gina-yamada Aug 17, 2023
3542b08
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 17, 2023
664c195
added validation for address and city
gina-yamada Aug 17, 2023
363e61a
fix linter error
gina-yamada Aug 17, 2023
da01123
create unique on change events to handles to clean input
gina-yamada Aug 18, 2023
9394182
Add event to grab value
gina-yamada Aug 18, 2023
7494707
delete unused input change handler function
gina-yamada Aug 18, 2023
6f0eadc
fix lint errors
gina-yamada Aug 18, 2023
95828ff
Add select change event, max length, trim on submission
gina-yamada Aug 18, 2023
e676b58
fix linter issues
gina-yamada Aug 18, 2023
ee9d675
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 18, 2023
78d8fc7
remove regex from address and city
gina-yamada Aug 22, 2023
201f27b
fix linter errors
gina-yamada Aug 22, 2023
f2cbb99
Add validation tests
gina-yamada Aug 22, 2023
89a4faa
Clean up duplicate tests, delete unnecessary input on form
gina-yamada Aug 22, 2023
9825e6b
fix linter issues
gina-yamada Aug 22, 2023
9ace0f7
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 22, 2023
9d64a38
Use regex/pattern to find err for space only input
gina-yamada Aug 23, 2023
5fb1b9e
Update zipcode to handle only 5 digits
gina-yamada Aug 24, 2023
ca54552
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 24, 2023
6be7c08
modified valid length for zip
gina-yamada Aug 24, 2023
0368108
Remove zipcode onchange handler
gina-yamada Aug 25, 2023
5ac43c1
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 25, 2023
3164439
fix linter error
gina-yamada Aug 25, 2023
e1e1340
update test
gina-yamada Aug 25, 2023
e2f3d19
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 25, 2023
c28f57f
updated test to remove try/catch
gina-yamada Aug 25, 2023
097a5a3
Merge branch 'main' of github.com:18F/identity-idp into yamada/LG-104…
gina-yamada Aug 28, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,88 @@ import { LOCATIONS_URL } from './in-person-location-post-office-search-step';

describe('FullAddressSearch', () => {
const sandbox = useSandbox();

context('validates form', () => {
it('displays an error for all required fields when input is empty', async () => {
const handleLocationsFound = sandbox.stub();
const { findByText, findAllByText } = render(
<SWRConfig value={{ provider: () => new Map() }}>
<FullAddressSearch onFoundLocations={handleLocationsFound} locationsURL={LOCATIONS_URL} />
</SWRConfig>,
);

await userEvent.click(
await findByText('in_person_proofing.body.location.po_search.search_button'),
);

const errors = await findAllByText('simple_form.required.text');
expect(errors).to.have.lengthOf(4);
});

it('displays an error for an invalid ZIP code length (length = 1)', async () => {
const handleLocationsFound = sandbox.stub();
const { findByText, findByLabelText, findAllByText } = render(
<SWRConfig value={{ provider: () => new Map() }}>
<FullAddressSearch onFoundLocations={handleLocationsFound} locationsURL={LOCATIONS_URL} />
</SWRConfig>,
);

await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.address_label'),
'200 main',
);
await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.city_label'),
'Endeavor',
);
await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.state_label'),
'DE',
);
await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.zipcode_label'),
'1',
);
await userEvent.click(
await findByText('in_person_proofing.body.location.po_search.search_button'),
);

const errors = await findAllByText('idv.errors.pattern_mismatch.zipcode_five');
expect(errors).to.have.lengthOf(1);
});

it('does not display an error for a valid ZIP code length (length = 5)', async () => {
const handleLocationsFound = sandbox.stub();
const { findByText, findByLabelText, queryByText } = render(
<SWRConfig value={{ provider: () => new Map() }}>
<FullAddressSearch onFoundLocations={handleLocationsFound} locationsURL={LOCATIONS_URL} />
</SWRConfig>,
);

await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.address_label'),
'200 main',
);
await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.city_label'),
'Endeavor',
);
await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.state_label'),
'DE',
);
await userEvent.type(
await findByLabelText('in_person_proofing.body.location.po_search.zipcode_label'),
'17201',
);
await userEvent.click(
await findByText('in_person_proofing.body.location.po_search.search_button'),
);

expect(queryByText('idv.errors.pattern_mismatch.zipcode')).to.be.null;
});
});

context('when an address is found', () => {
let server: SetupServer;
before(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,33 +50,65 @@ function useUspsLocations(locationsURL: string) {
const validatedStateFieldRef = useRef<HTMLFormElement>(null);
const validatedZipCodeFieldRef = useRef<HTMLFormElement>(null);

const handleLocationSearch = useCallback(
(event, addressValue, cityValue, stateValue, zipCodeValue) => {
event.preventDefault();
const checkValidityAndDisplayErrors = (address, city, state, zipCode) => {
let formIsValid = true;
const zipCodeIsValid = zipCode.length === 5 && !!zipCode.match(/\d{5}/);

if (address.length === 0) {
validatedAddressFieldRef.current?.setCustomValidity(t('simple_form.required.text'));
formIsValid = false;
} else {
validatedAddressFieldRef.current?.setCustomValidity('');
validatedAddressFieldRef.current?.reportValidity();
}

if (city.length === 0) {
formIsValid = false;
validatedCityFieldRef.current?.setCustomValidity(t('simple_form.required.text'));
} else {
validatedCityFieldRef.current?.setCustomValidity('');
validatedCityFieldRef.current?.reportValidity();
}

if (state.length === 0) {
formIsValid = false;
validatedStateFieldRef.current?.setCustomValidity(t('simple_form.required.text'));
} else {
validatedStateFieldRef.current?.setCustomValidity('');
validatedStateFieldRef.current?.reportValidity();
}

if (zipCode.length === 0) {
formIsValid = false;
validatedZipCodeFieldRef.current?.setCustomValidity(t('simple_form.required.text'));
} else {
validatedZipCodeFieldRef.current?.setCustomValidity('');
validatedZipCodeFieldRef.current?.reportValidity();

if (
addressValue.trim().length === 0 ||
cityValue.trim().length === 0 ||
stateValue.trim().length === 0 ||
zipCodeValue.trim().length === 0
) {
}

validatedAddressFieldRef.current?.reportValidity();
validatedCityFieldRef.current?.reportValidity();
validatedStateFieldRef.current?.reportValidity();
validatedZipCodeFieldRef.current?.reportValidity();

return formIsValid && zipCodeIsValid;
};

const handleLocationSearch = useCallback(
(event, addressValue, cityValue, stateValue, zipCodeValue) => {
event.preventDefault();
const address = addressValue.trim();
const city = cityValue.trim();
const zipCode = zipCodeValue.trim();

const formIsValid = checkValidityAndDisplayErrors(address, city, stateValue, zipCode);

if (!formIsValid) {
return;
}

setLocationQuery({
address: `${addressValue}, ${cityValue}, ${stateValue} ${zipCodeValue}`,
streetAddress: addressValue,
city: cityValue,
address: `${address}, ${city}, ${stateValue} ${zipCode}`,
streetAddress: address,
city,
state: stateValue,
zipCode: zipCodeValue,
zipCode,
});
},
[],
Expand Down Expand Up @@ -147,9 +179,11 @@ function FullAddressSearch({
input(target.value);
};

type SelectChangeEvent = React.ChangeEvent<HTMLSelectElement>;

const onAddressChange = inputChangeHandler(setAddressValue);
const onCityChange = inputChangeHandler(setCityValue);
const onStateChange = inputChangeHandler(setStateValue);
const onStateChange = (e: SelectChangeEvent) => setStateValue(e.target.value);
const onZipCodeChange = inputChangeHandler(setZipCodeValue);

useEffect(() => {
Expand Down Expand Up @@ -177,24 +211,38 @@ function FullAddressSearch({

return (
<>
<ValidatedField ref={validatedAddressFieldRef}>
<ValidatedField
ref={validatedAddressFieldRef}
messages={{
patternMismatch: t('simple_form.required.text'),
}}
>
<TextInput
required
ref={registerField('address')}
value={addressValue}
onChange={onAddressChange}
label={t('in_person_proofing.body.location.po_search.address_label')}
disabled={disabled}
maxLength={255}
pattern=".*\S.*$"
/>
</ValidatedField>
<ValidatedField ref={validatedCityFieldRef}>
<ValidatedField
ref={validatedCityFieldRef}
messages={{
patternMismatch: t('simple_form.required.text'),
}}
>
<TextInput
required
ref={registerField('city')}
value={cityValue}
onChange={onCityChange}
label={t('in_person_proofing.body.location.po_search.city_label')}
disabled={disabled}
maxLength={50}
pattern=".*\S.*$"
/>
</ValidatedField>
<ValidatedField ref={validatedStateFieldRef}>
Expand All @@ -216,7 +264,12 @@ function FullAddressSearch({
))}
</SelectInput>
</ValidatedField>
<ValidatedField ref={validatedZipCodeFieldRef}>
<ValidatedField
ref={validatedZipCodeFieldRef}
messages={{
patternMismatch: t('idv.errors.pattern_mismatch.zipcode_five'),
}}
>
<TextInput
required
className="tablet:grid-col-5"
Expand All @@ -225,6 +278,10 @@ function FullAddressSearch({
onChange={onZipCodeChange}
label={t('in_person_proofing.body.location.po_search.zipcode_label')}
disabled={disabled}
pattern="^\d{5}$"
maxLength={5}
minLength={5}
type="text"
/>
</ValidatedField>
<div className="margin-y-5">
Expand Down
1 change: 1 addition & 0 deletions config/locales/idv/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ en:
pattern_mismatch:
ssn: 'Enter a nine-digit Social Security number'
zipcode: Enter a 5 or 9 digit ZIP Code
zipcode_five: Enter a 5 digit ZIP Code
failure:
attempts_html:
one: For security reasons, you have <strong>one attempt</strong> remaining to
Expand Down
1 change: 1 addition & 0 deletions config/locales/idv/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ es:
pattern_mismatch:
ssn: 'Ingrese un número de Seguro Social de nueve dígitos'
zipcode: Ingresa un código postal de 5 o 9 dígitos
zipcode_five: Ingresa un código postal de 5 dígitos
failure:
attempts_html:
one: Por motivos de seguridad, le quedan <strong>un intento</strong> para añadir
Expand Down
1 change: 1 addition & 0 deletions config/locales/idv/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ fr:
pattern_mismatch:
ssn: 'Entrez un numéro de sécurité sociale à neuf chiffres'
zipcode: Entrez un code postal à 5 ou 9 chiffres
zipcode_five: Entrez un code postal à 5 chiffres
failure:
attempts_html:
one: Pour des raisons de sécurité, il vous reste <strong>une tentative</strong>
Expand Down