fix: make test suite runnable without DB/Chrome, add tests to CI
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m28s
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m28s
- Refactor index.ts to skip start() when NODE_ENV=test - Add test setup with mocks for db, keys, browser, verification, email, usage - Add vitest.config.ts with setup file - Rewrite tests to work with mocks (42 tests, all passing) - Add new tests: signup 410, recovery validation, CORS headers, error format, API root - Add test step to CI pipeline before Docker build
This commit is contained in:
parent
bc698b66b2
commit
b95994cc3c
6 changed files with 327 additions and 156 deletions
91
src/__tests__/setup.ts
Normal file
91
src/__tests__/setup.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
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", () => ({
|
||||
initBrowser: vi.fn().mockResolvedValue(undefined),
|
||||
closeBrowser: vi.fn().mockResolvedValue(undefined),
|
||||
renderPdf: vi.fn().mockResolvedValue(Buffer.from("%PDF-1.4 mock pdf content here")),
|
||||
renderUrlPdf: vi.fn().mockResolvedValue(Buffer.from("%PDF-1.4 mock url pdf content")),
|
||||
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", () => ({
|
||||
verifyToken: vi.fn().mockReturnValue({ status: "invalid" }),
|
||||
loadVerifications: vi.fn().mockResolvedValue(undefined),
|
||||
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: {} }),
|
||||
}));
|
||||
Loading…
Add table
Add a link
Reference in a new issue