/** * CFC API v3 快速测试 - 文件输出版 * 运行: node tests/run-api-tests-v3-file.js */ const fs = require('fs'); const path = require('path'); const BASE = 'http://cfc.iwintrue.com:80'; const ADMIN = { phone: '13800138000', userId: 7 }; let adminToken = null; const results = []; function log(msg) { results.push(`[LOG] ${msg}`); } function pass(name, detail) { results.push(`PASS|${name}|${detail || ''}`); } function fail(name, err, detail) { results.push(`FAIL|${name}|${err.message}${detail ? '|' + detail : ''}`); } function skip(name, reason) { results.push(`SKIP|${name}|${reason}`); } async function api(path, body, headers = {}) { try { const resp = await fetch(`${BASE}${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...headers }, body: body ? JSON.stringify(body) : undefined, }); const text = await resp.text(); let data; try { data = JSON.parse(text); } catch { data = null; } return { status: resp.status, data, ok: resp.ok, raw: text.substring(0, 200) }; } catch (err) { return { ok: false, data: null, error: err.message }; } } async function adminApi(path, body) { if (!adminToken) return { ok: false, data: null, error: '无token' }; return api(path, body, { Authorization: `Bearer ${adminToken}` }); } async function main() { log('=== 登录 ==='); await api('/api/admin-auth/send-code', { phone: ADMIN.phone }); const loginResp = await api('/api/admin-auth/login', { phone: ADMIN.phone, code: '123456' }); if (loginResp.data?.data?.token) { adminToken = loginResp.data.data.token; pass('Admin登录', `userId=${loginResp.data.data.adminId}`); } else { fail('Admin登录', new Error('无token'), loginResp.raw); } // NEW-01: 能量规则创建 log('=== NEW-01: 能量规则创建 ==='); let ruleId = null; const er = await adminApi('/api/admin/energy-rule/create', { ruleName: '自动化测试规则_NEW01_' + Date.now(), dimensionCode: 'body', eventType: 'checkin', energyValue: 5, status: 1, }); if (er.ok || er.data?.code === 200) { ruleId = er.data?.data?.id || er.data?.id; pass('NEW-01 创建能量规则', `id=${ruleId}`); } else { fail('NEW-01 创建能量规则', new Error(`code=${er.data?.code} msg=${er.data?.message || ''}`)); } // NEW-02: SKU列表 log('=== NEW-02: SKU列表 ==='); const sku = await adminApi('/api/admin/product/sku/list', { productId: 1 }); if (sku.ok || sku.data?.code === 200) { const count = Array.isArray(sku.data?.data) ? sku.data.data.length : 0; pass('NEW-02 SKU列表', `count=${count}`); } else { fail('NEW-02 SKU列表', new Error(`code=${sku.data?.code} msg=${sku.data?.message || ''}`)); } // NEW-03: 活动发布 log('=== NEW-03: 活动发布 ==='); let actId = null; const act = await adminApi('/api/activity/create', { title: '自动化E2E测试活动_NEW03_' + Date.now(), description: 'NEW-03修复验证', dimensionCode: 'body', startTime: new Date(Date.now() + 86400000 * 7).toISOString().replace('T', ' ').split('.')[0], endTime: new Date(Date.now() + 86400000 * 8).toISOString().replace('T', ' ').split('.')[0], location: '线上直播', maxParticipants: 30, }); if (act.ok || act.data?.code === 200) { actId = act.data?.data?.id || act.data?.id; pass('创建测试活动', `id=${actId}`); } else { fail('创建测试活动', new Error(`code=${act.data?.code} msg=${act.data?.message || ''}`)); } if (actId) { const pub = await adminApi('/api/activity/publish', { id: actId }); if (pub.ok || pub.data?.code === 200) { pass('NEW-03 发布活动', `id=${actId}`); } else { fail('NEW-03 发布活动', new Error(`code=${pub.data?.code} msg=${pub.data?.message || ''}`)); } } // ISSUE-001: 供应商下架 log('=== ISSUE-001: 供应商下架 ==='); const vs = await api('/api/product/shelve', { productId: 7, action: 'unshelve' }, { 'X-User-Id': '81069' }); if (vs.ok || vs.data?.code === 200) { pass('ISSUE-001 供应商下架', 'ok'); } else { fail('ISSUE-001 供应商下架', new Error(`code=${vs.data?.code} msg=${vs.data?.message || ''}`)); } // ISSUE-003: 创建用户 log('=== ISSUE-003: 创建用户 ==='); const phone = '139' + String(Math.floor(Math.random() * 1e9)).padStart(9, '0'); const cu = await adminApi('/api/admin/users/create', { phone, password: 'Test123456', name: '自动化测试用户', role: 'parent', }); if (cu.ok || cu.data?.code === 200) { pass('ISSUE-003 创建用户', `userId=${cu.data?.data?.id || cu.data?.id}`); } else { fail('ISSUE-003 创建用户', new Error(`code=${cu.data?.code} msg=${cu.data?.message || ''}`)); } // 新API: grantEnergy log('=== 新增API: energy.grantEnergy ==='); const ge = await adminApi('/api/energy/grantEnergy', { childId: 1, taskId: 1, amount: 10, dimensionCode: 'body' }); if (ge.ok || ge.data?.code === 200) { pass('energy.grantEnergy', 'ok'); } else { fail('energy.grantEnergy', new Error(`code=${ge.data?.code} msg=${ge.data?.message || ''}`)); } // 新API: points.checkAndGrantReward log('=== 新增API: points.checkAndGrantReward ==='); const pr = await adminApi('/api/points/checkAndGrantReward', { childId: 1, amount: 5 }); if (pr.ok || pr.data?.code === 200 || pr.data?.data === -1) { pass('points.checkAndGrantReward', `result=${pr.data?.data}`); } else { fail('points.checkAndGrantReward', new Error(`code=${pr.data?.code} msg=${pr.data?.message || ''}`)); } // 新API: growth.getRecordsByChild log('=== 新增API: growth.getRecordsByChild ==='); const gr = await adminApi('/api/growth/record/child/1', {}); if (gr.ok || gr.data?.code === 200) { const count = Array.isArray(gr.data?.data) ? gr.data.data.length : 0; pass('growth.getRecordsByChild', `count=${count}`); } else { fail('growth.getRecordsByChild', new Error(`code=${gr.data?.code} msg=${gr.data?.message || ''}`)); } // 生成报告 const passed = results.filter(r => r.startsWith('PASS')).length; const failed = results.filter(r => r.startsWith('FAIL')).length; const skipped = results.filter(r => r.startsWith('SKIP')).length; let report = `API 测试结果 - ${new Date().toLocaleString()}\n`; report += `========================================\n\n`; results.forEach(r => { report += r + '\n'; }); report += `\n========================================\n`; report += `总计: ${passed} PASS / ${failed} FAIL / ${skipped} SKIP\n`; const reportPath = path.join(__dirname, 'v3_results.txt'); fs.writeFileSync(reportPath, report, 'utf8'); console.log('Report: ' + reportPath); console.log('PASS=' + passed + ' FAIL=' + failed + ' SKIP=' + skipped); } main().catch(err => { const msg = 'ERROR: ' + err.message; console.log(msg); fs.writeFileSync(path.join(__dirname, 'v3_results.txt'), msg, 'utf8'); });