docfast/src/__tests__/signup.test.ts
Hoid 2793207b39
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m26s
Remove dead token-based verification system
- Remove verificationsCache array and loadVerifications() function from verification.ts
- Remove verifyToken() and verifyTokenSync() functions (multi-replica unsafe, never used)
- Remove createVerification() function (stores unused data)
- Remove GET /verify route and verifyPage() helper function
- Remove loadVerifications() call from startup
- Remove createVerification() usage from signup route
- Update imports and test mocks to match removed functions
- Keep active 6-digit code system intact (createPendingVerification, verifyCode, etc.)

All 559 tests passing. The active verification system using pending_verifications
table and 6-digit codes continues to work normally.
2026-03-08 08:07:20 +01:00

99 lines
4.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import express from "express";
import request from "supertest";
let app: express.Express;
beforeEach(async () => {
vi.clearAllMocks();
vi.resetModules();
const { isEmailVerified, createPendingVerification, verifyCode } = await import("../services/verification.js");
const { sendVerificationEmail } = await import("../services/email.js");
const { createFreeKey } = await import("../services/keys.js");
vi.mocked(isEmailVerified).mockResolvedValue(false);
vi.mocked(createPendingVerification).mockResolvedValue({ email: "test@test.com", code: "123456", createdAt: "", expiresAt: "", attempts: 0 });
vi.mocked(verifyCode).mockResolvedValue({ status: "ok" });
vi.mocked(createFreeKey).mockResolvedValue({ key: "free-key-123", tier: "free", email: "test@test.com", createdAt: "" });
vi.mocked(sendVerificationEmail).mockResolvedValue(true);
const { signupRouter } = await import("../routes/signup.js");
app = express();
app.use(express.json());
app.use("/signup", signupRouter);
});
describe("POST /signup/free", () => {
it("returns 400 for missing email", async () => {
const res = await request(app).post("/signup/free").send({});
expect(res.status).toBe(400);
});
it("returns 400 for invalid email format", async () => {
const res = await request(app).post("/signup/free").send({ email: "not-email" });
expect(res.status).toBe(400);
});
it("returns 409 for already verified email", async () => {
const { isEmailVerified } = await import("../services/verification.js");
vi.mocked(isEmailVerified).mockResolvedValue(true);
const res = await request(app).post("/signup/free").send({ email: "dup@test.com" });
expect(res.status).toBe(409);
});
it("returns 200 with verification_required for valid email", async () => {
const res = await request(app).post("/signup/free").send({ email: "new@test.com" });
expect(res.status).toBe(200);
expect(res.body.status).toBe("verification_required");
});
it("sends verification email asynchronously", async () => {
const { sendVerificationEmail } = await import("../services/email.js");
await request(app).post("/signup/free").send({ email: "new@test.com" });
await new Promise(r => setTimeout(r, 50));
expect(sendVerificationEmail).toHaveBeenCalledWith("new@test.com", "123456");
});
});
describe("POST /signup/verify", () => {
it("returns 400 for missing email/code", async () => {
const res = await request(app).post("/signup/verify").send({ email: "a@b.com" });
expect(res.status).toBe(400);
});
it("returns 409 for already verified email", async () => {
const { isEmailVerified } = await import("../services/verification.js");
vi.mocked(isEmailVerified).mockResolvedValue(true);
const res = await request(app).post("/signup/verify").send({ email: "dup@test.com", code: "123456" });
expect(res.status).toBe(409);
});
it("returns 410 for expired code", async () => {
const { verifyCode } = await import("../services/verification.js");
vi.mocked(verifyCode).mockResolvedValue({ status: "expired" });
const res = await request(app).post("/signup/verify").send({ email: "a@b.com", code: "123456" });
expect(res.status).toBe(410);
});
it("returns 429 for max attempts", async () => {
const { verifyCode } = await import("../services/verification.js");
vi.mocked(verifyCode).mockResolvedValue({ status: "max_attempts" });
const res = await request(app).post("/signup/verify").send({ email: "a@b.com", code: "123456" });
expect(res.status).toBe(429);
});
it("returns 400 for invalid code", async () => {
const { verifyCode } = await import("../services/verification.js");
vi.mocked(verifyCode).mockResolvedValue({ status: "invalid" });
const res = await request(app).post("/signup/verify").send({ email: "a@b.com", code: "999999" });
expect(res.status).toBe(400);
});
it("returns 200 with apiKey for valid code", async () => {
const res = await request(app).post("/signup/verify").send({ email: "a@b.com", code: "123456" });
expect(res.status).toBe(200);
expect(res.body).toMatchObject({ status: "verified", apiKey: "free-key-123" });
});
});