Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ export const MinisterHousingAllowanceReport = () => {
)}
{showPreviousRequests && (
<Stack direction="column" width={mainContentWidth} mt={4}>
<CurrentBoardApproved request={previousApprovedRequest} />
<CurrentBoardApproved
request={previousApprovedRequest}
hasOpenRequest={isCurrentRequestPending}
/>
</Stack>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { DeepPartial } from 'ts-essentials';
import TestRouter from '__tests__/util/TestRouter';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import theme from 'src/theme';
Expand All @@ -17,19 +18,40 @@ import { CurrentBoardApproved } from './CurrentBoardApproved';
const newRequestId = 'new-request-id';
const mutationSpy = jest.fn();
const mockPush = jest.fn();

const singleContext: Partial<ContextType> = {
isMarried: false,
preferredName: 'John',
spousePreferredName: '',
userHcmData: {
staffInfo: {
personNumber: '000123456',
},
} as unknown as HcmData,
spouseHcmData: null,
};

interface TestComponentProps {
contextValue: Partial<ContextType>;
contextValue?: Partial<ContextType>;
request?: typeof mockMHARequest;
router?: {
push?: jest.Mock;
query?: { accountListId?: string };
};
mocks?: DeepPartial<{
DuplicateMinistryHousingAllowanceRequest: DuplicateMinistryHousingAllowanceRequestMutation;
}>;
hasOpenRequest?: boolean;
}

const TestComponent: React.FC<TestComponentProps> = ({
contextValue,
contextValue = singleContext,
request,
router = {},
mocks,
hasOpenRequest,
}) => {
const approvedMHARequest = {
const approvedMHARequest = request ?? {
...mockMHARequest,
updatedAt: '2022-12-01',
requestAttributes: {
Expand All @@ -47,12 +69,16 @@ const TestComponent: React.FC<TestComponentProps> = ({
<GqlMockedProvider<{
DuplicateMinistryHousingAllowanceRequest: DuplicateMinistryHousingAllowanceRequestMutation;
}>
mocks={mocks}
onCall={mutationSpy}
>
<MinisterHousingAllowanceContext.Provider
value={contextValue as ContextType}
>
<CurrentBoardApproved request={approvedMHARequest} />
<CurrentBoardApproved
request={approvedMHARequest}
hasOpenRequest={hasOpenRequest}
/>
</MinisterHousingAllowanceContext.Provider>
</GqlMockedProvider>
</TestRouter>
Expand Down Expand Up @@ -105,19 +131,7 @@ describe('CurrentBoardApproved Component', () => {

it('should render correctly for single person', () => {
const { queryByText, queryByRole, getAllByText } = render(
<TestComponent
contextValue={{
isMarried: false,
preferredName: 'John',
spousePreferredName: '',
userHcmData: {
staffInfo: {
personNumber: '000123456',
},
} as unknown as HcmData,
spouseHcmData: null,
}}
/>,
<TestComponent />,
);

expect(queryByText('Current Board Approved MHA')).toBeInTheDocument();
Expand All @@ -141,42 +155,19 @@ describe('CurrentBoardApproved Component', () => {

it('should navigate to edit page with new requestId after duplicate mutation', async () => {
const { getByText } = render(
<ThemeProvider theme={theme}>
<TestRouter router={{ push: mockPush }}>
<GqlMockedProvider<{
DuplicateMinistryHousingAllowanceRequest: DuplicateMinistryHousingAllowanceRequestMutation;
}>
mocks={{
DuplicateMinistryHousingAllowanceRequest: {
duplicateMinistryHousingAllowanceRequest: {
ministryHousingAllowanceRequest: {
id: newRequestId,
},
},
<TestComponent
request={mockMHARequest}
router={{ push: mockPush }}
mocks={{
DuplicateMinistryHousingAllowanceRequest: {
duplicateMinistryHousingAllowanceRequest: {
ministryHousingAllowanceRequest: {
id: newRequestId,
},
}}
onCall={mutationSpy}
>
<MinisterHousingAllowanceContext.Provider
value={
{
isMarried: false,
preferredName: 'John',
spousePreferredName: '',
userHcmData: {
staffInfo: {
personNumber: '000123456',
},
} as unknown as HcmData,
spouseHcmData: null,
} as ContextType
}
>
<CurrentBoardApproved request={mockMHARequest} />
</MinisterHousingAllowanceContext.Provider>
</GqlMockedProvider>
</TestRouter>
</ThemeProvider>,
},
},
}}
/>,
);

const updateButton = getByText('Update Current MHA');
Expand All @@ -199,4 +190,11 @@ describe('CurrentBoardApproved Component', () => {
);
});
});

it('should hide Update Current MHA button when there is an open request', () => {
const { queryByText, getByText } = render(<TestComponent hasOpenRequest />);

expect(getByText('View Current MHA')).toBeInTheDocument();
expect(queryByText('Update Current MHA')).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,72 +24,75 @@

interface CurrentBoardApprovedProps {
request: MHARequest | null;
hasOpenRequest?: boolean;
}

export const CurrentBoardApproved: React.FC<CurrentBoardApprovedProps> = ({
request,
hasOpenRequest = false,
}) => {
const { t } = useTranslation();
const locale = useLocale();
const accountListId = useAccountListId();
const router = useRouter();
const currency = 'USD';

const [duplicateMHA] = useDuplicateMinistryHousingAllowanceRequestMutation();

const { isMarried, preferredName, spousePreferredName } =
useMinisterHousingAllowance();
const requestId = request?.id;

const { hrApprovedAt, approvedOverallAmount, staffSpecific, spouseSpecific } =
request?.requestAttributes || {};

const lastUpdated = request?.updatedAt ?? null;

const viewLink = getRequestUrl(accountListId, requestId, 'view');

const handleDuplicateRequest = async () => {
if (!requestId) {
return;
}

await duplicateMHA({
variables: {
input: {
requestId: requestId,
},
},
onCompleted: (data) => {
const newRequestId =
data?.duplicateMinistryHousingAllowanceRequest
?.ministryHousingAllowanceRequest.id;

if (newRequestId) {
router.push(getRequestUrl(accountListId, newRequestId, 'edit'));
}
},
});
};

const handlePrint = async () => {
if (!requestId) {
return;
}
await router.push(getRequestUrl(accountListId, requestId, 'view'));
setTimeout(() => window.print(), 500);
};

return (
<StatusCard
formType={t('MHA Request')}
title={t('Current Board Approved MHA')}
subtitle={t("Minister's Housing Allowance Status")}
icon={HomeSharp}
iconColor="success.main"
linkOneText={t('View Current MHA')}
linkOne={viewLink}
linkTwoText={t('Update Current MHA')}
handleLinkTwo={handleDuplicateRequest}
hideLinkTwoButton={hasOpenRequest}

Check warning on line 95 in src/components/Reports/MinisterHousingAllowance/SharedComponents/CurrentBoardApproved.tsx

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (main)

❌ Getting worse: Complex Method

CurrentBoardApproved:React.FC<CurrentBoardApprovedProps> already has high cyclomatic complexity, and now it increases in Lines of Code from 218 to 220. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
isRequest={false}
handlePrint={handlePrint}
handleConfirmCancel={() => {}}
Expand Down
Loading