From 2fa67877e95bb8fdd13f9e65d77decd0ca34826a Mon Sep 17 00:00:00 2001 From: Tore Brede <tore.brede@uib.no> Date: Wed, 6 Jul 2022 11:13:58 +0200 Subject: [PATCH] GREG-283: Fixing issue where default value for mobile country code was set on every rerender --- .../guest/register/steps/register.test.tsx | 94 ++++++++++++++++--- .../routes/guest/register/steps/register.tsx | 29 +++--- 2 files changed, 95 insertions(+), 28 deletions(-) diff --git a/frontend/src/routes/guest/register/steps/register.test.tsx b/frontend/src/routes/guest/register/steps/register.test.tsx index b5ac1b52..98fa1266 100644 --- a/frontend/src/routes/guest/register/steps/register.test.tsx +++ b/frontend/src/routes/guest/register/steps/register.test.tsx @@ -9,6 +9,8 @@ import GuestRegisterStep from './register' import { GuestRegisterData } from '../enteredGuestData' import AuthenticationMethod from '../authenticationMethod' import { GuestInviteInformation } from '../guestDataForm' +import userEvent from '@testing-library/user-event' +import { fireEvent } from '@testing-library/react' function getEmptyGuestData(): GuestInviteInformation { return { @@ -43,7 +45,7 @@ test('Guest register page showing passport field on manual registration', async initialGuestData={getEmptyGuestData()} registerData={null} /> - </LocalizationProvider> + </LocalizationProvider>, ) await waitFor(() => { @@ -68,7 +70,7 @@ test('Name not editable if present and invite is Feide', async () => { initialGuestData={testData} registerData={null} /> - </LocalizationProvider> + </LocalizationProvider>, ) await waitFor(() => { @@ -92,7 +94,7 @@ test('Name editable if missing and invite is Feide', async () => { initialGuestData={testData} registerData={null} /> - </LocalizationProvider> + </LocalizationProvider>, ) await waitFor(() => { @@ -117,7 +119,7 @@ test('Identifier fields disabled if invite is Feide and national ID present', as initialGuestData={testData} registerData={null} /> - </LocalizationProvider> + </LocalizationProvider>, ) await waitFor(() => { @@ -143,7 +145,7 @@ test('Identifier fields enabled if invite is Feide but national ID number missin initialGuestData={testData} registerData={null} /> - </LocalizationProvider> + </LocalizationProvider>, ) await waitFor(() => { @@ -169,7 +171,7 @@ test('Identifier fields disabled and name fields enabled if invite is ID-porten' initialGuestData={testData} registerData={null} /> - </LocalizationProvider> + </LocalizationProvider>, ) await waitFor(() => { @@ -222,14 +224,14 @@ test('Gender required to be set if gender field is showing', async () => { ref={reference} /> </LocalizationProvider> - </FeatureContext.Provider> + </FeatureContext.Provider>, ) reference.current?.doSubmit() // The validation should fail for gender since to value has been set const validationMessage = await waitFor(() => - screen.getByText('validation.genderIsRequired') + screen.getByText('validation.genderIsRequired'), ) expect(validationMessage).toBeInTheDocument() }) @@ -275,19 +277,19 @@ test('Gender not required to be set if gender field is not showing', async () => ref={reference} /> </LocalizationProvider> - </FeatureContext.Provider> + </FeatureContext.Provider>, ) reference.current?.doSubmit() await waitFor( () => { expect( - screen.queryByText('validation.genderIsRequired') + screen.queryByText('validation.genderIsRequired'), ).not.toBeInTheDocument() }, { timeout: 5000, - } + }, ) }) @@ -334,7 +336,7 @@ test('Guest not allowed to proceed in wizard if phone number is not valid', asyn ref={reference} /> </LocalizationProvider> - </FeatureContext.Provider> + </FeatureContext.Provider>, ) await act(async () => reference.current?.doSubmit()) @@ -385,7 +387,7 @@ test('Guest allowed to proceed in wizard if data is valid', async () => { ref={reference} /> </LocalizationProvider> - </FeatureContext.Provider> + </FeatureContext.Provider>, ) await act(async () => reference.current?.doSubmit()) @@ -452,3 +454,69 @@ test('Default country code gets set in form values', async () => { // @ts-ignore expect(guestRegisterData.mobilePhoneCountry).toEqual('NO') }) + + +test('Foreign country code gets set in form values', async () => { + // This stores the data sent from the form when the user clicks submit + let guestRegisterData: GuestRegisterData | null = null + const nextHandler = (registerData: GuestRegisterData) => { + guestRegisterData = registerData + + } + + + // +393892778451 + + const allFeaturesOn = { + displayContactAtUnit: true, + displayComment: true, + displayContactAtUnitGuestInput: true, + showGenderFieldForGuest: true, + } + + const formData: GuestRegisterData = { + firstName: 'Test', + lastName: 'Test2', + mobilePhoneCountry: '', + mobilePhone: '3892778472', + nationalIdNumber: '', + passportNumber: '123456', + passportNationality: 'IT', + 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>, + ) + + const countryCodeInput = screen.getByTestId('phone-country-code-select-inner') + fireEvent.change(countryCodeInput, { target: { value: 'IT' } }) + + expect(guestRegisterData).toBeNull() + await act(async () => reference.current?.doSubmit()) + // Check that the mobile phone country code has been set to what was entered + // @ts-ignore + expect(guestRegisterData.mobilePhoneCountry).toEqual('IT') +}) diff --git a/frontend/src/routes/guest/register/steps/register.tsx b/frontend/src/routes/guest/register/steps/register.tsx index 6b3b195d..2cca718c 100644 --- a/frontend/src/routes/guest/register/steps/register.tsx +++ b/frontend/src/routes/guest/register/steps/register.tsx @@ -65,7 +65,7 @@ const GuestRegisterStep = forwardRef( const [countryCode, setCountryCode] = useState<CountryCallingCode>(defaultCountryCode) const [passportNationality, setPassportNationality] = useState< string | undefined - >(undefined) + >(undefined) // Set suggestion for the gender field if gender is not already given in the input const [gender, setGender] = useState<string>( @@ -107,17 +107,6 @@ const GuestRegisterStep = forwardRef( } } - if (!registerData || !registerData.mobilePhoneCountry) { - // If there is no country code set in the registered data - // then set the default value. This is necessary even though - // the country code is set in a state variable above, because - // that does not cause the country code to be added to the - // form values by itself. If it was not set here it would be - // blank in the form even though the default value is shown - // in the select menu - setValue('mobilePhoneCountry', defaultCountryCode) - } - const validatePhoneNumber = ( countryCodeCallingCode: CountryCallingCode | undefined, phoneNumberToValidate: string @@ -141,7 +130,7 @@ const GuestRegisterStep = forwardRef( // it is necessary to do another pass here to make sure the phone number entered // really is valid const validationMessage = validatePhoneNumber( - countryCode, + data.mobilePhoneCountry, data.mobilePhone ) @@ -215,10 +204,10 @@ const GuestRegisterStep = forwardRef( const handleCountryCodeChange = (event: SelectChangeEvent) => { // There should always be a value in the event since it is // not possible to select a blank field in the select menu - // for country codes + // for country code const countryCodeType = event.target.value as CountryCode setCountryCode(countryCodeType) - setValue('mobilePhoneCountry', countryCodeType) + setValue('mobilePhoneCountry', countryCodeType, { shouldDirty: true, shouldTouch: true }) } const handleMobilePhoneChange = (value: any) => { @@ -263,8 +252,17 @@ const GuestRegisterStep = forwardRef( if (registerData?.passportNationality) { setPassportNationality(registerData.passportNationality) } + // Need to set both country code in state and in form + // because of the way the validation and form handling is done. + // It would be cleaner if it somehow is possible to only + // have the value in the form if (registerData?.mobilePhoneCountry) { setCountryCode(registerData.mobilePhoneCountry) + setValue('mobilePhoneCountry', registerData.mobilePhoneCountry) + } + else { + setCountryCode(defaultCountryCode) + setValue('mobilePhoneCountry', defaultCountryCode) } if (gender !== '') { @@ -552,6 +550,7 @@ const GuestRegisterStep = forwardRef( helperText={ errors.mobilePhone && errors.mobilePhone.message } + data-testid="mobile-phone-number-input" onChange={handleMobilePhoneChange} /> )} -- GitLab