-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(lamdba): add admin function for NOSO 2 #1060
base: main
Are you sure you want to change the base?
Changes from all commits
2174b09
b544f2c
ab37e48
2727577
d199239
432b0b1
873d26b
41e9caa
b15ea13
3281fbd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { describe, it, expect, vi, beforeEach } from "vitest"; | ||
import { handler } from "./submitNOSO"; | ||
import { APIGatewayEvent } from "node_modules/shared-types"; | ||
|
||
import { NOT_EXISTING_ITEM_ID, TEST_ITEM_ID } from "mocks"; | ||
|
||
vi.mock("libs/handler-lib", () => ({ | ||
response: vi.fn((data) => data), | ||
})); | ||
|
||
describe("handler", () => { | ||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
process.env.topicName = "test-topic"; | ||
}); | ||
|
||
it("should return 400 if event body is missing", async () => { | ||
const event = {} as APIGatewayEvent; | ||
const result = await handler(event); | ||
const expectedResult = { statusCode: 400, body: { message: "Event body required" } }; | ||
|
||
expect(result).toStrictEqual(expectedResult); | ||
}); | ||
|
||
it("should return 400 if package ID is not found", async () => { | ||
const noActionevent = { | ||
body: JSON.stringify({ packageId: "123", changeReason: "Nunya", authority: "test" }), | ||
} as APIGatewayEvent; | ||
|
||
const resultPackage = await handler(noActionevent); | ||
|
||
expect(resultPackage?.statusCode).toBe(400); | ||
}); | ||
it("should return 400 if admingChangeType is not found", async () => { | ||
const noApackageEvent = { | ||
body: JSON.stringify({ action: "123", changeReason: "Nunya" }), | ||
} as APIGatewayEvent; | ||
|
||
const resultAction = await handler(noApackageEvent); | ||
|
||
expect(resultAction?.statusCode).toBe(400); | ||
}); | ||
it("should return 400 if existing item is entered", async () => { | ||
const noActionevent = { | ||
body: JSON.stringify({ | ||
id: TEST_ITEM_ID, | ||
adminChangeType: "NOSO", | ||
authority: "SPA", | ||
submitterEmail: "[email protected]", | ||
submitterName: "Name", | ||
status: "submitted", | ||
changeMade: "change", | ||
changeReason: "reason", | ||
}), | ||
} as APIGatewayEvent; | ||
|
||
const result = await handler(noActionevent); | ||
|
||
const expectedResult = { | ||
statusCode: 400, | ||
body: { message: `Package with id: ${TEST_ITEM_ID} already exists.` }, | ||
}; | ||
expect(result).toStrictEqual(expectedResult); | ||
}); | ||
|
||
it("should submit a new item", async () => { | ||
const validItem = { | ||
body: JSON.stringify({ | ||
id: NOT_EXISTING_ITEM_ID, | ||
authority: "Medicaid SPA", | ||
status: "submitted", | ||
submitterEmail: "[email protected]", | ||
submitterName: "Name", | ||
adminChangeType: "NOSO", | ||
changeMade: "change", | ||
changeReason: "reason", | ||
}), | ||
} as APIGatewayEvent; | ||
|
||
const result = await handler(validItem); | ||
|
||
const expectedResult = { | ||
statusCode: 200, | ||
body: { message: `${NOT_EXISTING_ITEM_ID} has been submitted.` }, | ||
}; | ||
expect(result).toStrictEqual(expectedResult); | ||
}); | ||
|
||
it("should fail to create a package ID with no topic name", async () => { | ||
process.env.topicName = ""; | ||
const validItem = { | ||
body: JSON.stringify({ | ||
id: NOT_EXISTING_ITEM_ID, | ||
authority: "Medicaid SPA", | ||
status: "submitted", | ||
submitterEmail: "[email protected]", | ||
submitterName: "Name", | ||
adminChangeType: "NOSO", | ||
changeMade: "change", | ||
changeReason: "reason", | ||
}), | ||
} as APIGatewayEvent; | ||
|
||
const result = await handler(validItem); | ||
const expectedResult = { | ||
statusCode: 500, | ||
body: { message: "Topic name is not defined" }, | ||
}; | ||
expect(result).toStrictEqual(expectedResult); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { response } from "libs/handler-lib"; | ||
import { APIGatewayEvent } from "aws-lambda"; | ||
import { produceMessage } from "libs/api/kafka"; | ||
import { getPackage } from "libs/api/package"; | ||
import { ItemResult } from "shared-types/opensearch/main"; | ||
import { submitNOSOAdminSchema } from "./adminChangeSchemas"; | ||
import { z } from "zod"; | ||
|
||
import { getStatus } from "shared-types"; | ||
|
||
interface submitMessageType { | ||
id: string; | ||
authority: string; | ||
status: string; | ||
submitterEmail: string; | ||
submitterName: string; | ||
adminChangeType: string; | ||
stateStatus: string; | ||
cmsStatus: string; | ||
} | ||
|
||
const sendSubmitMessage = async (item: submitMessageType) => { | ||
const topicName = process.env.topicName as string; | ||
if (!topicName) { | ||
throw new Error("Topic name is not defined"); | ||
} | ||
|
||
const currentTime = Date.now(); | ||
|
||
await produceMessage( | ||
topicName, | ||
item.id, | ||
JSON.stringify({ | ||
...item, | ||
packageId: item.id, | ||
origin: "SEATool", | ||
isAdminChange: true, | ||
adminChangeType: "NOSO", | ||
description: null, | ||
event: "NOSO", | ||
state: item.id.substring(0, 2), | ||
makoChangedDate: currentTime, | ||
changedDate: currentTime, | ||
statusDate: currentTime, | ||
}), | ||
); | ||
|
||
return response({ | ||
statusCode: 200, | ||
body: { message: `${item.id} has been submitted.` }, | ||
}); | ||
}; | ||
|
||
export const handler = async (event: APIGatewayEvent) => { | ||
if (!event.body) { | ||
return response({ | ||
statusCode: 400, | ||
body: { message: "Event body required" }, | ||
}); | ||
} | ||
|
||
try { | ||
const item = submitNOSOAdminSchema.parse( | ||
typeof event.body === "string" ? JSON.parse(event.body) : event.body, | ||
); | ||
Comment on lines
+63
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there an advantage to this check? If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a weird thing that I do actually need, in aws the lamdba body is actually sent as a JSON object but if it was used as backend call it would be a string and actually the type: APIGatewayEvent. Since this is the last comment, thanks for the thorough review! |
||
|
||
const { stateStatus, cmsStatus } = getStatus(item.status); | ||
// check if it already exsists | ||
const currentPackage: ItemResult | undefined = await getPackage(item.id); | ||
|
||
if (currentPackage && currentPackage.found == true) { | ||
// if it exists and has origin OneMAC we shouldn't override it | ||
if (currentPackage._source.origin === "OneMAC") { | ||
return response({ | ||
statusCode: 400, | ||
body: { message: `Package with id: ${item.id} already exists.` }, | ||
}); | ||
} | ||
//otherwise we need to add the property origin so it shows up on our dashboard | ||
item["origin"] = "SEATool"; | ||
} | ||
|
||
return await sendSubmitMessage({ ...item, stateStatus, cmsStatus }); | ||
} catch (err) { | ||
console.error("Error has occured submitting package:", err); | ||
if (err instanceof z.ZodError) { | ||
return response({ | ||
statusCode: 400, | ||
body: { message: err.errors }, | ||
}); | ||
} | ||
|
||
return response({ | ||
statusCode: 500, | ||
body: { message: err.message || "Internal Server Error" }, | ||
}); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this supposed to be the
attachments
property? What are we expecting here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this so when I add the properties in "produceMessage" then it is sent to sinkMain those properties aren't cut out.
(New properties I want to stay: origin, isAdminChange, state, makoChangedDate, changedDate, statusDate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay and also I left a confusing comment that I have since deleted but for this type of NOSO's we don't need to have attachments.