// 已读取AGENTS.md import * as fs from 'fs'; import * as path from 'path'; /** * 第二十批回归闸门:充值赠金必须服务端按阶梯权威计算 */ describe('第二十批充值赠金权威性闸门', () => { const rootDir = path.resolve(__dirname, '../../'); const indexCode = fs.readFileSync(path.join(rootDir, 'server/src/index.ts'), 'utf-8'); const repoCode = fs.readFileSync(path.join(rootDir, 'server/src/db/repository.ts'), 'utf-8'); it('仓储层提供服务端赠金计算', () => { expect(repoCode).toContain('async computeRechargeBonusCents('); const start = repoCode.indexOf('async computeRechargeBonusCents('); const block = repoCode.slice(start, start + 700); expect(block).toContain('FROM recharge_tiers'); expect(block).toContain('status = 1'); expect(block).toContain('ORDER BY amount DESC'); }); it('预支付不再信任客户端赠金', () => { expect(indexCode).not.toContain('bonusCents: Math.round(Number(bonusAmount || 0) * 100)'); const start = indexCode.indexOf("app.post('/api/pay/wechat/prepay'"); const block = indexCode.slice(start, start + 5200); expect(block).toContain('computeRechargeBonusCents(amountCents)'); }); it('沙箱直接充值也不再信任客户端赠金', () => { expect(indexCode).not.toContain('rechargeUserBalance(userId, Number(amount), Number(bonusAmount || 0))'); const start = indexCode.indexOf("app.post('/api/users/:id/recharge'"); const block = indexCode.slice(start, start + 2400); expect(block).toContain('computeRechargeBonusCents(Math.round(amountYuan * 100))'); }); });