docfast/src/__tests__/setup.ts
DocFast CEO 4e00feb860
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
refactor: extract buildPdfOptions to DRY up renderPdf/renderUrlPdf (TDD)
- Extract shared PDF options construction into buildPdfOptions()
- Both renderPdf and renderUrlPdf now use the shared builder
- 5 TDD tests added (pdf-options-builder.test.ts)
- 633 tests passing, 0 tsc errors
2026-03-10 14:04:19 +01:00

95 lines
3.2 KiB
TypeScript

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<Record<string, unknown>>();
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" }),
}));