Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- 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
95 lines
3.2 KiB
TypeScript
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" }),
|
|
}));
|