From 6fab5d0d2086560aedfb08ab617581908594bc06 Mon Sep 17 00:00:00 2001 From: Thomas Walker Date: Wed, 8 Jan 2025 14:35:59 -0500 Subject: [PATCH] feat(test)-submit lambda (#987) * feat(test)-submit lambda * Update withdrawpackage to withdrawrai * linter corrections * Fix some test * Test for malformed objects * Remove import vs code added in * remove console.log * Updatign to use get requestcontext --- lib/lambda/search.test.ts | 2 +- lib/lambda/submit/index.test.ts | 257 ++++++++++++++ .../submit/indexMissingAttachments.test.ts | 193 +++++++++++ .../submissionPayloads/capitated-amendment.ts | 15 +- .../upload-subsequent-documents.ts | 17 +- lib/libs/api/auth/user.ts | 34 +- mocks/data/items.ts | 15 +- mocks/data/submit/attachments.ts | 319 ++++++++++++++++++ mocks/data/submit/base.ts | 207 ++++++++++++ mocks/data/submit/baseMissingAttachments.ts | 160 +++++++++ mocks/handlers/opensearch/main.ts | 26 +- 11 files changed, 1186 insertions(+), 59 deletions(-) create mode 100644 lib/lambda/submit/index.test.ts create mode 100644 lib/lambda/submit/indexMissingAttachments.test.ts create mode 100644 mocks/data/submit/attachments.ts create mode 100644 mocks/data/submit/base.ts create mode 100644 mocks/data/submit/baseMissingAttachments.ts diff --git a/lib/lambda/search.test.ts b/lib/lambda/search.test.ts index 07f10acfad..2d51b35d21 100644 --- a/lib/lambda/search.test.ts +++ b/lib/lambda/search.test.ts @@ -29,7 +29,7 @@ describe("getSearchData Handler", () => { const body = JSON.parse(res.body); expect(body).toBeTruthy(); expect(body?.hits?.hits).toBeTruthy(); - expect(body?.hits?.hits?.length).toEqual(11); + expect(body?.hits?.hits?.length).toEqual(12); }); it("should handle errors during processing", async () => { diff --git a/lib/lambda/submit/index.test.ts b/lib/lambda/submit/index.test.ts new file mode 100644 index 0000000000..c40f3c42ed --- /dev/null +++ b/lib/lambda/submit/index.test.ts @@ -0,0 +1,257 @@ +import { submit } from "./index"; +import { APIGatewayEvent } from "node_modules/shared-types"; +import { describe, it, expect, vi, afterEach, beforeEach } from "vitest"; +import { getRequestContext } from "mocks"; +import { + capitatedAmendmentBase, + appkBase, + capitatedInitial, + capitatedRenewal, + contractingAmmendment, + contractingInitial, + contractingRenewal, + newChipSubmission, + newMedicaidSubmission, + respondToRai, + temporaryExtension, + toggleWithdrawRai, + uploadSubsequentDocuments, + withdrawPackage, + withdrawRai, +} from "mocks/data/submit/base"; + +vi.mock("kafkajs", () => { + const producer = { + connect: vi.fn(), + send: vi.fn(), + disconnect: vi.fn(), + }; + const kafka = { + producer: () => producer, + }; + return { + Kafka: vi.fn(() => kafka), + Producer: vi.fn(() => producer), + }; +}); +describe("submit Lambda function", () => { + let brokerString: string | undefined; + beforeEach(() => { + brokerString = process.env.brokerString; + process.env.brokerString = "broker1,broker2"; + }); + + afterEach(() => { + process.env.brokerString = brokerString; + }); + it("should have no body", async () => { + const event = {} as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(400); + expect(result.body).toEqual('"Event body required"'); + }); + it("should have no event in the body", async () => { + const event = { + body: `{"event": ""}`, + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(400); + expect(result.body).toEqual('{"message":"Bad Request - Missing event name in body"}'); + }); + + it("should have a bad event in the body", async () => { + const event = { + body: `{"event": "Not a real event"}`, + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(400); + expect(result.body).toEqual('{"message":"Bad Request - Unknown event type Not a real event"}'); + }); + it("should start to create an capitated ammendment event", async () => { + const base = JSON.stringify(capitatedAmendmentBase); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an capitated ammendment event", async () => { + const base = JSON.stringify(capitatedAmendmentBase); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an app-k event", async () => { + const base = JSON.stringify(appkBase); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an capitated initial event", async () => { + const base = JSON.stringify(capitatedInitial); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an contracting ammendment event", async () => { + const base = JSON.stringify(contractingAmmendment); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an contracting initial event", async () => { + const base = JSON.stringify(contractingInitial); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an contracting renewal event", async () => { + const base = JSON.stringify(contractingRenewal); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an new chip submission event", async () => { + const base = JSON.stringify(newChipSubmission); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an new chip medicaid submission event", async () => { + const base = JSON.stringify(newMedicaidSubmission); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an new respond to rai event", async () => { + const base = JSON.stringify(respondToRai); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an temporary extension event", async () => { + const base = JSON.stringify(temporaryExtension); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an toggle withdraw event", async () => { + const base = JSON.stringify(toggleWithdrawRai); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an withdraw package event", async () => { + const base = JSON.stringify(withdrawPackage); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an withdraw rai event", async () => { + const base = JSON.stringify(withdrawRai); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an capitated renewal event", async () => { + const base = JSON.stringify(capitatedRenewal); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an contracting initial event", async () => { + const base = JSON.stringify(contractingInitial); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); + it("should start to create an upload subsequent documents event", async () => { + const base = JSON.stringify(uploadSubsequentDocuments); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(200); + expect(result.body).toEqual('{"message":"success"}'); + }); +}); diff --git a/lib/lambda/submit/indexMissingAttachments.test.ts b/lib/lambda/submit/indexMissingAttachments.test.ts new file mode 100644 index 0000000000..464d06d77d --- /dev/null +++ b/lib/lambda/submit/indexMissingAttachments.test.ts @@ -0,0 +1,193 @@ +import { submit } from "./index"; +import { APIGatewayEvent } from "node_modules/shared-types"; +import { describe, it, expect, vi, afterEach, beforeEach } from "vitest"; +import { bma } from "mocks/data/submit/baseMissingAttachments"; +import { getRequestContext } from "mocks"; + +vi.mock("kafkajs", () => { + const producer = { + connect: vi.fn(), + send: vi.fn(), + disconnect: vi.fn(), + }; + const kafka = { + producer: () => producer, + }; + return { + Kafka: vi.fn(() => kafka), + Producer: vi.fn(() => producer), + }; +}); +describe("submit Lambda function missing objects in event", () => { + let brokerString: string | undefined; + beforeEach(() => { + brokerString = process.env.brokerString; + process.env.brokerString = "broker1,broker2"; + }); + + afterEach(() => { + process.env.brokerString = brokerString; + }); + + it("should start to create an capitated ammendment event", async () => { + const base = JSON.stringify(bma.capitatedAmendmentBase); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + + it("should start to create an app-k event", async () => { + const base = JSON.stringify(bma.appkBase); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an capitated initial event", async () => { + const base = JSON.stringify(bma.capitatedInitial); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an contracting ammendment event", async () => { + const base = JSON.stringify(bma.contractingAmmendment); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an contracting initial event", async () => { + const base = JSON.stringify(bma.contractingInitial); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an contracting renewal event", async () => { + const base = JSON.stringify(bma.contractingRenewal); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an new chip submission event", async () => { + const base = JSON.stringify(bma.newChipSubmission); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an new chip medicaid submission event", async () => { + const base = JSON.stringify(bma.newMedicaidSubmission); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an new respond to rai event", async () => { + const base = JSON.stringify(bma.respondToRai); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an temporary extension event", async () => { + const base = JSON.stringify(bma.temporaryExtension); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an toggle withdraw event", async () => { + const base = JSON.stringify(bma.toggleWithdrawRai); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an withdraw package event", async () => { + const base = JSON.stringify(bma.withdrawPackage); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an withdraw rai event", async () => { + const base = JSON.stringify(bma.withdrawRai); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an capitated renewal event", async () => { + const base = JSON.stringify(bma.capitatedRenewal); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an contracting initial event", async () => { + const base = JSON.stringify(bma.contractingInitial); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); + it("should start to create an upload subsequent documents event", async () => { + const base = JSON.stringify(bma.uploadSubsequentDocuments); + + const event = { + body: base, + requestContext: getRequestContext(), + } as unknown as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + }); +}); diff --git a/lib/lambda/submit/submissionPayloads/capitated-amendment.ts b/lib/lambda/submit/submissionPayloads/capitated-amendment.ts index 97b1c8eb99..6bbb429583 100644 --- a/lib/lambda/submit/submissionPayloads/capitated-amendment.ts +++ b/lib/lambda/submit/submissionPayloads/capitated-amendment.ts @@ -1,20 +1,14 @@ // can/should add the additional frontend checks here import { events } from "shared-types/events"; -import { - isAuthorized, - getAuthDetails, - lookupUserAttributes, -} from "../../../libs/api/auth/user"; +import { isAuthorized, getAuthDetails, lookupUserAttributes } from "../../../libs/api/auth/user"; import { type APIGatewayEvent } from "aws-lambda"; import { itemExists } from "libs/api/package"; export const capitatedAmendment = async (event: APIGatewayEvent) => { if (!event.body) return; - const parsedResult = events["capitated-amendment"].baseSchema.safeParse( - JSON.parse(event.body), - ); + const parsedResult = events["capitated-amendment"].baseSchema.safeParse(JSON.parse(event.body)); if (!parsedResult.success) { throw parsedResult.error; } @@ -30,10 +24,7 @@ export const capitatedAmendment = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/lambda/submit/submissionPayloads/upload-subsequent-documents.ts b/lib/lambda/submit/submissionPayloads/upload-subsequent-documents.ts index 8d2a0e05b0..5c9baebbad 100644 --- a/lib/lambda/submit/submissionPayloads/upload-subsequent-documents.ts +++ b/lib/lambda/submit/submissionPayloads/upload-subsequent-documents.ts @@ -1,14 +1,14 @@ import { APIGatewayEvent } from "aws-lambda"; -import { getAuthDetails, lookupUserAttributes } from "lib/libs/api/auth/user"; -import { itemExists } from "lib/libs/api/package"; -import { events } from "lib/packages/shared-types"; +import { getAuthDetails, lookupUserAttributes } from "libs/api/auth/user"; +import { itemExists } from "libs/api/package"; +import { events } from "shared-types"; export const uploadSubsequentDocuments = async (event: APIGatewayEvent) => { if (event.body === null) return; - const parsedResult = events[ - "upload-subsequent-documents" - ].baseSchema.safeParse(JSON.parse(event.body)); + const parsedResult = events["upload-subsequent-documents"].baseSchema.safeParse( + JSON.parse(event.body), + ); if (parsedResult.success === false) { throw parsedResult.error; @@ -19,10 +19,7 @@ export const uploadSubsequentDocuments = async (event: APIGatewayEvent) => { } const authDetails = getAuthDetails(event); - const userAttr = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttr = await lookupUserAttributes(authDetails.userId, authDetails.poolId); const submitterEmail = userAttr.email; const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; diff --git a/lib/libs/api/auth/user.ts b/lib/libs/api/auth/user.ts index 71a2544d3e..9a2608d4e1 100644 --- a/lib/libs/api/auth/user.ts +++ b/lib/libs/api/auth/user.ts @@ -9,8 +9,7 @@ import { isCmsWriteUser, isCmsUser } from "shared-utils"; // Retrieve user authentication details from the APIGatewayEvent export function getAuthDetails(event: APIGatewayEvent) { - const authProvider = - event.requestContext.identity.cognitoAuthenticationProvider; + const authProvider = event.requestContext.identity.cognitoAuthenticationProvider; if (!authProvider) { throw new Error("No auth provider!"); } @@ -74,38 +73,27 @@ export async function fetchUserFromCognito( try { const listUsersResponse = await cognitoClient.send(commandListUsers); - if ( - listUsersResponse.Users === undefined || - listUsersResponse.Users.length !== 1 - ) { + if (listUsersResponse.Users === undefined || listUsersResponse.Users.length !== 1) { throw new Error("No user found with this sub"); } const currentUser = listUsersResponse.Users[0]; return currentUser; } catch (error) { - if ( - error instanceof Error && - error.message === "No user found with this sub" - ) { + if (error instanceof Error && error.message === "No user found with this sub") { throw error; } throw new Error("Error fetching user from Cognito"); } } -export const isAuthorized = async ( - event: APIGatewayEvent, - stateCode?: string | null, -) => { +export const isAuthorized = async (event: APIGatewayEvent, stateCode?: string | null) => { // Retrieve authentication details of the user const authDetails = getAuthDetails(event); // Look up user attributes from Cognito - const userAttributes = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttributes = await lookupUserAttributes(authDetails.userId, authDetails.poolId); + console.log(userAttributes); return ( isCmsUser(userAttributes) || (stateCode && userAttributes?.["custom:state"]?.includes(stateCode)) @@ -120,10 +108,7 @@ export const isAuthorizedToGetPackageActions = async ( const authDetails = getAuthDetails(event); // Look up user attributes from Cognito - const userAttributes = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttributes = await lookupUserAttributes(authDetails.userId, authDetails.poolId); return ( isCmsWriteUser(userAttributes) || (stateCode && userAttributes?.["custom:state"]?.includes(stateCode)) @@ -136,10 +121,7 @@ export const getStateFilter = async (event: APIGatewayEvent) => { const authDetails = getAuthDetails(event); // Look up user attributes from Cognito - const userAttributes = await lookupUserAttributes( - authDetails.userId, - authDetails.poolId, - ); + const userAttributes = await lookupUserAttributes(authDetails.userId, authDetails.poolId); if (!isCmsUser(userAttributes)) { if (userAttributes["custom:state"]) { diff --git a/mocks/data/items.ts b/mocks/data/items.ts index 7db383eee6..9bb2742052 100644 --- a/mocks/data/items.ts +++ b/mocks/data/items.ts @@ -4,6 +4,7 @@ import type { TestItemResult } from "../index.d"; export const EXISTING_ITEM_PENDING_ID = "MD-0002.R00.00"; export const EXISTING_ITEM_APPROVED_NEW_ID = "MD-0000.R00.00"; export const VALID_ITEM_TEMPORARY_EXTENSION_ID = "MD-0000.R00.TE00"; +export const VALID_ITEM_EXTENSION_ID = "VA-1111.R11.00"; export const EXISTING_ITEM_APPROVED_AMEND_ID = "MD-0000.R00.01"; export const EXISTING_ITEM_APPROVED_RENEW_ID = "MD-0000.R01.00"; export const EXISTING_ITEM_ID = "MD-00-0000"; @@ -17,7 +18,7 @@ export const CAPITATED_AMEND_ITEM_ID = "MD-006.R00.01"; export const CONTRACTING_INITIAL_ITEM_ID = "MD-007.R00.00"; export const CONTRACTING_AMEND_ITEM_ID = "MD-007.R00.01"; export const MISSING_CHANGELOG_ITEM_ID = "MD-008.R00.00"; -export const WITHDRAWN_CHANGELOG_ITEM_ID = "MD-009.R00.01"; +export const WITHDRAWN_CHANGELOG_ITEM_ID = "VA-11-2020"; export const INITIAL_RELEASE_APPK_ITEM_ID = "MD-010.R00.01"; export const SUBMISSION_ERROR_ITEM_ID = "Throw Submission Error"; export const GET_ERROR_ITEM_ID = "Throw Get Item Error"; @@ -65,6 +66,18 @@ const items: Record = { state: "MD", }, }, + [VALID_ITEM_EXTENSION_ID]: { + _id: VALID_ITEM_EXTENSION_ID, + found: true, + _source: { + id: VALID_ITEM_EXTENSION_ID, + seatoolStatus: SEATOOL_STATUS.APPROVED, + actionType: "New", + authority: "1915(b)", + origin: "OneMAC", + state: "MD", + }, + }, [EXISTING_ITEM_APPROVED_AMEND_ID]: { _id: EXISTING_ITEM_APPROVED_AMEND_ID, found: true, diff --git a/mocks/data/submit/attachments.ts b/mocks/data/submit/attachments.ts new file mode 100644 index 0000000000..1a08b179eb --- /dev/null +++ b/mocks/data/submit/attachments.ts @@ -0,0 +1,319 @@ +const bCapWaiverApplication = { + bCapWaiverApplication: { + label: "1915(b) Comprehensive (Capitated) Waiver Application Pre-print", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const bCapCostSpreadsheets = { + bCapCostSpreadsheets: { + label: "1915(b) Comprehensive (Capitated) Waiver Cost Effectiveness Spreadsheets", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const tribalConsultation = { + tribalConsultation: { + label: "Tribal Consultation", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const other = { + other: { + files: [ + { + filename: "misc-documents.pdf", + title: "Additional Supporting Documents", + bucket: "mako-outbox-attachments-635052997545", + key: "c22aa4dc-e1b6-41d5-bf64-e45b6f74f5af.pdf", + uploadDate: Date.now(), + }, + ], + label: "Other", + }, +}; +const appk = { + appk: { + label: "Appendix K Template", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const b4Waiver = { + b4WaiverApplication: { + label: "1915(b)(4) FFS Selective Contracting (Streamlined) Waiver Application Pre-print", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const b4IndependentAssessment = { + b4IndependentAssessment: { + label: + "1915(b)(4) FFS Selective Contracting (Streamlined) Independent Assessment (first two renewals only)", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const currentStatePlan = { + currentStatePlan: { + label: "Current State Plan", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const ammendedLanguage = { + amendedLanguage: { + label: "Amended State Plan Language", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const coverLetter = { + coverLetter: { + label: "Cover Letter", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const budgetDocuments = { + budgetDocuments: { + label: "Budget Document", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const publicNotice = { + publicNotice: { + label: "Public Notice", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const cmsForm = { + cmsForm179: { + label: "CMS Form 179", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +export const spaPages = { + spaPages: { + label: "Spa Pages", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const existingStatePlanPages = { + existingStatePlanPages: { + label: "Existing State Plan Page(s)", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const sfq = { + sfq: { + label: "Standard Funding Questions (SFQs)", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const tribalEngagement = { + tribalEngagement: { + label: "Document Demonstrating Good-Faith Tribal Engagement", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const raiResponseLetter = { + raiResponseLetter: { + label: "RAI Response Letter", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const waiverExtensionRequest = { + waiverExtensionRequest: { + label: "RAI Response Letter", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const supportingDocumentation = { + supportingDocumentation: { + label: "Supporting Documentation", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +const bCapIndependentAssessment = { + bCapIndependentAssessment: { + label: + "1915(b) Comprehensive (Capitated) Waiver Independent Assessment (first two renewals only)", + files: [ + { + filename: "appendix-k-amendment.docx", + title: "Appendix K Waiver Amendment", + bucket: "mako-outbox-attachments-635052997545", + key: "8b56f7ab-e1ad-4782-87f4-d43ab9d2f5d7.docx", + uploadDate: Date.now(), + }, + ], + }, +}; +export const attachments = { + ammendedLanguage, + appk, + bCapIndependentAssessment, + bCapCostSpreadsheets, + bCapWaiverApplication, + b4IndependentAssessment, + b4Waiver, + budgetDocuments, + cmsForm, + coverLetter, + currentStatePlan, + existingStatePlanPages, + publicNotice, + raiResponseLetter, + sfq, + spaPages, + supportingDocumentation, + tribalConsultation, + tribalEngagement, + waiverExtensionRequest, + other, +}; diff --git a/mocks/data/submit/base.ts b/mocks/data/submit/base.ts new file mode 100644 index 0000000000..4a134ce37c --- /dev/null +++ b/mocks/data/submit/base.ts @@ -0,0 +1,207 @@ +import { attachments } from "./attachments"; +export const capitatedAmendmentBase = { + id: "VA-1234.R11.01", + event: "capitated-amendment", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.bCapWaiverApplication, + ...attachments.bCapCostSpreadsheets, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const appkBase = { + id: "VA-1234.R11.01", + event: "app-k", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.appk, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", +}; +export const capitatedInitial = { + id: "VA-1234.R00.00", + event: "capitated-initial", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.bCapWaiverApplication, + ...attachments.bCapCostSpreadsheets, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const capitatedRenewal = { + id: "VA-1234.R01.00", + event: "capitated-renewal", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.bCapIndependentAssessment, + ...attachments.bCapWaiverApplication, + ...attachments.bCapCostSpreadsheets, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const contractingAmmendment = { + id: "VA-1234.R11.01", + event: "contracting-amendment", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.b4Waiver, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const contractingInitial = { + id: "VA-1234.R00.00", + event: "contracting-initial", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.b4Waiver, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const contractingRenewal = { + id: "VA-1234.R01.00", + event: "contracting-renewal", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.b4IndependentAssessment, + ...attachments.b4Waiver, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R01.00", +}; +export const newChipSubmission = { + id: "VA-11-2021", + event: "new-chip-submission", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.currentStatePlan, + ...attachments.ammendedLanguage, + ...attachments.coverLetter, + ...attachments.budgetDocuments, + ...attachments.publicNotice, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const newMedicaidSubmission = { + id: "VA-11-2021", + event: "new-medicaid-submission", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.cmsForm, + ...attachments.spaPages, + ...attachments.coverLetter, + ...attachments.tribalEngagement, + ...attachments.existingStatePlanPages, + ...attachments.publicNotice, + ...attachments.sfq, + ...attachments.tribalConsultation, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const respondToRai = { + id: "VA-11-2020", + event: "respond-to-rai", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.raiResponseLetter, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.11", +}; +export const temporaryExtension = { + id: "VA-1234.R11.TE12", + event: "temporary-extension", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.waiverExtensionRequest, + ...attachments.other, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.00", +}; +export const toggleWithdrawRai = { + id: "VA-11-2020", + event: "toggle-withdraw-rai", + authority: "1915(b)", + raiWithdrawEnabled: true, + proposedEffectiveDate: 1700000000, +}; +export const withdrawPackage = { + id: "VA-11-2020", + event: "withdraw-package", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.supportingDocumentation, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.00", +}; +export const withdrawRai = { + id: "VA-11-2020", + event: "withdraw-rai", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: { + ...attachments.supportingDocumentation, + }, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.00", +}; +export const uploadSubsequentDocuments = { + id: "VA-1111.R11.00", + event: "upload-subsequent-documents", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "VA-1111.R11.00", +}; diff --git a/mocks/data/submit/baseMissingAttachments.ts b/mocks/data/submit/baseMissingAttachments.ts new file mode 100644 index 0000000000..81cf3d70d2 --- /dev/null +++ b/mocks/data/submit/baseMissingAttachments.ts @@ -0,0 +1,160 @@ +const capitatedAmendmentBase = { + id: "SS-1234.R11.01", + event: "capitated-amendment", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const appkBase = { + id: "SS-1234.R11.01", + event: "app-k", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", +}; +const capitatedInitial = { + id: "SS-1234.R00.00", + event: "capitated-initial", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const capitatedRenewal = { + id: "SS-1234.R01.00", + event: "capitated-renewal", + authority: "1915(c)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const contractingAmmendment = { + id: "SS-1234.R11.01", + event: "contracting-amendment", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const contractingInitial = { + id: "SS-1234.R00.00", + event: "contracting-initial", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const contractingRenewal = { + id: "SS-1234.R01.00", + event: "contracting-renewal", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R01.00", +}; +const newChipSubmission = { + id: "SS-11-2021", + event: "new-chip-submission", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const newMedicaidSubmission = { + id: "SS-11-2021", + event: "new-medicaid-submission", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const respondToRai = { + id: "SS-11-2020", + event: "respond-to-rai", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.11", +}; +const temporaryExtension = { + id: "SS-1234.R11.TE1213112", + event: "temporary-extension", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.00", +}; +const toggleWithdrawRai = { + id: "SS-11-2020", + event: "toggle-withdraw-rai", + authority: "1915(b)", +}; +const withdrawPackage = { + id: "SS-11-202213210", + event: "withdraw-package", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.00", +}; +const withdrawRai = { + id: "SS-11-2023220", + event: "withdraw-rai", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + title: "Sample Title for Appendix K", + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.00", +}; +const uploadSubsequentDocuments = { + id: "SS-1111.R11.1300", + event: "upload-subsequent-documents", + authority: "1915(b)", + proposedEffectiveDate: 1700000000, + attachments: {}, + additionalInformation: "Some additional information about this submission.", + waiverNumber: "SS-1111.R11.00", +}; +export const bma = { + appkBase, + capitatedAmendmentBase, + capitatedInitial, + capitatedRenewal, + uploadSubsequentDocuments, + withdrawRai, + withdrawPackage, + toggleWithdrawRai, + temporaryExtension, + respondToRai, + newMedicaidSubmission, + newChipSubmission, + contractingRenewal, + contractingInitial, + contractingAmmendment, +}; diff --git a/mocks/handlers/opensearch/main.ts b/mocks/handlers/opensearch/main.ts index 9617c9b4ba..8f4398987e 100644 --- a/mocks/handlers/opensearch/main.ts +++ b/mocks/handlers/opensearch/main.ts @@ -19,8 +19,11 @@ const defaultMainDocumentHandler = http.get( } const itemId = id && Array.isArray(id) ? id[0] : id; const item = items[itemId] || null; - - return item ? HttpResponse.json(item) : new HttpResponse(null, { status: 404 }); + return item + ? HttpResponse.json(item) + : HttpResponse.json({ + found: false, + }); }, ); @@ -28,18 +31,19 @@ const defaultMainSearchHandler = http.post( "https://vpc-opensearchdomain-mock-domain.us-east-1.es.amazonaws.com/test-namespace-main/_search", async ({ request }) => { const { query } = await request.json(); - console.log({ query }) + console.log({ query }); if (query?.match_all?.id == "throw-error") { return new HttpResponse("Internal server error", { status: 500 }); } const must = query?.bool?.must; - console.log("must: ", JSON.stringify(must)) + console.log("must: ", JSON.stringify(must)); const mustTerms = getTermKeys(must); - console.log({ mustTerms }) + console.log({ mustTerms }); - const appkParentIdValue = getTermValues(must, "appkParentId.keyword") || getTermValues(must, "appkParentId"); + const appkParentIdValue = + getTermValues(must, "appkParentId.keyword") || getTermValues(must, "appkParentId"); if (appkParentIdValue) { const appkParentId = @@ -64,7 +68,11 @@ const defaultMainSearchHandler = http.post( "", ) as keyof TestAppkDocument; if (filterValue) { - appkChildren = filterItemsByTerm(appkChildren, filterTerm, filterValue); + appkChildren = filterItemsByTerm( + appkChildren, + filterTerm, + filterValue, + ); } }); } @@ -95,12 +103,12 @@ const defaultMainSearchHandler = http.post( if (itemHits.length > 0) { mustTerms.forEach((term) => { const filterValue = getTermValues(must, term); - console.log({ filterValue }) + console.log({ filterValue }); const filterTerm: keyof TestMainDocument = term.replace( ".keyword", "", ) as keyof TestMainDocument; - console.log({ filterTerm }) + console.log({ filterTerm }); if (filterValue) { itemHits = filterItemsByTerm(itemHits, filterTerm, filterValue); }