grocery-app/backend/tests/auth.middleware.test.js

119 lines
3.0 KiB
JavaScript

jest.mock("jsonwebtoken", () => ({
verify: jest.fn(),
}));
jest.mock("../models/session.model", () => ({
getActiveSessionWithUser: jest.fn(),
}));
jest.mock("../utils/logger", () => ({
logError: jest.fn(),
}));
const jwt = require("jsonwebtoken");
const Session = require("../models/session.model");
const auth = require("../middleware/auth");
function createResponse() {
const res = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
return res;
}
describe("auth middleware", () => {
const originalJwtSecret = process.env.JWT_SECRET;
beforeEach(() => {
process.env.JWT_SECRET = "test-secret";
jest.clearAllMocks();
});
afterAll(() => {
if (originalJwtSecret === undefined) {
delete process.env.JWT_SECRET;
} else {
process.env.JWT_SECRET = originalJwtSecret;
}
});
test("uses a valid bearer token without reading the session cookie", async () => {
jwt.verify.mockReturnValue({ id: 5, role: "admin" });
const req = {
headers: {
authorization: "Bearer valid-token",
cookie: "sid=session-id",
},
};
const res = createResponse();
const next = jest.fn();
await auth(req, res, next);
expect(jwt.verify).toHaveBeenCalledWith("valid-token", "test-secret");
expect(Session.getActiveSessionWithUser).not.toHaveBeenCalled();
expect(req.user).toEqual({ id: 5, role: "admin" });
expect(next).toHaveBeenCalled();
});
test("falls back to a valid session cookie when the bearer token is stale", async () => {
jwt.verify.mockImplementation(() => {
throw new Error("stale token");
});
Session.getActiveSessionWithUser.mockResolvedValue({
id: "session-id",
user_id: 7,
role: "user",
username: "shopper",
});
const req = {
headers: {
authorization: "Bearer stale-token",
cookie: "sid=session-id",
},
};
const res = createResponse();
const next = jest.fn();
await auth(req, res, next);
expect(Session.getActiveSessionWithUser).toHaveBeenCalledWith("session-id");
expect(req.user).toEqual({
id: 7,
role: "user",
username: "shopper",
});
expect(req.session_id).toBe("session-id");
expect(next).toHaveBeenCalled();
expect(res.status).not.toHaveBeenCalled();
});
test("rejects a stale bearer token when no session cookie is present", async () => {
jwt.verify.mockImplementation(() => {
throw new Error("stale token");
});
const req = {
headers: {
authorization: "Bearer stale-token",
},
};
const res = createResponse();
const next = jest.fn();
await auth(req, res, next);
expect(Session.getActiveSessionWithUser).not.toHaveBeenCalled();
expect(next).not.toHaveBeenCalled();
expect(res.status).toHaveBeenCalledWith(401);
expect(res.json).toHaveBeenCalledWith({
error: {
code: "unauthorized",
message: "Invalid or expired token",
},
});
});
});