diff --git a/lib/lambda/checkConsumerLag.test.ts b/lib/lambda/checkConsumerLag.test.ts index 2402eb5c4..a32d1c6cf 100644 --- a/lib/lambda/checkConsumerLag.test.ts +++ b/lib/lambda/checkConsumerLag.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi, afterEach } from "vitest"; +import { describe, it, expect, vi } from "vitest"; import { handler } from "./checkConsumerLag"; import { Context } from "aws-lambda"; import { @@ -10,31 +10,12 @@ import { TEST_MULTIPLE_TOPICS_TOPIC_NAME, TEST_MISSING_CONSUMER_FUNCTION_NAME, TEST_MISSING_CONSUMER_TOPIC_NAME, + mockedAdmin, } from "mocks"; -const mockKafkaAdmin = { - connect: vi.fn(), - describeGroups: vi.fn().mockResolvedValue({ - groups: [{ state: "Stable" }], - }), - fetchTopicOffsets: vi.fn().mockResolvedValue([{ offset: "100" }]), - fetchOffsets: vi.fn().mockResolvedValue([{ partitions: [{ offset: "100" }] }]), - disconnect: vi.fn(), -}; - -vi.mock("kafkajs", () => ({ - Kafka: vi.fn().mockImplementation(() => ({ - admin: vi.fn().mockReturnValue(mockKafkaAdmin), - })), -})); - describe("Lambda Handler", () => { const callback = vi.fn(); - afterEach(() => { - vi.clearAllMocks(); - }); - it("should handle successful execution with stable and current offsets", async () => { const event = { triggers: [ @@ -113,7 +94,7 @@ describe("Lambda Handler", () => { brokerString: "broker1,broker2", }; - mockKafkaAdmin.describeGroups.mockRejectedValueOnce(new Error("Kafka admin error")); + mockedAdmin.describeGroups.mockRejectedValueOnce(new Error("Kafka admin error")); await handler(event, {} as Context, callback); diff --git a/lib/lambda/submit/index.test.ts b/lib/lambda/submit/index.test.ts index c40f3c42e..405fbd849 100644 --- a/lib/lambda/submit/index.test.ts +++ b/lib/lambda/submit/index.test.ts @@ -1,55 +1,17 @@ +import { describe, it, expect } from "vitest"; 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"; +import { events } 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": ""}`, @@ -67,191 +29,19 @@ describe("submit Lambda function", () => { 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"}'); + describe("successfully submit event types", () => { + it.each(events.map((event) => [event.event, JSON.stringify(event)]))( + "should successfully submit %s event", + async (_, base) => { + 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 index 464d06d77..68889f097 100644 --- a/lib/lambda/submit/indexMissingAttachments.test.ts +++ b/lib/lambda/submit/indexMissingAttachments.test.ts @@ -1,188 +1,16 @@ +import { describe, it, expect } from "vitest"; 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"; +import { eventsAttachmentRequired } 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 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); - + it.each( + eventsAttachmentRequired.map((event) => [ + event.event, + JSON.stringify({ ...event, attachments: {} }), + ]), + )("should return a 500 if %s event is missing attachments", async (_, base) => { const event = { body: base, requestContext: getRequestContext(), diff --git a/lib/lambda/submit/indexUnauthorized.test.ts b/lib/lambda/submit/indexUnauthorized.test.ts index bb91124b5..0875583a2 100644 --- a/lib/lambda/submit/indexUnauthorized.test.ts +++ b/lib/lambda/submit/indexUnauthorized.test.ts @@ -1,107 +1,20 @@ +import { describe, it, expect } from "vitest"; 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 { automatedStateSubmitterUsername } from "mocks/data/users/stateSubmitters"; -import { - capitatedAmendmentBase, - appkBase, - capitatedInitial, - capitatedRenewal, - contractingAmmendment, - contractingInitial, - contractingRenewal, - newChipSubmission, - newMedicaidSubmission, - respondToRai, - temporaryExtension, - toggleWithdrawRai, - withdrawPackage, - withdrawRai, -} from "mocks/data/submit/base"; +import { getRequestContext, automatedStateSubmitter } from "mocks"; +import { eventsAuthorizationRequired } 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.each([ - [ - "should not have authorization to create a capitated ammendment event", - JSON.stringify(capitatedAmendmentBase), - ], - ["should not have authorization to create a appk event", JSON.stringify(appkBase)], - [ - "should not have authorization to create a capitated initial event", - JSON.stringify(capitatedInitial), - ], - [ - "should not have authorization to create a capitated renewal event", - JSON.stringify(capitatedRenewal), - ], - [ - "should not have authorization to create a contracting ammendment event", - JSON.stringify(contractingAmmendment), - ], - [ - "should not have authorization to create a contracting renewal event", - JSON.stringify(contractingRenewal), - ], - [ - "should not have authorization to create a contracting initial event", - JSON.stringify(contractingInitial), - ], - [ - "should not have authorization to create a new medicaid submission event", - JSON.stringify(newMedicaidSubmission), - ], - [ - "should not have authorization to create a new chip submission event", - JSON.stringify(newChipSubmission), - ], - [ - "should not have authorization to create a respond to rai event", - JSON.stringify(respondToRai), - ], - [ - "should not have authorization to create a temporary extension event", - JSON.stringify(temporaryExtension), - ], - [ - "should not have authorization to create a toggle withdraw rai event", - JSON.stringify(toggleWithdrawRai), - ], - [ - "should not have authorization to create a withdraw package event", - JSON.stringify(withdrawPackage), - ], - ["should not have authorization to create a withdraw rai event", JSON.stringify(withdrawRai)], - ])("%s", async (_, base) => { - const event = { - body: base, - requestContext: getRequestContext(automatedStateSubmitterUsername), - } as APIGatewayEvent; - const result = await submit(event); - expect(result.statusCode).toEqual(500); - expect(result.body).toEqual('{"message":"Internal server error"}'); - }); +describe("submit Lambda function with unauthorized submitter", () => { + it.each(eventsAuthorizationRequired.map((event) => [event.event, JSON.stringify(event)]))( + "should return a 500 if not authorized to submit %s event", + async (_, base) => { + const event = { + body: base, + requestContext: getRequestContext(automatedStateSubmitter), + } as APIGatewayEvent; + const result = await submit(event); + expect(result.statusCode).toEqual(500); + expect(result.body).toEqual('{"message":"Internal server error"}'); + }, + ); }); diff --git a/lib/libs/api/kafka.test.ts b/lib/libs/api/kafka.test.ts index 7dd611373..c9f2a76c4 100644 --- a/lib/libs/api/kafka.test.ts +++ b/lib/libs/api/kafka.test.ts @@ -1,31 +1,13 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; -import { Producer } from "kafkajs"; +import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { produceMessage, getProducer } from "./kafka"; - -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), - }; -}); +import { mockedProducer } from "mocks"; describe("Kafka producer functions", () => { - let mockProducer: Producer; let brokerString: string | undefined; beforeEach(() => { brokerString = process.env.brokerString; process.env.brokerString = "broker1,broker2"; - - mockProducer = new Producer(); }); afterEach(() => { @@ -34,7 +16,7 @@ describe("Kafka producer functions", () => { it("should create a Kafka producer", () => { const producer = getProducer(); - expect(producer).toBe(mockProducer); + expect(producer).toEqual(mockedProducer); }); it("should produce a message successfully", async () => { @@ -44,8 +26,8 @@ describe("Kafka producer functions", () => { await produceMessage(topic, key, value); - expect(mockProducer.connect).toHaveBeenCalled(); - expect(mockProducer.send).toHaveBeenCalledWith({ + expect(mockedProducer.connect).toHaveBeenCalled(); + expect(mockedProducer.send).toHaveBeenCalledWith({ topic, messages: [ { @@ -56,7 +38,7 @@ describe("Kafka producer functions", () => { }, ], }); - expect(mockProducer.disconnect).toHaveBeenCalled(); + expect(mockedProducer.disconnect).toHaveBeenCalled(); }); it("should handle errors when producing a message", async () => { @@ -65,12 +47,12 @@ describe("Kafka producer functions", () => { const value = JSON.stringify({ foo: "bar" }); const error = new Error("Failed to send message"); - mockProducer.send.mockRejectedValueOnce(error); + mockedProducer.send.mockRejectedValueOnce(error); await produceMessage(topic, key, value); - expect(mockProducer.connect).toHaveBeenCalled(); - expect(mockProducer.send).toHaveBeenCalledWith({ + expect(mockedProducer.connect).toHaveBeenCalled(); + expect(mockedProducer.send).toHaveBeenCalledWith({ topic, messages: [ { @@ -81,7 +63,7 @@ describe("Kafka producer functions", () => { }, ], }); - expect(mockProducer.disconnect).toHaveBeenCalled(); + expect(mockedProducer.disconnect).toHaveBeenCalled(); }); it("should throw an error if brokerString is not defined", () => { diff --git a/lib/libs/email/getAllStateUsers.test.ts b/lib/libs/email/getAllStateUsers.test.ts index 5f1a2195a..129b2acc3 100644 --- a/lib/libs/email/getAllStateUsers.test.ts +++ b/lib/libs/email/getAllStateUsers.test.ts @@ -1,46 +1,34 @@ import { getAllStateUsers } from "./getAllStateUsers"; -import { describe, it, expect, beforeEach, vi } from "vitest"; - -vi.mock("./getAllStateUsers"); +import { describe, it, expect } from "vitest"; +import { USER_POOL_ID } from "mocks"; describe("getAllStateUsers", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - it("should fetch users successfully", async () => { - vi.mocked(getAllStateUsers).mockResolvedValue([ + const result = await getAllStateUsers({ userPoolId: USER_POOL_ID, state: "CA" }); + expect(result).toEqual([ { - firstName: "John", - lastName: "Doe", - email: "john.doe@example.com", - formattedEmailAddress: "John Doe ", + firstName: "George", + lastName: "Harrison", + email: "george@example.com", + formattedEmailAddress: "George Harrison ", }, - ]); - - const result = await getAllStateUsers({ userPoolId: "ID", state: "CA" }); - expect(result).toEqual([ { - firstName: "John", - lastName: "Doe", - email: "john.doe@example.com", - formattedEmailAddress: "John Doe ", + firstName: "State", + lastName: "Multi", + email: "statemulti@example.com", + formattedEmailAddress: "State Multi ", + }, + { + firstName: "Otto", + lastName: "State", + email: "automated-state@example.com", + formattedEmailAddress: "Otto State ", }, ]); }); it("should return an empty array when no users are found", async () => { - vi.mocked(getAllStateUsers).mockResolvedValue([]); - - const result = await getAllStateUsers({ userPoolId: "ID", state: "CA" }); + const result = await getAllStateUsers({ userPoolId: USER_POOL_ID, state: "MA" }); expect(result).toEqual([]); }); - - it("should throw an error when there is an issue fetching users", async () => { - vi.mocked(getAllStateUsers).mockRejectedValue(new Error("Error fetching users")); - - await expect(getAllStateUsers({ userPoolId: "ID", state: "CA" })).rejects.toThrow( - "Error fetching users", - ); - }); }); diff --git a/lib/libs/email/vitest.setup.ts b/lib/libs/email/vitest.setup.ts index 8c59f1666..bfc8e2a7e 100644 --- a/lib/libs/email/vitest.setup.ts +++ b/lib/libs/email/vitest.setup.ts @@ -1,9 +1,21 @@ import { afterAll, afterEach, beforeAll, beforeEach, vi } from "vitest"; +import { mockedServiceServer as mockedServer } from "mocks/server"; +import { REGION, setDefaultStateSubmitter } from "mocks"; -beforeAll(() => {}); +beforeAll(() => { + setDefaultStateSubmitter(); + + console.log("starting MSW listener for email tests"); + mockedServer.listen({ + onUnhandledRequest: "warn", + }); +}); beforeEach(() => { + process.env.REGION_A = REGION; + process.env.region = REGION; process.env.isDev = "true"; + vi.useFakeTimers(); const now = new Date(2023, 0, 1); vi.setSystemTime(now); @@ -12,8 +24,13 @@ beforeEach(() => { afterEach(() => { vi.useRealTimers(); vi.clearAllMocks(); + + setDefaultStateSubmitter(); + mockedServer.resetHandlers(); }); afterAll(() => { vi.clearAllMocks(); + + mockedServer.close(); }); diff --git a/lib/vitest.setup.ts b/lib/vitest.setup.ts index e354c3157..3e3c11585 100644 --- a/lib/vitest.setup.ts +++ b/lib/vitest.setup.ts @@ -1,4 +1,4 @@ -import { Amplify } from "aws-amplify"; +import { afterAll, afterEach, beforeAll, beforeEach, vi } from "vitest"; import { API_CONFIG, API_ENDPOINT, @@ -14,16 +14,25 @@ import { USER_POOL_ID, ATTACHMENT_BUCKET_NAME, ATTACHMENT_BUCKET_REGION, + KAFKA_BROKERS, setDefaultStateSubmitter, + mockedKafka, } from "mocks"; import { mockedServiceServer as mockedServer } from "mocks/server"; -import { afterAll, afterEach, beforeAll, beforeEach, vi } from "vitest"; +import { Amplify } from "aws-amplify"; Amplify.configure({ API: API_CONFIG, Auth: AUTH_CONFIG, }); +vi.mock("kafkajs", async (importOriginal) => { + return { + ...(await importOriginal()), + Kafka: mockedKafka, + }; +}); + beforeAll(() => { setDefaultStateSubmitter(); @@ -55,6 +64,7 @@ beforeEach(() => { process.env.emailAddressLookupSecretName = "mock-email-secret"; // pragma: allowlist secret process.env.DLQ_URL = "https://sqs.us-east-1.amazonaws.com/123/test"; process.env.configurationSetName = "SES"; + process.env.brokerString = KAFKA_BROKERS; }); afterEach(() => { @@ -62,14 +72,11 @@ afterEach(() => { vi.clearAllMocks(); setDefaultStateSubmitter(); - // Reset any request handlers that we may add during the tests, - // so they don't affect other tests. mockedServer.resetHandlers(); }); afterAll(() => { - vi.clearAllMocks(); + vi.resetAllMocks(); - // Clean up after the tests are finished. mockedServer.close(); }); diff --git a/mocks/consts.ts b/mocks/consts.ts index 67c78c1b9..6e6d2a1d6 100644 --- a/mocks/consts.ts +++ b/mocks/consts.ts @@ -12,6 +12,7 @@ export const OPENSEARCH_INDEX_NAMESPACE = "test-namespace-"; export const CLOUDFORMATION_NOTIFICATION_DOMAIN = "https://test-cfn.amazonaws.com"; export const ATTACHMENT_BUCKET_NAME = "test-bucket"; export const ATTACHMENT_BUCKET_REGION = REGION; +export const KAFKA_BROKERS = "kafka1:9092,kafka2:9092"; export const ACCESS_KEY_ID = "ASIAZHXA3XOU7XZ53M36"; // pragma: allowlist secret export const SECRET_KEY = "UWKCFxhrgbPnixgLnL1JKwFEwiK9ZKvTAtpk8cGa"; // pragma: allowlist secret diff --git a/mocks/data/submit/attachments.ts b/mocks/data/submit/attachments.ts index 1a08b179e..30ce31acc 100644 --- a/mocks/data/submit/attachments.ts +++ b/mocks/data/submit/attachments.ts @@ -111,7 +111,7 @@ const currentStatePlan = { ], }, }; -const ammendedLanguage = { +const amendedLanguage = { amendedLanguage: { label: "Amended State Plan Language", files: [ @@ -295,7 +295,7 @@ const bCapIndependentAssessment = { }, }; export const attachments = { - ammendedLanguage, + amendedLanguage, appk, bCapIndependentAssessment, bCapCostSpreadsheets, diff --git a/mocks/data/submit/base.ts b/mocks/data/submit/base.ts index 4a134ce37..4429b13ff 100644 --- a/mocks/data/submit/base.ts +++ b/mocks/data/submit/base.ts @@ -1,5 +1,5 @@ import { attachments } from "./attachments"; -export const capitatedAmendmentBase = { +const capitatedAmendmentBase = { id: "VA-1234.R11.01", event: "capitated-amendment", authority: "1915(c)", @@ -14,7 +14,7 @@ export const capitatedAmendmentBase = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const appkBase = { +const appkBase = { id: "VA-1234.R11.01", event: "app-k", authority: "1915(c)", @@ -26,7 +26,7 @@ export const appkBase = { }, additionalInformation: "Some additional information about this submission.", }; -export const capitatedInitial = { +const capitatedInitial = { id: "VA-1234.R00.00", event: "capitated-initial", authority: "1915(c)", @@ -41,7 +41,7 @@ export const capitatedInitial = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const capitatedRenewal = { +const capitatedRenewal = { id: "VA-1234.R01.00", event: "capitated-renewal", authority: "1915(c)", @@ -57,7 +57,7 @@ export const capitatedRenewal = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const contractingAmmendment = { +const contractingAmendment = { id: "VA-1234.R11.01", event: "contracting-amendment", authority: "1915(b)", @@ -71,7 +71,7 @@ export const contractingAmmendment = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const contractingInitial = { +const contractingInitial = { id: "VA-1234.R00.00", event: "contracting-initial", authority: "1915(b)", @@ -85,7 +85,7 @@ export const contractingInitial = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const contractingRenewal = { +const contractingRenewal = { id: "VA-1234.R01.00", event: "contracting-renewal", authority: "1915(b)", @@ -100,7 +100,7 @@ export const contractingRenewal = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R01.00", }; -export const newChipSubmission = { +const newChipSubmission = { id: "VA-11-2021", event: "new-chip-submission", authority: "1915(b)", @@ -108,7 +108,7 @@ export const newChipSubmission = { title: "Sample Title for Appendix K", attachments: { ...attachments.currentStatePlan, - ...attachments.ammendedLanguage, + ...attachments.amendedLanguage, ...attachments.coverLetter, ...attachments.budgetDocuments, ...attachments.publicNotice, @@ -118,7 +118,7 @@ export const newChipSubmission = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const newMedicaidSubmission = { +const newMedicaidSubmission = { id: "VA-11-2021", event: "new-medicaid-submission", authority: "1915(b)", @@ -138,7 +138,7 @@ export const newMedicaidSubmission = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const respondToRai = { +const respondToRai = { id: "VA-11-2020", event: "respond-to-rai", authority: "1915(b)", @@ -151,7 +151,7 @@ export const respondToRai = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.11", }; -export const temporaryExtension = { +const temporaryExtension = { id: "VA-1234.R11.TE12", event: "temporary-extension", authority: "1915(b)", @@ -164,14 +164,14 @@ export const temporaryExtension = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.00", }; -export const toggleWithdrawRai = { +const toggleWithdrawRai = { id: "VA-11-2020", event: "toggle-withdraw-rai", authority: "1915(b)", raiWithdrawEnabled: true, proposedEffectiveDate: 1700000000, }; -export const withdrawPackage = { +const withdrawPackage = { id: "VA-11-2020", event: "withdraw-package", authority: "1915(b)", @@ -183,7 +183,7 @@ export const withdrawPackage = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.00", }; -export const withdrawRai = { +const withdrawRai = { id: "VA-11-2020", event: "withdraw-rai", authority: "1915(b)", @@ -195,7 +195,7 @@ export const withdrawRai = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.00", }; -export const uploadSubsequentDocuments = { +const uploadSubsequentDocuments = { id: "VA-1111.R11.00", event: "upload-subsequent-documents", authority: "1915(b)", @@ -205,3 +205,23 @@ export const uploadSubsequentDocuments = { additionalInformation: "Some additional information about this submission.", waiverNumber: "VA-1111.R11.00", }; + +export const eventsAttachmentRequired = [ + appkBase, + capitatedAmendmentBase, + capitatedInitial, + capitatedRenewal, + withdrawPackage, + temporaryExtension, + respondToRai, + newMedicaidSubmission, + newChipSubmission, + contractingRenewal, + contractingInitial, + contractingAmendment, + withdrawRai, +]; + +export const eventsAuthorizationRequired = [...eventsAttachmentRequired, toggleWithdrawRai]; + +export const events = [...eventsAuthorizationRequired, uploadSubsequentDocuments]; diff --git a/mocks/data/submit/baseMissingAttachments.ts b/mocks/data/submit/baseMissingAttachments.ts deleted file mode 100644 index 81cf3d70d..000000000 --- a/mocks/data/submit/baseMissingAttachments.ts +++ /dev/null @@ -1,160 +0,0 @@ -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/data/users/stateSubmitters.ts b/mocks/data/users/stateSubmitters.ts index 9b0d30e60..b2e5bb67d 100644 --- a/mocks/data/users/stateSubmitters.ts +++ b/mocks/data/users/stateSubmitters.ts @@ -55,7 +55,7 @@ export const stateSubmitter: TestUserData = { }, { Name: "custom:state", - Value: "VA,OH,SC,CO,GA,MD", + Value: "VA,OH,SC,CO,CA,MD", }, { Name: "custom:cms-roles", diff --git a/mocks/handlers/aws/cognito.ts b/mocks/handlers/aws/cognito.ts index 026dbc017..84a58d7dd 100644 --- a/mocks/handlers/aws/cognito.ts +++ b/mocks/handlers/aws/cognito.ts @@ -17,6 +17,7 @@ import type { } from "../../index.d"; import { findUserByUsername } from "../authUtils"; import { APIGatewayEventRequestContext } from "shared-types"; +import { userResponses } from "../../data/users"; const getUsernameFromAccessToken = (accessToken?: string): string | undefined => { if (accessToken) { @@ -338,33 +339,34 @@ export const identityProviderServiceHandler = http.post< } if (target == "AWSCognitoIdentityProviderService.ListUsers") { - let username: string = ""; - try { - const { Filter } = (await request.json()) as IdpListUsersRequestBody; + const { Filter } = (await request.json()) as IdpListUsersRequestBody; - username = Filter.replace("sub = ", "").replaceAll('"', ""); - } catch { - if (process.env.MOCK_USER_USERNAME) { - username = process.env.MOCK_USER_USERNAME; - } - } - if (username) { - const user = findUserByUsername(username); - if (user) { - return HttpResponse.json({ - Users: [ - { - Attributes: user.UserAttributes, - Username: user.Username, - UserStatus: "CONFIRMED", - Enabled: true, - }, - ], - }); + if (Filter && Filter.startsWith("sub = ")) { + const username = Filter.replace("sub = ", "").replaceAll('"', ""); + if (username) { + const user = findUserByUsername(username); + if (user) { + return HttpResponse.json({ + Users: [ + { + Attributes: user.UserAttributes, + Username: user.Username, + UserStatus: "CONFIRMED", + Enabled: true, + }, + ], + }); + } } } + return HttpResponse.json({ - Users: [], + Users: userResponses.map((user) => ({ + Attributes: user.UserAttributes, + Username: user.Username, + UserStatus: "CONFIRMED", + Enabled: true, + })), }); } diff --git a/mocks/helpers/index.ts b/mocks/helpers/index.ts new file mode 100644 index 000000000..f3ae14d1a --- /dev/null +++ b/mocks/helpers/index.ts @@ -0,0 +1 @@ +export * from "./kafka-test-helpers"; diff --git a/mocks/helpers/kafka-test-helpers.ts b/mocks/helpers/kafka-test-helpers.ts new file mode 100644 index 000000000..368a7c076 --- /dev/null +++ b/mocks/helpers/kafka-test-helpers.ts @@ -0,0 +1,22 @@ +import { vi } from "vitest"; + +export const mockedProducer = { + connect: vi.fn(), + send: vi.fn(), + disconnect: vi.fn(), +}; + +export const mockedAdmin = { + connect: vi.fn(), + describeGroups: vi.fn().mockResolvedValue({ + groups: [{ state: "Stable" }], + }), + fetchTopicOffsets: vi.fn().mockResolvedValue([{ offset: "100" }]), + fetchOffsets: vi.fn().mockResolvedValue([{ partitions: [{ offset: "100" }] }]), + disconnect: vi.fn(), +}; + +export const mockedKafka = vi.fn(() => ({ + producer: vi.fn(() => mockedProducer), + admin: vi.fn(() => mockedAdmin), +})); diff --git a/mocks/index.d.ts b/mocks/index.d.ts index 6764d1eec..ab1ab37c0 100644 --- a/mocks/index.d.ts +++ b/mocks/index.d.ts @@ -59,7 +59,8 @@ export type IdpRefreshRequestBody = { export type IdpListUsersRequestBody = { UserPoolId: string; - Filter: string; + Limit?: number; + Filter?: string; }; export type AdminGetUserRequestBody = { diff --git a/mocks/index.ts b/mocks/index.ts index add75df43..71232aaea 100644 --- a/mocks/index.ts +++ b/mocks/index.ts @@ -1,6 +1,7 @@ export * from "./consts"; export * from "./data"; export * from "./handlers"; +export * from "./helpers"; export * from "./index.d"; export { http, HttpResponse } from "msw";