import { describe, it, expect } from 'vitest'; import { validateMaintenanceVisit } from '../validation'; describe('Maintenance Visit Validation', () => { describe('validateMaintenanceVisit', () => { it('should validate a complete maintenance visit successfully', () => { const validData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك والفلتر', cost: 150.50, paymentStatus: 'paid', kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(validData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should skip validation for missing vehicleId (partial validation)', () => { const partialData = { customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should reject invalid vehicleId', () => { const invalidData = { vehicleId: 0, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.vehicleId).toBe('المركبة مطلوبة'); }); it('should skip validation for missing customerId (partial validation)', () => { const partialData = { vehicleId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should reject invalid customerId', () => { const invalidData = { vehicleId: 1, customerId: -1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.customerId).toBe('العميل مطلوب'); }); it('should skip validation for missing maintenanceType (partial validation)', () => { const partialData = { vehicleId: 1, customerId: 1, description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should reject empty maintenanceType', () => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: ' ', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.maintenanceType).toBe('نوع الصيانة مطلوب'); }); it('should skip validation for missing description (partial validation)', () => { const partialData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should reject empty description', () => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: '', cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.description).toBe('وصف الصيانة مطلوب'); }); it('should reject description that is too long', () => { const longDescription = 'أ'.repeat(501); // 501 characters const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: longDescription, cost: 150.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.description).toBe('الوصف يجب أن يكون أقل من 500 حرف'); }); it('should skip validation for missing cost (partial validation)', () => { const partialData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should reject negative cost', () => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: -10.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.cost).toBe('التكلفة يجب أن تكون بين 0 و 999999.99'); }); it('should reject cost that is too high', () => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 1000000.00, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.cost).toBe('التكلفة يجب أن تكون بين 0 و 999999.99'); }); it('should validate payment status', () => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, paymentStatus: 'invalid_status', kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.paymentStatus).toBe('حالة الدفع غير صحيحة'); }); it('should accept valid payment statuses', () => { const validStatuses = ['pending', 'paid', 'partial', 'cancelled']; validStatuses.forEach(status => { const validData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, paymentStatus: status, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(validData); expect(result.isValid).toBe(true); }); }); it('should skip validation for missing kilometers (partial validation)', () => { const partialData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should reject negative kilometers', () => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: -1000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.kilometers).toBe('عدد الكيلومترات يجب أن يكون رقم موجب'); }); it('should accept zero kilometers', () => { const validData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 0, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(validData); expect(result.isValid).toBe(true); }); it('should skip validation for missing nextVisitDelay (partial validation)', () => { const partialData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should accept valid nextVisitDelay values', () => { const validDelays = [1, 2, 3, 4]; validDelays.forEach(delay => { const validData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: delay, }; const result = validateMaintenanceVisit(validData); expect(result.isValid).toBe(true); }); }); it('should reject invalid nextVisitDelay values', () => { const invalidDelays = [0, 5, 6, -1]; invalidDelays.forEach(delay => { const invalidData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.00, kilometers: 50000, nextVisitDelay: delay, }; const result = validateMaintenanceVisit(invalidData); expect(result.isValid).toBe(false); expect(result.errors.nextVisitDelay).toBe('فترة الزيارة التالية يجب أن تكون 1، 2، 3، أو 4 أشهر'); }); }); it('should handle partial validation for updates', () => { const partialData = { maintenanceType: 'فحص دوري', cost: 200.00, }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(true); expect(Object.keys(result.errors)).toHaveLength(0); }); it('should validate partial data with errors', () => { const partialData = { maintenanceType: '', cost: -50.00, paymentStatus: 'invalid', }; const result = validateMaintenanceVisit(partialData); expect(result.isValid).toBe(false); expect(result.errors.maintenanceType).toBe('نوع الصيانة مطلوب'); expect(result.errors.cost).toBe('التكلفة يجب أن تكون بين 0 و 999999.99'); expect(result.errors.paymentStatus).toBe('حالة الدفع غير صحيحة'); }); it('should accept zero cost', () => { const validData = { vehicleId: 1, customerId: 1, maintenanceType: 'فحص مجاني', description: 'فحص مجاني للعميل', cost: 0, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(validData); expect(result.isValid).toBe(true); }); it('should accept decimal cost values', () => { const validData = { vehicleId: 1, customerId: 1, maintenanceType: 'تغيير زيت', description: 'تغيير زيت المحرك', cost: 150.75, kilometers: 50000, nextVisitDelay: 3, }; const result = validateMaintenanceVisit(validData); expect(result.isValid).toBe(true); }); }); });