const test = require('node:test'); const assert = require('node:assert/strict'); const Joi = require('joi'); const { validateRequest } = require('../src/middlewares/validate-request'); const { commonErrorHandler } = require('../src/helpers'); const { crud, projects, tourPages, users, } = require('../src/validators/request-schemas'); function runMiddleware(middleware, req) { return new Promise((resolve) => { middleware(req, {}, (error) => resolve(error || null)); }); } test('validateRequest applies converted sanitized values to request parts', async () => { const req = { query: { limit: '25', page: '2', field: 'createdAt', sort: 'DESC', name: 'Lobby', }, }; const error = await runMiddleware(validateRequest(crud.list), req); assert.equal(error, null); assert.equal(req.query.limit, 25); assert.equal(req.query.page, 2); assert.equal(req.query.name, 'Lobby'); }); test('validateRequest returns structured request validation error details', async () => { const req = { body: { data: ['not-object'], }, }; const error = await runMiddleware(validateRequest(crud.create), req); assert.equal(error.code, 400); assert.equal(error.isRequestValidation, true); assert.equal(error.details[0].path, 'body.data'); }); test('commonErrorHandler sends request validation errors as JSON', () => { const error = { code: 400, message: 'Invalid request', isRequestValidation: true, details: [{ path: 'body.email', message: 'email is required' }], }; const res = { statusCode: null, payload: null, status(code) { this.statusCode = code; return this; }, send(payload) { this.payload = payload; return this; }, }; commonErrorHandler(error, {}, res, () => {}); assert.equal(res.statusCode, 400); assert.deepEqual(res.payload, { error: 'Invalid request', details: [{ path: 'body.email', message: 'email is required' }], }); }); test('user update schema preserves omitted permissions fields', async () => { const req = { params: { id: '094121b9-c567-469a-b256-ba221b7fd5d6' }, body: { data: { firstName: 'Admin', }, }, }; const error = await runMiddleware(validateRequest(users.update), req); assert.equal(error, null); assert.equal( Object.prototype.hasOwnProperty.call(req.body.data, 'custom_permissions'), false, ); assert.equal( Object.prototype.hasOwnProperty.call( req.body.data, 'allowed_private_production_project_ids', ), false, ); }); test('create schemas reject missing fields required before service layer', async () => { const userError = await runMiddleware(validateRequest(users.create), { body: { data: { firstName: 'No Email' } }, }); const projectError = await runMiddleware(validateRequest(projects.create), { body: { data: { name: 'No Slug' } }, }); const tourPageError = await runMiddleware(validateRequest(tourPages.create), { body: { data: { name: 'No Project', slug: 'no-project' } }, }); assert.equal(userError.isRequestValidation, true); assert.equal(projectError.isRequestValidation, true); assert.equal(tourPageError.isRequestValidation, true); }); test('validateRequest rejects invalid schema maps during route setup', () => { assert.throws( () => validateRequest({ body: Joi.object(), cookies: Joi.object() }), /Unsupported request validation part/, ); });