قرار المالك 2026-07-27: الباك إند المعتمد صار باك إند سيرو PHP، ويُنقل إلى هذا المستودع كنسخة جديدة باسم «انطلق» على api.intaleqapp.com. backend/ → backend-archive/ (305 ملفاً، إعادة تسمية بلا تعديل محتوى) + README-ARCHIVE.md يوضّح سبب الأرشفة وسبب عدم الحذف: scripts/e2e-test.mjs هو أدق توثيق سلوكي لدورة الرحلة كاملة، ويبقى مرجعاً عند بناء الوحدات الناقصة في باك إند PHP (المحفظتان · الاستحقاقات · محرّك التسعير · الوحدات). مسارات backend/ في docs/*.md لم تُعدَّل عمداً — سجلّ تاريخي. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
85 lines
3.0 KiB
TypeScript
85 lines
3.0 KiB
TypeScript
import { BadRequestException } from '@nestjs/common';
|
|
import { PhoneService } from './phone.service';
|
|
|
|
describe('PhoneService — تطبيع أرقام الهاتف (docs/17 D1)', () => {
|
|
let phones: PhoneService;
|
|
|
|
beforeEach(() => {
|
|
phones = new PhoneService();
|
|
});
|
|
|
|
describe('الأردن (jo)', () => {
|
|
it('الصيغة المحلية بالصفر', () => {
|
|
expect(phones.normalize('0790000000', 'jo')).toBe('962790000000');
|
|
});
|
|
|
|
it('الصيغة الدولية بالفعل', () => {
|
|
expect(phones.normalize('962790000000', 'jo')).toBe('962790000000');
|
|
});
|
|
|
|
it('بادئة + دولية', () => {
|
|
expect(phones.normalize('+962790000000', 'jo')).toBe('962790000000');
|
|
});
|
|
|
|
it('بادئة 00 بدل +', () => {
|
|
expect(phones.normalize('00962790000000', 'jo')).toBe('962790000000');
|
|
});
|
|
|
|
it('فراغات وشرطات لا تؤثر', () => {
|
|
expect(phones.normalize('+962 79-000-0000', 'jo')).toBe('962790000000');
|
|
});
|
|
|
|
it('محلي بلا صفر بادئ', () => {
|
|
expect(phones.normalize('790000000', 'jo')).toBe('962790000000');
|
|
});
|
|
});
|
|
|
|
describe('مصر (eg) — لبس المالك: "01" يُظنّ مفتاحاً وهو ليس كذلك', () => {
|
|
it('الصيغة المحلية بالصفر (11 رقماً) تُحسب بمفتاح 20 الصحيح لا "2"', () => {
|
|
const r = phones.normalize('01012345678', 'eg');
|
|
expect(r).toBe('201012345678');
|
|
expect(r.startsWith('20')).toBe(true); // لا "2" فقط
|
|
});
|
|
|
|
it('الصيغة الدولية بالفعل', () => {
|
|
expect(phones.normalize('201012345678', 'eg')).toBe('201012345678');
|
|
});
|
|
|
|
it('بادئة +', () => {
|
|
expect(phones.normalize('+201012345678', 'eg')).toBe('201012345678');
|
|
});
|
|
});
|
|
|
|
describe('سوريا (sy)', () => {
|
|
it('الصيغة المحلية بالصفر', () => {
|
|
expect(phones.normalize('0944000000', 'sy')).toBe('963944000000');
|
|
});
|
|
});
|
|
|
|
describe('نفس الرقم الحقيقي بصيغ مختلفة → مفتاح واحد فقط', () => {
|
|
it('لا يتعدد الحساب لنفس الرقم', () => {
|
|
const variants = ['0790000000', '962790000000', '+962790000000', '00962790000000'];
|
|
const results = new Set(variants.map((v) => phones.normalize(v, 'jo')));
|
|
expect(results.size).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('مدخلات غير صالحة', () => {
|
|
it('طول خاطئ يُرفض لا يُخمَّن', () => {
|
|
expect(() => phones.normalize('12345', 'jo')).toThrow(BadRequestException);
|
|
});
|
|
|
|
it('نص فارغ يُرفض', () => {
|
|
expect(() => phones.normalize('', 'jo')).toThrow(BadRequestException);
|
|
});
|
|
|
|
it('حروف بلا أرقام تُرفض', () => {
|
|
expect(() => phones.normalize('abc-def', 'jo')).toThrow(BadRequestException);
|
|
});
|
|
});
|
|
|
|
it('دولة غير معروفة تسقط لخطة افتراضية بلا انهيار', () => {
|
|
expect(() => phones.normalize('0790000000', 'xx')).not.toThrow();
|
|
});
|
|
});
|