后端: 身份与归属鉴权收口; 资金安全(结算闸门/支付防篡改/报名费真实扣款/赠金/结算唯一入账/提现打款); 数据泄露与隐私; 登录与密钥安全(默认密钥闸门/登录限流); 可观测性; 启动自检. 微信: 商家转账到零钱提现打款闭环(含回调/查单/失败退回佣金); 订阅消息真实下发闭环与后台模板字段对齐. 后台: 财务/微信支付配置读取失败锁定; 看板/待办/走势去假数据; 打款与测试推送文案修正. 小程序: 请求层错误透传与登录过期提示; 多页失败反馈与乐观回滚; 帮助中心FAQ页面化. 测试: 新增 40+ 回归护栏与真实 MySQL 冒烟(75 套件/599 用例全绿).
80 行
4.0 KiB
TypeScript
80 行
4.0 KiB
TypeScript
// 已读取AGENTS.md
|
||
import * as fs from 'fs';
|
||
import * as path from 'path';
|
||
|
||
/**
|
||
* 第三十八批回归闸门:小程序写操作失败不得再伪装成功
|
||
*/
|
||
describe('第三十八批小程序失败反馈闸门', () => {
|
||
const rootDir = path.resolve(__dirname, '../../');
|
||
const workspace = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/expert/workspace.vue'), 'utf-8');
|
||
const orderList = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/order/list.vue'), 'utf-8');
|
||
|
||
it('大神工作台:抢单/拒单/提交完成/接单状态切换失败必须提示', () => {
|
||
expect(workspace).toContain('抢单失败,请稍后重试');
|
||
expect(workspace).toContain('拒单失败,请稍后重试');
|
||
expect(workspace).toContain('提交失败,请稍后重试');
|
||
expect(workspace).toContain('接单状态切换失败,请稍后重试');
|
||
});
|
||
|
||
it('抢单失败不再无条件提示成功并移出订单池', () => {
|
||
const start = workspace.indexOf('const grabOrder = async');
|
||
const block = workspace.slice(start, start + 700);
|
||
expect(block).toContain('return;');
|
||
expect(block.indexOf('抢单失败')).toBeLessThan(block.indexOf("'抢单成功已接单'"));
|
||
});
|
||
|
||
it('订单列表:取消失败必须提示且不本地改成已取消', () => {
|
||
const start = orderList.indexOf('const cancelOrder =');
|
||
const block = orderList.slice(start, start + 900);
|
||
expect(block).toContain('取消失败,请稍后重试');
|
||
expect(block).toContain('loadLiveOrders()');
|
||
});
|
||
|
||
it('社区页:删除/上车申请失败必须提示', () => {
|
||
const ci = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/community/index.vue'), 'utf-8');
|
||
const cd = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/community/detail.vue'), 'utf-8');
|
||
for (const code of [ci, cd]) {
|
||
expect(code).toContain('删除失败,请重试');
|
||
expect(code).toContain('申请失败,请重试');
|
||
}
|
||
});
|
||
|
||
it('设置保存:API 层不得吞错,页面失败需回滚并提示', () => {
|
||
const apiCode = fs.readFileSync(path.join(rootDir, 'pwuniapp/common/api.js'), 'utf-8');
|
||
const settings = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/user/settings.vue'), 'utf-8');
|
||
const start = apiCode.indexOf('export async function updateUserSettings(');
|
||
const block = apiCode.slice(start, start + 700);
|
||
expect(block).toContain('throw err;');
|
||
expect(block).not.toContain('return {\n userId: uid,');
|
||
expect(settings).toContain('设置同步失败,请稍后重试');
|
||
expect(settings).toContain('privacyHidePhone.value = prev');
|
||
});
|
||
|
||
it('点赞:接口层不得吞错,页面需回滚乐观状态', () => {
|
||
const apiCode = fs.readFileSync(path.join(rootDir, 'pwuniapp/common/api.js'), 'utf-8');
|
||
const likeStart = apiCode.indexOf('export async function likePost(');
|
||
const likeBlock = apiCode.slice(likeStart, likeStart + 500);
|
||
expect(likeBlock).toContain('throw err;');
|
||
expect(likeBlock).not.toContain('return null;');
|
||
|
||
const ci = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/community/index.vue'), 'utf-8');
|
||
const cd = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/community/detail.vue'), 'utf-8');
|
||
expect(ci).toContain('回滚乐观更新');
|
||
expect(cd).toContain('回滚乐观更新');
|
||
});
|
||
|
||
it('订单动作:取消/验收接口层不得吞错,验收失败需提示', () => {
|
||
const apiCode = fs.readFileSync(path.join(rootDir, 'pwuniapp/common/api.js'), 'utf-8');
|
||
for (const fn of ['export async function cancelOrder(', 'export async function completeOrder(']) {
|
||
const block = apiCode.slice(apiCode.indexOf(fn), apiCode.indexOf(fn) + 500);
|
||
expect(block).toContain('throw err;');
|
||
expect(block).not.toContain('return null;');
|
||
}
|
||
const orderList2 = fs.readFileSync(path.join(rootDir, 'pwuniapp/pages/order/list.vue'), 'utf-8');
|
||
const start = orderList2.indexOf('const confirmComplete =');
|
||
const block = orderList2.slice(start, start + 900);
|
||
expect(block).toContain('确认验收失败,请稍后重试');
|
||
});
|
||
});
|