From 6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Thu, 2 Jul 2026 11:55:17 -0700 Subject: Init --- .../consumer/t/ConsumerRequestProcessor.spec.ts | 200 +++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 Homework/cs5260/consumer/t/ConsumerRequestProcessor.spec.ts (limited to 'Homework/cs5260/consumer/t/ConsumerRequestProcessor.spec.ts') diff --git a/Homework/cs5260/consumer/t/ConsumerRequestProcessor.spec.ts b/Homework/cs5260/consumer/t/ConsumerRequestProcessor.spec.ts new file mode 100644 index 0000000..28d785b --- /dev/null +++ b/Homework/cs5260/consumer/t/ConsumerRequestProcessor.spec.ts @@ -0,0 +1,200 @@ +import { randomUUID } from "node:crypto"; +import { Widget, WidgetRequest, WidgetT } from "@/shared/schema"; +import { expect, mock, test } from "bun:test"; +import { ConsumerRequestProcessor } from "@/consumer/processor"; +import { VoidLogger } from "@/shared/t"; + +const widgetDAOFactory = (): any => { + return { + retrieve: mock(async (widget: WidgetT) => { + return widget; + }), + save: mock(async (widget: WidgetT) => { + return widget; + }), + delete: mock(async (widget: WidgetT) => { + return widget; + }), + }; +}; + +test("when create request then warns when already existant and not save", async () => { + const logger = new VoidLogger(); + logger.warn = mock((_s) => {}); + + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (widget: WidgetT) => widget); + + const newWidgetRequest = WidgetRequest.parse({ + type: "create", + requestId: randomUUID(), + owner: "simponic", + widgetId: randomUUID(), + }); + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(newWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save).toHaveBeenCalledTimes(0); + expect(logger.warn).toHaveBeenCalledTimes(1); +}); + +test("when create request then saves in dao if not exist", async () => { + const logger = new VoidLogger(); + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (_widget: WidgetT) => { + return undefined; + }); + + const newWidgetRequest = WidgetRequest.parse({ + type: "create", + requestId: randomUUID(), + owner: "simponic", + widgetId: randomUUID(), + }); + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(newWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save).toHaveBeenCalledTimes(1); +}); + +test("when delete request then fails and warns if not exists", async () => { + const logger = new VoidLogger(); + logger.warn = mock((_s) => {}); + + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (_widget: WidgetT) => { + return undefined; + }); + + const deleteWidgetRequest = WidgetRequest.parse({ + type: "delete", + requestId: randomUUID(), + owner: "simponic", + widgetId: randomUUID(), + }); + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(deleteWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.delete).toHaveBeenCalledTimes(0); + expect(logger.warn).toHaveBeenCalledTimes(1); +}); + +test("when delete request then success if exists", async () => { + const logger = new VoidLogger(); + + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (widget: WidgetT) => { + return widget; + }); + + const deleteWidgetRequest = WidgetRequest.parse({ + type: "delete", + requestId: randomUUID(), + owner: "simponic", + widgetId: randomUUID(), + }); + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(deleteWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.delete).toHaveBeenCalledTimes(1); +}); + +test("when update request then deletes empty string values", async () => { + const logger = new VoidLogger(); + + const testWidget = Widget.parse({ + id: "test-widget", + owner: "simponic", + label: "current label", + }); + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (_widget: WidgetT) => testWidget); + + const updateWidgetRequest = WidgetRequest.parse({ + type: "update", + requestId: randomUUID(), + owner: "simponic", + widgetId: testWidget.id, + label: "", + }); + + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(updateWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save.mock.calls[0][0]).toEqual( + Widget.parse({ id: "test-widget", owner: "simponic" }), // "label" has been removed + ); +}); + +test("when update attempts to overwrite owner then update fails and warns", async () => { + const logger = new VoidLogger(); + logger.warn = mock((_s) => {}); + + const testWidget = Widget.parse({ + id: "test-widget", + owner: "simponic", + label: "current label", + }); + + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (_widget: WidgetT) => testWidget); + + const newWidgetRequest = WidgetRequest.parse({ + type: "update", + requestId: randomUUID(), + owner: "newOwner", + widgetId: testWidget.id, + }); + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(newWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save).toHaveBeenCalledTimes(0); + expect(logger.warn).toHaveBeenCalledTimes(1); +}); + +test("when update mutable attribute field unspecified then not overwritten", async () => { + const logger = new VoidLogger(); + + const testWidget = Widget.parse({ + id: "test-widget", + owner: "simponic", + label: "non-overwritten label", + }); + + const mockWidgetDAO = widgetDAOFactory(); + mockWidgetDAO.retrieve = mock(async (_widget: WidgetT) => testWidget); + + const newWidgetRequest = WidgetRequest.parse({ + type: "update", + requestId: randomUUID(), + owner: testWidget.owner, + widgetId: testWidget.id, + description: "", + }); + const processor = new ConsumerRequestProcessor(mockWidgetDAO, logger); + + await processor.processRequest(newWidgetRequest); + + expect(mockWidgetDAO.retrieve).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save).toHaveBeenCalledTimes(1); + expect(mockWidgetDAO.save.mock.calls[0][0]).toEqual( + Widget.parse({ + id: "test-widget", + owner: "simponic", + label: "non-overwritten label", + }), + ); +}); -- cgit v1.3