| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /**
- * 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');
- });
|