Skip to content

Commit

Permalink
undo manually adding Angelas changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Rocio De Santiago authored and Rocio De Santiago committed Jan 27, 2025
1 parent b9c3db1 commit f10f2a2
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 189 deletions.
34 changes: 2 additions & 32 deletions services/app-api/handlers/reports/buildReport.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ jest.mock("../../storage/reports", () => ({
putReport: () => putMock(),
}));

const validateReportPayloadMock = jest.fn();
jest.mock("../../utils/reportValidation", () => ({
validateReportPayload: () => validateReportPayloadMock(),
}));

describe("Test create report handler", () => {
beforeEach(() => {
jest.clearAllMocks();
Expand All @@ -25,7 +20,8 @@ describe("Test create report handler", () => {
} as User;
const reportOptions = {
name: "report1",
} as ReportOptions;
year: 2026,
} as unknown as ReportOptions;
const report = await buildReport(
ReportType.QMS,
state,
Expand All @@ -40,29 +36,3 @@ describe("Test create report handler", () => {
expect(putMock).toHaveBeenCalled();
});
});

describe("Test validation error", () => {
beforeEach(() => {
jest.clearAllMocks();
});

test("Test that a validation failure throws invalid request error", async () => {
// Manually throw validation error
validateReportPayloadMock.mockImplementation(() => {
throw new Error("you be havin some validatin errors");
});

const state = "PA";
const user = {
fullName: "James Holden",
email: "[email protected]",
} as User;
const reportOptions = {
name: "report1",
} as ReportOptions;

expect(async () => {
await buildReport(ReportType.QMS, state, reportOptions, user);
}).rejects.toThrow("Invalid request");
});
});
30 changes: 12 additions & 18 deletions services/app-api/handlers/reports/buildReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
} from "../../types/reports";
import { User } from "../../types/types";
import { CMIT_LIST } from "../../forms/cmit";
import { validateReportPayload } from "../../utils/reportValidation";
import { logger } from "../../libs/debug-lib";

const reportTemplates = {
[ReportType.QMS]: qmsReportTemplate,
Expand All @@ -25,8 +23,10 @@ export const buildReport = async (
user: User
) => {
const report = structuredClone(reportTemplates[reportType]) as Report;
// TODO: Save version to db (filled or unfilled?)

// TODO: Get version by year
if (reportOptions.year != 2026) {
throw new Error("ERROR: Year should be 2026");
}
report.state = state;
report.id = KSUID.randomSync().string;
report.created = Date.now();
Expand All @@ -36,7 +36,13 @@ export const buildReport = async (
report.type = reportType;
report.status = ReportStatus.NOT_STARTED;
report.name = reportOptions.name;
report.options = reportOptions.options;
report.year = reportOptions.year;
report.options = {
cahps: reportOptions.cahps,
hciidd: reportOptions.hciidd,
nciad: reportOptions.nciad,
pom: reportOptions.pom,
};

if (reportType == ReportType.QMS) {
/*
Expand Down Expand Up @@ -67,20 +73,8 @@ export const buildReport = async (
report.pages = report.pages.concat(measurePages);
}

/**
* Report should always be valid in this function, but we're going
* to send it through the report validator for a sanity check
*/
let validatedReport: Report | undefined;
try {
validatedReport = await validateReportPayload(report);
} catch (err) {
logger.error(err);
throw new Error("Invalid request");
}

// Save
await putReport(validatedReport);
await putReport(report);
return report;
};

Expand Down
91 changes: 4 additions & 87 deletions services/app-api/handlers/reports/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,12 @@ import { StatusCodes } from "../../libs/response-lib";
import { proxyEvent } from "../../testing/proxyEvent";
import { APIGatewayProxyEvent, UserRoles } from "../../types/types";
import { canWriteState } from "../../utils/authorization";
import {
incorrectTypeReport,
invalidFormPageReport,
invalidMeasureLookupReport,
invalidMeasureTemplatesReport,
invalidParentPageReport,
invalidRadioCheckedChildrenReport,
missingStateReport,
validReport,
} from "../../utils/tests/mockReport";
import { updateReport } from "./update";

jest.mock("../../utils/authentication", () => ({
authenticatedUser: jest.fn().mockResolvedValue({
role: UserRoles.STATE_USER,
state: "PA",
fullName: "Anthony Soprano",
}),
}));

Expand All @@ -30,15 +19,12 @@ jest.mock("../../storage/reports", () => ({
putReport: () => jest.fn(),
}));

const report = JSON.stringify(validReport);
const reportObj = { type: "QMS", state: "PA", id: "QMSPA123" };
const report = JSON.stringify(reportObj);

const testEvent: APIGatewayProxyEvent = {
...proxyEvent,
pathParameters: {
reportType: "QMS",
state: "NJ",
id: "2rRaoAFm8yLB2N2wSkTJ0iRTDu0",
},
pathParameters: { reportType: "QMS", state: "PA", id: "QMSPA123" },
headers: { "cognito-identity-id": "test" },
body: report,
};
Expand Down Expand Up @@ -82,7 +68,7 @@ describe("Test update report handler", () => {
const badState = {
...proxyEvent,
pathParameters: { reportType: "QMS", state: "PA", id: "QMSPA123" },
body: JSON.stringify({ ...validReport, state: "OR" }),
body: JSON.stringify({ ...reportObj, state: "OR" }),
} as APIGatewayProxyEvent;
const badId = {
...proxyEvent,
Expand All @@ -104,72 +90,3 @@ describe("Test update report handler", () => {
expect(res.statusCode).toBe(StatusCodes.Ok);
});
});

describe("Test update report validation failures", () => {
beforeEach(() => {
jest.clearAllMocks();
});

test("throws an error when validating a report with missing state", async () => {
const missingStateEvent = {
...testEvent,
body: JSON.stringify(missingStateReport),
};

const res = await updateReport(missingStateEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
test("throws an error when validating a report with incorrect report type", async () => {
const incorrectReportTypeEvent = {
...testEvent,
body: JSON.stringify(incorrectTypeReport),
};

const res = await updateReport(incorrectReportTypeEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
test("throws an error when validating invalid measure templates", async () => {
const invalidMeasureTemplatesEvent = {
...testEvent,
body: JSON.stringify(invalidMeasureTemplatesReport),
};

const res = await updateReport(invalidMeasureTemplatesEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
test("throws an error when validating invalid measure lookup object", async () => {
const invalidMeasureLookupEvent = {
...testEvent,
body: JSON.stringify(invalidMeasureLookupReport),
};

const res = await updateReport(invalidMeasureLookupEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
test("throws an error when validating invalid form page object", async () => {
const invalidFormPageEvent = {
...testEvent,
body: JSON.stringify(invalidFormPageReport),
};

const res = await updateReport(invalidFormPageEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
test("throws an error when validating invalid parent page object", async () => {
const invalidParentPageEvent = {
...testEvent,
body: JSON.stringify(invalidParentPageReport),
};

const res = await updateReport(invalidParentPageEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
test("throws an error when validating invalid radio element checked children object", async () => {
const invalidRadioCheckedChildrenEvent = {
...testEvent,
body: JSON.stringify(invalidRadioCheckedChildrenReport),
};
const res = await updateReport(invalidRadioCheckedChildrenEvent);
expect(res.statusCode).toBe(StatusCodes.BadRequest);
});
});
13 changes: 2 additions & 11 deletions services/app-api/handlers/reports/update.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { logger } from "../../libs/debug-lib";
import { handler } from "../../libs/handler-lib";
import { parseReportParameters } from "../../libs/param-lib";
import { badRequest, forbidden, ok } from "../../libs/response-lib";
import { putReport } from "../../storage/reports";
import { Report, ReportStatus } from "../../types/reports";
import { canWriteState } from "../../utils/authorization";
import { error } from "../../utils/constants";
import { validateReportPayload } from "../../utils/reportValidation";

export const updateReport = handler(parseReportParameters, async (request) => {
const { reportType, state, id } = request.parameters;
Expand All @@ -33,15 +31,8 @@ export const updateReport = handler(parseReportParameters, async (request) => {
report.lastEdited = Date.now();
report.lastEditedBy = user.fullName;

let validatedPayload: Report | undefined;
try {
validatedPayload = await validateReportPayload(request.body);
} catch (err) {
logger.error(err);
return badRequest("Invalid request");
}

await putReport(validatedPayload);
// Validation required.
await putReport(report);

return ok();
});
1 change: 0 additions & 1 deletion services/app-api/types/reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ export const isResultRowButton = (

export type RadioTemplate = {
type: ElementType.Radio;
formKey?: string;
label: string;
helperText?: string;
value: ChoiceTemplate[];
Expand Down
12 changes: 7 additions & 5 deletions services/app-api/utils/reportValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
string,
} from "yup";
import {
Report,
ReportStatus,
ReportType,
MeasureTemplateName,
Expand Down Expand Up @@ -40,6 +39,7 @@ const textboxTemplateSchema = object().shape({
label: string().required(),
helperText: string().notRequired(),
answer: string().notRequired(),
required: string().notRequired(),
});

const dateTemplateSchema = object().shape({
Expand Down Expand Up @@ -92,13 +92,12 @@ const pageElementSchema = lazy((value: PageElement): Schema<any> => {
case ElementType.StatusTable:
return statusTableTemplateSchema;
default:
throw new Error("Page Element type is not valid");
return mixed().notRequired(); // Fallback, although it should never be hit
}
});

const radioTemplateSchema = object().shape({
type: string().required(ElementType.Radio),
formKey: string().notRequired(), // TODO: may be able to remove in future
label: string().required(),
helperText: string().notRequired(),
value: array().of(
Expand All @@ -110,6 +109,7 @@ const radioTemplateSchema = object().shape({
})
),
answer: string().notRequired(),
required: string().notRequired(),
});

const buttonLinkTemplateSchema = object().shape({
Expand Down Expand Up @@ -248,7 +248,9 @@ const reportValidateSchema = object().shape({
measureTemplates: measureTemplatesSchema,
});

export const validateReportPayload = async (payload: object | undefined) => {
export const validateUpdateReportPayload = async (
payload: object | undefined
) => {
if (!payload) {
throw new Error(error.MISSING_DATA);
}
Expand All @@ -257,5 +259,5 @@ export const validateReportPayload = async (payload: object | undefined) => {
stripUnknown: true,
});

return validatedPayload as Report;
return validatedPayload;
};
20 changes: 2 additions & 18 deletions services/app-api/utils/tests/mockReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const validReport: Report = {
lastEditedByEmail: "[email protected]",
status: ReportStatus.NOT_STARTED,
name: "yeehaw",
year: 2026,
options: {},
};

export const missingStateReport = {
Expand Down Expand Up @@ -164,21 +166,3 @@ export const invalidRadioCheckedChildrenReport = {
},
} as Record<MeasureTemplateName, MeasurePageTemplate>,
};

export const invalidPageElementType = {
...validReport,
pages: [
{
id: "general-info",
title: "General Info",
type: PageType.Standard,
sidebar: true,
elements: [
{
type: "badElementType", // Doesn't use ElementType enum
text: "State of Program Information",
},
],
},
],
};
Loading

0 comments on commit f10f2a2

Please sign in to comment.