149 lines
6.3 KiB
JavaScript
149 lines
6.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const zod_1 = require("zod");
|
|
const validation_middleware_1 = require("../../src/api/middleware/validation.middleware");
|
|
// Mock Express request, response, and next
|
|
const mockRequest = (data = {}) => ({
|
|
body: data.body || {},
|
|
query: data.query || {},
|
|
params: data.params || {}
|
|
});
|
|
const mockResponse = () => {
|
|
const res = {};
|
|
res.status = jest.fn().mockReturnValue(res);
|
|
res.json = jest.fn().mockReturnValue(res);
|
|
return res;
|
|
};
|
|
const mockNext = jest.fn();
|
|
describe('Validation Middleware', () => {
|
|
afterEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
describe('validate', () => {
|
|
const testSchema = zod_1.z.object({
|
|
name: zod_1.z.string().min(1),
|
|
age: zod_1.z.number().min(0).max(150)
|
|
});
|
|
it('should pass validation with valid data', async () => {
|
|
const req = mockRequest({ body: { name: 'John', age: 30 } });
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validate)(testSchema, 'body');
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
expect(req.body).toEqual({ name: 'John', age: 30 });
|
|
});
|
|
it('should fail validation with invalid data', async () => {
|
|
const req = mockRequest({ body: { name: '', age: -5 } });
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validate)(testSchema, 'body');
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).not.toHaveBeenCalled();
|
|
expect(res.status).toHaveBeenCalledWith(400);
|
|
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({
|
|
success: false,
|
|
error: 'Validation failed',
|
|
details: expect.arrayContaining([
|
|
expect.objectContaining({
|
|
field: expect.any(String),
|
|
message: expect.any(String)
|
|
})
|
|
])
|
|
}));
|
|
});
|
|
it('should validate query parameters', async () => {
|
|
const querySchema = zod_1.z.object({
|
|
page: zod_1.z.coerce.number().min(1),
|
|
limit: zod_1.z.coerce.number().min(1).max(100)
|
|
});
|
|
const req = mockRequest({ query: { page: '2', limit: '50' } });
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validate)(querySchema, 'query');
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).toHaveBeenCalled();
|
|
expect(req.query).toEqual({ page: 2, limit: 50 });
|
|
});
|
|
it('should validate params', async () => {
|
|
const paramsSchema = zod_1.z.object({
|
|
id: zod_1.z.string().uuid()
|
|
});
|
|
const req = mockRequest({
|
|
params: { id: '123e4567-e89b-12d3-a456-426614174000' }
|
|
});
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validate)(paramsSchema, 'params');
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).toHaveBeenCalled();
|
|
});
|
|
});
|
|
describe('validateMultiple', () => {
|
|
const schemas = {
|
|
body: zod_1.z.object({
|
|
title: zod_1.z.string().min(1)
|
|
}),
|
|
query: zod_1.z.object({
|
|
page: zod_1.z.coerce.number().min(1)
|
|
}),
|
|
params: zod_1.z.object({
|
|
id: zod_1.z.string().uuid()
|
|
})
|
|
};
|
|
it('should validate multiple sources successfully', async () => {
|
|
const req = mockRequest({
|
|
body: { title: 'Test' },
|
|
query: { page: '1' },
|
|
params: { id: '123e4567-e89b-12d3-a456-426614174000' }
|
|
});
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validateMultiple)(schemas);
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
expect(req.body).toEqual({ title: 'Test' });
|
|
expect(req.query).toEqual({ page: 1 });
|
|
});
|
|
it('should collect errors from multiple sources', async () => {
|
|
const req = mockRequest({
|
|
body: { title: '' }, // Invalid
|
|
query: { page: '0' }, // Invalid
|
|
params: { id: 'not-a-uuid' } // Invalid
|
|
});
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validateMultiple)(schemas);
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).not.toHaveBeenCalled();
|
|
expect(res.status).toHaveBeenCalledWith(400);
|
|
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({
|
|
success: false,
|
|
error: 'Validation failed',
|
|
details: expect.arrayContaining([
|
|
expect.objectContaining({ source: 'body' }),
|
|
expect.objectContaining({ source: 'query' }),
|
|
expect.objectContaining({ source: 'params' })
|
|
])
|
|
}));
|
|
});
|
|
it('should handle partial schemas', async () => {
|
|
const partialSchemas = {
|
|
body: zod_1.z.object({
|
|
name: zod_1.z.string()
|
|
})
|
|
// No query or params schemas
|
|
};
|
|
const req = mockRequest({
|
|
body: { name: 'Test' },
|
|
query: { anything: 'goes' },
|
|
params: { whatever: 'works' }
|
|
});
|
|
const res = mockResponse();
|
|
const middleware = (0, validation_middleware_1.validateMultiple)(partialSchemas);
|
|
await middleware(req, res, mockNext);
|
|
expect(mockNext).toHaveBeenCalled();
|
|
expect(req.body).toEqual({ name: 'Test' });
|
|
// Query and params should remain unchanged
|
|
expect(req.query).toEqual({ anything: 'goes' });
|
|
expect(req.params).toEqual({ whatever: 'works' });
|
|
});
|
|
});
|
|
});
|
|
//# sourceMappingURL=validation.middleware.test.js.map
|