import { describe, test, expect } from "bun:test"; import { GeneratedQuoteController } from "../../../src/controllers/GeneratedQuoteController"; import { buildMockGeneratedQuote, buildMockOpportunity, buildMockUser, } from "../../setup"; describe("GeneratedQuoteController", () => { // ------------------------------------------------------------------- // Constructor // ------------------------------------------------------------------- describe("constructor", () => { test("sets core identification fields", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); expect(ctrl.id).toBe("quote-1"); expect(ctrl.quoteFileName).toBe("Quote-TestOpp.pdf"); expect(ctrl.opportunityId).toBe("opp-1"); expect(ctrl.createdById).toBe("user-1"); }); test("sets quoteRegenData", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); expect(ctrl.quoteRegenData).toEqual({ theme: "default" }); }); test("sets quoteFile as Uint8Array", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); expect(ctrl.quoteFile).toBeInstanceOf(Uint8Array); expect(ctrl.quoteFile.length).toBe(4); }); test("sets timestamps", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); expect(ctrl.createdAt).toBeInstanceOf(Date); expect(ctrl.updatedAt).toBeInstanceOf(Date); }); test("wraps included opportunity in OpportunityController", () => { const opp = buildMockOpportunity(); const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ opportunity: opp }), ); const json = ctrl.toJson({ includeOpportunity: true }); expect(json.opportunity).toBeDefined(); expect(json.opportunity.id).toBe("opp-1"); }); test("wraps included createdBy in UserController", () => { const user = buildMockUser({ roles: [] }); const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ createdBy: user }), ); const json = ctrl.toJson({ includeCreatedBy: true }); expect(json.createdBy).toBeDefined(); expect(json.createdBy.id).toBe("user-1"); }); test("sets _opportunity to null when opportunity not included", () => { const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ opportunity: null }), ); const json = ctrl.toJson({ includeOpportunity: true }); expect(json.opportunity).toBeUndefined(); }); test("sets _createdBy to null when createdBy not included", () => { const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ createdBy: null }), ); const json = ctrl.toJson({ includeCreatedBy: true }); expect(json.createdBy).toBeUndefined(); }); test("handles null createdById", () => { const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ createdById: null }), ); expect(ctrl.createdById).toBeNull(); }); }); // ------------------------------------------------------------------- // toJson // ------------------------------------------------------------------- describe("toJson()", () => { test("returns core fields by default", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); const json = ctrl.toJson(); expect(json.id).toBe("quote-1"); expect(json.quoteFileName).toBe("Quote-TestOpp.pdf"); expect(json.opportunityId).toBe("opp-1"); expect(json.createdById).toBe("user-1"); expect(json.createdAt).toBeInstanceOf(Date); expect(json.updatedAt).toBeInstanceOf(Date); }); test("excludes quoteFile by default", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); const json = ctrl.toJson(); expect(json.quoteFile).toBeUndefined(); }); test("excludes quoteRegenData by default", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); const json = ctrl.toJson(); expect(json.quoteRegenData).toBeUndefined(); }); test("includes quoteRegenData when requested", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); const json = ctrl.toJson({ includeRegenData: true }); expect(json.quoteRegenData).toEqual({ theme: "default" }); }); test("includes quoteFile as raw Uint8Array when includeFile is true", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); const json = ctrl.toJson({ includeFile: true }); expect(json.quoteFile).toBeInstanceOf(Uint8Array); }); test("includes quoteFile as base64 when both flags set", () => { const ctrl = new GeneratedQuoteController(buildMockGeneratedQuote()); const json = ctrl.toJson({ includeFile: true, encodeFileAsBase64: true, }); expect(typeof json.quoteFile).toBe("string"); // Should be valid base64 expect(() => Buffer.from(json.quoteFile, "base64")).not.toThrow(); }); test("excludes opportunity when not requested", () => { const opp = buildMockOpportunity(); const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ opportunity: opp }), ); const json = ctrl.toJson(); expect(json.opportunity).toBeUndefined(); }); test("includes opportunity when requested and available", () => { const opp = buildMockOpportunity(); const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ opportunity: opp }), ); const json = ctrl.toJson({ includeOpportunity: true }); expect(json.opportunity).toBeDefined(); expect(json.opportunity.name).toBe("Test Opportunity"); }); test("excludes createdBy when not requested", () => { const user = buildMockUser({ roles: [] }); const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ createdBy: user }), ); const json = ctrl.toJson(); expect(json.createdBy).toBeUndefined(); }); test("includes createdBy when requested and available", () => { const user = buildMockUser({ roles: [] }); const ctrl = new GeneratedQuoteController( buildMockGeneratedQuote({ createdBy: user }), ); const json = ctrl.toJson({ includeCreatedBy: true }); expect(json.createdBy).toBeDefined(); expect(json.createdBy.name).toBe("Test User"); }); }); });