Fix jwt-token

This commit is contained in:
2025-09-14 21:07:43 +02:00
parent d6293dd8ba
commit 019eb8c2b2
20 changed files with 7185 additions and 29 deletions

View File

@@ -0,0 +1,291 @@
const { describe, it, beforeEach, afterEach, before, after } = require('mocha');
const { expect } = require('chai');
const sinon = require('sinon');
const { validateRequest } = require('../../middleware/validation');
const Joi = require('joi');
const { mockRequest, mockResponse, mockNext } = require('../setup');
describe('Validation Middleware', () => {
describe('validateRequest', () => {
const testSchema = Joi.object({
name: Joi.string().required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(0).max(120).optional(),
tags: Joi.array().items(Joi.string()).optional()
});
it('should pass validation with valid data', () => {
const req = mockRequest({
body: {
name: 'John Doe',
email: 'john@example.com',
age: 30,
tags: ['admin', 'user']
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(next.errors).to.have.length(0);
expect(req.body).to.deep.equal({
name: 'John Doe',
email: 'john@example.com',
age: 30,
tags: ['admin', 'user']
});
});
it('should fail validation with missing required field', () => {
const req = mockRequest({
body: {
email: 'john@example.com'
// missing name
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(res.statusCode).to.equal(400);
expect(res.data.success).to.be.false;
expect(res.data.message).to.include('name');
});
it('should fail validation with invalid email', () => {
const req = mockRequest({
body: {
name: 'John Doe',
email: 'invalid-email'
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(res.statusCode).to.equal(400);
expect(res.data.success).to.be.false;
expect(res.data.message).to.include('email');
});
it('should fail validation with invalid age', () => {
const req = mockRequest({
body: {
name: 'John Doe',
email: 'john@example.com',
age: -5
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(res.statusCode).to.equal(400);
expect(res.data.success).to.be.false;
expect(res.data.message).to.include('age');
});
it('should strip unknown fields', () => {
const req = mockRequest({
body: {
name: 'John Doe',
email: 'john@example.com',
unknownField: 'should be removed'
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(next.errors).to.have.length(0);
expect(req.body).to.not.have.property('unknownField');
});
it('should handle array validation', () => {
const req = mockRequest({
body: {
name: 'John Doe',
email: 'john@example.com',
tags: ['valid', 'tags']
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(next.errors).to.have.length(0);
expect(req.body.tags).to.deep.equal(['valid', 'tags']);
});
it('should fail with invalid array items', () => {
const req = mockRequest({
body: {
name: 'John Doe',
email: 'john@example.com',
tags: ['valid', 123, 'invalid-number']
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(res.statusCode).to.equal(400);
expect(res.data.success).to.be.false;
});
it('should handle nested object validation', () => {
const nestedSchema = Joi.object({
user: Joi.object({
name: Joi.string().required(),
profile: Joi.object({
age: Joi.number().required(),
preferences: Joi.array().items(Joi.string())
}).required()
}).required()
});
const req = mockRequest({
body: {
user: {
name: 'John',
profile: {
age: 30,
preferences: ['dark-mode', 'notifications']
}
}
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(nestedSchema);
middleware(req, res, next);
expect(next.errors).to.have.length(0);
});
it('should provide detailed error messages', () => {
const req = mockRequest({
body: {
name: '',
email: 'invalid',
age: 150
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(testSchema);
middleware(req, res, next);
expect(res.statusCode).to.equal(400);
expect(res.data.success).to.be.false;
expect(res.data.message).to.be.a('string');
expect(res.data.details).to.be.an('array');
expect(res.data.details.length).to.be.greaterThan(0);
});
it('should handle alternative schemas', () => {
const altSchema = Joi.alternatives().try(
Joi.object({
type: Joi.string().valid('user').required(),
username: Joi.string().required()
}),
Joi.object({
type: Joi.string().valid('device').required(),
deviceId: Joi.number().required()
})
);
const req1 = mockRequest({
body: {
type: 'user',
username: 'john'
}
});
const res1 = mockResponse();
const next1 = mockNext();
const middleware1 = validateRequest(altSchema);
middleware1(req1, res1, next1);
expect(next1.errors).to.have.length(0);
const req2 = mockRequest({
body: {
type: 'device',
deviceId: 123
}
});
const res2 = mockResponse();
const next2 = mockNext();
const middleware2 = validateRequest(altSchema);
middleware2(req2, res2, next2);
expect(next2.errors).to.have.length(0);
});
it('should handle query parameter validation', () => {
const querySchema = Joi.object({
page: Joi.number().integer().min(1).default(1),
limit: Joi.number().integer().min(1).max(100).default(10),
search: Joi.string().optional()
});
const req = mockRequest({
query: {
page: '2',
limit: '20',
search: 'test'
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(querySchema, 'query');
middleware(req, res, next);
expect(next.errors).to.have.length(0);
expect(req.query.page).to.equal(2); // Should be converted to number
expect(req.query.limit).to.equal(20);
});
it('should handle params validation', () => {
const paramsSchema = Joi.object({
id: Joi.number().integer().positive().required(),
slug: Joi.string().alphanum().optional()
});
const req = mockRequest({
params: {
id: '123',
slug: 'test-slug'
}
});
const res = mockResponse();
const next = mockNext();
const middleware = validateRequest(paramsSchema, 'params');
middleware(req, res, next);
expect(next.errors).to.have.length(0);
expect(req.params.id).to.equal(123);
});
});
});