"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