import { describe, it, expect } from 'vitest'; import { validateVehicle } from '../validation'; describe('Vehicle Validation', () => { describe('validateVehicle', () => { const validVehicleData = { plateNumber: 'ABC-123', bodyType: 'سيدان', manufacturer: 'تويوتا', model: 'كامري', year: 2020, transmission: 'Automatic', fuel: 'Gasoline', useType: 'personal', ownerId: 1, }; it('should validate a complete valid vehicle', () => { const result = validateVehicle(validVehicleData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should validate a minimal valid vehicle', () => { const minimalData = { plateNumber: 'ABC-123', bodyType: 'سيدان', manufacturer: 'تويوتا', model: 'كامري', year: 2020, transmission: 'Automatic', fuel: 'Gasoline', useType: 'personal', ownerId: 1, }; const result = validateVehicle(minimalData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); describe('plateNumber validation', () => { it('should require plate number', () => { const result = validateVehicle({ ...validVehicleData, plateNumber: '' }); expect(result.isValid).toBe(false); expect(result.errors.plateNumber).toBe('رقم اللوحة مطلوب'); }); it('should require plate number to not be just whitespace', () => { const result = validateVehicle({ ...validVehicleData, plateNumber: ' ' }); expect(result.isValid).toBe(false); expect(result.errors.plateNumber).toBe('رقم اللوحة مطلوب'); }); }); describe('bodyType validation', () => { it('should require body type', () => { const result = validateVehicle({ ...validVehicleData, bodyType: '' }); expect(result.isValid).toBe(false); expect(result.errors.bodyType).toBe('نوع الهيكل مطلوب'); }); it('should require body type to not be just whitespace', () => { const result = validateVehicle({ ...validVehicleData, bodyType: ' ' }); expect(result.isValid).toBe(false); expect(result.errors.bodyType).toBe('نوع الهيكل مطلوب'); }); }); describe('manufacturer validation', () => { it('should require manufacturer', () => { const result = validateVehicle({ ...validVehicleData, manufacturer: '' }); expect(result.isValid).toBe(false); expect(result.errors.manufacturer).toBe('الشركة المصنعة مطلوبة'); }); it('should require manufacturer to not be just whitespace', () => { const result = validateVehicle({ ...validVehicleData, manufacturer: ' ' }); expect(result.isValid).toBe(false); expect(result.errors.manufacturer).toBe('الشركة المصنعة مطلوبة'); }); }); describe('model validation', () => { it('should require model', () => { const result = validateVehicle({ ...validVehicleData, model: '' }); expect(result.isValid).toBe(false); expect(result.errors.model).toBe('الموديل مطلوب'); }); it('should require model to not be just whitespace', () => { const result = validateVehicle({ ...validVehicleData, model: ' ' }); expect(result.isValid).toBe(false); expect(result.errors.model).toBe('الموديل مطلوب'); }); }); describe('year validation', () => { it('should not validate undefined year (partial validation)', () => { const result = validateVehicle({ ...validVehicleData, year: undefined as any }); expect(result.isValid).toBe(true); expect(result.errors.year).toBeUndefined(); }); it('should reject year below minimum', () => { const result = validateVehicle({ ...validVehicleData, year: 1989 }); expect(result.isValid).toBe(false); expect(result.errors.year).toContain('السنة يجب أن تكون بين 1990'); }); it('should reject year above maximum', () => { const currentYear = new Date().getFullYear(); const result = validateVehicle({ ...validVehicleData, year: currentYear + 2 }); expect(result.isValid).toBe(false); expect(result.errors.year).toContain('السنة يجب أن تكون بين'); }); it('should accept current year', () => { const currentYear = new Date().getFullYear(); const result = validateVehicle({ ...validVehicleData, year: currentYear }); expect(result.isValid).toBe(true); }); it('should accept next year', () => { const nextYear = new Date().getFullYear() + 1; const result = validateVehicle({ ...validVehicleData, year: nextYear }); expect(result.isValid).toBe(true); }); }); describe('transmission validation', () => { it('should require transmission', () => { const result = validateVehicle({ ...validVehicleData, transmission: '' }); expect(result.isValid).toBe(false); expect(result.errors.transmission).toBe('نوع ناقل الحركة غير صحيح'); }); it('should accept valid transmission types', () => { const automaticResult = validateVehicle({ ...validVehicleData, transmission: 'Automatic' }); const manualResult = validateVehicle({ ...validVehicleData, transmission: 'Manual' }); expect(automaticResult.isValid).toBe(true); expect(manualResult.isValid).toBe(true); }); it('should reject invalid transmission types', () => { const result = validateVehicle({ ...validVehicleData, transmission: 'CVT' }); expect(result.isValid).toBe(false); expect(result.errors.transmission).toBe('نوع ناقل الحركة غير صحيح'); }); }); describe('fuel validation', () => { it('should require fuel type', () => { const result = validateVehicle({ ...validVehicleData, fuel: '' }); expect(result.isValid).toBe(false); expect(result.errors.fuel).toBe('نوع الوقود غير صحيح'); }); it('should accept valid fuel types', () => { const validFuels = ['Gasoline', 'Diesel', 'Hybrid', 'Mild Hybrid', 'Electric']; validFuels.forEach(fuel => { const result = validateVehicle({ ...validVehicleData, fuel }); expect(result.isValid).toBe(true); }); }); it('should reject invalid fuel types', () => { const result = validateVehicle({ ...validVehicleData, fuel: 'Nuclear' }); expect(result.isValid).toBe(false); expect(result.errors.fuel).toBe('نوع الوقود غير صحيح'); }); }); describe('cylinders validation', () => { it('should accept valid cylinder counts', () => { const validCylinders = [1, 2, 3, 4, 6, 8, 10, 12]; validCylinders.forEach(cylinders => { const result = validateVehicle({ ...validVehicleData, cylinders }); expect(result.isValid).toBe(true); }); }); it('should reject cylinder count below minimum', () => { const result = validateVehicle({ ...validVehicleData, cylinders: 0 }); expect(result.isValid).toBe(false); expect(result.errors.cylinders).toContain('عدد الأسطوانات يجب أن يكون بين 1'); }); it('should reject cylinder count above maximum', () => { const result = validateVehicle({ ...validVehicleData, cylinders: 16 }); expect(result.isValid).toBe(false); expect(result.errors.cylinders).toContain('عدد الأسطوانات يجب أن يكون بين 1 و 12'); }); it('should accept null/undefined cylinders', () => { const result1 = validateVehicle({ ...validVehicleData, cylinders: undefined }); const result2 = validateVehicle({ ...validVehicleData, cylinders: null as any }); expect(result1.isValid).toBe(true); expect(result2.isValid).toBe(true); }); }); describe('engineDisplacement validation', () => { it('should accept valid engine displacements', () => { const validDisplacements = [1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0]; validDisplacements.forEach(engineDisplacement => { const result = validateVehicle({ ...validVehicleData, engineDisplacement }); expect(result.isValid).toBe(true); }); }); it('should reject engine displacement at zero', () => { const result = validateVehicle({ ...validVehicleData, engineDisplacement: 0 }); expect(result.isValid).toBe(false); expect(result.errors.engineDisplacement).toContain('سعة المحرك يجب أن تكون بين 0.1'); }); it('should reject engine displacement above maximum', () => { const result = validateVehicle({ ...validVehicleData, engineDisplacement: 15.0 }); expect(result.isValid).toBe(false); expect(result.errors.engineDisplacement).toContain('سعة المحرك يجب أن تكون بين 0.1 و 10'); }); it('should accept null/undefined engine displacement', () => { const result1 = validateVehicle({ ...validVehicleData, engineDisplacement: undefined }); const result2 = validateVehicle({ ...validVehicleData, engineDisplacement: null as any }); expect(result1.isValid).toBe(true); expect(result2.isValid).toBe(true); }); }); describe('useType validation', () => { it('should require use type', () => { const result = validateVehicle({ ...validVehicleData, useType: '' }); expect(result.isValid).toBe(false); expect(result.errors.useType).toBe('نوع الاستخدام غير صحيح'); }); it('should accept valid use types', () => { const validUseTypes = ['personal', 'taxi', 'apps', 'loading', 'travel']; validUseTypes.forEach(useType => { const result = validateVehicle({ ...validVehicleData, useType }); expect(result.isValid).toBe(true); }); }); it('should reject invalid use types', () => { const result = validateVehicle({ ...validVehicleData, useType: 'military' }); expect(result.isValid).toBe(false); expect(result.errors.useType).toBe('نوع الاستخدام غير صحيح'); }); }); describe('ownerId validation', () => { it('should not validate undefined owner ID (partial validation)', () => { const result = validateVehicle({ ...validVehicleData, ownerId: undefined as any }); expect(result.isValid).toBe(true); expect(result.errors.ownerId).toBeUndefined(); }); it('should reject zero owner ID', () => { const result = validateVehicle({ ...validVehicleData, ownerId: 0 }); expect(result.isValid).toBe(false); expect(result.errors.ownerId).toBe('مالك المركبة مطلوب'); }); it('should reject negative owner ID', () => { const result = validateVehicle({ ...validVehicleData, ownerId: -1 }); expect(result.isValid).toBe(false); expect(result.errors.ownerId).toBe('مالك المركبة مطلوب'); }); it('should accept positive owner ID', () => { const result = validateVehicle({ ...validVehicleData, ownerId: 5 }); expect(result.isValid).toBe(true); }); }); describe('multiple validation errors', () => { it('should return all validation errors', () => { const invalidData = { plateNumber: '', bodyType: '', manufacturer: '', model: '', year: 1980, transmission: 'Invalid', fuel: 'Invalid', cylinders: 20, engineDisplacement: 15.0, useType: 'Invalid', ownerId: 0, }; const result = validateVehicle(invalidData); expect(result.isValid).toBe(false); expect(Object.keys(result.errors)).toContain('plateNumber'); expect(Object.keys(result.errors)).toContain('bodyType'); expect(Object.keys(result.errors)).toContain('manufacturer'); expect(Object.keys(result.errors)).toContain('model'); expect(Object.keys(result.errors)).toContain('year'); expect(Object.keys(result.errors)).toContain('transmission'); expect(Object.keys(result.errors)).toContain('fuel'); expect(Object.keys(result.errors)).toContain('cylinders'); expect(Object.keys(result.errors)).toContain('engineDisplacement'); expect(Object.keys(result.errors)).toContain('useType'); expect(Object.keys(result.errors)).toContain('ownerId'); }); }); describe('partial validation', () => { it('should validate only provided fields', () => { const partialData = { plateNumber: 'XYZ-789', year: 2021, }; const result = validateVehicle(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should validate only provided fields with errors', () => { const partialData = { plateNumber: '', year: 1980, cylinders: 20, }; const result = validateVehicle(partialData); expect(result.isValid).toBe(false); expect(Object.keys(result.errors)).toContain('plateNumber'); expect(Object.keys(result.errors)).toContain('year'); expect(Object.keys(result.errors)).toContain('cylinders'); expect(Object.keys(result.errors)).not.toContain('manufacturer'); expect(Object.keys(result.errors)).not.toContain('model'); }); }); }); });