Просмотр исходного кода

test(frontend): 身份参数加固回归测试 + 修复过期断言

- 修复 getPendingWishes 断言(wrapper 实际发送空 body {})
- 修复 X-User-Id header 断言(改为断言不再发送)
- 新增 identity parameter hardening 4 个回归测试:
  request 不发 X-User-Id 头、测评 wrapper 无参且 body 为空、today-tasks 仅含 memberId
Xiaogang Liao 2 месяцев назад
Родитель
Сommit
8c3559dd48
1 измененных файлов с 48 добавлено и 5 удалено
  1. 48 5
      cfc-frontend/__tests__/api/api.test.js

+ 48 - 5
cfc-frontend/__tests__/api/api.test.js

@@ -126,11 +126,11 @@ describe('auth API', () => {
     expect(opts.header.Authorization).toBe('Bearer my-jwt-token')
   })
 
-  test('X-User-Id header is set', async () => {
+  test('X-User-Id header is NOT sent (removed for security)', async () => {
     mockSuccess({ code: 200 })
     global.uni._storage.userId = '99'
     await api.getUserInfo()
-    expect(lastRequest().header['X-User-Id']).toBe('99')
+    expect(lastRequest().header['X-User-Id']).toBeUndefined()
   })
 
   test('rejects on non-200 code', async () => {
@@ -415,10 +415,10 @@ describe('rewards & wishes API', () => {
     expect(lastRequest().data.memberId).toBe(5)
   })
 
-  test('getPendingWishes sends POST with familyId', async () => {
+  test('getPendingWishes sends POST with empty body', async () => {
     mockSuccess({ code: 200 })
-    await api.getPendingWishes(1)
-    expect(lastRequest().data.familyId).toBe(1)
+    await api.getPendingWishes()
+    expect(lastRequest().data).toEqual({})
   })
 
   test('getWishes sends POST with params', async () => {
@@ -446,6 +446,49 @@ describe('rewards & wishes API', () => {
   })
 })
 
+// --------------- identity parameter hardening ---------------
+// 前端不再向后端发送可伪造的 userId / familyId / childId(仅 memberId),
+// 身份一律由后端从 JWT 推导。以下断言锁定这一不变量。
+
+describe('identity parameter hardening', () => {
+  beforeEach(() => {
+    global.uni._storage.token = 'test-token'
+  })
+
+  test('request() does NOT send X-User-Id header', async () => {
+    mockSuccess({ code: 200 })
+    await api.getPendingWishes()
+    const opts = lastRequest()
+    expect(opts.header['X-User-Id']).toBeUndefined()
+  })
+
+  test('getMyAssessmentResults sends empty body, no userId', async () => {
+    mockSuccess({ code: 200 })
+    await api.getMyAssessmentResults()
+    const opts = lastRequest()
+    expect(opts.data).toEqual({})
+    expect(opts.data.userId).toBeUndefined()
+  })
+
+  test('getChildAssessmentResults sends empty body, no userId', async () => {
+    mockSuccess({ code: 200 })
+    await api.getChildAssessmentResults()
+    const opts = lastRequest()
+    expect(opts.data).toEqual({})
+    expect(opts.data.userId).toBeUndefined()
+  })
+
+  test('getTodayTasksByCategory sends only memberId and category', async () => {
+    mockSuccess({ code: 200 })
+    await api.getTodayTasksByCategory(7, 'wisdom')
+    const opts = lastRequest()
+    expect(opts.data.memberId).toBe(7)
+    expect(opts.data.category).toBe('wisdom')
+    expect(opts.data.childId).toBeUndefined()
+    expect(opts.data.userId).toBeUndefined()
+  })
+})
+
 // --------------- guide / packages module ---------------
 
 describe('guide & packages API', () => {