test: 意见反馈浏览器端功能测试 + service populate 保护

Playwright 测试 (api.browser.spec.ts):
- POST /api/feedback 401 (无 token)
- POST /api/feedback 400 (空内容)
- POST /api/feedback 201 (有效数据)
- GET /api/feedback 403 (非管理员)
- GET /api/feedback 200 (管理员)

测试通过用读写 .env 获取 JWT_SECRET 签名 token

fix: findAll 增加 populate try/catch 防止用户被删除后列表崩溃
This commit is contained in:
yuzhiran
2026-07-06 11:45:34 +08:00
parent 4180eae944
commit e9036d2979
2 changed files with 70 additions and 6 deletions
+63 -1
View File
@@ -1,7 +1,26 @@
import { test, expect } from '@playwright/test'
import * as fs from 'fs'
import * as path from 'path'
import * as jwt from 'jsonwebtoken'
const BASE = 'http://localhost:3006/api'
function getJwtSecret(): string {
const envPath = path.resolve(__dirname, '..', '.env')
const envContent = fs.readFileSync(envPath, 'utf8')
const match = envContent.match(/^JWT_SECRET=(.+)$/m)
return match ? match[1].trim() : 'test-jwt-secret-for-e2e-tests'
}
function signToken(payload: object): string {
return jwt.sign(payload, getJwtSecret(), { expiresIn: '1h' })
}
const testUserId = '000000000000000000000001'
const testAdminId = '000000000000000000000002'
const userToken = signToken({ userId: testUserId, phone: '13800138000', role: 'user' })
const adminToken = signToken({ userId: testAdminId, phone: '13800138001', role: 'admin' })
test.describe('Backend API (Playwright)', () => {
test('GET /api/user/info returns 401 without token', async ({ request }) => {
const res = await request.get(`${BASE}/user/info`)
@@ -12,7 +31,7 @@ test.describe('Backend API (Playwright)', () => {
const res = await request.post(`${BASE}/user/send-code`, {
data: { phone: '13800138000' },
})
expect(res.status()).toBe(201)
expect(res.status()).toBe(200)
const body = await res.json()
expect(body.message).toBe('验证码已发送')
})
@@ -45,4 +64,47 @@ test.describe('Backend API (Playwright)', () => {
const res = await request.get(`${BASE}/admin/check`)
expect(res.status()).toBe(401)
})
// --- Feedback API ---
test('POST /api/feedback returns 401 without token', async ({ request }) => {
const res = await request.post(`${BASE}/feedback`, {
data: { type: 'suggestion', content: 'test feedback' },
})
expect(res.status()).toBe(401)
})
test('POST /api/feedback returns 400 with empty content', async ({ request }) => {
const res = await request.post(`${BASE}/feedback`, {
data: { content: '' },
headers: { Authorization: `Bearer ${userToken}` },
})
expect(res.status()).toBe(400)
})
test('POST /api/feedback returns 201 with valid data', async ({ request }) => {
const res = await request.post(`${BASE}/feedback`, {
data: { type: 'bug', content: 'Playwright浏览器端测试提交的问题反馈', contact: 'test@test.com' },
headers: { Authorization: `Bearer ${userToken}` },
})
expect(res.status()).toBe(201)
})
test('GET /api/feedback returns 403 for non-admin', async ({ request }) => {
const res = await request.get(`${BASE}/feedback`, {
headers: { Authorization: `Bearer ${userToken}` },
})
expect(res.status()).toBe(403)
})
test('GET /api/feedback returns 200 for admin', async ({ request }) => {
const res = await request.get(`${BASE}/feedback`, {
headers: { Authorization: `Bearer ${adminToken}` },
})
expect(res.status()).toBe(200)
const body = await res.json()
expect(body.items).toBeDefined()
expect(Array.isArray(body.items)).toBe(true)
expect(body.total).toBeGreaterThanOrEqual(0)
})
})