Add tests and implementation for ServiceDetailPage and PriceInput components

- Implement PriceInput component tests to validate Persian and Arabic numeral handling, input formatting, and controlled behavior.
- Create ServiceDetailPage component with detailed service information, including pricing, insurance coverage, and editing capabilities.
- Add API tests for service item detail retrieval and coverage synchronization with insurance contracts.
- Ensure proper error handling and user feedback for service item retrieval and coverage management.
This commit is contained in:
hamed
2026-07-18 12:10:49 +03:30
parent f1d58e1604
commit 42d9ad26c5
27 changed files with 1758 additions and 284 deletions
+61
View File
@@ -2,6 +2,9 @@ import { describe, it, expect } from 'vitest';
import { z } from 'zod';
import {
digitsOnly,
formatYear,
parseUserNumber,
parseUserNumberClamped,
persianSafeNumber,
iranNationalCodeSchema,
iranNationalCodeOptionalSchema,
@@ -150,6 +153,64 @@ describe('digitsOnly', () => {
});
});
describe('formatYear', () => {
it('سال شمسی را بدون جداکننده‌ی هزارگان می‌دهد', () => {
expect(formatYear(1404)).toBe('۱۴۰۴');
});
it('برخلاف formatNumber جداکننده نمی‌گذارد', () => {
expect(formatNumber(1404)).not.toBe(formatYear(1404));
});
});
describe('parseUserNumber', () => {
it('رقم فارسی را به عدد تبدیل می‌کند', () => {
expect(parseUserNumber('۲۵')).toBe(25);
});
it('رقم عربی را به عدد تبدیل می‌کند', () => {
expect(parseUserNumber('٢٥')).toBe(25);
});
it('جداکننده هزارگان و فاصله را نادیده می‌گیرد', () => {
expect(parseUserNumber('1,200')).toBe(1200);
expect(parseUserNumber('۸۵٬۰۰۰')).toBe(85000);
expect(parseUserNumber(' ۹۰ ')).toBe(90);
});
it('اعشار فارسی را می‌پذیرد', () => {
expect(parseUserNumber('۱۲.۵')).toBe(12.5);
});
it('عدد منفی را می‌پذیرد', () => {
expect(parseUserNumber('-۳')).toBe(-3);
});
it('عدد را دست‌نخورده رد می‌کند', () => {
expect(parseUserNumber(42)).toBe(42);
});
it('خالی و null → null', () => {
expect(parseUserNumber('')).toBeNull();
expect(parseUserNumber(null)).toBeNull();
expect(parseUserNumber(undefined)).toBeNull();
});
it('ورودی نامعتبر → null و هرگز NaN', () => {
expect(parseUserNumber('abc')).toBeNull();
expect(parseUserNumber('۱۲ب۳')).toBeNull();
expect(parseUserNumber('.')).toBeNull();
});
});
describe('parseUserNumberClamped', () => {
it('مقدار داخل بازه را دست‌نخورده برمی‌گرداند', () => {
expect(parseUserNumberClamped('۲۵', 0, 100)).toBe(25);
});
it('بیشتر از سقف را به سقف می‌برد', () => {
expect(parseUserNumberClamped('۱۵۰', 0, 100)).toBe(100);
});
it('کمتر از کف را به کف می‌برد', () => {
expect(parseUserNumberClamped('-۵', 0, 100)).toBe(0);
});
it('ورودی نامعتبر → null (نه کف)', () => {
expect(parseUserNumberClamped('abc', 0, 100)).toBeNull();
expect(parseUserNumberClamped('', 0, 100)).toBeNull();
});
});
describe('persianSafeNumber', () => {
it('رشته‌ی فارسی را قبل از عدد شدن نرمال می‌کند', () => {
const schema = persianSafeNumber(z.coerce.number());