import { describe, test, expect, mock, beforeEach } from "bun:test"; import { GeneratedQuoteController } from "../../src/controllers/GeneratedQuoteController"; import { buildMockGeneratedQuote, buildMockOpportunity, buildMockUser, } from "../setup"; /** * The Proxy-based prisma mock in setup.ts creates a fresh mock() for every * property access, so we cannot use `(prisma.x.findFirst as any).mockReturnValueOnce()` * because the manager's import access gets a different mock. * * Instead, we mock the entire constants module per-test with stable mock functions. */ function createStablePrismaMock( overrides: Record> = {}, ) { return new Proxy( {}, { get(_target, model: string) { if (model === "$connect" || model === "$disconnect") return mock(() => Promise.resolve()); if (overrides[model]) return overrides[model]; return new Proxy( {}, { get() { return mock(() => Promise.resolve(null)); }, }, ); }, }, ); } describe("generatedQuotes manager", () => { // ------------------------------------------------------------------- // fetch // ------------------------------------------------------------------- describe("fetch()", () => { test("returns a GeneratedQuoteController when found", async () => { const mockData = buildMockGeneratedQuote(); const findFirst = mock(() => Promise.resolve(mockData)); mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findFirst }, }), })); // Re-import to pick up the fresh mock const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); const result = await generatedQuotes.fetch("quote-1"); expect(result).toBeInstanceOf(GeneratedQuoteController); expect(result.id).toBe("quote-1"); }); test("throws GenericError with 404 when not found", async () => { const findFirst = mock(() => Promise.resolve(null)); mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findFirst }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); try { await generatedQuotes.fetch("nonexistent"); expect(true).toBe(false); } catch (e: any) { expect(e.name).toBe("GeneratedQuoteNotFound"); expect(e.status).toBe(404); } }); }); // ------------------------------------------------------------------- // fetchByOpportunity // ------------------------------------------------------------------- describe("fetchByOpportunity()", () => { test("returns array of GeneratedQuoteController", async () => { const rows = [ buildMockGeneratedQuote({ id: "q-1" }), buildMockGeneratedQuote({ id: "q-2" }), ]; const findMany = mock(() => Promise.resolve(rows)); mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findMany }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); const result = await generatedQuotes.fetchByOpportunity("opp-1"); expect(result).toHaveLength(2); expect(result[0]).toBeInstanceOf(GeneratedQuoteController); expect(result[0].id).toBe("q-1"); }); test("returns empty array when none found", async () => { const findMany = mock(() => Promise.resolve([])); mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findMany }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); const result = await generatedQuotes.fetchByOpportunity("opp-999"); expect(result).toEqual([]); }); }); // ------------------------------------------------------------------- // fetchByCreator // ------------------------------------------------------------------- describe("fetchByCreator()", () => { test("returns array of GeneratedQuoteController", async () => { const rows = [buildMockGeneratedQuote({ id: "q-1" })]; const findMany = mock(() => Promise.resolve(rows)); mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findMany }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); const result = await generatedQuotes.fetchByCreator("user-1"); expect(result).toHaveLength(1); expect(result[0]).toBeInstanceOf(GeneratedQuoteController); }); }); // ------------------------------------------------------------------- // create // ------------------------------------------------------------------- describe("create()", () => { test("throws 404 when opportunity not found", async () => { mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ opportunity: { findFirst: mock(() => Promise.resolve(null)) }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); try { await generatedQuotes.create({ quoteRegenData: {}, quoteFile: Buffer.from("pdf"), quoteFileName: "test.pdf", opportunityId: "nonexistent-opp", createdById: "user-1", }); expect(true).toBe(false); } catch (e: any) { expect(e.name).toBe("OpportunityNotFound"); expect(e.status).toBe(404); } }); test("throws 404 when user not found", async () => { mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ opportunity: { findFirst: mock(() => Promise.resolve({ id: "opp-1" })), }, user: { findFirst: mock(() => Promise.resolve(null)) }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); try { await generatedQuotes.create({ quoteRegenData: {}, quoteFile: Buffer.from("pdf"), quoteFileName: "test.pdf", opportunityId: "opp-1", createdById: "nonexistent-user", }); expect(true).toBe(false); } catch (e: any) { expect(e.name).toBe("UserNotFound"); expect(e.status).toBe(404); } }); test("creates and returns GeneratedQuoteController", async () => { const mockQuote = buildMockGeneratedQuote(); mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ opportunity: { findFirst: mock(() => Promise.resolve({ id: "opp-1" })), }, user: { findFirst: mock(() => Promise.resolve({ id: "user-1" })) }, generatedQuotes: { create: mock(() => Promise.resolve(mockQuote)) }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); const result = await generatedQuotes.create({ quoteRegenData: { theme: "default" }, quoteFile: Buffer.from("pdf-content"), quoteFileName: "Quote.pdf", opportunityId: "opp-1", createdById: "user-1", }); expect(result).toBeInstanceOf(GeneratedQuoteController); expect(result.id).toBe("quote-1"); }); }); // ------------------------------------------------------------------- // delete // ------------------------------------------------------------------- describe("delete()", () => { test("throws 404 when quote not found", async () => { mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findFirst: mock(() => Promise.resolve(null)) }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); try { await generatedQuotes.delete("nonexistent"); expect(true).toBe(false); } catch (e: any) { expect(e.name).toBe("GeneratedQuoteNotFound"); expect(e.status).toBe(404); } }); test("deletes successfully when quote exists", async () => { mock.module("../../src/constants", () => ({ prisma: createStablePrismaMock({ generatedQuotes: { findFirst: mock(() => Promise.resolve({ id: "quote-1" })), delete: mock(() => Promise.resolve(undefined)), }, }), })); const { generatedQuotes } = await import("../../src/managers/generatedQuotes"); await expect(generatedQuotes.delete("quote-1")).resolves.toBeUndefined(); }); }); });