forked from Deen-Bridge/dnb-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathemailRoutes.test.js
More file actions
67 lines (54 loc) · 2.38 KB
/
Copy pathemailRoutes.test.js
File metadata and controls
67 lines (54 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { jest } from "@jest/globals";
import request from "supertest";
import app from "../app.js";
import logger from "../src/config/logger.js";
// SENDLIB_API_KEY/URL are stripped by test/jest.setup.js, so in the test env
// sendMail logs the email body via [EMAIL LOG] instead of delivering. That lets
// us inspect the generated OTP. (Bodies are never logged in dev/prod.)
const extractOtpFromLog = (logCalls) => {
const emailLog = logCalls
.map((call) => call[0])
.find((msg) => typeof msg === "string" && msg.includes("[EMAIL LOG]"));
const match = emailLog && emailLog.match(/#166534;">(\d+)<\/span>/);
return match ? match[1] : null;
};
describe("OTP email route", () => {
let loggerInfoSpy;
beforeAll(() => {
loggerInfoSpy = jest.spyOn(logger, "info");
});
afterAll(() => {
jest.restoreAllMocks();
});
it("generates a fresh OTP per request (no shared module-level code)", async () => {
const res1 = await request(app).post("/api/email").send({ email: "one@example.com" });
const res2 = await request(app).post("/api/email").send({ email: "two@example.com" });
expect(res1.statusCode).toBe(200);
expect(res1.body.success).toBe(true);
expect(res2.statusCode).toBe(200);
const otp1 = extractOtpFromLog(loggerInfoSpy.mock.calls);
// Logs accumulate across requests; take the last two [EMAIL LOG] entries.
const calls = loggerInfoSpy.mock.calls.map((c) => c[0]);
const emailLogs = calls.filter((m) => typeof m === "string" && m.includes("[EMAIL LOG]"));
const otp2 = emailLogs.length >= 2
? (emailLogs[emailLogs.length - 1].match(/#166534;">(\d+)<\/span>/) || [])[1]
: null;
expect(otp1).toBeDefined();
expect(otp2).toBeDefined();
expect(otp1).toHaveLength(6);
expect(otp2).toHaveLength(6);
expect(otp1).not.toBe(otp2);
});
it("never returns the OTP in the response body", async () => {
const res = await request(app).post("/api/email").send({ email: "safe@example.com" });
expect(res.statusCode).toBe(200);
expect(res.body.success).toBe(true);
expect(res.body).not.toHaveProperty("otp");
});
it("rejects missing or non-string email", async () => {
const missing = await request(app).post("/api/email").send({});
expect(missing.statusCode).toBe(400);
const invalid = await request(app).post("/api/email").send({ email: 12345 });
expect(invalid.statusCode).toBe(400);
});
});