import { jest } from '@jest/globals'; import { authenticate, generateToken, generateRefreshToken } from '../../../../../services/api-gateway/src/middleware/auth.js'; import jwt from 'jsonwebtoken'; // Mock dependencies jest.mock('jsonwebtoken'); jest.mock('../../../../../services/api-gateway/src/utils/cache.js', () => ({ cache: { get: jest.fn(), set: jest.fn(), del: jest.fn() } })); describe('Auth Middleware', () => { let req, res, next; beforeEach(() => { req = { headers: {}, user: null }; res = { status: jest.fn(() => res), json: jest.fn(() => res) }; next = jest.fn(); jest.clearAllMocks(); }); describe('authenticate', () => { it('should authenticate valid token', async () => { const token = 'valid-token'; const decodedToken = { userId: 'user123', role: 'user', permissions: ['read', 'write'] }; req.headers.authorization = `Bearer ${token}`; jwt.verify.mockReturnValue(decodedToken); await authenticate(req, res, next); expect(jwt.verify).toHaveBeenCalledWith(token, process.env.JWT_SECRET); expect(req.user).toEqual(decodedToken); expect(req.token).toBe(token); expect(next).toHaveBeenCalled(); }); it('should reject missing authorization header', async () => { await authenticate(req, res, next); expect(res.status).toHaveBeenCalledWith(401); expect(res.json).toHaveBeenCalledWith({ success: false, error: 'No token provided' }); expect(next).not.toHaveBeenCalled(); }); it('should reject invalid token format', async () => { req.headers.authorization = 'InvalidFormat token'; await authenticate(req, res, next); expect(res.status).toHaveBeenCalledWith(401); expect(res.json).toHaveBeenCalledWith({ success: false, error: 'Invalid token format' }); }); it('should reject expired token', async () => { req.headers.authorization = 'Bearer expired-token'; jwt.verify.mockImplementation(() => { throw new Error('jwt expired'); }); await authenticate(req, res, next); expect(res.status).toHaveBeenCalledWith(401); expect(res.json).toHaveBeenCalledWith({ success: false, error: 'Token expired' }); }); it('should reject blacklisted token', async () => { const token = 'blacklisted-token'; req.headers.authorization = `Bearer ${token}`; const { cache } = require('../../../../../services/api-gateway/src/utils/cache.js'); cache.get.mockResolvedValue('1'); await authenticate(req, res, next); expect(cache.get).toHaveBeenCalledWith(`blacklist:${token}`); expect(res.status).toHaveBeenCalledWith(401); expect(res.json).toHaveBeenCalledWith({ success: false, error: 'Token has been revoked' }); }); }); describe('generateToken', () => { it('should generate access token with correct payload', () => { const payload = { userId: 'user123', role: 'admin', permissions: ['all'] }; const expectedToken = 'generated-token'; jwt.sign.mockReturnValue(expectedToken); const token = generateToken(payload); expect(jwt.sign).toHaveBeenCalledWith( payload, process.env.JWT_SECRET, { expiresIn: '24h' } ); expect(token).toBe(expectedToken); }); }); describe('generateRefreshToken', () => { it('should generate refresh token with correct payload', () => { const payload = { userId: 'user123', role: 'user' }; const expectedToken = 'refresh-token'; jwt.sign.mockReturnValue(expectedToken); const token = generateRefreshToken(payload); expect(jwt.sign).toHaveBeenCalledWith( payload, process.env.JWT_SECRET, { expiresIn: '7d' } ); expect(token).toBe(expectedToken); }); }); });