文件
Henglianshutong/tests/verify_decorate_partner_centers_spec.js

153 行
8.1 KiB
JavaScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
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(" 首页金刚区装修调整与服务中心待开发页面规范化测试");
console.log("========================================================\n");
// 1. 静态资源完整性验证
console.log("一、静态资源完整性验证:");
const expectedIcons = [
'menu_city_center.png',
'menu_city_center_v2.png',
'menu_city_partner.png',
'menu_city_partner_v2.png',
'menu_province_center.png',
'menu_province_center_v2.png',
'menu_province_partner.png',
'menu_province_partner_v2.png',
'menu_region_branch.png',
'menu_region_branch_v2.png'
];
expectedIcons.forEach(iconName => {
const iconPath = path.resolve(__dirname, '../public/uploads/decorate', iconName);
assert(fs.existsSync(iconPath), `图标文件存在: ${iconName}`);
if (fs.existsSync(iconPath)) {
const stats = fs.statSync(iconPath);
assert(stats.size > 10000, `图标大小正常(超高清 320x320,${stats.size} 字节): ${iconName}`);
}
});
// 2. 生成脚本与前端代码验证
console.log("\n二、生成脚本与前端代码优化验证:");
const bannerScript = path.resolve(__dirname, '../scripts/generate_banners.py');
const bannerContent = fs.readFileSync(bannerScript, 'utf-8');
assert(bannerContent.includes('build_partner_centers_menu_icons'), 'generate_banners.py 包含新业务中心徽标生成函数');
assert(bannerContent.includes('menu_city_center.png') && bannerContent.includes('menu_region_branch.png'),
'generate_banners.py 包含5个新徽标配置定义');
const menuButtonVue = path.resolve(__dirname, '../uniapp/sheep/components/s-menu-button/s-menu-button.vue');
const menuButtonContent = fs.readFileSync(menuButtonVue, 'utf-8');
assert(menuButtonContent.includes('font-size: 24rpx;'), 's-menu-button.vue 优化了文字大小为 24rpx,完美适配 5 列 6 字符单行排版');
const richtextVue = path.resolve(__dirname, '../uniapp/pages/public/richtext.vue');
const richtextContent = fs.readFileSync(richtextVue, 'utf-8');
assert(richtextContent.includes('defaultPendingContent') && richtextContent.includes('待开发,敬请期待'),
'richtext.vue 增加了待开发默认降级与优雅展示兜底');
const sqlFile = path.resolve(__dirname, '../docs/sql/decorate-update-partner-centers-2026.sql');
assert(fs.existsSync(sqlFile), '已归档 SQL 迁移脚本 docs/sql/decorate-update-partner-centers-2026.sql');
// 3. 业务逻辑与参数模拟测试
console.log("\n三、前端业务跳转与标题回显逻辑模拟测试:");
const expectedItems = [
{ name: '市级运营中心', sub: '运营', file: 'menu_city_center.png' },
{ name: '市级合伙人', sub: '合伙', file: 'menu_city_partner.png' },
{ name: '省级服务中心', sub: '服务', file: 'menu_province_center.png' },
{ name: '省级合伙人', sub: '合伙', file: 'menu_province_partner.png' },
{ name: '大区分公司', sub: '分公司', file: 'menu_region_branch.png' },
];
expectedItems.forEach(item => {
const targetUrl = `/pages/public/richtext?id=5&title=${item.name}`;
const [page, query] = targetUrl.split('?');
const params = new URLSearchParams(query);
assert(page === '/pages/public/richtext', `路由路径正确: ${item.name}`);
assert(params.get('id') === '5', `指向待开发富文本记录 ID 5: ${item.name}`);
assert(params.get('title') === item.name, `导航栏标题参数正确回显: ${item.name}`);
});
// 4. API 模拟测试(正常场景、业务失败场景、参数错误场景)
console.log("\n四、线上 API 模拟测试(正常/业务失败/边界条件):");
try {
const remoteScript = `#!/bin/bash
curl -s -k --resolve henglian.gynhc.com:443:127.0.0.1 -H 'platform: WechatMiniProgram' 'https://henglian.gynhc.com/addons/shopro/index/init' > /tmp/api_test_init.json
curl -s -k --resolve henglian.gynhc.com:443:127.0.0.1 'https://henglian.gynhc.com/addons/shopro/data.richtext?id=5' > /tmp/api_test_rich5.json
curl -s -k --resolve henglian.gynhc.com:443:127.0.0.1 'https://henglian.gynhc.com/addons/shopro/data.richtext?id=999999' > /tmp/api_test_notfound.json
curl -s -k --resolve henglian.gynhc.com:443:127.0.0.1 'https://henglian.gynhc.com/addons/shopro/data.richtext' > /tmp/api_test_empty.json
`;
fs.writeFileSync('/tmp/local_test_api.sh', remoteScript);
execSync(`sshpass -p 'Bjsslxz1' scp -o StrictHostKeyChecking=no /tmp/local_test_api.sh root@118.184.172.94:/tmp/test_api.sh`);
execSync(`sshpass -p 'Bjsslxz1' ssh -o StrictHostKeyChecking=no root@118.184.172.94 "bash /tmp/test_api.sh"`);
const fetchCmd = `sshpass -p 'Bjsslxz1' ssh -o StrictHostKeyChecking=no root@118.184.172.94 "cat /tmp/api_test_init.json && echo '===SEP===' && cat /tmp/api_test_rich5.json && echo '===SEP===' && cat /tmp/api_test_notfound.json && echo '===SEP===' && cat /tmp/api_test_empty.json"`;
const fetched = execSync(fetchCmd, { timeout: 20000 }).toString();
const parts = fetched.split('===SEP===').map(p => p.trim());
const initRes = JSON.parse(parts[0]);
const richtextRes = JSON.parse(parts[1]);
const notFoundRes = JSON.parse(parts[2]);
const emptyIdRes = JSON.parse(parts[3]);
assert(initRes.code === 1, '正常场景: index/init 接口返回 code=1 成功');
const homeComp = initRes.data?.template?.home?.data || [];
const menuBtn = homeComp.find(c => c.type === 'menuButton');
assert(!!menuBtn, '正常场景: 首页装修模板中包含 menuButton 组件');
const list = menuBtn?.data?.list || [];
assert(list.length === 5, `正常场景: menuButton 包含 5 个金刚区项目(实际 ${list.length} 个)`);
assert(menuBtn?.data?.layout === 2, '正常场景: menuButton 采用 layout=2 纯图标模式');
assert(menuBtn?.data?.iconSize === 120, '正常场景: menuButton 配置了 iconSize=120rpx 高清大尺寸');
assert(list.every(item => item.title?.text === ''), '正常场景: 金刚区下方文本已全部清空,避免折行重叠');
assert(list.every(item => item.src && item.src.includes('_v2.png')), '正常场景: 图标全部升级为 _v2.png 320x320 超清大字版,彻底击穿客户端强缓存');
const expectedTitles = ['市级运营中心', '市级合伙人', '省级服务中心', '省级合伙人', '大区分公司'];
const allUrlsCorrect = list.every((item, idx) => item.url === `/pages/public/richtext?id=5&title=${encodeURIComponent(expectedTitles[idx])}`);
assert(allUrlsCorrect, '正常场景: 5 个项目的跳转链接均正确绑定富文本待开发页及对应标题');
// 场景 2:正常场景 - 富文本待开发数据接口
assert(richtextRes.code === 1, '正常场景: data.richtext?id=5 接口返回 code=1 成功');
assert(richtextRes.data?.title === '待开发,敬请期待', '正常场景: 富文本标题为“待开发,敬请期待”');
assert(richtextRes.data?.content.includes('待开发,敬请期待'), '正常场景: 富文本内容包含“待开发,敬请期待”卡片');
// 场景 3:业务失败场景 - 请求不存在的富文本 ID
assert(notFoundRes.code === 0, '业务失败场景: 请求不存在的 id=999999 返回 code=0 业务失败拦截');
assert(!!notFoundRes.msg, `业务失败场景: 返回友好提示信息 (${notFoundRes.msg})`);
// 场景 4:参数边界场景 - 不传任何 ID
assert(emptyIdRes.code === 0, '参数边界场景: 缺失 id 参数返回 code=0 并受全局异常/参数校验保护');
} catch (err) {
console.error("API 测试执行异常:", err.message);
failed++;
}
console.log("\n========================================================");
console.log(`测试完成: 通过 ${passed} 项, 失败 ${failed} 项`);
console.log("========================================================");
if (failed > 0) {
process.exit(1);
}