diff --git a/frontend/src/assets/locales/en/transfer.json b/frontend/src/assets/locales/en/transfer.json index 14ba125bd..47a263a61 100644 --- a/frontend/src/assets/locales/en/transfer.json +++ b/frontend/src/assets/locales/en/transfer.json @@ -81,5 +81,6 @@ "Declined": "Declined", "Rescinded": "Rescinded" }, - "zeroDollarInstructionText": "If proposing a zero-dollar transfer, use the comment box below to provide an explanation for this value." + "zeroDollarInstructionText": "If proposing a zero-dollar transfer, use the comment box below to provide an explanation for this value.", + "categoryCheckbox": "Select the checkbox to set the transfer as Category D if the price is significantly less than fair market value. This will override the default category determined by the agreement and approval dates indicated above." } diff --git a/frontend/src/views/Transfers/AddEditViewTransfer.jsx b/frontend/src/views/Transfers/AddEditViewTransfer.jsx index 4dfb34c09..9dc9b0c54 100644 --- a/frontend/src/views/Transfers/AddEditViewTransfer.jsx +++ b/frontend/src/views/Transfers/AddEditViewTransfer.jsx @@ -441,7 +441,9 @@ export const AddEditViewTransfer = () => { hasAnyRole(roles.analyst) && ( <> - + )} diff --git a/frontend/src/views/Transfers/components/CategoryCheckbox.jsx b/frontend/src/views/Transfers/components/CategoryCheckbox.jsx index 968d04033..a50e73fc8 100644 --- a/frontend/src/views/Transfers/components/CategoryCheckbox.jsx +++ b/frontend/src/views/Transfers/components/CategoryCheckbox.jsx @@ -5,8 +5,10 @@ import { Checkbox, FormControlLabel } from '@mui/material' import { useQueryClient } from '@tanstack/react-query' import { useEffect } from 'react' import { useParams } from 'react-router-dom' +import { useTranslation } from 'react-i18next' -export const CategoryCheckbox = () => { +export const CategoryCheckbox = ({ isDisabled = false }) => { + const { t } = useTranslation(['transfer']) const { transferId } = useParams() const queryClient = useQueryClient() const setLoading = useLoadingStore((state) => state.setLoading) @@ -36,15 +38,14 @@ export const CategoryCheckbox = () => { data-test="checkbox" checked={transferData?.transferCategory?.category === 'D'} onClick={(e) => updateCategory(e.target.checked ? 'D' : null)} + disabled={isDisabled} /> } label={ - - Select the checkbox to set the transfer as{' '} - Category D if the price is significantly less than - fair market value. This will override the default category - determined by the agreement and approval dates indicated above. - + } /> diff --git a/frontend/src/views/Transfers/components/__tests__/CategoryCheckbox.test.jsx b/frontend/src/views/Transfers/components/__tests__/CategoryCheckbox.test.jsx index 236d84f95..f6fc8712f 100644 --- a/frontend/src/views/Transfers/components/__tests__/CategoryCheckbox.test.jsx +++ b/frontend/src/views/Transfers/components/__tests__/CategoryCheckbox.test.jsx @@ -7,7 +7,7 @@ import { useTransfer, useUpdateCategory } from '@/hooks/useTransfer' import { useLoadingStore } from '@/stores/useLoadingStore' const keycloak = vi.hoisted(() => ({ - useKeycloak: vi.fn(), + useKeycloak: vi.fn() })) vi.mock('@react-keycloak/web', () => keycloak) @@ -16,17 +16,17 @@ vi.mock('react-router-dom', async () => { const actual = await vi.importActual('react-router-dom') return { ...actual, - useParams: () => ({ transferId: '123' }), + useParams: () => ({ transferId: '123' }) } }) vi.mock('@/hooks/useTransfer', () => ({ useTransfer: vi.fn(), - useUpdateCategory: vi.fn(), + useUpdateCategory: vi.fn() })) vi.mock('@/stores/useLoadingStore', () => ({ - useLoadingStore: vi.fn(), + useLoadingStore: vi.fn() })) describe('CategoryCheckbox Component', () => { @@ -36,14 +36,17 @@ describe('CategoryCheckbox Component', () => { beforeEach(() => { keycloak.useKeycloak.mockReturnValue({ keycloak: { authenticated: true }, - initialized: true, + initialized: true }) // Correctly mock useLoadingStore to handle the selector - useLoadingStore.mockImplementation((selector) => selector({ setLoading: setLoadingMock })) + useLoadingStore.mockImplementation((selector) => + selector({ setLoading: setLoadingMock }) + ) + // Mock updateCategory hook useUpdateCategory.mockReturnValue({ - mutate: mutateMock, + mutate: mutateMock }) // Reset mocks @@ -58,7 +61,7 @@ describe('CategoryCheckbox Component', () => { it('should render the component', () => { useTransfer.mockReturnValue({ data: {}, - isFetching: false, + isFetching: false }) render(, { wrapper }) @@ -70,7 +73,7 @@ describe('CategoryCheckbox Component', () => { it('should display the checkbox as checked when category is "D"', () => { useTransfer.mockReturnValue({ data: { transferCategory: { category: 'D' } }, - isFetching: false, + isFetching: false }) render(, { wrapper }) @@ -82,7 +85,7 @@ describe('CategoryCheckbox Component', () => { it('should display the checkbox as unchecked when category is not "D"', () => { useTransfer.mockReturnValue({ data: { transferCategory: { category: null } }, - isFetching: false, + isFetching: false }) render(, { wrapper }) @@ -94,7 +97,7 @@ describe('CategoryCheckbox Component', () => { it('should call updateCategory with null when unchecking the checkbox', () => { useTransfer.mockReturnValue({ data: { transferCategory: { category: 'D' } }, - isFetching: false, + isFetching: false }) render(, { wrapper }) @@ -108,7 +111,7 @@ describe('CategoryCheckbox Component', () => { it('should call updateCategory with "D" when checking the checkbox', () => { useTransfer.mockReturnValue({ data: { transferCategory: { category: null } }, - isFetching: false, + isFetching: false }) render(, { wrapper }) @@ -122,11 +125,28 @@ describe('CategoryCheckbox Component', () => { it('should set loading state appropriately during fetch', () => { useTransfer.mockReturnValue({ data: {}, - isFetching: false, + isFetching: false }) render(, { wrapper }) expect(setLoadingMock).toHaveBeenCalledWith(false) }) + + it('should disable the checkbox when isDisabled is true', () => { + useTransfer.mockReturnValue({ + data: { transferCategory: { category: null } }, + isFetching: false + }) + + render(, { wrapper }) + + const checkboxWrapper = screen.getByTestId('checkbox') + const checkboxInput = checkboxWrapper.querySelector( + 'input[type="checkbox"]' + ) + + // Verify the input is indeed disabled + expect(checkboxInput).toBeDisabled() + }) })