feat: add testing setup with Vitest and Testing Library
- Updated package.json to include Vitest and Testing Library dependencies and scripts for testing. - Created a test suite for the ProvinceProvider context to validate cityId and province detection based on subdomains. - Implemented unit tests for utility functions in helper/index.js, including phone number formatting and validation. - Added tests for state information retrieval in lib/getStateInfo.js, ensuring correct city and state matching based on subdomains. - Developed tests for appointment slot adaptation and availability checks in lib/appointmentSlots.js. - Created tests for token storage functionality in lib/tokenStore.js. - Implemented sanitization and JSON parsing tests in lib/sanitize.js. - Added CASL ability tests in lib/ability.js to verify user access rights. - Created tests for cookie management in lib/refreshCookie.js. - Developed tests for patient user representation in lib/representationAdapters.js. - Implemented client-side state information retrieval tests in lib/getStateInfoClient.js. - Created tests for canonical URL generation in lib/getCanonicalUrl.js. - Developed tests for clinic API service functions in services/clinicApi.js. - Added request wrapper tests in services/response.js to ensure correct API interaction. - Set up Vitest configuration in vitest.config.mjs for JSX support and alias resolution. - Created setup and utility files for testing environment in test/setup.js and test/utils.jsx.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
changeNumToDefault,
|
||||
formatPhoneNumber,
|
||||
validatePhoneNumber,
|
||||
isValidIranNationalCode,
|
||||
getCleanNumberValue,
|
||||
imageUrl,
|
||||
QueryForDoctorsFilter,
|
||||
} from '@/helper';
|
||||
|
||||
describe('changeNumToDefault', () => {
|
||||
it('رقم فارسی و عربی → انگلیسی', () => {
|
||||
expect(changeNumToDefault('۰۹۱۲')).toBe('0912');
|
||||
expect(changeNumToDefault('٠٩١٢')).toBe('0912');
|
||||
});
|
||||
it('ورودی falsy → رشته خالی', () => {
|
||||
expect(changeNumToDefault('')).toBe('');
|
||||
expect(changeNumToDefault(null)).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatPhoneNumber', () => {
|
||||
it('۹ رقم را به فرمت "## ### ####" در میآورد', () => {
|
||||
expect(formatPhoneNumber('912345678')).toBe('91 234 5678');
|
||||
});
|
||||
it('رقم فارسی را نرمال و به ۹ رقم محدود میکند', () => {
|
||||
expect(formatPhoneNumber('۰۹۱۲۳۴۵۶۷۸۹')).toBe('09 123 4567');
|
||||
});
|
||||
it('کاراکترهای غیررقمی را حذف میکند', () => {
|
||||
expect(formatPhoneNumber('912-345-678')).toBe('91 234 5678');
|
||||
});
|
||||
});
|
||||
|
||||
describe('validatePhoneNumber', () => {
|
||||
it.each([
|
||||
['09123456789', true],
|
||||
['9123456789', false],
|
||||
['08123456789', false],
|
||||
['0912345678', false],
|
||||
['', false],
|
||||
])('%s → valid=%s', (input, valid) => {
|
||||
expect(validatePhoneNumber(input).valid).toBe(valid);
|
||||
});
|
||||
it('رقم غیرانگلیسی → پیام مخصوص', () => {
|
||||
const r = validatePhoneNumber('۰۹۱۲۳۴۵۶۷۸۹');
|
||||
expect(r.valid).toBe(false);
|
||||
expect(r.text).toBe('فقط از اعداد انگلیسی استفاده کنید.');
|
||||
});
|
||||
it('ورودی معتبر → text=null', () => {
|
||||
expect(validatePhoneNumber('09123456789')).toEqual({ valid: true, text: null });
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValidIranNationalCode', () => {
|
||||
it('کدملی معتبر را میپذیرد', () => {
|
||||
expect(isValidIranNationalCode('0013542419')).toBe(true);
|
||||
});
|
||||
it.each([
|
||||
['1111111111', false], // ارقام یکسان
|
||||
['123', false], // طول نادرست
|
||||
['0013542410', false], // رقم کنترلی غلط
|
||||
['', false],
|
||||
])('%s → %s', (input, expected) => {
|
||||
expect(isValidIranNationalCode(input)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCleanNumberValue', () => {
|
||||
it('رقم فارسی + جداکننده → عدد', () => {
|
||||
expect(getCleanNumberValue('۱۲۳۴')).toBe(1234);
|
||||
});
|
||||
it('اعشار را حفظ میکند', () => {
|
||||
expect(getCleanNumberValue('12.5')).toBe(12.5);
|
||||
});
|
||||
it('ورودی نامعتبر → مقدار پیشفرض', () => {
|
||||
expect(getCleanNumberValue('abc')).toBe(0);
|
||||
expect(getCleanNumberValue('abc', 7)).toBe(7);
|
||||
});
|
||||
});
|
||||
|
||||
describe('imageUrl', () => {
|
||||
it('URL مطلق دستنخورده', () => {
|
||||
expect(imageUrl('https://x.com/a.jpg')).toBe('https://x.com/a.jpg');
|
||||
});
|
||||
it('/uploads با NEXT_PUBLIC_API_URL پیشوند میگیرد', () => {
|
||||
expect(imageUrl('/uploads/a.jpg')).toBe('http://api.test.local/uploads/a.jpg');
|
||||
});
|
||||
it('مسیر /assets دستنخورده', () => {
|
||||
expect(imageUrl('/assets/images/x.png')).toBe('/assets/images/x.png');
|
||||
});
|
||||
it('خالی → fallback', () => {
|
||||
expect(imageUrl('')).toBe('/assets/images/user.png');
|
||||
});
|
||||
});
|
||||
|
||||
describe('QueryForDoctorsFilter', () => {
|
||||
it('فیلدهای معتبر را نگاشت و فیلدهای پیشفرض را حذف میکند', () => {
|
||||
const q = QueryForDoctorsFilter({
|
||||
active: 1,
|
||||
specialty: { name: 'قلب' },
|
||||
city: { name: 'یزد' },
|
||||
gender: 'مرد',
|
||||
degree: 'همه موارد', // باید حذف شود
|
||||
name: ' ', // باید حذف شود
|
||||
sort: 4,
|
||||
});
|
||||
expect(q).toEqual({ active: 1, specialty: 'قلب', city: 'یزد', gender: 'مرد', sort: 4 });
|
||||
});
|
||||
it('gender «هر دو» و sort خارج از 3..5 حذف میشوند', () => {
|
||||
const q = QueryForDoctorsFilter({ gender: 'هر دو', sort: 9 });
|
||||
expect(q.gender).toBeUndefined();
|
||||
expect(q.sort).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user