import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { FACTOR_CODE_MIN_LEN, SanadBuilders, assertFactorCode, buildFactorCode, extractMandehRaw, normalizeIranMobile, normalizeMandehResponse, } from '../src/integrations/tahesab/tahesab-methods'; const FACTOR = 'crm-test-factor-code-0001'; /** ترتیب پارامترها از docs/integrations/tahesab-openapi.json؛ اگر این تست شکست، سند با پارامتر غلط به ته‌حساب می‌رود */ const DOC_PARAMS = { buySaleGold: [ 'Sabte_Kol_Or_Movaghat_1_0', 'Moshtari_Code', 'Factor_Number', 'Radif_Number', 'Shamsi_Year', 'Shamsi_Month', 'Shamsi_Day', 'Vazn', 'Ayar', 'ثابت', 'ثابت', 'BuyOrSale_0_1', 'Mazaneh', 'MazanehIsMesghalOrGeram_0_1', 'IsMotefaregheOrAbshode_0_1', 'MablaghKol', 'Sharh', 'Factor_Code', 'HavalehBe_Mcode', 'MultiRadif', 'Jens_Felez', 'Zaman_Tasvie', ], buySaleSekeh: [ 'Sabte_Kol_Or_Movaghat_1_0', 'Moshtari_Code', 'Factor_Number', 'Radif_Number', 'Shamsi_Year', 'Shamsi_Month', 'Shamsi_Day', 'Vazn', 'Ayar', 'Count', 'Name_Sekeh', 'BuyOrSale_0_1', 'Mazaneh', 'MablaghKol', 'Sharh', 'Factor_Code', 'ثابت', 'MultiRadif', 'Jens_Felez', 'ArzName', ], vkhGold: [ 'Sabte_Kol_Or_Movaghat_1_0', 'Moshtari_Code', 'Factor_Number', 'Radif_Number', 'Shamsi_Year', 'Shamsi_Month', 'Shamsi_Day', 'Vazn', 'Ayar', 'Ang_Number', 'Name_az', 'IsVoroodOrKhorooj_0_1', 'IsMotefaregheOrAbshode_0_1', 'Sharh', 'Factor_Code', 'HavalehBe_Mcode', 'MultiRadif', 'Jens_Felez', 'IsSharti', ], newMoshtari: [ 'Moshtari_Name', 'GroupName', 'Tel', 'Address', 'CodeMeli', 'Tarikh_Tavalod', 'Moaref', 'Code_Moaref', 'Moshtari_Code', 'Jens_Felez', ], } as const; function byName(names: readonly string[], args: unknown[]) { assert.equal(args.length, names.length, 'تعداد پارامترها با مستندات ته‌حساب یکی نیست'); const out: Record = {}; names.forEach((n, i) => { if (n !== 'ثابت') out[n] = args[i]; }); return out; } describe('normalizeIranMobile', () => { it('حذف پیش‌شماره‌ها و کاراکترهای اضافه', () => { assert.equal(normalizeIranMobile('09121234567'), '9121234567'); assert.equal(normalizeIranMobile('+98 912 123 4567'), '9121234567'); assert.equal(normalizeIranMobile('989121234567'), '9121234567'); assert.equal(normalizeIranMobile('9121234567'), '9121234567'); }); it('ورودی نامعتبر', () => { assert.equal(normalizeIranMobile(''), null); assert.equal(normalizeIranMobile(null), null); assert.equal(normalizeIranMobile('12345'), null); }); }); describe('Factor_Code', () => { it('کد ساخته‌شده حداقل طول را دارد و یکتاست', () => { const a = buildFactorCode(); const b = buildFactorCode(); assert.ok(a.length >= FACTOR_CODE_MIN_LEN); assert.notEqual(a, b); }); it('کد کوتاه رد می‌شود', () => { assert.throws(() => assertFactorCode('short')); assert.throws(() => assertFactorCode('')); assert.doesNotThrow(() => assertFactorCode(FACTOR)); }); it('سازنده‌های سند بدون Factor_Code معتبر خطا می‌دهند', () => { assert.throws(() => SanadBuilders.vkhGold({ moshtariCode: 1, year: 1405, month: 7, day: 16, vazn: 1, ayar: 750, angNumber: 1, nameAz: 'az', isVoroodOrKhorooj: 1, isAbshode: 1, sharh: '', factorCode: 'x', }), ); }); }); describe('SanadBuilders مطابق مستندات ته‌حساب', () => { it('خرید و فروش آبشده', () => { const p = byName( DOC_PARAMS.buySaleGold, SanadBuilders.buySaleGold({ moshtariCode: 1355, year: 1405, month: 7, day: 16, vazn: 1.25, ayar: 750, buyOrSale: 1, mazaneh: 4_600_000, mazanehIsGeram: 0, isAbshode: 1, mablaghKol: 10_000_000, sharh: 'شرح', factorCode: FACTOR, havalehBeMcode: 2, jensFelez: 2, zamanTasvie: '1405-07-20', }), ); assert.deepEqual(p, { Sabte_Kol_Or_Movaghat_1_0: 1, Moshtari_Code: 1355, Factor_Number: -1, Radif_Number: 1, Shamsi_Year: 1405, Shamsi_Month: 7, Shamsi_Day: 16, Vazn: 1.25, Ayar: 750, BuyOrSale_0_1: 1, Mazaneh: 4_600_000, MazanehIsMesghalOrGeram_0_1: 0, IsMotefaregheOrAbshode_0_1: 1, MablaghKol: 10_000_000, Sharh: 'شرح', Factor_Code: FACTOR, HavalehBe_Mcode: 2, MultiRadif: -1, Jens_Felez: 2, Zaman_Tasvie: '1405-07-20', }); }); it('خرید و فروش سکه', () => { const p = byName( DOC_PARAMS.buySaleSekeh, SanadBuilders.buySaleSekeh({ moshtariCode: 1355, year: 1405, month: 7, day: 16, vazn: 8.13, ayar: 900, count: 2, nameSekeh: 'تمام', buyOrSale: 0, mazaneh: 1, mablaghKol: 500, sharh: 's', factorCode: FACTOR, }), ); assert.equal(p.Count, 2); assert.equal(p.Name_Sekeh, 'تمام'); assert.equal(p.BuyOrSale_0_1, 0); assert.equal(p.MablaghKol, 500); assert.equal(p.Factor_Code, FACTOR); assert.equal(p.Jens_Felez, 0); assert.equal(p.ArzName, 'IRR'); }); it('ورود و خروج آبشده', () => { const p = byName( DOC_PARAMS.vkhGold, SanadBuilders.vkhGold({ moshtariCode: 7, year: 1405, month: 1, day: 2, vazn: 3.5, ayar: 750, angNumber: 12, nameAz: 'آزمایشگاه', isVoroodOrKhorooj: 0, isAbshode: 1, sharh: 's', factorCode: FACTOR, isSharti: true, }), ); assert.equal(p.Vazn, 3.5); assert.equal(p.Ang_Number, 12); assert.equal(p.Name_az, 'آزمایشگاه'); assert.equal(p.IsVoroodOrKhorooj_0_1, 0); assert.equal(p.Factor_Code, FACTOR); assert.equal(p.IsSharti, true); }); it('مشتری جدید', () => { const p = byName( DOC_PARAMS.newMoshtari, SanadBuilders.newMoshtari({ name: 'علی', tel: '09121234567', jensFelez: 2 }), ); assert.deepEqual(p, { Moshtari_Name: 'علی', GroupName: 'CRM', Tel: '09121234567', Address: '', CodeMeli: '', Tarikh_Tavalod: '', Moaref: '', Code_Moaref: '-1', Moshtari_Code: -1, Jens_Felez: 2, }); }); }); describe('پاسخ مانده حساب', () => { const raw = { MandeHesab: [ { Code: 1355, MandeyeMali: '135040598', MandeyeVazni: -1.5, MandeyeArz_USD: null, details: [ { Name: 'سکه تمام', Value: '2', Value1: null, Value2: 2, Value3: null, Value4: 'null' }, ], }, ], }; it('extractMandehRaw هیچ مقداری را تغییر نمی‌دهد', () => { const { fields, details } = extractMandehRaw(raw); assert.deepEqual(fields, [ { key: 'Code', value: '1355' }, { key: 'MandeyeMali', value: '135040598' }, { key: 'MandeyeVazni', value: '-1.5' }, { key: 'MandeyeArz_USD', value: null }, ]); assert.deepEqual(details, [ { Name: 'سکه تمام', Value: '2', Value1: null, Value2: '2', Value3: null, Value4: null }, ]); }); it('extractMandehRaw با پاسخ خالی یا خراب', () => { assert.deepEqual(extractMandehRaw(null), { fields: [], details: [] }); assert.deepEqual(extractMandehRaw({}), { fields: [], details: [] }); assert.deepEqual(extractMandehRaw({ MandeHesab: [] }), { fields: [], details: [] }); }); it('normalizeMandehResponse', () => { const n = normalizeMandehResponse(raw); assert.equal(n.rialBalance, 135040598); assert.equal(n.goldBalance, -1.5); assert.equal(n.mandehDetail.length, 1); assert.equal(normalizeMandehResponse({}).goldBalance, null); }); });