import { vi } from "vitest"; // Must be set before any imports process.env.NODE_ENV = "test"; process.env.API_KEYS = "test-key"; // Mock database vi.mock("../services/db.js", () => { const mockPool = { connect: vi.fn().mockResolvedValue({ query: vi.fn().mockResolvedValue({ rows: [{ version: "PostgreSQL 17.4" }], rowCount: 0 }), release: vi.fn(), }), query: vi.fn().mockResolvedValue({ rows: [], rowCount: 0 }), end: vi.fn().mockResolvedValue(undefined), on: vi.fn(), totalCount: 10, idleCount: 8, waitingCount: 0, }; return { default: mockPool, pool: mockPool, initDatabase: vi.fn().mockResolvedValue(undefined), queryWithRetry: vi.fn().mockResolvedValue({ rows: [], rowCount: 0 }), connectWithRetry: vi.fn().mockResolvedValue({ query: vi.fn().mockResolvedValue({ rows: [], rowCount: 0 }), release: vi.fn(), }), cleanupStaleData: vi.fn().mockResolvedValue({ expiredVerifications: 0, staleKeys: 0, orphanedUsage: 0 }), isTransientError: vi.fn().mockReturnValue(false), }; }); // Mock keys service with in-memory store vi.mock("../services/keys.js", () => { const keys = [ { key: "test-key", tier: "pro" as const, email: "test@docfast.dev", createdAt: new Date().toISOString() }, ]; return { loadKeys: vi.fn().mockResolvedValue(undefined), isValidKey: vi.fn((k: string) => keys.some((e) => e.key === k)), getKeyInfo: vi.fn((k: string) => keys.find((e) => e.key === k)), isProKey: vi.fn((k: string) => keys.find((e) => e.key === k)?.tier === "pro"), getAllKeys: vi.fn(() => [...keys]), createFreeKey: vi.fn(), createProKey: vi.fn(), downgradeByCustomer: vi.fn(), findKeyByCustomerId: vi.fn(), updateKeyEmail: vi.fn(), updateEmailByCustomer: vi.fn(), }; }); // Mock browser service vi.mock("../services/browser.js", async (importOriginal) => { const actual = await importOriginal>(); return { buildPdfOptions: actual.buildPdfOptions, initBrowser: vi.fn().mockResolvedValue(undefined), closeBrowser: vi.fn().mockResolvedValue(undefined), renderPdf: vi.fn().mockResolvedValue({ pdf: Buffer.from("%PDF-1.4 mock pdf content here"), durationMs: 10 }), renderUrlPdf: vi.fn().mockResolvedValue({ pdf: Buffer.from("%PDF-1.4 mock url pdf content"), durationMs: 10 }), getPoolStats: vi.fn().mockReturnValue({ poolSize: 16, totalPages: 16, availablePages: 14, queueDepth: 0, pdfCount: 0, restarting: false, uptimeMs: 10000, browsers: [], }), }; }); // Mock verification service vi.mock("../services/verification.js", () => ({ createPendingVerification: vi.fn().mockResolvedValue({ email: "test@test.com", code: "123456" }), verifyCode: vi.fn().mockResolvedValue({ status: "ok" }), })); // Mock email service vi.mock("../services/email.js", () => ({ sendVerificationEmail: vi.fn().mockResolvedValue(undefined), })); // Mock usage middleware vi.mock("../middleware/usage.js", () => ({ usageMiddleware: vi.fn((_req: any, _res: any, next: any) => next()), loadUsageData: vi.fn().mockResolvedValue(undefined), getUsageStats: vi.fn().mockReturnValue({ totalRequests: 0, keys: {} }), getUsageForKey: vi.fn().mockReturnValue({ count: 0, monthKey: "2026-01" }), }));