const { describe, test, expect, beforeEach } = require("@jest/globals"); const fs = require("fs").promises; const path = require("path"); // Mock the config jest.mock("../../config", () => ({ email: { user: "test@example.com" }, gif: { enabled: false, url: "", alt: "" }, })); // Mock fs for template loading jest.mock("fs", () => ({ promises: { readFile: jest.fn(), }, })); const templateEngine = require("../../lib/templateEngine"); describe("TemplateEngine", () => { beforeEach(() => { jest.clearAllMocks(); // Clear template cache templateEngine.templates = {}; }); describe("formatFirmData", () => { test("should format firm data correctly", () => { const firmData = { firmName: "Test Law Firm", location: "Test City", website: "https://test.com", contactEmail: "test@testfirm.com", }; const result = templateEngine.formatFirmData(firmData); expect(result).toEqual({ firmName: "Test Law Firm", location: "Test City", website: "https://test.com", email: "test@testfirm.com", greeting: "Legal Professional", }); }); test("should handle missing data gracefully", () => { const firmData = { firmName: "Test Firm", }; const result = templateEngine.formatFirmData(firmData); expect(result).toEqual({ firmName: "Test Firm", location: undefined, website: undefined, email: undefined, greeting: "Legal Professional", }); }); test("should use name as greeting when available", () => { const firmData = { firmName: "Test Firm", name: "John Doe", contactEmail: "john@test.com", }; const result = templateEngine.formatFirmData(firmData); expect(result.greeting).toBe("John Doe"); }); }); describe("loadTemplate", () => { test("should load and compile templates", async () => { const mockHtmlContent = "

{{title}}

"; const mockTxtContent = "{{title}}"; fs.readFile .mockResolvedValueOnce(mockHtmlContent) .mockResolvedValueOnce(mockTxtContent); const result = await templateEngine.loadTemplate("test"); expect(fs.readFile).toHaveBeenCalledTimes(2); expect(result).toHaveProperty("html"); expect(result).toHaveProperty("text"); expect(typeof result.html).toBe("function"); expect(typeof result.text).toBe("function"); }); test("should cache loaded templates", async () => { const mockHtmlContent = "

{{title}}

"; const mockTxtContent = "{{title}}"; fs.readFile .mockResolvedValueOnce(mockHtmlContent) .mockResolvedValueOnce(mockTxtContent); // Load template twice await templateEngine.loadTemplate("test"); await templateEngine.loadTemplate("test"); // Should only read files once due to caching expect(fs.readFile).toHaveBeenCalledTimes(2); }); test("should throw error when template loading fails", async () => { fs.readFile.mockRejectedValue(new Error("File not found")); await expect(templateEngine.loadTemplate("nonexistent")).rejects.toThrow( "Failed to load template nonexistent" ); }); }); describe("render", () => { test("should render template with data", async () => { const mockHtmlContent = "

Hello {{name}}

"; const mockTxtContent = "Hello {{name}}"; fs.readFile .mockResolvedValueOnce(mockHtmlContent) .mockResolvedValueOnce(mockTxtContent); const result = await templateEngine.render("test", { name: "World" }); expect(result.html).toContain("Hello World"); expect(result.text).toContain("Hello World"); }); test("should include default sender data", async () => { const mockHtmlContent = "From: {{senderName}}"; const mockTxtContent = "From: {{senderName}}"; fs.readFile .mockResolvedValueOnce(mockHtmlContent) .mockResolvedValueOnce(mockTxtContent); const result = await templateEngine.render("test", {}); expect(result.html).toContain("John Smith"); expect(result.text).toContain("John Smith"); }); }); });