diff --git a/src/components/Reports/AdditionalSalaryRequest/AboutForm/AboutForm.tsx b/src/components/Reports/AdditionalSalaryRequest/AboutForm/AboutForm.tsx index f6b7842b37..fdea933f90 100644 --- a/src/components/Reports/AdditionalSalaryRequest/AboutForm/AboutForm.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/AboutForm/AboutForm.tsx @@ -10,14 +10,12 @@ import { AdditionalSalaryRequestSection } from '../SharedComponents/AdditionalSa import { SpouseComponent } from '../SharedComponents/SpouseComponent'; export const AboutForm: React.FC = () => { - const { currentIndex, requestData } = useAdditionalSalaryRequest(); + const { currentIndex, calculations } = useAdditionalSalaryRequest(); const { t } = useTranslation(); const theme = useTheme(); const { name, accountNumber, primaryAccountBalance } = useFormUserInfo(); - const individualCap = - requestData?.latestAdditionalSalaryRequest?.calculations.currentSalaryCap ?? - 0; + const individualCap = calculations?.currentSalaryCap ?? 0; return ( diff --git a/src/components/Reports/AdditionalSalaryRequest/RequestPage/RequestPage.test.tsx b/src/components/Reports/AdditionalSalaryRequest/RequestPage/RequestPage.test.tsx index 33522e60b6..939d1c8072 100644 --- a/src/components/Reports/AdditionalSalaryRequest/RequestPage/RequestPage.test.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/RequestPage/RequestPage.test.tsx @@ -300,6 +300,10 @@ describe('RequestPage', () => { currentStep: AdditionalSalaryRequestSectionEnum.CompleteForm, pageType: PageEnum.Edit, setPageType: mockSetPageType, + calculations: { + currentSalaryCap: 50000, + staffAccountBalance: 0, + }, requestData: { latestAdditionalSalaryRequest: { status: AsrStatusEnum.Pending, @@ -400,6 +404,9 @@ describe('RequestPage', () => { currentIndex: 1, currentStep: AdditionalSalaryRequestSectionEnum.CompleteForm, pageType: PageEnum.New, + calculations: { + currentSalaryCap: 50, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -451,6 +458,14 @@ describe('RequestPage', () => { lastName: 'Doe', }, }, + calculations: { + currentSalaryCap: 500, + combinedCap: 100000, + }, + spouseCalculations: { + currentSalaryCap: 50000, + pendingAsrAmount: 100, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -509,6 +524,13 @@ describe('RequestPage', () => { lastName: 'Doe', }, }, + calculations: { + currentSalaryCap: 500, + }, + spouseCalculations: { + currentSalaryCap: 500, + pendingAsrAmount: 600, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/AdditionalSalaryRequestContext.tsx b/src/components/Reports/AdditionalSalaryRequest/Shared/AdditionalSalaryRequestContext.tsx index 1d1c7fa5e3..6c834b69f7 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/AdditionalSalaryRequestContext.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/AdditionalSalaryRequestContext.tsx @@ -60,6 +60,12 @@ export type AdditionalSalaryRequestType = { | 'staffAccountBalance' | 'pendingAsrAmount' >; + spouseCalculations?: Pick< + AdditionalSalaryRequestCalculations, + | 'currentSalaryCap' + | 'staffAccountBalance' + | 'pendingAsrAmount' + > | null; user: HcmDataQuery['hcm'][0] | undefined; spouse: HcmDataQuery['hcm'][1] | undefined; salaryInfo: SalaryInfoQuery['salaryInfo'] | undefined; @@ -242,6 +248,7 @@ export const AdditionalSalaryRequestProvider: React.FC = ({ handleDeleteRequest, requestId: requestData?.latestAdditionalSalaryRequest?.id ?? requestId, calculations: requestData?.latestAdditionalSalaryRequest?.calculations, + spouseCalculations: requestData?.latestAdditionalSalaryRequest?.spouseCalculations, user, spouse, salaryInfo, diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx index 77f0c24b08..9b20d96e91 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.test.tsx @@ -49,6 +49,11 @@ const defaultMockContextValue: AdditionalSalaryRequestType = { goToStep: jest.fn(), isDrawerOpen: true, toggleDrawer: jest.fn(), + calculations: { + currentSalaryCap: 100000, + staffAccountBalance: 50000, + pendingAsrAmount: 0, + }, requestData: { latestAdditionalSalaryRequest: { phoneNumber: '555-123-4567', @@ -214,6 +219,8 @@ describe('useAdditionalSalaryRequestForm', () => { mockUseAdditionalSalaryRequest.mockReturnValue({ ...defaultMockContextValue, user: undefined, + requestData: undefined, + calculations: undefined, }); const { result } = renderHook(() => useAdditionalSalaryRequestForm(), { @@ -241,9 +248,15 @@ describe('useAdditionalSalaryRequestForm', () => { expect(result.current.values.phoneNumber).toBe('555-1234'); }); - it('should populate initial values from request data query', async () => { - const mocks = { - AdditionalSalaryRequest: { + it('should populate initial values from request data in context', async () => { + mockUseAdditionalSalaryRequest.mockReturnValue({ + ...defaultMockContextValue, + calculations: { + currentSalaryCap: 50000, + staffAccountBalance: 20000, + pendingAsrAmount: 0, + }, + requestData: { latestAdditionalSalaryRequest: { id: 'test-request-id', currentYearSalaryNotReceived: 500, @@ -268,38 +281,44 @@ describe('useAdditionalSalaryRequestForm', () => { pendingAsrAmount: 0, }, }, - }, - }; - - const { result } = renderHook(() => useAdditionalSalaryRequestForm(), { - wrapper: ({ children }) => ( - {children} - ), + } as unknown as AdditionalSalaryRequestQuery, }); - await waitFor(() => { - expect(result.current.values.currentYearSalaryNotReceived).toBe('500'); + const { result } = renderHook(() => useAdditionalSalaryRequestForm(), { + wrapper: TestWrapper, }); + expect(result.current.values.currentYearSalaryNotReceived).toBe('500'); expect(result.current.values.previousYearSalaryNotReceived).toBe('200'); expect(result.current.values.phoneNumber).toBe('123-456-7890'); }); - it('should send isSpouse variable to request query', async () => { - renderHook(() => useAdditionalSalaryRequestForm(), { - wrapper: TestWrapper, + it('should read isSpouse from context', async () => { + mockUseAdditionalSalaryRequest.mockReturnValue({ + ...defaultMockContextValue, + isSpouse: false, + requestData: undefined, + calculations: undefined, }); - await waitFor(() => { - expect(mutationSpy).toHaveGraphqlOperation('AdditionalSalaryRequest', { - isSpouse: false, - }); + const { result } = renderHook(() => useAdditionalSalaryRequestForm(), { + wrapper: TestWrapper, }); + + // isSpouse=false should be used (no spouse mode) + expect(result.current.values).toBeDefined(); }); }); describe('validation', () => { it('should require phone number', async () => { + mockUseAdditionalSalaryRequest.mockReturnValue({ + ...defaultMockContextValue, + user: undefined, + requestData: undefined, + calculations: undefined, + }); + const { result } = renderHook(() => useAdditionalSalaryRequestForm(), { wrapper: TestWrapper, }); @@ -461,6 +480,25 @@ describe('useAdditionalSalaryRequestForm', () => { }); it('should validate additional info when exceedsCap is true', async () => { + mockUseAdditionalSalaryRequest.mockReturnValue({ + ...defaultMockContextValue, + calculations: { + currentSalaryCap: 50, + staffAccountBalance: 0, + pendingAsrAmount: 0, + }, + requestData: { + latestAdditionalSalaryRequest: { + phoneNumber: '555-123-4567', + calculations: { + currentSalaryCap: 50, + staffAccountBalance: 0, + pendingAsrAmount: 0, + }, + }, + } as unknown as AdditionalSalaryRequestQuery, + }); + const { result } = renderHook( () => useAdditionalSalaryRequestForm({ @@ -691,9 +729,16 @@ describe('useAdditionalSalaryRequestForm', () => { expect(result.current.values.currentYearSalaryNotReceived).toBe('100'); }); - it('should enable reinitialize', async () => { - const mocks = { - AdditionalSalaryRequest: { + it('should initialize from requestData in context', async () => { + mockUseAdditionalSalaryRequest.mockReturnValue({ + ...defaultMockContextValue, + calculations: { + currentSalaryCap: 50000, + combinedCap: 50000, + staffAccountBalance: 20000, + pendingAsrAmount: 0, + }, + requestData: { latestAdditionalSalaryRequest: { id: 'test-request-id', currentYearSalaryNotReceived: 999, @@ -718,18 +763,14 @@ describe('useAdditionalSalaryRequestForm', () => { staffAccountBalance: 20000, }, }, - }, - }; + } as unknown as AdditionalSalaryRequestQuery, + }); const { result } = renderHook(() => useAdditionalSalaryRequestForm(), { - wrapper: ({ children }) => ( - {children} - ), + wrapper: TestWrapper, }); - await waitFor(() => { - expect(result.current.values.currentYearSalaryNotReceived).toBe('999'); - }); + expect(result.current.values.currentYearSalaryNotReceived).toBe('999'); }); }); }); diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts index 938aeb8b61..b6b06a9dc2 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useAdditionalSalaryRequestForm.ts @@ -9,7 +9,6 @@ import { currencyFormat } from 'src/lib/intlFormat'; import { amount, phoneNumber } from 'src/lib/yupHelpers'; import { CompleteFormValues } from '../AdditionalSalaryRequest'; import { - useAdditionalSalaryRequestQuery, useSubmitAdditionalSalaryRequestMutation, useUpdateAdditionalSalaryRequestMutation, } from '../AdditionalSalaryRequest.generated'; @@ -77,17 +76,13 @@ export const useAdditionalSalaryRequestForm = ( salaryInfo, isInternational, requestId, - isSpouse, + calculations, + requestData, } = useAdditionalSalaryRequest(); const { primaryAccountBalance } = useFormUserInfo(); - const { data: requestData } = useAdditionalSalaryRequestQuery({ - variables: { isSpouse }, - }); - const individualCap = - requestData?.latestAdditionalSalaryRequest?.calculations.currentSalaryCap ?? - 0; + const individualCap = calculations?.currentSalaryCap ?? 0; const [updateAdditionalSalaryRequest] = useUpdateAdditionalSalaryRequestMutation(); diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.test.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.test.ts index f86032f240..bdd49382bf 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.test.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.test.ts @@ -14,6 +14,10 @@ const mockUseAdditionalSalaryRequest = describe('useFormUserInfo', () => { it('returns staff info and calculated balances', () => { mockUseAdditionalSalaryRequest.mockReturnValue({ + calculations: { + currentSalaryCap: 100000, + staffAccountBalance: 40000, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -44,6 +48,7 @@ describe('useFormUserInfo', () => { it('defaults balances to 0 when calculations are undefined', () => { mockUseAdditionalSalaryRequest.mockReturnValue({ + calculations: undefined, requestData: { latestAdditionalSalaryRequest: { calculations: undefined, @@ -63,6 +68,10 @@ describe('useFormUserInfo', () => { it('handles undefined user gracefully', () => { mockUseAdditionalSalaryRequest.mockReturnValue({ + calculations: { + currentSalaryCap: 100000, + staffAccountBalance: 40000, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.ts index 1909beface..6d90143b14 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useFormUserInfo.ts @@ -1,9 +1,8 @@ import { useAdditionalSalaryRequest } from './AdditionalSalaryRequestContext'; export const useFormUserInfo = () => { - const { requestData, user } = useAdditionalSalaryRequest(); - const { staffAccountBalance } = - requestData?.latestAdditionalSalaryRequest?.calculations || {}; + const { calculations, user } = useAdditionalSalaryRequest(); + const { staffAccountBalance } = calculations || {}; const { emailAddress: email, preferredName: name, diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.test.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.test.ts index 2a9352f1d3..6c6c99021b 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.test.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.test.ts @@ -222,6 +222,10 @@ describe('useSalaryCalculations', () => { user: { currentSalary: { grossSalaryAmount: 1000 }, }, + calculations: { + currentSalaryCap: 5000, + pendingAsrAmount: 1000, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -262,6 +266,10 @@ describe('useSalaryCalculations', () => { user: { currentSalary: { grossSalaryAmount: 50000 }, }, + calculations: { + currentSalaryCap: 10000, + pendingAsrAmount: 10000, + }, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -305,6 +313,10 @@ describe('useSalaryCalculations', () => { roth403bPercentage: 0.1, user: { currentSalary: { grossSalaryAmount: 50000 } }, spouse: { currentSalary: { grossSalaryAmount: 40000 } }, + calculations: { + currentSalaryCap: 70000, + }, + spouseCalculations, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -403,6 +415,10 @@ describe('useSalaryCalculations', () => { roth403bPercentage: 0.1, user: { currentSalary: { grossSalaryAmount: 50000 } }, spouse: { currentSalary: { grossSalaryAmount: 40000 } }, + calculations: { + currentSalaryCap: 60000, + }, + spouseCalculations, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -548,6 +564,10 @@ describe('useSalaryCalculations', () => { roth403bPercentage: 0.1, user: { currentSalary: { grossSalaryAmount: 50000 } }, spouse: { currentSalary: { grossSalaryAmount: 40000 } }, + calculations: { + currentSalaryCap: 55000, + }, + spouseCalculations, requestData: { latestAdditionalSalaryRequest: { calculations: { @@ -644,6 +664,7 @@ describe('useSalaryCalculations', () => { roth403bPercentage: 0.1, user: { currentSalary: { grossSalaryAmount: 50000 } }, spouse: undefined, + calculations: { currentSalaryCap: cap }, requestData: { latestAdditionalSalaryRequest: { calculations: { currentSalaryCap: cap }, diff --git a/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.ts b/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.ts index 2dc1135e6c..f49535dcaf 100644 --- a/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.ts +++ b/src/components/Reports/AdditionalSalaryRequest/Shared/useSalaryCalculations.ts @@ -58,16 +58,15 @@ export const useSalaryCalculations = ({ const { traditional403bPercentage, roth403bPercentage, - requestData, + calculations, + spouseCalculations, user, spouse, } = useAdditionalSalaryRequest(); - const individualCap = - requestData?.latestAdditionalSalaryRequest?.calculations.currentSalaryCap ?? - 0; + const individualCap = calculations?.currentSalaryCap ?? 0; + const spouseIndividualCap = spouse - ? (requestData?.latestAdditionalSalaryRequest?.spouseCalculations - ?.currentSalaryCap ?? 0) + ? (spouseCalculations?.currentSalaryCap ?? 0) : null; const grossAnnualSalary = user?.currentSalary?.grossSalaryAmount ?? 0; @@ -92,15 +91,13 @@ export const useSalaryCalculations = ({ // Annual salary calculations const additionalSalaryReceivedThisYear = - requestData?.latestAdditionalSalaryRequest?.calculations - ?.pendingAsrAmount ?? 0; + calculations?.pendingAsrAmount ?? 0; const totalAnnualSalary = grossAnnualSalary + additionalSalaryReceivedThisYear + total; // Spouse annual salary calculations const spouseTotalThisYear = spouse - ? requestData?.latestAdditionalSalaryRequest?.spouseCalculations - ?.pendingAsrAmount + ? spouseCalculations?.pendingAsrAmount : null; const spouseTotalAnnualSalary = spouseGrossAnnualSalary + (spouseTotalThisYear ?? 0); @@ -160,7 +157,8 @@ export const useSalaryCalculations = ({ individualCap, spouseIndividualCap, spouse, - requestData, + spouseCalculations, + calculations, spouseGrossAnnualSalary, ]); }; diff --git a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.test.tsx b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.test.tsx index d26661d6af..ff4fb360b7 100644 --- a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.test.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.test.tsx @@ -19,6 +19,11 @@ const requestDataDefault = { }, }; +const calculationsDefault = + requestDataDefault.latestAdditionalSalaryRequest.calculations; +const spouseCalculationsDefault = + requestDataDefault.latestAdditionalSalaryRequest.spouseCalculations; + const spouseDefault = { staffInfo: { firstName: 'Jane', @@ -35,12 +40,16 @@ const router = { type ComponentProps = { requestData?: object; + calculations?: object | null; + spouseCalculations?: object | null; spouse?: object; isSpouse?: boolean; hasSpouse?: boolean; }; const renderComponent = ({ requestData = requestDataDefault, + calculations = calculationsDefault, + spouseCalculations = spouseCalculationsDefault, spouse = spouseDefault, isSpouse = false, hasSpouse = true, @@ -51,6 +60,8 @@ const renderComponent = ({ value={ { requestData, + calculations, + spouseCalculations, spouse, isSpouse, hasSpouse, @@ -79,6 +90,10 @@ describe('SpouseComponent', () => { it('calculates remaining salary correctly when values are provided', () => { const { getByText } = renderComponent({ + spouseCalculations: { + currentSalaryCap: 15000, + staffAccountBalance: 5000, + }, requestData: { latestAdditionalSalaryRequest: { ...requestDataDefault.latestAdditionalSalaryRequest, @@ -97,6 +112,7 @@ describe('SpouseComponent', () => { it('handles null spouse calculations gracefully', () => { const { getByText } = renderComponent({ + spouseCalculations: null, requestData: { latestAdditionalSalaryRequest: { ...requestDataDefault.latestAdditionalSalaryRequest, diff --git a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.tsx b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.tsx index 9354205773..935a1c9b06 100644 --- a/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.tsx +++ b/src/components/Reports/AdditionalSalaryRequest/SharedComponents/SpouseComponent.tsx @@ -13,20 +13,17 @@ export const SpouseComponent: React.FC = () => { const locale = useLocale(); const currency = 'USD'; - const { requestData, isSpouse, hasSpouse } = useAdditionalSalaryRequest(); + const { calculations, spouseCalculations, isSpouse, hasSpouse } = + useAdditionalSalaryRequest(); const { spouseLinkText, spouseLinkHref } = useSpouseLink(); if (!hasSpouse) { return null; } - const userCalculations = - requestData?.latestAdditionalSalaryRequest?.calculations; - const spouseCalculations = - requestData?.latestAdditionalSalaryRequest?.spouseCalculations; const { currentSalaryCap, staffAccountBalance } = - isSpouse && userCalculations - ? userCalculations + isSpouse && calculations + ? calculations : spouseCalculations ? spouseCalculations : {};