test: enhance security middleware and token management tests

- Added comprehensive test coverage for TokenManager encryption and validation methods
- Implemented detailed test scenarios for security middleware functions
- Updated test cases to handle edge cases and improve input validation
- Refactored test mocks to provide more robust and realistic testing environment
- Improved error handling and input validation in security-related components
This commit is contained in:
jango-blockchained
2025-02-03 18:44:38 +01:00
parent 4e89e5458c
commit d17d881e7b
12 changed files with 658 additions and 428 deletions

View File

@@ -0,0 +1,109 @@
import { Request, Response, NextFunction } from 'express';
import { validateRequest, sanitizeInput } from '../../src/security/middleware';
type MockRequest = {
headers: {
'content-type'?: string;
authorization?: string;
};
body?: any;
is: jest.MockInstance<string | false | null, [type: string | string[]]>;
};
type MockResponse = {
status: jest.MockInstance<MockResponse, [code: number]>;
json: jest.MockInstance<MockResponse, [body: any]>;
setHeader: jest.MockInstance<MockResponse, [name: string, value: string]>;
};
describe('Security Middleware', () => {
let mockRequest: MockRequest;
let mockResponse: MockResponse;
let nextFunction: jest.Mock;
beforeEach(() => {
mockRequest = {
headers: {},
body: {},
is: jest.fn<string | false | null, [string | string[]]>().mockReturnValue('json')
};
mockResponse = {
status: jest.fn<MockResponse, [number]>().mockReturnThis(),
json: jest.fn<MockResponse, [any]>().mockReturnThis(),
setHeader: jest.fn<MockResponse, [string, string]>().mockReturnThis()
};
nextFunction = jest.fn();
});
describe('validateRequest', () => {
it('should pass valid requests', () => {
mockRequest.headers.authorization = 'Bearer valid-token';
validateRequest(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(nextFunction).toHaveBeenCalled();
});
it('should reject requests without authorization header', () => {
validateRequest(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(mockResponse.status).toHaveBeenCalledWith(401);
expect(mockResponse.json).toHaveBeenCalledWith(expect.objectContaining({
error: expect.stringContaining('authorization')
}));
});
it('should reject requests with invalid authorization format', () => {
mockRequest.headers.authorization = 'invalid-format';
validateRequest(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(mockResponse.status).toHaveBeenCalledWith(401);
expect(mockResponse.json).toHaveBeenCalledWith(expect.objectContaining({
error: expect.stringContaining('Bearer')
}));
});
});
describe('sanitizeInput', () => {
it('should pass requests without body', () => {
delete mockRequest.body;
sanitizeInput(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(nextFunction).toHaveBeenCalled();
});
it('should sanitize HTML in request body', () => {
mockRequest.body = {
text: '<script>alert("xss")</script>Hello',
nested: {
html: '<img src="x" onerror="alert(1)">World'
}
};
sanitizeInput(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(mockRequest.body.text).toBe('Hello');
expect(mockRequest.body.nested.html).toBe('World');
expect(nextFunction).toHaveBeenCalled();
});
it('should handle non-object bodies', () => {
mockRequest.body = '<p>text</p>';
sanitizeInput(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(mockRequest.body).toBe('text');
expect(nextFunction).toHaveBeenCalled();
});
it('should preserve non-string values', () => {
mockRequest.body = {
number: 42,
boolean: true,
null: null,
array: [1, 2, 3]
};
sanitizeInput(mockRequest as unknown as Request, mockResponse as unknown as Response, nextFunction);
expect(mockRequest.body).toEqual({
number: 42,
boolean: true,
null: null,
array: [1, 2, 3]
});
expect(nextFunction).toHaveBeenCalled();
});
});
});