273 lines
8.6 KiB
TypeScript
273 lines
8.6 KiB
TypeScript
/**
|
|
* Logger Middleware Integration Tests
|
|
*
|
|
* Tests the Hono middleware functionality of the @stock-bot/logger package,
|
|
* verifying that all middleware components work correctly together.
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
|
|
import {
|
|
loggingMiddleware,
|
|
errorLoggingMiddleware,
|
|
performanceMiddleware,
|
|
securityMiddleware,
|
|
businessEventMiddleware,
|
|
comprehensiveLoggingMiddleware
|
|
} from '../src';
|
|
import { loggerTestHelpers } from './setup';
|
|
|
|
describe('Logger Middleware Integration', () => {
|
|
beforeEach(() => {
|
|
// Clear logs before each test
|
|
loggerTestHelpers.clearCapturedLogs();
|
|
});
|
|
|
|
describe('Basic Logging Middleware', () => {
|
|
it('should log incoming requests', async () => {
|
|
// Create middleware with test logger
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = loggingMiddleware({
|
|
serviceName: 'test-service',
|
|
logger: testLogger
|
|
});
|
|
|
|
// Create mock context
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/test',
|
|
method: 'GET'
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify request was logged
|
|
expect(logs.length).toBeGreaterThan(0);
|
|
expect(logs[0].level).toBe('http');
|
|
expect(logs[0].msg).toContain('HTTP Request');
|
|
});
|
|
|
|
it('should skip logging for defined paths', async () => {
|
|
// Create middleware with skip paths
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = loggingMiddleware({
|
|
serviceName: 'test-service',
|
|
logger: testLogger,
|
|
skipPaths: ['/test']
|
|
});
|
|
|
|
// Create mock context with path that should be skipped
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/test',
|
|
method: 'GET'
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify no logs were captured
|
|
expect(logs.length).toBe(0);
|
|
});
|
|
|
|
it('should log request/response details', async () => {
|
|
// Create middleware that logs bodies
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = loggingMiddleware({
|
|
serviceName: 'test-service',
|
|
logger: testLogger,
|
|
logRequestBody: true,
|
|
logResponseBody: true
|
|
});
|
|
|
|
// Create mock context with response status
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/api/data',
|
|
method: 'POST',
|
|
res: {
|
|
status: 200,
|
|
body: { success: true }
|
|
}
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify request and response were logged
|
|
expect(logs.length).toBeGreaterThan(0);
|
|
// First log is HTTP request started, and final log is HTTP request completed
|
|
expect(logs[0].msg).toContain('HTTP Request started');
|
|
expect(logs[logs.length-1].msg).toContain('HTTP Request completed');
|
|
});
|
|
});
|
|
|
|
describe('Error Logging Middleware', () => {
|
|
it('should log errors from next middleware', async () => {
|
|
// Create middleware
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = errorLoggingMiddleware(testLogger);
|
|
|
|
// Create mock context
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/api/error',
|
|
method: 'GET'
|
|
});
|
|
|
|
// Create next function that throws error
|
|
const mockNext = async () => {
|
|
throw new Error('Test error');
|
|
};
|
|
|
|
// Execute middleware
|
|
try {
|
|
await middleware(mockContext, mockNext);
|
|
} catch (error) {
|
|
// Error should be re-thrown after logging
|
|
}
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify error was logged
|
|
expect(logs.length).toBe(1);
|
|
expect(logs[0].level).toBe('error');
|
|
expect(logs[0].msg).toContain('Unhandled HTTP error');
|
|
});
|
|
});
|
|
|
|
describe('Performance Middleware', () => {
|
|
it('should log performance metrics for requests', async () => {
|
|
// Create middleware
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = performanceMiddleware('test-operation', testLogger);
|
|
|
|
// Create mock context
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/api/data',
|
|
method: 'GET'
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify performance metrics were logged
|
|
expect(logs.length).toBe(1);
|
|
expect(logs[0].level).toBe('info');
|
|
expect(logs[0].msg).toContain('Operation completed');
|
|
expect(logs[0].performance).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Security Middleware', () => {
|
|
it('should log security events', async () => {
|
|
// Create middleware
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = securityMiddleware(testLogger);
|
|
|
|
// Create mock context with auth header
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/api/secure',
|
|
method: 'GET',
|
|
req: {
|
|
headers: {
|
|
'authorization': 'Bearer test-token'
|
|
}
|
|
}
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify security event was logged
|
|
expect(logs.length).toBe(1);
|
|
expect(logs[0].level).toBe('info');
|
|
expect(logs[0].msg).toContain('Authentication attempt');
|
|
expect(logs[0].type).toBe('security_event');
|
|
});
|
|
});
|
|
|
|
describe('Business Event Middleware', () => {
|
|
it('should log business events with custom metadata', async () => {
|
|
// Create middleware with custom business endpoints
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = businessEventMiddleware(testLogger);
|
|
|
|
// Create mock context with business path
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/api/orders',
|
|
method: 'POST',
|
|
res: { status: 201 }
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify business event was logged
|
|
expect(logs.length).toBe(1);
|
|
expect(logs[0].level).toBe('info');
|
|
expect(logs[0].msg).toContain('Business operation completed');
|
|
expect(logs[0].type).toBe('business_event');
|
|
});
|
|
});
|
|
|
|
describe('Comprehensive Logging Middleware', () => {
|
|
it('should combine multiple logging features', async () => {
|
|
// Create middleware
|
|
const testLogger = loggerTestHelpers.createTestLogger('middleware-test');
|
|
const middleware = comprehensiveLoggingMiddleware({
|
|
serviceName: 'test-service',
|
|
logger: testLogger
|
|
});
|
|
|
|
// Create mock context
|
|
const mockContext = loggerTestHelpers.createHonoContextMock({
|
|
path: '/api/data',
|
|
method: 'GET',
|
|
req: {
|
|
headers: {
|
|
'authorization': 'Bearer test-token'
|
|
}
|
|
}
|
|
});
|
|
const mockNext = loggerTestHelpers.createNextMock();
|
|
|
|
// Execute middleware
|
|
await middleware(mockContext, mockNext);
|
|
|
|
// Get captured logs
|
|
const logs = loggerTestHelpers.getCapturedLogs();
|
|
|
|
// Verify multiple log entries from different middleware components
|
|
expect(logs.length).toBeGreaterThan(1);
|
|
|
|
// Should have logs from security, logging, and performance middleware
|
|
const securityLog = logs.find(log => log.type === 'security_event');
|
|
const requestLog = logs.find(log => log.msg?.includes('HTTP Request'));
|
|
|
|
expect(securityLog).toBeDefined();
|
|
expect(requestLog).toBeDefined();
|
|
});
|
|
});
|
|
});
|