From b5c0d16251e8cfe3b9c88cc282775f17b0ec3a3a Mon Sep 17 00:00:00 2001
From: Bastien DUMONT <bdumont@grandlyon.com>
Date: Wed, 9 Oct 2024 11:29:27 +0200
Subject: [PATCH] apple to GRDf & fix tests

---
 .../ExpiredConsentModal.spec.tsx              |  2 +-
 .../ExpiredConsentModal.tsx                   | 28 +--------
 .../GRDFConnect/GrdfConnectView.tsx           | 59 ++++++++++++-------
 .../SGEConnect/SgeConnectView.spec.tsx        | 31 +++++-----
 .../Connection/SGEConnect/SgeConnectView.tsx  | 19 +-----
 .../SGEConnect/StepAddress.spec.tsx           | 18 ++----
 .../SGEConnect/StepConsent.spec.tsx           | 14 +----
 .../SGEConnect/StepIdentityAndPdl.spec.tsx    | 19 ++----
 .../__snapshots__/StepAddress.spec.tsx.snap   |  8 +--
 src/components/Connection/useForm.tsx         | 15 +++++
 tests/__mocks__/forms.mock.ts                 | 14 +++++
 11 files changed, 110 insertions(+), 117 deletions(-)
 create mode 100644 tests/__mocks__/forms.mock.ts

diff --git a/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.spec.tsx b/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.spec.tsx
index ced72db8d..c50602afd 100644
--- a/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.spec.tsx
+++ b/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.spec.tsx
@@ -68,7 +68,7 @@ describe('ExpiredConsentModal component', () => {
     await act(async () => {
       await userEvent.click(screen.getByText('consent_outdated.yes'))
     })
-    expect(mockAppDispatch).toHaveBeenCalledTimes(2)
+    expect(mockAppDispatch).toHaveBeenCalledTimes(1)
     expect(mockedNavigate).toHaveBeenCalledTimes(1)
   })
   it('should click on close modal', async () => {
diff --git a/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.tsx b/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.tsx
index 8959ba88e..b01fcb166 100644
--- a/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.tsx
+++ b/src/components/Connection/ExpiredConsentModal/ExpiredConsentModal.tsx
@@ -7,14 +7,10 @@ import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
 import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton'
 import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
 import { FluidType } from 'enums'
-import { AccountSgeData } from 'models'
 import React, { useCallback } from 'react'
 import { useNavigate } from 'react-router-dom'
-import {
-  setShouldRefreshConsent,
-  updateSgeStore,
-} from 'store/global/global.slice'
-import { useAppDispatch, useAppSelector } from 'store/hooks'
+import { setShouldRefreshConsent } from 'store/global/global.slice'
+import { useAppDispatch } from 'store/hooks'
 import { getFluidName } from 'utils/utils'
 import './expiredConsentModal.scss'
 
@@ -34,26 +30,8 @@ const ExpiredConsentModal = ({
   const { t } = useI18n()
   const navigate = useNavigate()
   const dispatch = useAppDispatch()
-  const { fluidStatus } = useAppSelector(state => state.ecolyo.global)
   const launchUpdateConsent = useCallback(() => {
     if (fluidType === FluidType.ELECTRICITY) {
-      const accountData = fluidStatus[FluidType.ELECTRICITY].connection.account
-        ?.auth as AccountSgeData
-      // store the previous account data since the onDelete will remove account from DB
-      dispatch(
-        updateSgeStore({
-          currentStep: 0,
-          firstName: accountData.firstname,
-          lastName: accountData.lastname,
-          pdl: parseInt(accountData.pointId),
-          address: accountData.address,
-          zipCode: parseInt(accountData.postalCode),
-          city: accountData.city,
-          dataConsent: true,
-          pdlConfirm: true,
-          shouldLaunchAccount: true,
-        })
-      )
       dispatch(setShouldRefreshConsent(true))
       toggleModal()
       navigate(`/consumption/${FluidType[fluidType].toLocaleLowerCase()}`)
@@ -62,7 +40,7 @@ const ExpiredConsentModal = ({
       toggleModal()
       navigate(`/connect/${FluidType[fluidType].toLocaleLowerCase()}`)
     }
-  }, [dispatch, fluidStatus, fluidType, navigate, toggleModal])
+  }, [dispatch, fluidType, navigate, toggleModal])
 
   return (
     <Dialog
diff --git a/src/components/Connection/GRDFConnect/GrdfConnectView.tsx b/src/components/Connection/GRDFConnect/GrdfConnectView.tsx
index 9661de4e1..e26af2bc9 100644
--- a/src/components/Connection/GRDFConnect/GrdfConnectView.tsx
+++ b/src/components/Connection/GRDFConnect/GrdfConnectView.tsx
@@ -11,6 +11,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
 import { useNavigate } from 'react-router-dom'
 import { useAppSelector } from 'store/hooks'
 import '../connection.scss'
+import { FormData, useFormData } from '../useForm'
 import StepConsent from './StepConsent'
 import { StepIdentity } from './StepIdentity'
 
@@ -18,11 +19,21 @@ export enum GrdfStep {
   Identity,
   Consent,
 }
+
+const createInitialState = (formData?: FormData): AccountGRDFData => ({
+  lastname: formData?.lastName ?? '',
+  firstname: formData?.firstName ?? '',
+  pce: formData?.pce ?? '',
+  postalCode: formData?.zipCode ?? '',
+  email: '',
+})
+
 /**
  * http://ecolyo.cozy.tools:8080/#/connect/gas
  */
 export const GrdfConnectView = () => {
   const navigate = useNavigate()
+  const { formData } = useFormData()
   const { instanceSettings } = useUserInstanceSettings()
   const { fluidStatus } = useAppSelector(state => state.ecolyo.global)
   const currentFluidStatus = fluidStatus[FluidType.GAS]
@@ -30,13 +41,9 @@ export const GrdfConnectView = () => {
 
   const [launchConnection, setLaunchConnection] = useState(false)
   const [currentStep, setCurrentStep] = useState<GrdfStep>(GrdfStep.Identity)
-  const [formData, setFormData] = useState<AccountGRDFData>({
-    lastname: '',
-    firstname: '',
-    email: '',
-    postalCode: '',
-    pce: '',
-  })
+  const [grdfState, setGrdfState] = useState<AccountGRDFData>(
+    createInitialState()
+  )
   const [formConsent, setFormConsent] = useState({
     dataConsent: false,
     pceConfirm: false,
@@ -48,13 +55,25 @@ export const GrdfConnectView = () => {
   }
 
   const [connect, update] = useKonnectorAuth(FluidType.GAS, {
-    grdfAuthData: formData,
+    grdfAuthData: grdfState,
   })
 
   useEffect(() => {
-    setFormData(prev => ({ ...prev, email: instanceSettings.email ?? '' }))
+    setGrdfState(prev => ({ ...prev, email: instanceSettings.email ?? '' }))
   }, [instanceSettings])
 
+  useEffect(
+    function applyFormData() {
+      if (formData) {
+        setGrdfState(prevState => ({
+          ...prevState,
+          ...createInitialState(formData),
+        }))
+      }
+    },
+    [formData]
+  )
+
   useEffect(() => {
     async function launchConnect() {
       if (launchConnection) {
@@ -74,11 +93,11 @@ export const GrdfConnectView = () => {
   const isNextValid = useCallback(() => {
     if (currentStep === GrdfStep.Identity) {
       return (
-        formData.firstname !== '' &&
-        formData.lastname !== '' &&
-        formData.postalCode !== '' &&
-        formData.email.includes('@') &&
-        formData.pce.length === 14
+        grdfState.firstname !== '' &&
+        grdfState.lastname !== '' &&
+        grdfState.postalCode !== '' &&
+        grdfState.email.includes('@') &&
+        grdfState.pce.length === 14
       )
     } else if (currentStep === GrdfStep.Consent) {
       return formConsent.dataConsent && formConsent.pceConfirm
@@ -88,11 +107,11 @@ export const GrdfConnectView = () => {
     currentStep,
     formConsent.dataConsent,
     formConsent.pceConfirm,
-    formData.email,
-    formData.firstname,
-    formData.lastname,
-    formData.pce,
-    formData.postalCode,
+    grdfState.email,
+    grdfState.firstname,
+    grdfState.lastname,
+    grdfState.pce,
+    grdfState.postalCode,
   ])
 
   const handleNext = useCallback(() => {
@@ -113,7 +132,7 @@ export const GrdfConnectView = () => {
 
   const renderStep = (step: GrdfStep) => {
     if (step === GrdfStep.Identity) {
-      return <StepIdentity formData={formData} setFormData={setFormData} />
+      return <StepIdentity formData={grdfState} setFormData={setGrdfState} />
     } else {
       return (
         <StepConsent
diff --git a/src/components/Connection/SGEConnect/SgeConnectView.spec.tsx b/src/components/Connection/SGEConnect/SgeConnectView.spec.tsx
index 3941573aa..f659b47e5 100644
--- a/src/components/Connection/SGEConnect/SgeConnectView.spec.tsx
+++ b/src/components/Connection/SGEConnect/SgeConnectView.spec.tsx
@@ -18,6 +18,23 @@ jest.mock('components/Hooks/useKonnectorAuth', () =>
   jest.fn(() => [mockConnect, mockUpdate])
 )
 
+// mock sge state with shouldLaunchAccount set to true
+jest.mock('components/Connection/useForm', () => ({
+  useFormData: jest.fn().mockReturnValue({ formData: {} }),
+  createInitialSgeState: jest.fn().mockReturnValue({
+    address: '',
+    lastName: '',
+    firstName: '',
+    pdl: 0,
+    zipCode: 0,
+    city: '',
+    currentStep: 0,
+    dataConsent: false,
+    shouldLaunchAccount: true,
+    pdlConfirm: false,
+  }),
+}))
+
 describe('SgeConnectView component', () => {
   beforeEach(() => {
     jest.clearAllMocks()
@@ -57,16 +74,6 @@ describe('SgeConnectView component', () => {
 
   describe('should test methods from useKonnectorAuth hook', () => {
     it('should launch account and trigger creation process', () => {
-      const store = createMockEcolyoStore({
-        global: {
-          ...mockGlobalState,
-          sgeConnect: {
-            ...mockGlobalState.sgeConnect,
-            shouldLaunchAccount: true,
-          },
-        },
-      })
-
       render(
         <Provider store={store}>
           <SgeConnectView />
@@ -79,10 +86,6 @@ describe('SgeConnectView component', () => {
         global: {
           ...mockGlobalState,
           fluidStatus: [SgeStatusWithAccount],
-          sgeConnect: {
-            ...mockGlobalState.sgeConnect,
-            shouldLaunchAccount: true,
-          },
         },
       })
       render(
diff --git a/src/components/Connection/SGEConnect/SgeConnectView.tsx b/src/components/Connection/SGEConnect/SgeConnectView.tsx
index 795c4ced6..32dc5d065 100644
--- a/src/components/Connection/SGEConnect/SgeConnectView.tsx
+++ b/src/components/Connection/SGEConnect/SgeConnectView.tsx
@@ -12,7 +12,7 @@ import { useNavigate } from 'react-router-dom'
 import { setShouldRefreshConsent } from 'store/global/global.slice'
 import { useAppDispatch, useAppSelector } from 'store/hooks'
 import '../connection.scss'
-import { useFormData, type FormData } from '../useForm'
+import { createInitialSgeState, useFormData } from '../useForm'
 import StepAddress from './StepAddress'
 import StepConsent from './StepConsent'
 import StepIdentityAndPdl from './StepIdentityAndPdl'
@@ -27,19 +27,6 @@ export type SGEKeysForm =
   | 'dataConsent'
   | 'pdlConfirm'
 
-const createInitialState = (formData?: FormData): SgeStore => ({
-  address: formData?.address ?? '',
-  lastName: formData?.lastName ?? '',
-  firstName: formData?.firstName ?? '',
-  pdl: formData?.pdl ? parseInt(formData.pdl) : null,
-  zipCode: formData?.zipCode ? parseInt(formData.zipCode) : null,
-  city: formData?.city ?? '',
-  currentStep: SgeStep.Address,
-  dataConsent: false,
-  shouldLaunchAccount: false,
-  pdlConfirm: false,
-})
-
 /**
  * http://ecolyo.cozy.tools:8080/#/connect/electricity
  */
@@ -49,7 +36,7 @@ const SgeConnectView = () => {
   const dispatch = useAppDispatch()
   const { formData } = useFormData()
   const [isLoading, setIsLoading] = useState(false)
-  const [sgeState, setSgeState] = useState<SgeStore>(createInitialState())
+  const [sgeState, setSgeState] = useState<SgeStore>(createInitialSgeState())
   const [currentStep, setCurrentStep] = useState<SgeStep>(
     SgeStep.IdentityAndPDL
   )
@@ -71,7 +58,7 @@ const SgeConnectView = () => {
       if (formData) {
         setSgeState(prevState => ({
           ...prevState,
-          ...createInitialState(formData),
+          ...createInitialSgeState(formData),
         }))
       }
     },
diff --git a/src/components/Connection/SGEConnect/StepAddress.spec.tsx b/src/components/Connection/SGEConnect/StepAddress.spec.tsx
index e7e1326c2..8ba9d9443 100644
--- a/src/components/Connection/SGEConnect/StepAddress.spec.tsx
+++ b/src/components/Connection/SGEConnect/StepAddress.spec.tsx
@@ -1,7 +1,7 @@
 import { act, render, screen } from '@testing-library/react'
 import { userEvent } from '@testing-library/user-event'
 import React from 'react'
-import { mockGlobalState } from 'tests/__mocks__/store'
+import { mockSgeState } from 'tests/__mocks__/forms.mock'
 import StepAddress from './StepAddress'
 
 const mockHandleChange = jest.fn()
@@ -9,10 +9,7 @@ const mockHandleChange = jest.fn()
 describe('StepAddress component', () => {
   it('should be rendered correctly', () => {
     const { container } = render(
-      <StepAddress
-        sgeState={mockGlobalState.sgeConnect}
-        onChange={mockHandleChange}
-      />
+      <StepAddress sgeState={mockSgeState} onChange={mockHandleChange} />
     )
     expect(container).toMatchSnapshot()
   })
@@ -20,10 +17,7 @@ describe('StepAddress component', () => {
   describe('should change inputs', () => {
     beforeEach(() => {
       render(
-        <StepAddress
-          sgeState={mockGlobalState.sgeConnect}
-          onChange={mockHandleChange}
-        />
+        <StepAddress sgeState={mockSgeState} onChange={mockHandleChange} />
       )
     })
     it('should change address value', async () => {
@@ -40,9 +34,9 @@ describe('StepAddress component', () => {
         name: 'auth.enedissgegrandlyon.zipCode',
       })
       await act(async () => {
-        await userEvent.type(input, '0')
+        await userEvent.type(input, '1')
       })
-      expect(mockHandleChange).toHaveBeenCalledWith('zipCode', '0', 5)
+      expect(mockHandleChange).toHaveBeenCalledWith('zipCode', '1', 5)
     })
 
     it('should change city value', async () => {
@@ -58,7 +52,7 @@ describe('StepAddress component', () => {
   it('should have an existing zipCode value', () => {
     render(
       <StepAddress
-        sgeState={{ ...mockGlobalState.sgeConnect, zipCode: 69200 }}
+        sgeState={{ ...mockSgeState, zipCode: 69200 }}
         onChange={mockHandleChange}
       />
     )
diff --git a/src/components/Connection/SGEConnect/StepConsent.spec.tsx b/src/components/Connection/SGEConnect/StepConsent.spec.tsx
index 642ebccb3..72fb90150 100644
--- a/src/components/Connection/SGEConnect/StepConsent.spec.tsx
+++ b/src/components/Connection/SGEConnect/StepConsent.spec.tsx
@@ -1,7 +1,7 @@
 import { render, screen } from '@testing-library/react'
 import { userEvent } from '@testing-library/user-event'
 import React from 'react'
-import { mockGlobalState } from 'tests/__mocks__/store'
+import { mockSgeState } from 'tests/__mocks__/forms.mock'
 import StepConsent from './StepConsent'
 
 const mockHandleChange = jest.fn()
@@ -9,21 +9,13 @@ const mockHandleChange = jest.fn()
 describe('StepConsent component', () => {
   it('should be rendered correctly', () => {
     const { container } = render(
-      <StepConsent
-        sgeState={mockGlobalState.sgeConnect}
-        onChange={mockHandleChange}
-      />
+      <StepConsent sgeState={mockSgeState} onChange={mockHandleChange} />
     )
     expect(container).toMatchSnapshot()
   })
 
   it('should change dataConsent and pdlConfirm value', async () => {
-    render(
-      <StepConsent
-        sgeState={mockGlobalState.sgeConnect}
-        onChange={mockHandleChange}
-      />
-    )
+    render(<StepConsent sgeState={mockSgeState} onChange={mockHandleChange} />)
     const consentCheckbox = screen.getByLabelText(
       'auth.enedissgegrandlyon.consentCheck1'
     )
diff --git a/src/components/Connection/SGEConnect/StepIdentityAndPdl.spec.tsx b/src/components/Connection/SGEConnect/StepIdentityAndPdl.spec.tsx
index 42846fe60..db0bb7e1d 100644
--- a/src/components/Connection/SGEConnect/StepIdentityAndPdl.spec.tsx
+++ b/src/components/Connection/SGEConnect/StepIdentityAndPdl.spec.tsx
@@ -1,7 +1,7 @@
 import { act, render, screen } from '@testing-library/react'
 import userEvent from '@testing-library/user-event'
 import React from 'react'
-import { mockGlobalState } from 'tests/__mocks__/store'
+import { mockSgeState } from 'tests/__mocks__/forms.mock'
 import StepIdentityAndPdl from './StepIdentityAndPdl'
 
 const mockHandleChange = jest.fn()
@@ -9,20 +9,14 @@ const mockHandleChange = jest.fn()
 describe('StepIdentityAndPdl component', () => {
   it('should be rendered correctly', () => {
     const { container } = render(
-      <StepIdentityAndPdl
-        sgeState={mockGlobalState.sgeConnect}
-        onChange={mockHandleChange}
-      />
+      <StepIdentityAndPdl sgeState={mockSgeState} onChange={mockHandleChange} />
     )
     expect(container).toMatchSnapshot()
   })
 
   it('should be able to change fields', async () => {
     render(
-      <StepIdentityAndPdl
-        sgeState={mockGlobalState.sgeConnect}
-        onChange={mockHandleChange}
-      />
+      <StepIdentityAndPdl sgeState={mockSgeState} onChange={mockHandleChange} />
     )
     const firstNameInput = screen.getByRole('textbox', {
       name: 'auth.enedissgegrandlyon.firstName',
@@ -51,10 +45,7 @@ describe('StepIdentityAndPdl component', () => {
 
   it('should open hint modal', async () => {
     render(
-      <StepIdentityAndPdl
-        sgeState={mockGlobalState.sgeConnect}
-        onChange={mockHandleChange}
-      />
+      <StepIdentityAndPdl sgeState={mockSgeState} onChange={mockHandleChange} />
     )
     await act(async () => {
       await userEvent.click(
@@ -68,7 +59,7 @@ describe('StepIdentityAndPdl component', () => {
     render(
       <StepIdentityAndPdl
         sgeState={{
-          ...mockGlobalState.sgeConnect,
+          ...mockSgeState,
           pdl: 11111111111111,
           firstName: 'Zack',
           lastName: 'Ichan',
diff --git a/src/components/Connection/SGEConnect/__snapshots__/StepAddress.spec.tsx.snap b/src/components/Connection/SGEConnect/__snapshots__/StepAddress.spec.tsx.snap
index 1e960609d..310b53b3a 100644
--- a/src/components/Connection/SGEConnect/__snapshots__/StepAddress.spec.tsx.snap
+++ b/src/components/Connection/SGEConnect/__snapshots__/StepAddress.spec.tsx.snap
@@ -58,8 +58,8 @@ exports[`StepAddress component should be rendered correctly 1`] = `
       class="MuiFormControl-root MuiTextField-root"
     >
       <label
-        class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required"
-        data-shrink="false"
+        class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled Mui-required Mui-required"
+        data-shrink="true"
         for="zipCode"
         id="zipCode-label"
       >
@@ -81,14 +81,14 @@ exports[`StepAddress component should be rendered correctly 1`] = `
           id="zipCode"
           required=""
           type="number"
-          value=""
+          value="0"
         />
         <fieldset
           aria-hidden="true"
           class="PrivateNotchedOutline-root-1 MuiOutlinedInput-notchedOutline"
         >
           <legend
-            class="PrivateNotchedOutline-legendLabelled-3"
+            class="PrivateNotchedOutline-legendLabelled-3 PrivateNotchedOutline-legendNotched-4"
           >
             <span>
               auth.enedissgegrandlyon.zipCode
diff --git a/src/components/Connection/useForm.tsx b/src/components/Connection/useForm.tsx
index 1f7240c3f..341d07753 100644
--- a/src/components/Connection/useForm.tsx
+++ b/src/components/Connection/useForm.tsx
@@ -1,6 +1,8 @@
 import { Q, QueryDefinition, useQuery } from 'cozy-client'
 import { QueryOptions } from 'cozy-client/types/types'
 import { FORM_DOCTYPE } from 'doctypes'
+import { SgeStep } from 'enums'
+import { SgeStore } from 'models'
 
 export type QueryParams = (arg?: any) => {
   definition: QueryDefinition
@@ -40,3 +42,16 @@ export const useFormData = () => {
     lastError,
   }
 }
+
+export const createInitialSgeState = (formData?: FormData): SgeStore => ({
+  address: formData?.address ?? '',
+  lastName: formData?.lastName ?? '',
+  firstName: formData?.firstName ?? '',
+  pdl: formData?.pdl ? parseInt(formData.pdl) : null,
+  zipCode: formData?.zipCode ? parseInt(formData.zipCode) : null,
+  city: formData?.city ?? '',
+  currentStep: SgeStep.Address,
+  dataConsent: false,
+  shouldLaunchAccount: false,
+  pdlConfirm: false,
+})
diff --git a/tests/__mocks__/forms.mock.ts b/tests/__mocks__/forms.mock.ts
new file mode 100644
index 000000000..9f3f43e67
--- /dev/null
+++ b/tests/__mocks__/forms.mock.ts
@@ -0,0 +1,14 @@
+import { SgeStore } from 'models'
+
+export const mockSgeState: SgeStore = {
+  address: '',
+  lastName: '',
+  firstName: '',
+  pdl: 0,
+  zipCode: 0,
+  city: '',
+  currentStep: 0,
+  dataConsent: false,
+  shouldLaunchAccount: false,
+  pdlConfirm: false,
+}
-- 
GitLab