425 lines
12 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
}); |