From 51cb74db64ea88d793c518cce35eba5b4ddd8f5d Mon Sep 17 00:00:00 2001 From: Lucas Cordeiro Date: Tue, 12 Jul 2022 11:32:27 -0300 Subject: [PATCH] Fix logic for address mismatch log --- react/selectors/fields.ts | 2 +- react/validateAddress.test.ts | 106 +++++++++++++++++++++++++++++++--- react/validateAddress.ts | 27 +++------ 3 files changed, 106 insertions(+), 29 deletions(-) diff --git a/react/selectors/fields.ts b/react/selectors/fields.ts index b75d8225..7aff6618 100644 --- a/react/selectors/fields.ts +++ b/react/selectors/fields.ts @@ -30,7 +30,7 @@ function isGeolocationRule(rule: Rule): rule is GeolocationRule { return !('name' in rule) } -export function getField(fieldName: Fields, rules: Rules) { +export function getField(fieldName: Fields, rules: Rules): Rule | undefined { if ('fields' in rules) { return rules.fields.find((field) => field.name === fieldName) } diff --git a/react/validateAddress.test.ts b/react/validateAddress.test.ts index c18b3391..bcbb83d1 100644 --- a/react/validateAddress.test.ts +++ b/react/validateAddress.test.ts @@ -21,6 +21,7 @@ import { import * as mockMetrics from './metrics' import type { PostalCodeRules } from './types/rules' import type { AddressWithValidation, FillableFields } from './types/address' +import { addNewField } from './transforms/address' jest.mock('./metrics', () => ({ logGeolocationAddressMismatch: jest.fn(), @@ -451,10 +452,42 @@ describe('Geolocation', () => { >).mockClear() }) + it("should not log if there's no mismatch", () => { + const rules: PostalCodeRules = { + country: 'ARG', + abbr: 'AR', + fields: [ + { + name: 'state' as const, + label: 'state', + required: true, + options: ['Santa Fe'], + }, + { + name: 'city' as const, + label: 'city', + required: true, + basedOn: 'state' as const, + optionsMap: { 'Santa Fe': ['Rosario'] }, + }, + ], + } + + const validOption = validateField( + geolocationAddress.state.value, + 'state', + geolocationAddress, + rules + ) + + expect(validOption.valid).toBe(true) + expect(mockMetrics.logGeolocationAddressMismatch).toBeCalledTimes(0) + }) + it('should log state mismatch', () => { - const rules = { - country: 'BRA', - abbr: 'BR', + const rules: PostalCodeRules = { + country: 'ARG', + abbr: 'AR', fields: [ { name: 'state' as const, @@ -484,9 +517,9 @@ describe('Geolocation', () => { }) it('should log city mismatch', () => { - const rules = { - country: 'BRA', - abbr: 'BR', + const rules: PostalCodeRules = { + country: 'ARG', + abbr: 'AR', fields: [ { name: 'state' as const, @@ -517,9 +550,9 @@ describe('Geolocation', () => { }) it('should not log city mismatch if state is also a mismatch', () => { - const rules = { - country: 'BRA', - abbr: 'BR', + const rules: PostalCodeRules = { + country: 'ARG', + abbr: 'AR', fields: [ { name: 'state' as const, @@ -548,6 +581,61 @@ describe('Geolocation', () => { expect(validOption.valid).toBe(false) expect(mockMetrics.logGeolocationAddressMismatch).toBeCalledTimes(0) }) + + it('should log neighborhood mismatch based on state', () => { + const rules: PostalCodeRules = { + country: 'CHL', + abbr: 'CL', + fields: [ + { + name: 'state', + label: 'state', + required: true, + options: ['Región Metropolitana'], + level: 1, + }, + { + name: 'neighborhood', + label: 'neighborhood', + required: true, + optionsMap: { 'Región Metropolitana': ['Alhué'] }, + basedOn: 'state', + level: 2, + }, + { + name: 'city', + label: 'state', + required: true, + }, + ], + } + + const myAddress = addNewField( + ({ + state: { value: 'Región Metropolitana' }, + neighborhood: { value: 'Non-existent neighborhood' }, + city: { value: 'Talca' }, + } as unknown) as AddressWithValidation, + 'geolocationAutoCompleted', + true + ) + + const result = validateField( + myAddress.neighborhood.value, + 'neighborhood', + myAddress, + rules + ) + + expect(result.valid).toBe(false) + expect(mockMetrics.logGeolocationAddressMismatch).toHaveBeenCalledTimes(1) + expect(mockMetrics.logGeolocationAddressMismatch).toHaveBeenCalledWith( + expect.objectContaining({ + fieldValue: 'Non-existent neighborhood', + fieldName: 'neighborhood', + }) + ) + }) }) describe('isValidAddress()', () => { diff --git a/react/validateAddress.ts b/react/validateAddress.ts index 14bc9ec8..e62263e4 100644 --- a/react/validateAddress.ts +++ b/react/validateAddress.ts @@ -381,31 +381,20 @@ function logIfGeolocationAddressMismatchExists( address: AddressWithValidation, rules: PostalCodeRules ) { - if (name === 'city') { - const stateField = getField('state', rules) as PostalCodeFieldRule - - const stateResult = validateOptions( - address.state.value, - stateField, - address, - rules - ) + const field = getField(name, rules) - if (!stateResult.valid) { - return - } - } + if (field && 'basedOn' in field && field.basedOn) { + const { basedOn } = field + const basedOnField = getField(basedOn, rules) as PostalCodeFieldRule - if (name === 'neighborhood') { - const cityField = getField('city', rules) as PostalCodeFieldRule - const cityResult = validateOptions( - address.city.value, - cityField, + const result = validateOptions( + address[basedOn].value, + basedOnField, address, rules ) - if (!cityResult.valid) { + if (!result.valid) { return } }