From 17f95096b66dd98de165963426dfcbdde2a1c7a0 Mon Sep 17 00:00:00 2001
From: Tore Brede <Tore.Brede@uib.no>
Date: Thu, 17 Feb 2022 16:11:54 +0100
Subject: [PATCH] GREG-215: Make gender required if field is showing

---
 frontend/public/locales/en/common.json        |   3 +-
 frontend/public/locales/nb/common.json        |   3 +-
 frontend/public/locales/nn/common.json        |   3 +-
 .../guest/register/steps/register.test.tsx    | 115 +++++++++++++++++-
 .../routes/guest/register/steps/register.tsx  |  64 ++++++----
 5 files changed, 158 insertions(+), 30 deletions(-)

diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json
index 8ce73823..9a60da89 100644
--- a/frontend/public/locales/en/common.json
+++ b/frontend/public/locales/en/common.json
@@ -121,7 +121,8 @@
     "phoneNumberAndCountryCode": "Both country code and phone number must be set",
     "passportNationalityAndNumber": "Both passport nationality and number need to be set",
     "doubleIdentity": "*You have input both national ID and passport. Please choose only one.",
-    "nationalIdOrPassport": "National ID or passport information need to be entered"
+    "nationalIdOrPassport": "National ID or passport information need to be entered",
+    "genderIsRequired": "Gender is required"
   },
   "button": {
     "yes": "Yes",
diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json
index 204f5074..75ffadd0 100644
--- a/frontend/public/locales/nb/common.json
+++ b/frontend/public/locales/nb/common.json
@@ -121,7 +121,8 @@
     "phoneNumberAndCountryCode": "Både landkode og telefonnummer må være satt",
     "passportNationalityAndNumber": "Både passnasjonalitet og nummer må være satt",
     "doubleIdentity": "*Du har fylt inn begge feltene over. Bruk kun ett av de.",
-    "nationalIdOrPassport": "Fødselsnummer/D-nummer eller passinformasjon må spesifiseres"
+    "nationalIdOrPassport": "Fødselsnummer/D-nummer eller passinformasjon må spesifiseres",
+    "genderIsRequired": "Kjønn er obligatorisk"
   },
   "button": {
     "yes": "Ja",
diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json
index 42a7248e..4eefad7f 100644
--- a/frontend/public/locales/nn/common.json
+++ b/frontend/public/locales/nn/common.json
@@ -121,7 +121,8 @@
     "phoneNumberAndCountryCode": "Både landkode og telefonnummer må vere satt",
     "passportNationalityAndNumber": "Både passnasjonalitet og nummer må vere satt",
     "doubleIdentity": "*Du har fylt inn begge felta over. Bruk berre eitt av dei.",
-    "nationalIdOrPassport": "Fødselsnummer/D-nummer eller passinformasjon må spesifiserast"
+    "nationalIdOrPassport": "Fødselsnummer/D-nummer eller passinformasjon må spesifiserast",
+    "genderIsRequired": "Kjønn er obligatorisk"
   },
   "button": {
     "yes": "Ja",
diff --git a/frontend/src/routes/guest/register/steps/register.test.tsx b/frontend/src/routes/guest/register/steps/register.test.tsx
index d88a1312..bb090e97 100644
--- a/frontend/src/routes/guest/register/steps/register.test.tsx
+++ b/frontend/src/routes/guest/register/steps/register.test.tsx
@@ -1,7 +1,8 @@
-import React from 'react'
 import { render, screen, waitFor } from 'test-utils'
 import AdapterDateFns from '@mui/lab/AdapterDateFns'
 import { LocalizationProvider } from '@mui/lab'
+import { addYears } from 'date-fns/fp'
+import { FeatureContext } from 'contexts'
 import GuestRegisterStep from './register'
 import { GuestRegisterData } from '../enteredGuestData'
 import AuthenticationMethod from '../authenticationMethod'
@@ -175,3 +176,115 @@ test('Identifier fields disabled and name fields enabled if invite is ID-porten'
     expect(screen.queryByTestId('passport-nationality-input')).toBeEnabled()
   })
 })
+
+test('Gender required to be set if gender field is showing', async () => {
+  const nextHandler = (registerData: GuestRegisterData) => {
+    console.log(`Entered data: ${registerData}`)
+  }
+
+  const allFeaturesOn = {
+    displayContactAtUnit: true,
+    displayComment: true,
+    displayContactAtUnitGuestInput: true,
+    showGenderFieldForGuest: true,
+  }
+
+  const formData: GuestRegisterData = {
+    firstName: 'Test',
+    lastName: 'Test2',
+    mobilePhoneCountry: 'NO',
+    mobilePhone: '97543980',
+    nationalIdNumber: '',
+    passportNumber: '12345678',
+    passportNationality: 'NO',
+    dateOfBirth: addYears(-20)(new Date()),
+    gender: null,
+  }
+
+  const testData = getEmptyGuestData()
+
+  // Need this to be able to call on the submit-method on the form
+  const reference = {
+    current: {
+      doSubmit: jest.fn(),
+    },
+  }
+
+  render(
+    <FeatureContext.Provider value={allFeaturesOn}>
+      <LocalizationProvider dateAdapter={AdapterDateFns}>
+        <GuestRegisterStep
+          nextHandler={nextHandler}
+          initialGuestData={testData}
+          registerData={formData}
+          ref={reference}
+        />
+      </LocalizationProvider>
+    </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')
+  )
+  expect(validationMessage).toBeInTheDocument()
+})
+
+test('Gender not required to be set if gender field is not showing', async () => {
+  const nextHandler = (registerData: GuestRegisterData) => {
+    console.log(`Entered data: ${registerData}`)
+  }
+
+  const showGenderFieldOff = {
+    displayContactAtUnit: true,
+    displayComment: true,
+    displayContactAtUnitGuestInput: true,
+    showGenderFieldForGuest: false,
+  }
+
+  const formData: GuestRegisterData = {
+    firstName: 'Test',
+    lastName: 'Test2',
+    mobilePhoneCountry: 'NO',
+    mobilePhone: '97543980',
+    nationalIdNumber: '',
+    passportNumber: '12345678',
+    passportNationality: 'NO',
+    dateOfBirth: addYears(-20)(new Date()),
+    gender: null,
+  }
+
+  const testData = getEmptyGuestData()
+  const reference = {
+    current: {
+      doSubmit: jest.fn(),
+    },
+  }
+
+  render(
+    <FeatureContext.Provider value={showGenderFieldOff}>
+      <LocalizationProvider dateAdapter={AdapterDateFns}>
+        <GuestRegisterStep
+          nextHandler={nextHandler}
+          initialGuestData={testData}
+          registerData={formData}
+          ref={reference}
+        />
+      </LocalizationProvider>
+    </FeatureContext.Provider>
+  )
+
+  reference.current?.doSubmit()
+  await waitFor(
+    () => {
+      expect(
+        screen.queryByText('validation.genderIsRequired')
+      ).not.toBeInTheDocument()
+    },
+    {
+      timeout: 5000,
+    }
+  )
+})
diff --git a/frontend/src/routes/guest/register/steps/register.tsx b/frontend/src/routes/guest/register/steps/register.tsx
index efe84feb..74f02396 100644
--- a/frontend/src/routes/guest/register/steps/register.tsx
+++ b/frontend/src/routes/guest/register/steps/register.tsx
@@ -68,7 +68,7 @@ const GuestRegisterStep = forwardRef(
       string | undefined
     >(undefined)
 
-    // Set suggestion for gender field is a gender is not already given in the input
+    // Set suggestion for the gender field if gender is not already given in the input
     const [gender, setGender] = useState<string>(
       !initialGuestData.gender || !initialGuestData.gender.trim()
         ? extractGenderOrBlank(initialGuestData.fnr)
@@ -77,6 +77,7 @@ const GuestRegisterStep = forwardRef(
 
     const [idErrorState, setIdErrorState] = useState<string>('')
     const [phoneErrorState, setPhoneErrorState] = useState<string>('')
+    const [genderErrorState, setGenderErrorState] = useState<string>('')
     const { displayContactAtUnitGuestInput } = useContext(FeatureContext)
 
     console.log('register step registerData', registerData)
@@ -158,6 +159,12 @@ const GuestRegisterStep = forwardRef(
       }
       setIdErrorState('')
 
+      if (showGenderFieldForGuest && !gender) {
+        setGenderErrorState(t('validation.genderIsRequired'))
+        return
+      }
+      setGenderErrorState('')
+
       console.log('register submit errors', errors)
 
       if (!Object.keys(errors).length) {
@@ -369,31 +376,36 @@ const GuestRegisterStep = forwardRef(
               />
 
               {showGenderFieldForGuest && (
-                <Select
-                  sx={{
-                    maxHeight: '2.5rem',
-                    minWidth: '5rem',
-                    marginRight: '0.5rem',
-                  }}
-                  labelId="gender-select"
-                  id="gender-select-id"
-                  displayEmpty
-                  onChange={handleGenderChange}
-                  value={gender}
-                  renderValue={(selected: any) => {
-                    if (!selected) {
-                      return t('input.gender')
-                    }
-                    return t(`input.${selected}`)
-                  }}
-                >
-                  {/* Keep it simple and hardcode the gender values */}
-                  <MenuItem disabled value="">
-                    {t('input.gender')}
-                  </MenuItem>
-                  <MenuItem value="male">{t('input.male')}</MenuItem>
-                  <MenuItem value="female">{t('input.female')}</MenuItem>
-                </Select>
+                <>
+                  <Select
+                    sx={{
+                      maxHeight: '2.5rem',
+                      minWidth: '5rem',
+                      marginRight: '0.5rem',
+                    }}
+                    labelId="gender-select"
+                    id="gender-select-id"
+                    displayEmpty
+                    onChange={handleGenderChange}
+                    value={gender}
+                    renderValue={(selected: any) => {
+                      if (!selected) {
+                        return t('input.gender')
+                      }
+                      return t(`input.${selected}`)
+                    }}
+                  >
+                    {/* Keep it simple and hardcode the gender values */}
+                    <MenuItem disabled value="">
+                      {t('input.gender')}
+                    </MenuItem>
+                    <MenuItem value="male">{t('input.male')}</MenuItem>
+                    <MenuItem value="female">{t('input.female')}</MenuItem>
+                  </Select>
+                  {genderErrorState && (
+                    <Typography color="error">{genderErrorState}</Typography>
+                  )}
+                </>
               )}
 
               <Controller
-- 
GitLab