import { Request, Response } from 'express'; import { validateRequest, sanitizeInput, errorHandler, rateLimiter, securityHeaders } from '../../src/security/index.js'; interface MockRequest extends Partial { headers: Record; is: jest.Mock; } describe('Security Middleware', () => { let mockRequest: MockRequest; let mockResponse: Partial; let mockNext: jest.Mock; beforeEach(() => { mockRequest = { method: 'POST', headers: { 'content-type': 'application/json', 'authorization': 'Bearer validToken' }, is: jest.fn().mockReturnValue(true), body: { test: 'data' } }; mockResponse = { status: jest.fn().mockReturnThis(), json: jest.fn(), setHeader: jest.fn(), set: jest.fn() }; mockNext = jest.fn(); }); describe('Request Validation', () => { it('should pass valid requests', () => { validateRequest( mockRequest as Request, mockResponse as Response, mockNext ); expect(mockNext).toHaveBeenCalled(); expect(mockResponse.status).not.toHaveBeenCalled(); }); it('should reject requests with invalid content type', () => { mockRequest.is = jest.fn().mockReturnValue(false); validateRequest( mockRequest as Request, mockResponse as Response, mockNext ); expect(mockResponse.status).toHaveBeenCalledWith(415); expect(mockResponse.json).toHaveBeenCalledWith({ error: 'Unsupported Media Type - Content-Type must be application/json' }); }); it('should reject requests without authorization', () => { mockRequest.headers = {}; validateRequest( mockRequest as Request, mockResponse as Response, mockNext ); expect(mockResponse.status).toHaveBeenCalledWith(401); expect(mockResponse.json).toHaveBeenCalledWith({ error: 'Invalid or expired token' }); }); it('should reject requests with invalid token', () => { mockRequest.headers.authorization = 'Bearer invalid.token.format'; validateRequest( mockRequest as Request, mockResponse as Response, mockNext ); expect(mockResponse.status).toHaveBeenCalledWith(401); }); it('should handle GET requests without body validation', () => { mockRequest.method = 'GET'; mockRequest.body = undefined; validateRequest( mockRequest as Request, mockResponse as Response, mockNext ); expect(mockNext).toHaveBeenCalled(); }); }); describe('Input Sanitization', () => { it('should remove HTML tags from request body', () => { mockRequest.body = { text: '', nested: { html: '' } }; sanitizeInput( mockRequest as Request, mockResponse as Response, mockNext ); expect(mockRequest.body.text).not.toContain('