Skip to content

Commit

Permalink
Dev -> Val (#11534)
Browse files Browse the repository at this point in the history
  • Loading branch information
BearHanded authored Dec 14, 2023
2 parents 20b06df + 7a485ca commit 6357cd3
Show file tree
Hide file tree
Showing 67 changed files with 692 additions and 518 deletions.
60 changes: 60 additions & 0 deletions services/app-api/handlers/reports/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jest.mock("../../utils/debugging/debug-lib", () => ({
flush: jest.fn(),
}));

global.structuredClone = (val: any) => JSON.parse(JSON.stringify(val));

const mockProxyEvent = {
...proxyEvent,
headers: { "cognito-identity-id": "test" },
Expand Down Expand Up @@ -61,6 +63,33 @@ const creationEvent: APIGatewayProxyEvent = {
}),
};

const createPccmEvent: APIGatewayProxyEvent = {
...mockProxyEvent,
body: JSON.stringify({
fieldData: {
stateName: "Alabama",
},
metadata: {
reportType: "MCPAR",
programName: "testProgram",
status: "Not started",
reportingPeriodStartDate: 162515200000,
reportingPeriodEndDate: 168515200000,
dueDate: 168515200000,
combinedData: false,
lastAlteredBy: "Thelonious States",
fieldDataId: "mockReportFieldData",
formTemplateId: "mockReportJson",
programIsPCCM: [
{
value: "Yes",
key: "programIsPCCM-yes_programIsPCCM",
},
],
},
}),
};

const creationEventWithNoFieldData: APIGatewayProxyEvent = {
...mockProxyEvent,
body: JSON.stringify({ fieldData: undefined }),
Expand Down Expand Up @@ -208,6 +237,37 @@ describe("Test createReport API method", () => {
expect(body.fieldData.plans).toBeUndefined();
});

test("Test successful run of PCCM report creation, not copied", async () => {
const res = await createReport(createPccmEvent, null);

const body = JSON.parse(res.body);
expect(res.statusCode).toBe(StatusCodes.CREATED);
expect(body.status).toContain("Not started");
expect(body.fieldDataId).toBeDefined;
expect(body.formTemplateId).toBeDefined;
expect(body.formTemplateId).not.toEqual(
mockMcparReport.metadata.formTemplateId
);
expect(body.programIsPCCM).toEqual([
{
value: "Yes",
key: "programIsPCCM-yes_programIsPCCM",
},
]);
expect(body.fieldData.stateName).toBe("Alabama");
expect(body.formTemplate.validationJson).toMatchObject({
stateName: "text",
});
expect(body.fieldData.plans).toBeUndefined();
expect(body.fieldData.sanctions).toBeUndefined();
expect(body.fieldData.state_statewideMedicaidEnrollment).toBeUndefined();
expect(
body.fieldData.state_statewideMedicaidManagedCareEnrollment
).toBeUndefined();
expect(body.fieldData.programName).toBeUndefined();
expect(body.fieldData.plans).toBeUndefined();
});

test("Test attempted report creation with invalid data fails", async () => {
const res = await createReport(creationEventWithInvalidData, null);
expect(res.statusCode).toBe(StatusCodes.SERVER_ERROR);
Expand Down
11 changes: 10 additions & 1 deletion services/app-api/handlers/reports/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ import {
} from "../../utils/types";
import { getOrCreateFormTemplate } from "../../utils/formTemplates/formTemplates";
import { logger } from "../../utils/logging";
import { copyFieldDataFromSource } from "../../utils/reports/reports";
import {
copyFieldDataFromSource,
makePCCMModifications,
} from "../../utils/reports/reports";

export const createReport = handler(async (event, _context) => {
if (!hasPermissions(event, [UserRoles.STATE_USER, UserRoles.STATE_REP])) {
Expand Down Expand Up @@ -140,6 +143,12 @@ export const createReport = handler(async (event, _context) => {
} else {
newFieldData = validatedFieldData;
}

// make necessary modifications for PCCM
if (isProgramPCCM) {
newFieldData = makePCCMModifications(newFieldData);
}

const fieldDataParams: S3Put = {
Bucket: reportBucket,
Key: getFieldDataKey(state, fieldDataId),
Expand Down
13 changes: 13 additions & 0 deletions services/app-api/utils/formTemplates/formTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,18 @@ export const generatePCCMTemplate = (originalReportTemplate: any) => {
}
}

// make additional form modifications as necessary
makePCCMTemplateModifications(reportTemplate);

return reportTemplate;
};

const makePCCMTemplateModifications = (reportTemplate: ReportJson) => {
// Find Question C1.I.3 Program type in Section C.I and disable it
const programTypeQuestion =
reportTemplate.routes[2].children![0].form!.fields[3];
if (programTypeQuestion.id !== "program_type") {
throw new Error("Update PCCM logic!");
}
programTypeQuestion.props!.disabled = true;
};
15 changes: 14 additions & 1 deletion services/app-api/utils/reports/reports.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { copyFieldDataFromSource } from "./reports";
import { copyFieldDataFromSource, makePCCMModifications } from "./reports";
import { ReportType } from "../../utils/types";
import { mockReportJson } from "../../utils/testing/setupJest";
describe("Test copyFieldDataFromSource", () => {
Expand All @@ -13,4 +13,17 @@ describe("Test copyFieldDataFromSource", () => {
);
expect(res).toEqual({ stateName: "Minnesota" });
});

test("Test makePCCMModifications sets correct field data", () => {
let testFieldData = {};
testFieldData = makePCCMModifications(testFieldData);
expect(testFieldData).toEqual({
program_type: [
{
key: "program_type-atiwcA9QUE2eoTchV2ZLtw", // pragma: allowlist secret
value: "Primary Care Case Management (PCCM) Entity",
},
],
});
});
});
12 changes: 12 additions & 0 deletions services/app-api/utils/reports/reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,15 @@ function isEntity(rootKey: string): rootKey is keyof typeof McparFieldsToCopy {
function nonEmptyObject(obj: AnyObject) {
return Object.keys(obj).length > 0;
}

export function makePCCMModifications(fieldData: any) {
// Section C.I, Question C1.I.3 Program type; select PCCM option
fieldData.program_type = [
{
key: "program_type-atiwcA9QUE2eoTchV2ZLtw", // pragma: allowlist secret
value: "Primary Care Case Management (PCCM) Entity",
},
];

return fieldData;
}
14 changes: 7 additions & 7 deletions services/ui-src/src/components/app/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import { act } from "react-dom/test-utils";
import { axe } from "jest-axe";
// utils
import {
mockStateUser,
mockNoUser,
mockNoUserStore,
RouterWrappedComponent,
mockUseStore,
} from "utils/testing/setupJest";
import { useUser, UserProvider } from "utils";
import { UserProvider, useStore } from "utils";
//components
import { App } from "components";

jest.mock("utils/auth/useUser");
const mockedUseUser = useUser as jest.MockedFunction<typeof useUser>;
jest.mock("utils/state/useStore");
const mockedUseStore = useStore as jest.MockedFunction<typeof useStore>;
mockedUseStore.mockReturnValue(mockUseStore);

const appComponent = (
<RouterWrappedComponent>
Expand All @@ -24,15 +25,14 @@ const appComponent = (

describe("Test App", () => {
test("App is visible", async () => {
mockedUseUser.mockReturnValue(mockStateUser);
await act(async () => {
await render(appComponent);
});
expect(screen.getByTestId("app-container")).toBeVisible();
});

test("App renders local logins if there is no user", async () => {
mockedUseUser.mockReturnValue(mockNoUser);
mockedUseStore.mockReturnValue(mockNoUserStore);
await act(async () => {
await render(appComponent);
});
Expand Down
12 changes: 9 additions & 3 deletions services/ui-src/src/components/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useContext, useEffect } from "react";
import { useLocation, Route, Routes } from "react-router-dom";
import { ErrorBoundary } from "react-error-boundary";
// components
Expand All @@ -21,12 +21,18 @@ import {
fireTealiumPageView,
isApparentReportPage,
makeMediaQueryClasses,
useUser,
UserContext,
useStore,
} from "utils";

export const App = () => {
const mqClasses = makeMediaQueryClasses();
const { logout, user, showLocalLogins } = useUser();

// state management
const context = useContext(UserContext);
const { logout } = context;
const { user, showLocalLogins } = useStore();

const { pathname, key } = useLocation();
const isExportPage = pathname.includes("/export");

Expand Down
43 changes: 31 additions & 12 deletions services/ui-src/src/components/app/AppRoutes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import { createMemoryHistory } from "history";
// components
import { AppRoutes } from "components";
// utils
import { useUser, UserProvider } from "utils";
import { UserProvider, useStore } from "utils";
import {
mockAdminUser,
mockAdminUserStore,
mockBannerStore,
mockLDFlags,
mockStateUser,
mockStateUserNoReports,
mockStateUserStore,
mockStateUserStoreNoReports,
} from "utils/testing/setupJest";
// verbiage
import notFoundVerbiage from "verbiage/pages/not-found";

jest.mock("utils/auth/useUser");
const mockedUseUser = useUser as jest.MockedFunction<typeof useUser>;
jest.mock("utils/state/useStore");
const mockedUseStore = useStore as jest.MockedFunction<typeof useStore>;

mockLDFlags.setDefault({ mlrReport: true });

Expand All @@ -34,7 +35,10 @@ const tempScroll = window.HTMLElement.prototype.scrollIntoView;
describe("Test AppRoutes for admin-specific routes", () => {
beforeEach(async () => {
window.HTMLElement.prototype.scrollIntoView = function () {};
mockedUseUser.mockReturnValue(mockAdminUser);
mockedUseStore.mockReturnValue({
...mockAdminUserStore,
...mockBannerStore,
});
history = createMemoryHistory();
history.push("/admin");
await act(async () => {
Expand All @@ -52,7 +56,10 @@ describe("Test AppRoutes for admin-specific routes", () => {

describe("Test AppRoutes for non-admin-specific routes", () => {
beforeEach(async () => {
mockedUseUser.mockReturnValue(mockStateUser);
mockedUseStore.mockReturnValue({
...mockStateUserStore,
...mockBannerStore,
});
history = createMemoryHistory();
history.push("/admin");
await act(async () => {
Expand All @@ -68,7 +75,10 @@ describe("Test AppRoutes for non-admin-specific routes", () => {

describe("Test AppRoutes for non-admin-specific routes", () => {
beforeEach(async () => {
mockedUseUser.mockReturnValue(mockStateUser);
mockedUseStore.mockReturnValue({
...mockStateUserStore,
...mockBannerStore,
});
history = createMemoryHistory();
history.push("/admin");
await act(async () => {
Expand All @@ -84,7 +94,10 @@ describe("Test AppRoutes for non-admin-specific routes", () => {

describe("Test AppRoutes 404 handling", () => {
beforeEach(async () => {
mockedUseUser.mockReturnValue(mockStateUser);
mockedUseStore.mockReturnValue({
...mockStateUserStore,
...mockBannerStore,
});
history = createMemoryHistory();
history.push("/obviously-fake-route");
await act(async () => {
Expand All @@ -100,7 +113,10 @@ describe("Test AppRoutes 404 handling", () => {
describe("Test AppRoutes for MCPAR report-specific routes", () => {
beforeEach(async () => {
window.HTMLElement.prototype.scrollIntoView = function () {};
mockedUseUser.mockReturnValue(mockStateUser);
mockedUseStore.mockReturnValue({
...mockStateUserStore,
...mockBannerStore,
});
history = createMemoryHistory();
history.push("/mcpar");
await act(async () => {
Expand All @@ -119,7 +135,10 @@ describe("Test AppRoutes for MCPAR report-specific routes", () => {
describe("Test AppRoutes for state users without report-specific access", () => {
beforeEach(async () => {
window.HTMLElement.prototype.scrollIntoView = function () {};
mockedUseUser.mockReturnValue(mockStateUserNoReports);
mockedUseStore.mockReturnValue({
...mockStateUserStoreNoReports,
...mockBannerStore,
});
history = createMemoryHistory();
history.push("/mlr");
await act(async () => {
Expand Down
9 changes: 6 additions & 3 deletions services/ui-src/src/components/app/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ import {
} from "components";
// utils
import { ReportRoute, ReportType } from "types";
import { ScrollToTopComponent, useUser } from "utils";
import { ScrollToTopComponent, useStore } from "utils";
import { Fragment, useContext } from "react";
import { Flex, Spinner } from "@chakra-ui/react";

export const AppRoutes = () => {
const { userIsAdmin, userReports } = useUser().user ?? {};
const mlrReport = useFlags()?.mlrReport;
const { userIsAdmin, userReports } = useStore().user ?? {};
const { report, contextIsLoaded } = useContext(ReportContext);

// LaunchDarkly
const mlrReport = useFlags()?.mlrReport;

// determine if the user has access to specific reports
const userReportAccess = {
MCPAR: userReports?.includes("MCPAR") || userIsAdmin,
Expand Down
14 changes: 7 additions & 7 deletions services/ui-src/src/components/cards/TemplateCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { TemplateCard } from "components";
// utils
import {
mockLDFlags,
mockStateUser,
mockStateUserNoReports,
mockStateUserStore,
mockStateUserStoreNoReports,
RouterWrappedComponent,
} from "utils/testing/setupJest";
import { useUser } from "utils";
import { useStore } from "utils";
// verbiage
import verbiage from "verbiage/pages/home";

Expand All @@ -23,8 +23,8 @@ jest.mock("utils/other/useBreakpoint", () => ({
})),
}));

jest.mock("utils/auth/useUser");
const mockedUseUser = useUser as jest.MockedFunction<typeof useUser>;
jest.mock("utils/state/useStore");
const mockedUseStore = useStore as jest.MockedFunction<typeof useStore>;

const mockUseNavigate = jest.fn();

Expand Down Expand Up @@ -79,15 +79,15 @@ describe("Test MCPAR TemplateCard", () => {
});

test("MCPAR TemplateCard navigates to next route on link click", async () => {
mockedUseUser.mockReturnValue(mockStateUser);
mockedUseStore.mockReturnValue(mockStateUserStore);
const templateCardLink = screen.getByText(mcparTemplateVerbiage.link.text)!;
await userEvent.click(templateCardLink);
const expectedRoute = mcparTemplateVerbiage.link.route;
await expect(mockUseNavigate).toHaveBeenCalledWith(expectedRoute);
});

test("'Enter MCPAR' button is disabled for user with no access to this report", async () => {
mockedUseUser.mockReturnValue(mockStateUserNoReports);
mockedUseStore.mockReturnValue(mockStateUserStoreNoReports);
const templateCardLink = screen.getByText(mcparTemplateVerbiage.link.text)!;
expect(templateCardLink).toBeDisabled;
});
Expand Down
Loading

0 comments on commit 6357cd3

Please sign in to comment.