qapinterface
Version:
Comprehensive API utilities for Node.js applications including authentication, security, request processing, and response handling with zero external dependencies
108 lines (89 loc) • 2.95 kB
JavaScript
const TestRunner = require('./TestRunner');
const { createValidator } = require('../utility/validation');
const { z } = require('zod');
const test = new TestRunner();
test.describe('Validation Utilities', () => {
test.describe('createValidator()', () => {
const userSchema = z.object({
id: z.string().uuid(),
name: z.string().min(3),
email: z.string().email(),
age: z.number().int().positive().optional()
});
const validateUser = createValidator({ body: userSchema });
test.it('should validate correct input', async () => {
const req = {
body: {
id: '123e4567-e89b-12d3-a456-426614174000',
name: 'John Doe',
email: 'john@example.com',
age: 30
}
};
let nextCalled = false;
const next = () => { nextCalled = true; };
await validateUser(req, {}, next);
test.expect(nextCalled).to.be.true;
});
test.it('should reject invalid email', async () => {
const req = {
body: {
id: '123e4567-e89b-12d3-a456-426614174000',
name: 'John Doe',
email: 'invalid-email',
age: 30
}
};
let status = 200;
const res = {
status: (s) => { status = s; return res; },
json: (data) => data
};
await validateUser(req, res, () => {});
test.expect(status).to.equal(400);
});
test.it('should handle missing required field', async () => {
const req = {
body: {
id: '123e4567-e89b-12d3-a456-426614174000',
email: 'john@example.com'
// Missing 'name'
}
};
let status = 200;
const res = {
status: (s) => { status = s; return res; },
json: (data) => data
};
await validateUser(req, res, () => {});
test.expect(status).to.equal(400);
});
});
test.describe('custom validation rules', () => {
const passwordSchema = z.string()
.min(8)
.regex(/[A-Z]/, 'Must contain at least one uppercase letter')
.regex(/[0-9]/, 'Must contain at least one number');
const validatePassword = createValidator({ body: z.object({ password: passwordSchema }) });
test.it('should validate strong password', async () => {
const req = { body: { password: 'SecurePass123' } };
let nextCalled = false;
await validatePassword(req, {}, () => { nextCalled = true; });
test.expect(nextCalled).to.be.true;
});
test.it('should reject weak password', async () => {
const req = { body: { password: 'weak' } };
let status = 200;
const res = {
status: (s) => { status = s; return res; },
json: (data) => data
};
await validatePassword(req, res, () => {});
test.expect(status).to.equal(400);
});
});
});
(async () => {
await test.run();
test.summary();
})();