Files
clinicpro/assets/admin/lib/utils.test.ts
T
hamed 6084dc5d6b feat: add comprehensive tests for UI components, hooks, and API interactions
- Implement tests for Pagination, StatusBadge, ConfirmDialog, and MobileInput components.
- Add tests for useSubscription, usePaymentConfig, and usePwaInstall hooks.
- Create tests for API requests in the api module, including success and error handling.
- Add utility function tests for formatting and validating Iranian mobile numbers.
- Implement tests for BlogFormPage and BlogsPage to validate form submissions and data fetching.
- Add tests for LoginPage to ensure proper validation and state management.
- Create tests for authStore and uiStore to validate state management and functionality.
- Set up Vitest configuration and testing utilities for consistent testing environment.
2026-06-28 22:58:15 +03:30

171 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import {
formatRial,
formatNumber,
toDate,
formatDate,
formatDateTime,
toGregorianDate,
maskMobile,
cn,
toEnglishDigits,
sanitizeMobileInput,
isValidIranMobile,
IRAN_MOBILE_RE,
iranMobileSchema,
iranMobileOptionalSchema,
} from '@/lib/utils';
const PERSIAN_DIGITS = /[۰-۹]/;
describe('formatRial', () => {
it('عدد را با جداکننده فارسی و پسوند تومان برمی‌گرداند', () => {
const out = formatRial(1000);
expect(out).toContain('تومان');
expect(out).toMatch(PERSIAN_DIGITS);
});
it('صفر را هم فرمت می‌کند', () => {
expect(formatRial(0)).toContain('تومان');
});
});
describe('formatNumber', () => {
it('رقم فارسی برمی‌گرداند', () => {
expect(formatNumber(1234)).toMatch(PERSIAN_DIGITS);
});
});
describe('toDate', () => {
it('null و رشته خالی → null', () => {
expect(toDate(null)).toBeNull();
expect(toDate(undefined)).toBeNull();
expect(toDate('')).toBeNull();
});
it('عدد را به‌عنوان ثانیه (×۱۰۰۰) تفسیر می‌کند', () => {
const d = toDate(1_700_000_000);
expect(d).toBeInstanceOf(Date);
expect(d!.getTime()).toBe(1_700_000_000 * 1000);
});
it('Y-m-d را ظهر محلی می‌گیرد (نه نیمه‌شب UTC)', () => {
const d = toDate('2024-03-21');
expect(d!.getHours()).toBe(12);
expect(d!.getFullYear()).toBe(2024);
});
it('رشته ISO کامل را پارس می‌کند', () => {
const d = toDate('2024-03-21T08:30:00Z');
expect(d).toBeInstanceOf(Date);
expect(isNaN(d!.getTime())).toBe(false);
});
});
describe('formatDate', () => {
it('ورودی نامعتبر → "—"', () => {
expect(formatDate(null)).toBe('—');
expect(formatDate('not-a-date')).toBe('—');
});
it('timestamp ثانیه‌ای معتبر → رشته شمسی با رقم فارسی', () => {
const out = formatDate(1_700_000_000);
expect(out).not.toBe('—');
expect(out).toMatch(PERSIAN_DIGITS);
});
});
describe('formatDateTime', () => {
it('ورودی نامعتبر → "—"', () => {
expect(formatDateTime(undefined)).toBe('—');
});
it('معتبر → شامل ساعت و رقم فارسی', () => {
const out = formatDateTime(1_700_000_000);
expect(out).not.toBe('—');
expect(out).toMatch(PERSIAN_DIGITS);
});
});
describe('toGregorianDate', () => {
it('YYYY-MM-DD با صفر پیش‌رو', () => {
expect(toGregorianDate(new Date(2024, 0, 5))).toBe('2024-01-05');
expect(toGregorianDate(new Date(2024, 11, 31))).toBe('2024-12-31');
});
});
describe('maskMobile', () => {
it('شماره ۱۱ رقمی را ماسک می‌کند', () => {
expect(maskMobile('09123456789')).toBe('0912***789');
});
it('شماره کوتاه‌تر از ۷ رقم بدون تغییر', () => {
expect(maskMobile('123')).toBe('123');
});
});
describe('cn', () => {
it('مقادیر falsy را حذف و بقیه را با فاصله می‌چسباند', () => {
expect(cn('a', false, null, undefined, 'b')).toBe('a b');
expect(cn()).toBe('');
});
});
describe('toEnglishDigits', () => {
it('رقم فارسی به انگلیسی', () => {
expect(toEnglishDigits('۰۹۱۲۳۴۵۶۷۸۹')).toBe('09123456789');
});
it('رقم عربی به انگلیسی', () => {
expect(toEnglishDigits('٠٩١٢')).toBe('0912');
});
it('ورودی خالی → رشته خالی', () => {
expect(toEnglishDigits('')).toBe('');
});
it('کاراکترهای غیررقمی را دست‌نخورده نگه می‌دارد', () => {
expect(toEnglishDigits('شماره ۰۹')).toBe('شماره 09');
});
});
describe('sanitizeMobileInput', () => {
it('غیررقم حذف، رقم فارسی نرمال، حداکثر ۱۱ رقم', () => {
expect(sanitizeMobileInput('۰۹۱۲-۳۴۵ ۶۷۸۹۰۱۲')).toBe('09123456789');
});
it('فقط حروف → خالی', () => {
expect(sanitizeMobileInput('abc')).toBe('');
});
});
describe('isValidIranMobile / IRAN_MOBILE_RE', () => {
it.each([
['09123456789', true],
['۰۹۱۲۳۴۵۶۷۸۹', true],
['9123456789', false],
['08123456789', false],
['0912345678', false],
['091234567890', false],
])('%s → %s', (input, expected) => {
expect(isValidIranMobile(input as string)).toBe(expected);
});
it('regex مستقیم روی ارقام انگلیسی', () => {
expect(IRAN_MOBILE_RE.test('09120000000')).toBe(true);
});
});
describe('iranMobileSchema', () => {
it('رقم فارسی را پذیرفته و نرمال می‌کند', () => {
expect(iranMobileSchema.parse('۰۹۱۲۳۴۵۶۷۸۹')).toBe('09123456789');
});
it('جداکننده‌ها را حذف می‌کند', () => {
expect(iranMobileSchema.parse('0912-345-6789')).toBe('09123456789');
});
it('شماره نامعتبر → ناموفق', () => {
const r = iranMobileSchema.safeParse('12345');
expect(r.success).toBe(false);
});
});
describe('iranMobileOptionalSchema', () => {
it('رشته خالی مجاز است', () => {
expect(iranMobileOptionalSchema.parse('')).toBe('');
});
it('شماره معتبر نرمال می‌شود', () => {
expect(iranMobileOptionalSchema.parse('۰۹۱۲۳۴۵۶۷۸۹')).toBe('09123456789');
});
it('شماره نیمه‌کاره → ناموفق', () => {
expect(iranMobileOptionalSchema.safeParse('0912').success).toBe(false);
});
});