@kenniy/godeye-data-contracts
Version:
Enterprise-grade base repository architecture for GOD-EYE microservices with zero overhead and maximum code reuse
226 lines (225 loc) • 10.4 kB
JavaScript
;
/**
* Validation System Tests
* Tests the unified validation decorators and transformations
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const class_validator_1 = require("class-validator");
const class_transformer_1 = require("class-transformer");
const validation_1 = require("../core/validation");
// Test DTOs
class TestUserDto {
}
__decorate([
(0, validation_1.IsValidId)(),
__metadata("design:type", String)
], TestUserDto.prototype, "id", void 0);
__decorate([
(0, validation_1.IsRequiredEmail)(),
(0, validation_1.ToLowerCase)(),
(0, validation_1.Trim)(),
__metadata("design:type", String)
], TestUserDto.prototype, "email", void 0);
__decorate([
(0, validation_1.IsOptionalEmail)(),
__metadata("design:type", String)
], TestUserDto.prototype, "alternateEmail", void 0);
__decorate([
(0, validation_1.IsPhoneNumber)(),
__metadata("design:type", String)
], TestUserDto.prototype, "phone", void 0);
__decorate([
(0, validation_1.TransformDate)(),
__metadata("design:type", Date)
], TestUserDto.prototype, "birthDate", void 0);
__decorate([
(0, validation_1.TransformArray)(),
__metadata("design:type", Array)
], TestUserDto.prototype, "tags", void 0);
class TestOptionalDto {
}
__decorate([
(0, validation_1.IsOptionalEmail)(),
__metadata("design:type", String)
], TestOptionalDto.prototype, "email", void 0);
__decorate([
(0, validation_1.IsPhoneNumber)(['US', 'NG']),
__metadata("design:type", String)
], TestOptionalDto.prototype, "phone", void 0);
describe('Validation System', () => {
describe('IsValidId decorator', () => {
it('should validate UUID format', async () => {
const dto = new TestUserDto();
dto.id = '550e8400-e29b-41d4-a716-446655440000';
dto.email = 'test@example.com';
dto.phone = '+1234567890';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const idErrors = errors.filter(e => e.property === 'id');
expect(idErrors).toHaveLength(0);
});
it('should validate MongoDB ObjectId format', async () => {
const dto = new TestUserDto();
dto.id = '507f1f77bcf86cd799439011';
dto.email = 'test@example.com';
dto.phone = '+1234567890';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const idErrors = errors.filter(e => e.property === 'id');
expect(idErrors).toHaveLength(0);
});
it('should validate numeric ID format', async () => {
const dto = new TestUserDto();
dto.id = '12345';
dto.email = 'test@example.com';
dto.phone = '+1234567890';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const idErrors = errors.filter(e => e.property === 'id');
expect(idErrors).toHaveLength(0);
});
it('should reject invalid ID formats', async () => {
const dto = new TestUserDto();
dto.id = 'invalid-id';
dto.email = 'test@example.com';
dto.phone = '+1234567890';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const idErrors = errors.filter(e => e.property === 'id');
expect(idErrors.length).toBeGreaterThan(0);
});
});
describe('Email validation decorators', () => {
it('should validate required email', async () => {
const dto = new TestUserDto();
dto.id = '123';
dto.email = 'valid@example.com';
dto.phone = '+1234567890';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const emailErrors = errors.filter(e => e.property === 'email');
expect(emailErrors).toHaveLength(0);
});
it('should reject invalid email format', async () => {
const dto = new TestUserDto();
dto.id = '123';
dto.email = 'invalid-email';
dto.phone = '+1234567890';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const emailErrors = errors.filter(e => e.property === 'email');
expect(emailErrors.length).toBeGreaterThan(0);
});
it('should allow empty optional email', async () => {
const dto = new TestOptionalDto();
dto.phone = '+1234567890';
// email is undefined - should be valid
const errors = await (0, class_validator_1.validate)(dto);
const emailErrors = errors.filter(e => e.property === 'email');
expect(emailErrors).toHaveLength(0);
});
});
describe('Phone validation decorator', () => {
it('should validate basic phone number', async () => {
const dto = new TestUserDto();
dto.id = '123';
dto.email = 'test@example.com';
dto.phone = '+1-234-567-8900';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const phoneErrors = errors.filter(e => e.property === 'phone');
expect(phoneErrors).toHaveLength(0);
});
it('should validate phone with spaces and parentheses', async () => {
const dto = new TestUserDto();
dto.id = '123';
dto.email = 'test@example.com';
dto.phone = '+1 (234) 567-8900';
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const phoneErrors = errors.filter(e => e.property === 'phone');
expect(phoneErrors).toHaveLength(0);
});
it('should reject invalid phone format', async () => {
const dto = new TestUserDto();
dto.id = '123';
dto.email = 'test@example.com';
dto.phone = 'abc123'; // Invalid characters
dto.birthDate = new Date();
dto.tags = ['tag1'];
const errors = await (0, class_validator_1.validate)(dto);
const phoneErrors = errors.filter(e => e.property === 'phone');
expect(phoneErrors.length).toBeGreaterThan(0);
});
});
describe('Transform decorators', () => {
it('should transform email to lowercase and trim', () => {
const input = { email: ' TEST@EXAMPLE.COM ' };
const dto = (0, class_transformer_1.plainToClass)(TestUserDto, input);
expect(dto.email).toBe('test@example.com');
});
it('should transform string date to Date object', () => {
const input = { birthDate: '2024-01-15T10:00:00Z' };
const dto = (0, class_transformer_1.plainToClass)(TestUserDto, input);
expect(dto.birthDate).toBeInstanceOf(Date);
expect(dto.birthDate.getFullYear()).toBe(2024);
});
it('should transform comma-separated string to array', () => {
const input = { tags: 'tag1,tag2,tag3' };
const dto = (0, class_transformer_1.plainToClass)(TestUserDto, input);
expect(Array.isArray(dto.tags)).toBe(true);
expect(dto.tags).toEqual(['tag1', 'tag2', 'tag3']);
});
it('should handle array input for TransformArray', () => {
const input = { tags: ['tag1', 'tag2'] };
const dto = (0, class_transformer_1.plainToClass)(TestUserDto, input);
expect(Array.isArray(dto.tags)).toBe(true);
expect(dto.tags).toEqual(['tag1', 'tag2']);
});
});
describe('ValidationUtils', () => {
it('should validate UUID ID', () => {
expect(validation_1.ValidationUtils.isValidId('550e8400-e29b-41d4-a716-446655440000')).toBe(true);
expect(validation_1.ValidationUtils.isValidId('invalid-id')).toBe(false);
});
it('should validate ObjectId', () => {
expect(validation_1.ValidationUtils.isValidId('507f1f77bcf86cd799439011')).toBe(true);
expect(validation_1.ValidationUtils.isValidId('invalid-objectid')).toBe(false);
});
it('should validate numeric ID', () => {
expect(validation_1.ValidationUtils.isValidId('12345')).toBe(true);
expect(validation_1.ValidationUtils.isValidId('abc123')).toBe(false);
});
it('should validate email format', () => {
expect(validation_1.ValidationUtils.isValidEmail('test@example.com')).toBe(true);
expect(validation_1.ValidationUtils.isValidEmail('invalid-email')).toBe(false);
});
it('should validate pagination parameters', () => {
const result = validation_1.ValidationUtils.validatePagination(2, 10);
expect(result.page).toBe(2);
expect(result.limit).toBe(10);
});
it('should correct invalid pagination parameters', () => {
const result = validation_1.ValidationUtils.validatePagination(-1, 1000);
expect(result.page).toBe(1); // Min page
expect(result.limit).toBe(100); // Max limit (assuming MAX_LIMIT = 100)
});
});
});