diff --git a/frontend/src/app/testResults/TestResultCorrectionModal.test.tsx b/frontend/src/app/testResults/TestResultCorrectionModal.test.tsx index 079f7238ae..42007ae072 100644 --- a/frontend/src/app/testResults/TestResultCorrectionModal.test.tsx +++ b/frontend/src/app/testResults/TestResultCorrectionModal.test.tsx @@ -7,6 +7,7 @@ import { act, render, screen, waitFor, within } from "@testing-library/react"; import "./TestResultCorrectionModal.scss"; import userEvent from "@testing-library/user-event"; import configureStore from "redux-mock-store"; +import { MockedResponse } from "@apollo/client/testing/core"; import { TestCorrectionReasons, @@ -60,6 +61,26 @@ jest.mock("react-router-dom", () => { useNavigate: () => mockedNavigate, }; }); +const renderModal = ( + isFacilityDeleted: boolean, + mocks: ReadonlyArray, + initialEntries?: any[] | undefined +) => { + render( + + + + {}} + isFacilityDeleted={isFacilityDeleted} + /> + + + + ); +}; describe("TestResultCorrectionModal", () => { let component: any; @@ -71,19 +92,7 @@ describe("TestResultCorrectionModal", () => { }); it("renders the correction reason dropdown menu", async () => { - render( - - - - {}} - /> - - - - ); + renderModal(false, []); const expectedCorrectionReasons = Object.values(TestCorrectionReasons); @@ -107,6 +116,7 @@ describe("TestResultCorrectionModal", () => { data={testResult} testResultId={internalId} closeModal={() => {}} + isFacilityDeleted={false} /> @@ -138,33 +148,23 @@ describe("TestResultCorrectionModal", () => { }, }, ]; - beforeEach(() => { - render( - - - - {}} - /> - - - - ); + markAsErrorMockDidComplete = false; }); + it.each([true, false])( + "sends a GraphQL request to perform the removal", + async (isFacilityDeleted) => { + renderModal(isFacilityDeleted, mocks); + await act( + async () => + await userEvent.click(await screen.findByText("Yes, I'm sure")) + ); - it("sends a GraphQL request to perform the removal", async () => { - await act( - async () => - await userEvent.click(await screen.findByText("Yes, I'm sure")) - ); - - await waitFor(() => { - expect(markAsErrorMockDidComplete).toBe(true); - }); - }); + await waitFor(() => { + expect(markAsErrorMockDidComplete).toBe(true); + }); + } + ); }); describe("when correcting for incorrect result", () => { @@ -191,24 +191,11 @@ describe("TestResultCorrectionModal", () => { ]; beforeEach(() => { - render( - - - - {}} - /> - - - - ); + markAsCorrectMockDidComplete = false; }); it("sends a GraphQL request on submit to initiate correction", async () => { + renderModal(false, mocks, [`/results/1?facility=${mockFacilityID}`]); const dropdown = await screen.findByLabelText( "Please select a reason for correcting this test result." ); @@ -231,6 +218,24 @@ describe("TestResultCorrectionModal", () => { ); }); }); + it("prevents submission when facility is deleted", async () => { + renderModal(true, mocks, [`/results/1?facility=${mockFacilityID}`]); + const dropdown = await screen.findByLabelText( + "Please select a reason for correcting this test result." + ); + await act( + async () => + await userEvent.selectOptions( + dropdown, + TestCorrectionReasons.INCORRECT_RESULT + ) + ); + + expect(await screen.findByText("Yes, I'm sure")).toBeDisabled(); + expect( + screen.getByText("Can't update test result for deleted facility") + ).toBeInTheDocument(); + }); }); describe("when correcting for a reason not listed", () => { @@ -274,21 +279,7 @@ describe("TestResultCorrectionModal", () => { }, }, ]; - beforeEach(async () => { - render( - - - - {}} - /> - - - - ); - + const selectOther = async () => { const dropdown = await screen.findByLabelText( "Please select a reason for correcting this test result." ); @@ -300,9 +291,15 @@ describe("TestResultCorrectionModal", () => { expect( await screen.findByText("Additional information", { exact: false }) ).toBeInTheDocument(); + }; + beforeEach(async () => { + markAsErrorMockDidComplete = false; + markAsCorrectionMockDidComplete = false; }); it("renders sub-form", async () => { + renderModal(false, mocks); + await selectOther(); const additionalDetails = await screen.findByTestId( "additionalInformation" ); @@ -324,6 +321,8 @@ describe("TestResultCorrectionModal", () => { }); it("prevents submission if additional details not populated", async () => { + renderModal(false, mocks); + await selectOther(); const correctionActionOption = screen.getByLabelText( TestCorrectionActions.CORRECT_RESULT ); @@ -334,6 +333,8 @@ describe("TestResultCorrectionModal", () => { }); it("prevents submission if additional details does not meet minimum character requirement", async () => { + renderModal(false, mocks); + await selectOther(); const additionalDetails = await screen.findByTestId( "additionalInformation" ); @@ -349,6 +350,8 @@ describe("TestResultCorrectionModal", () => { }); it("prevents submission if correction action not selected", async () => { + renderModal(false, mocks); + await selectOther(); const additionalDetails = await screen.findByTestId( "additionalInformation" ); @@ -361,7 +364,35 @@ describe("TestResultCorrectionModal", () => { }); describe("correction actions", () => { - it("mark as error sends GraphQL request to remove test", async () => { + it.each([true, false])( + "mark as error sends GraphQL request to remove test", + async (isFacilityDeleted) => { + renderModal(isFacilityDeleted, mocks); + await selectOther(); + const additionalDetails = await screen.findByTestId( + "additionalInformation" + ); + await act( + async () => + await userEvent.type(additionalDetails, "Some good reason") + ); + const correctionActionOption = screen.getByLabelText( + TestCorrectionActions.MARK_AS_ERROR, + { exact: false } + ); + await act(async () => await userEvent.click(correctionActionOption)); + + const submitButton = await screen.findByText("Yes, I'm sure"); + await act(async () => await userEvent.click(submitButton)); + await waitFor(() => { + expect(markAsErrorMockDidComplete).toBe(true); + }); + } + ); + + it("mark as incorrect results sends GraphQL request to correct test", async () => { + renderModal(false, mocks); + await selectOther(); const additionalDetails = await screen.findByTestId( "additionalInformation" ); @@ -369,20 +400,21 @@ describe("TestResultCorrectionModal", () => { async () => await userEvent.type(additionalDetails, "Some good reason") ); - const correctionActionOption = screen.getByLabelText( - TestCorrectionActions.MARK_AS_ERROR, + + const correctionActionOption = screen.getAllByLabelText( + TestCorrectionActions.CORRECT_RESULT, { exact: false } - ); - await act(async () => await userEvent.click(correctionActionOption)); + )[0]; + await act(async () => await userEvent.click(correctionActionOption)); const submitButton = await screen.findByText("Yes, I'm sure"); await act(async () => await userEvent.click(submitButton)); - await waitFor(() => { - expect(markAsErrorMockDidComplete).toBe(true); - }); + await waitFor(() => expect(markAsCorrectionMockDidComplete).toBe(true)); }); - it("mark as incorrect results sends GraphQL request to correct test", async () => { + it("mark as incorrect results is blocked when facility is deleted", async () => { + renderModal(true, mocks); + await selectOther(); const additionalDetails = await screen.findByTestId( "additionalInformation" ); @@ -397,10 +429,74 @@ describe("TestResultCorrectionModal", () => { )[0]; await act(async () => await userEvent.click(correctionActionOption)); - const submitButton = await screen.findByText("Yes, I'm sure"); - await act(async () => await userEvent.click(submitButton)); - await waitFor(() => expect(markAsCorrectionMockDidComplete).toBe(true)); + expect(await screen.findByText("Yes, I'm sure")).toBeDisabled(); + expect( + screen.getByText("Can't update test result for deleted facility") + ).toBeInTheDocument(); + }); + }); + }); + + describe("when correcting for incorrect test date", () => { + let markAsCorrectMockDidComplete = false; + const mocks = [ + { + request: { + query: MARK_TEST_AS_CORRECTION, + variables: { + id: internalId, + reason: TestCorrectionReason.INCORRECT_TEST_DATE, + }, + }, + result: () => { + markAsCorrectMockDidComplete = true; + + return { + data: { + correctTestMarkAsCorrection: { internalId }, + }, + }; + }, + }, + ]; + beforeEach(() => { + markAsCorrectMockDidComplete = false; + }); + it("sends a GraphQL request to edit results", async () => { + renderModal(false, mocks); + const dropdown = await screen.findByLabelText( + "Please select a reason for correcting this test result." + ); + await act( + async () => + await userEvent.selectOptions( + dropdown, + TestCorrectionReasons.INCORRECT_TEST_DATE + ) + ); + const submitButton = await screen.findByText("Yes, I'm sure"); + await act(async () => await userEvent.click(submitButton)); + await waitFor(() => { + expect(markAsCorrectMockDidComplete).toBe(true); }); }); + it("should block submission for incorrect test date when facility is deleted", async () => { + renderModal(true, mocks); + const dropdown = await screen.findByLabelText( + "Please select a reason for correcting this test result." + ); + await act( + async () => + await userEvent.selectOptions( + dropdown, + TestCorrectionReasons.INCORRECT_TEST_DATE + ) + ); + + expect(await screen.findByText("Yes, I'm sure")).toBeDisabled(); + expect( + screen.getByText("Can't update test date for deleted facility") + ).toBeInTheDocument(); + }); }); }); diff --git a/frontend/src/app/testResults/TestResultCorrectionModal.tsx b/frontend/src/app/testResults/TestResultCorrectionModal.tsx index 6d27b4dade..663381e95d 100644 --- a/frontend/src/app/testResults/TestResultCorrectionModal.tsx +++ b/frontend/src/app/testResults/TestResultCorrectionModal.tsx @@ -110,6 +110,7 @@ export const MARK_TEST_AS_CORRECTION = gql` interface Props { data: any; // testQuery result + isFacilityDeleted: boolean; testResultId: string | undefined; closeModal: () => void; } @@ -118,6 +119,7 @@ export const DetachedTestResultCorrectionModal = ({ testResultId, data, closeModal, + isFacilityDeleted = false, }: Props) => { const [markTestAsError] = useMutation(MARK_TEST_AS_ERROR); const [markTestAsCorrection] = useMutation(MARK_TEST_AS_CORRECTION); @@ -167,6 +169,20 @@ export const DetachedTestResultCorrectionModal = ({ }); }; + const validationMessageForDeletedFacility = () => { + if (isFacilityDeleted) { + if ( + reason === TestCorrectionReason.INCORRECT_RESULT || + (reason === TestCorrectionReason.OTHER && + action === TestCorrectionAction.CORRECT_RESULT) + ) { + return "Can't update test result for deleted facility"; + } else if (reason === TestCorrectionReason.INCORRECT_TEST_DATE) { + return "Can't update test date for deleted facility"; + } + } + return ""; + }; return ( - setReason(e.target.value as TestCorrectionReason)} selectedValue={reason} @@ -220,13 +239,23 @@ export const DetachedTestResultCorrectionModal = ({ )}
+ {isFacilityDeleted && ( + <> + + You can only update duplicate tests and errors from a deleted + facility. Contact support@simplereport.gov for help. + +
+ + )}