import { beforeEach, describe, expect, it, vi } from "vitest"; const createSupportTicketMock = vi.fn(); const sendToRolesMock = vi.fn(); const t = ((key: string, fallback?: string) => fallback ?? key) as never; describe("SupportTicketsServer", () => { beforeEach(() => { vi.resetModules(); vi.clearAllMocks(); vi.doMock("../db/supportTickets.db.server", () => ({ createSupportTicket: createSupportTicketMock })); vi.doMock("~/modules/notifications/services/.server/NotificationService", () => ({ default: { sendToRoles: sendToRolesMock }, })); createSupportTicketMock.mockImplementation(async (data) => ({ id: "ticket_1", ...data })); }); it("creates redacted inline tickets and notifies platform admins", async () => { const { default: SupportTicketsServer } = await import("./SupportTickets.server"); await expect( SupportTicketsServer.createInline({ t, tenantId: "tenant_1", userId: "user_1", subject: "Need help with token=sk_live_secret", message: "My api_key=abc123 should not leak", fromUrl: "/acme/dashboard?token=abc", }), ).resolves.toMatchObject({ id: "ticket_1", source: "inline", tenantId: "tenant_1", userId: "user_1" }); expect(createSupportTicketMock).toHaveBeenCalledWith( expect.objectContaining({ source: "inline", subject: expect.not.stringContaining("sk_live_secret"), message: expect.not.stringContaining("abc123"), fromUrl: expect.not.stringContaining("token=abc"), }), ); expect(sendToRolesMock).toHaveBeenCalledWith( expect.objectContaining({ channel: "admin-users", tenantId: null, }), ); }); it("creates idempotency-addressable inbound email tickets", async () => { const { default: SupportTicketsServer } = await import("./SupportTickets.server"); await SupportTicketsServer.createFromInboundEmail({ tenantId: "tenant_1", fromEmail: "customer@example.test", subject: "Inbound support", message: "Please help", inboundMessageId: "mail_1", }); expect(createSupportTicketMock).toHaveBeenCalledWith( expect.objectContaining({ source: "email", inboundMessageId: "mail_1", fromEmail: "[REDACTED_EMAIL]", }), ); }); });