138 lines
4 KiB
JavaScript
138 lines
4 KiB
JavaScript
const { requireAuth } = require('../../../middleware/auth');
|
|
const { User } = require('../../../models');
|
|
|
|
describe('Auth Middleware', () => {
|
|
let req, res, next;
|
|
|
|
beforeEach(() => {
|
|
req = {
|
|
path: '/api/tasks',
|
|
session: {},
|
|
};
|
|
res = {
|
|
status: jest.fn().mockReturnThis(),
|
|
json: jest.fn(),
|
|
};
|
|
next = jest.fn();
|
|
});
|
|
|
|
it('should skip authentication for health check', async () => {
|
|
req.path = '/api/health';
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(next).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should skip authentication for login route', async () => {
|
|
req.path = '/api/login';
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(next).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should skip authentication for current_user route', async () => {
|
|
req.path = '/api/current_user';
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(next).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should return 401 if no session', async () => {
|
|
req.session = null;
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(401);
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
error: 'Authentication required',
|
|
});
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should return 401 if no userId in session', async () => {
|
|
req.session = {};
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(401);
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
error: 'Authentication required',
|
|
});
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should return 401 and destroy session if user not found', async () => {
|
|
const bcrypt = require('bcrypt');
|
|
const user = await User.create({
|
|
email: 'test@example.com',
|
|
password_digest: await bcrypt.hash('password123', 10),
|
|
});
|
|
|
|
req.session = {
|
|
userId: user.id + 1, // Non-existent user ID
|
|
destroy: jest.fn(),
|
|
};
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(req.session.destroy).toHaveBeenCalled();
|
|
expect(res.status).toHaveBeenCalledWith(401);
|
|
expect(res.json).toHaveBeenCalledWith({ error: 'User not found' });
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should set currentUser and call next for valid session', async () => {
|
|
const bcrypt = require('bcrypt');
|
|
const user = await User.create({
|
|
email: 'test@example.com',
|
|
password_digest: await bcrypt.hash('password123', 10),
|
|
});
|
|
|
|
req.session = {
|
|
userId: user.id,
|
|
};
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(req.currentUser).toBeDefined();
|
|
expect(req.currentUser.id).toBe(user.id);
|
|
expect(req.currentUser.email).toBe(user.email);
|
|
expect(next).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should handle database errors', async () => {
|
|
// Mock console.error to suppress expected error log in test output
|
|
const originalConsoleError = console.error;
|
|
console.error = jest.fn();
|
|
|
|
// Mock User.findByPk to throw an error
|
|
const originalFindByPk = User.findByPk;
|
|
User.findByPk = jest
|
|
.fn()
|
|
.mockRejectedValue(new Error('Database connection error'));
|
|
|
|
req.session = {
|
|
userId: 123,
|
|
destroy: jest.fn(),
|
|
};
|
|
|
|
await requireAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(500);
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
error: 'Authentication error',
|
|
});
|
|
expect(next).not.toHaveBeenCalled();
|
|
|
|
// Restore original methods
|
|
User.findByPk = originalFindByPk;
|
|
console.error = originalConsoleError;
|
|
});
|
|
});
|