// 已读取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 apiCode = fs.readFileSync(path.join(rootDir, 'pwuniapp/common/api.js'), 'utf-8'); const routeBlock = (marker: string, len = 1200) => { const start = indexCode.indexOf(marker); expect(start).toBeGreaterThan(-1); return indexCode.slice(start, start + len); }; describe('1. 组局发起人身份以服务端会话为准', () => { it('创建组局必须经 resolveSecureUserId 绑定发起人', () => { const block = routeBlock("app.post('/api/activities',"); expect(block).toContain("'发起组局'"); expect(block).not.toContain("req.body?.creatorId || req.headers['x-user-id'] || 1001"); }); }); describe('2. 组局解散人身份以服务端会话为准', () => { it('解散组局:管理员走签名 token,其余经 resolveSecureUserId', () => { const block = routeBlock("app.post('/api/activities/:id/cancel'"); expect(block).toContain('isVerifiedAdminRequest(req)'); expect(block).toContain("'解散组局'"); expect(block).not.toContain("const callerId = Number(hostId ||"); }); }); describe('3. 抢单身份以服务端会话为准', () => { it('接单必须经 resolveSecureUserId 且写库用服务端身份', () => { const block = routeBlock("app.post('/api/orders/:id/claim'"); expect(block).toContain("'接单'"); expect(block).toContain('claimOrder(orderId, { ...(req.body || {}), expertId: operatorId })'); }); }); describe('4. 搭子上车申请身份以服务端会话为准', () => { it('上车申请必须经 resolveSecureUserId', () => { const block = routeBlock("app.post('/api/posts/:id/apply'"); expect(block).toContain("'申请加入搭子车队'"); expect(block).not.toContain("applicantId || req.headers['x-user-id'] || 1001"); }); }); describe('5. 用户设置读写归属', () => { it('设置读写必须经 resolveSecureUserId', () => { const getBlock = routeBlock("app.get('/api/users/:id/settings'"); const postBlock = routeBlock("app.post('/api/users/:id/settings'"); expect(getBlock).toContain("'查看个人设置'"); expect(postBlock).toContain("'保存个人设置'"); }); }); describe('6. 小程序端写接口携带真实身份', () => { it('组局/抢单/上车/报名/退席均注入当前用户身份', () => { expect(apiCode).toContain('creatorId: normalizeUserId(payload.creatorId)'); expect(apiCode).toContain('hostId: normalizeUserId(hostId)'); expect(apiCode).toContain('userId: normalizeUserId(params.userId)'); expect(apiCode).toContain('userId: normalizeUserId(userId),'); expect(apiCode).toContain('userId: normalizeUserId(expertData.userId)'); expect(apiCode).toContain('applicantId: normalizeUserId(applyData.applicantId)'); }); }); });