const fs = require('fs'); const path = require('path'); let passed = 0; let failed = 0; function assert(condition, testName, detail = '') { if (condition) { console.log(` [PASS] ${testName}`); passed++; } else { console.error(` [FAIL] ${testName} - ${detail}`); failed++; } } console.log("========================================================"); console.log(" 兑换券释放计划点击穿透与释放明细 TDD 自动化测试"); console.log("========================================================\n"); // 1. 后端 Index 控制器契约校验 const controllerPath = path.resolve(__dirname, '../addons/shopro/controller/partner/Index.php'); assert(fs.existsSync(controllerPath), 'Index.php 控制器文件存在'); const controllerContent = fs.readFileSync(controllerPath, 'utf-8'); assert( controllerContent.includes('public function voucherLogs()'), 'Index.php 控制器包含 voucherLogs() 接口方法' ); assert( controllerContent.includes("order_sn") && controllerContent.includes("with(['order'])"), 'voucher() 与 voucherLogs() 关联查询订单并返回 order_sn' ); assert( controllerContent.includes('reward_type') && controllerContent.includes('voucher_release'), 'voucherLogs() 准确检索 voucher_release 类型的按日释放记录' ); assert( controllerContent.includes('planIds') && controllerContent.includes('formula'), 'voucherLogs() 包含针对 plan_id 的归属过滤并提取 formula 说明' ); // 2. 前端 API 契约校验 const apiPath = path.resolve(__dirname, '../uniapp/sheep/api/partner.js'); assert(fs.existsSync(apiPath), 'partner.js API 文件存在'); const apiContent = fs.readFileSync(apiPath, 'utf-8'); assert( apiContent.includes('voucherLogs:') && apiContent.includes('partner.index/voucherLogs'), 'partner.js 正确导出 voucherLogs API 方法' ); // 3. 前端 voucher.vue 交互与弹窗校验 const vuePath = path.resolve(__dirname, '../uniapp/pages/commission/voucher.vue'); assert(fs.existsSync(vuePath), 'voucher.vue 页面文件存在'); const vueContent = fs.readFileSync(vuePath, 'utf-8'); assert( vueContent.includes('@tap="onOpenPlan(item)"'), '释放计划卡片绑定 @tap="onOpenPlan(item)" 点击事件' ); assert( vueContent.includes('plan-clickable-card') && vueContent.includes('查看释放明细'), '计划卡片包含可点击态类名及「查看释放明细」交互引导' ); assert( vueContent.includes('showLogs') && vueContent.includes('su-popup'), '包含承载释放明细的 su-popup 抽屉弹窗' ); assert( vueContent.includes('logs-plan-summary') && vueContent.includes('activePlan'), '弹窗内部包含当前计划的概览进度与释放额度摘要' ); assert( vueContent.includes('planLogs') && vueContent.includes('log-row-amount'), '弹窗内部包含按日释放流水列表及释放金额展示' ); assert( vueContent.includes('logs-empty') && vueContent.includes('暂无释放记录'), '包含优雅的无流水空状态友好提示' ); assert( vueContent.includes('async function onOpenPlan') && vueContent.includes('sheep.$api.partner.voucherLogs'), '页面定义了 onOpenPlan 异步方法并调用 voucherLogs 获取实时数据' ); console.log("\n--------------------------------------------------------"); console.log(`测试执行结果: 通过 ${passed} 项, 失败 ${failed} 项`); console.log("========================================================\n"); if (failed > 0) { process.exit(1); }