car_mms/app/lib/__tests__/maintenance-visit-validation.test.ts
2025-09-11 14:22:27 +03:00

425 lines
12 KiB
TypeScript

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);
});
});
});