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