39948-vm/backend/tests/request-validation.test.js

130 lines
3.4 KiB
JavaScript

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/,
);
});