From 5fdec1c5e174dbb69838d90f93326f5ea577149c Mon Sep 17 00:00:00 2001 From: Tore Brede <Tore.Brede@uib.no> Date: Tue, 15 Mar 2022 17:48:52 +0100 Subject: [PATCH] GREG-233: Prohibiting user form continuing with invalid phone number --- .../guest/register/steps/register.test.tsx | 108 ++++++++++++++++++ .../routes/guest/register/steps/register.tsx | 35 +++++- 2 files changed, 137 insertions(+), 6 deletions(-) diff --git a/frontend/src/routes/guest/register/steps/register.test.tsx b/frontend/src/routes/guest/register/steps/register.test.tsx index bb090e97..dfecd65c 100644 --- a/frontend/src/routes/guest/register/steps/register.test.tsx +++ b/frontend/src/routes/guest/register/steps/register.test.tsx @@ -288,3 +288,111 @@ test('Gender not required to be set if gender field is not showing', async () => } ) }) + +test('Guest not allowed to proceed in wizard if phone number is not valid', async () => { + const nextHandler = jest.fn() + + const allFeaturesOn = { + displayContactAtUnit: true, + displayComment: true, + displayContactAtUnitGuestInput: true, + showGenderFieldForGuest: true, + } + + const formData: GuestRegisterData = { + firstName: 'Test', + lastName: 'Test2', + mobilePhoneCountry: 'NO', + mobilePhone: '50', + nationalIdNumber: '', + passportNumber: '12345678', + passportNationality: 'NO', + dateOfBirth: addYears(-20)(new Date()), + gender: 'male', + } + + const testData = getEmptyGuestData() + testData.gender = 'male' + const submitMock = jest.fn() + + // Need this to be able to call on the submit-method on the form + const reference = { + current: { + doSubmit: submitMock, + }, + } + + render( + <FeatureContext.Provider value={allFeaturesOn}> + <LocalizationProvider dateAdapter={AdapterDateFns}> + <GuestRegisterStep + nextHandler={nextHandler} + initialGuestData={testData} + registerData={formData} + ref={reference} + /> + </LocalizationProvider> + </FeatureContext.Provider> + ) + + reference.current?.doSubmit() + + // TODO It is stupid to wait like this, but I have not found a wait-for function in jest + await new Promise((r) => setTimeout(r, 500)) + + expect(nextHandler.mock.calls.length).toBe(0) +}) + +test('Guest allowed to proceed in wizard if data is valid', async () => { + const nextHandler = jest.fn() + + const allFeaturesOn = { + displayContactAtUnit: true, + displayComment: true, + displayContactAtUnitGuestInput: true, + showGenderFieldForGuest: true, + } + + const formData: GuestRegisterData = { + firstName: 'Test', + lastName: 'Test2', + mobilePhoneCountry: 'NO', + mobilePhone: '97543992', + nationalIdNumber: '', + passportNumber: '12345678', + passportNationality: 'NO', + dateOfBirth: addYears(-20)(new Date()), + gender: 'male', + } + + const testData = getEmptyGuestData() + testData.gender = 'male' + const submitMock = jest.fn() + + // Need this to be able to call on the submit-method on the form + const reference = { + current: { + doSubmit: submitMock, + }, + } + + render( + <FeatureContext.Provider value={allFeaturesOn}> + <LocalizationProvider dateAdapter={AdapterDateFns}> + <GuestRegisterStep + nextHandler={nextHandler} + initialGuestData={testData} + registerData={formData} + ref={reference} + /> + </LocalizationProvider> + </FeatureContext.Provider> + ) + + reference.current?.doSubmit() + + // TODO It is stupid to wait like this, but I have not found a wait-for function in jest + await new Promise((r) => setTimeout(r, 500)) + + expect(nextHandler.mock.calls.length).toBe(1) +}) diff --git a/frontend/src/routes/guest/register/steps/register.tsx b/frontend/src/routes/guest/register/steps/register.tsx index c14ad288..5463e401 100644 --- a/frontend/src/routes/guest/register/steps/register.tsx +++ b/frontend/src/routes/guest/register/steps/register.tsx @@ -108,6 +108,16 @@ const GuestRegisterStep = forwardRef( } } + const validatePhoneNumber = ( + countryCodeCallingCode: CountryCallingCode | undefined, + phoneNumberToValidate: string + ) => { + const phoneNumberWithCountryCode = `+${getCountryCallingCode( + countryCodeCallingCode as CountryCode + )}${phoneNumberToValidate}` + return isValidMobilePhoneNumber(phoneNumberWithCountryCode) + } + const submit: SubmitHandler<GuestRegisterData> = async (data) => { console.log('submit data is', data) const result = await trigger() @@ -122,6 +132,22 @@ const GuestRegisterStep = forwardRef( // Phone checks passed, clear error message setPhoneErrorState('') + // Because the phone number validation is handled outside the hook form validation + // it is necessary to do another pass here to make sure the phone number entered + // really is valid + const validationMessage = validatePhoneNumber( + countryCode, + data.mobilePhone + ) + + if (validationMessage !== true) { + setError('mobilePhone', { + type: 'manual', + message: validationMessage || undefined, + }) + return + } + if ( !data.nationalIdNumber && !data.passportNumber && @@ -196,12 +222,9 @@ const GuestRegisterStep = forwardRef( // The country code and the rest of the mobile number are in two fields, so cannot // register the field directly in form, but need to have extra logic defined // to combine the values before writing them to the form handling - - const phoneNumberWithCountryCode = `+${getCountryCallingCode( - countryCode as CountryCode - )}${value.target.value}` - const isValidPhoneNumber = isValidMobilePhoneNumber( - phoneNumberWithCountryCode + const isValidPhoneNumber = validatePhoneNumber( + countryCode, + value.target.value ) if (isValidPhoneNumber === true) { -- GitLab