From 7501b0bb330af1971ac0acffe97aa1c9bbf69f92 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Sun, 19 Jul 2026 00:54:13 +0300 Subject: [PATCH] fix(test): pricing script declared success after doing nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit عطلان في سكربت التسعير، كشفهما أول تشغيل حقيقي: 1. **إعلان نجاح على العدم** — الأخطر. فشل تسجيل الدخول فجُمع صفر صفّ، فمرّ كل تحقّق فراغاً وطبع «الاختبار ناجح». اختبار يعلن النجاح وهو لم ينفّذ شيئاً أسوأ من اختبار يفشل: الفشل يُرى. أُضيف حارس عدم + تحقّق تغطية (المنفَّذ مقابل المتوقَّع)، وكلاهما يُخرج برمز فشل. 2. **تسجيل الدخول تجاوز `send-otp`** — تجاوز التطوير في `verifyOtp` مشروط بـ`OTP_DEV_MODE=true`، وبدونه لا رمز في Redis فيُرفض الثابت 1234 بـ401. صار يمرّ بـ`send-otp` ويأخذ `dev_code` من استجابتها، ويقول صراحةً حين يكون الوضع التطويري مطفأً بدل أن يفشل بلا تفسير. Co-Authored-By: Claude Opus 4.8 --- backend/scripts/pricing-test.mjs | 44 ++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/backend/scripts/pricing-test.mjs b/backend/scripts/pricing-test.mjs index dda1e0d..365eabf 100644 --- a/backend/scripts/pricing-test.mjs +++ b/backend/scripts/pricing-test.mjs @@ -114,9 +114,23 @@ function testPhone(countryPack, seed) { async function loginRider(tenantSlug, countryPack, seed) { const phone = testPhone(countryPack, seed); - // وضع OTP التطويري: رمز ثابت 1234 يُنشئ الحساب ويسجّل الدخول بنداء واحد - // (بلا حاجة لـ/auth/send-otp أولاً) — نفس نمط e2e-test.mjs. - const r = await api('POST', '/auth/verify-otp', { tenant: tenantSlug, body: { phone, code: CODE } }); + + // **يجب** المرور بـ`send-otp` أولاً: تجاوز التطوير في `verifyOtp` مشروط + // بـ`OTP_DEV_MODE=true`، وبدونه لا يوجد رمز في Redis أصلاً فيُرفض أي رمز + // نرسله. النسخة الأولى نادت `verify-otp` مباشرةً بالرمز الثابت 1234 + // فسقطت بـ401 على سيرفر وضعه التطويري مطفأ — وهو الوضع الصحيح لسيرفر حي. + const sent = await api('POST', '/auth/send-otp', { tenant: tenantSlug, body: { phone } }); + const code = sent.body?.dev_code ?? CODE; + + if (!sent.body?.dev_code) { + console.error( + ` ⚠️ لا يوجد dev_code في استجابة send-otp — يعني OTP_DEV_MODE مطفأ.\n` + + ` هذا السكربت يحتاجه لتسجيل دخول راكب اختبار. فعّله مؤقتاً في .env ثم` + + ` أعد تشغيل الـapi، وأطفئه بعد الانتهاء.`, + ); + } + + const r = await api('POST', '/auth/verify-otp', { tenant: tenantSlug, body: { phone, code } }); if (!r.body?.access_token) { console.error(` ❌ فشل تسجيل الدخول (${phone}): ${r.status} ${JSON.stringify(r.body)}`); } @@ -178,6 +192,20 @@ async function main() { } console.log('\n=== النتائج ===\n'); + + // **حارس العدم**: النسخة الأولى طبعت «الاختبار ناجح» بعد أن فشل تسجيل + // الدخول وجُمع صفر صفّ — لأن كل تحقّق كان على مجموعة فارغة فمرّ فراغاً. + // اختبار يعلن النجاح وهو لم ينفّذ شيئاً أسوأ من اختبار يفشل: الفشل يُرى. + const expected = TENANTS.length * RIDES.length * SERVICE_CLASSES.length; + if (rows.length === 0) { + console.error('❌ لم يُنفَّذ ولا طلب واحد — لا نتيجة تُقرأ. راجع أخطاء تسجيل الدخول أعلاه.'); + process.exitCode = 1; + return; + } + if (rows.length < expected) { + console.error(`⚠️ نُفِّذ ${rows.length} من ${expected} طلباً — التغطية ناقصة.`); + } + const noQuote = rows.filter((r) => !r.tariffFound); if (noQuote.length) { console.error(`❌ ${noQuote.length} طلب بلا سعر (تعرفة مفقودة) — هذا هو العطل الذي أصلحناه، فوجوده الآن خطأ حرج:`); @@ -218,13 +246,13 @@ async function main() { } if (orderOk) console.log('✅ الفان أغلى من الاقتصادي في كل رحلة وكل بلد.'); - console.log(failedExitCode(noQuote.length, orderOk)); -} + // المقارنة تحتاج الفئتين معاً؛ غيابهما يعني تحقّقاً لم يقع لا تحقّقاً نجح. + const comparable = rows.filter((r) => ['economy', 'van'].includes(r.serviceClass)).length; + if (comparable === 0) console.error('⚠️ لا بيانات كافية للمقارنة — التحقّق أعلاه لم يقع فعلياً.'); -function failedExitCode(missing, orderOk) { - const bad = missing > 0 || !orderOk; + const bad = noQuote.length > 0 || !orderOk || rows.length < expected; process.exitCode = bad ? 1 : 0; - return bad ? '\n❌ فشل الاختبار.' : '\n✅ الاختبار ناجح.'; + console.log(bad ? '\n❌ فشل الاختبار.' : `\n✅ الاختبار ناجح (${rows.length} طلباً).`); } main().catch((e) => {