/** * R44修复测试:安全的 JSON 解析工具函数 */ // 直接复制纯 JS 函数进行测试(避免 Next.js 依赖问题) function safeJsonParse( jsonString: string, fallback: T, logError: boolean = false ): T { try { return JSON.parse(jsonString) } catch (error) { if (logError) { console.warn('[SafeJSON] JSON 解析失败:', error) } return fallback } } function safeJsonParseWithError( jsonString: string ): { data: T | null; error: string | null } { try { const data = JSON.parse(jsonString) as T return { data, error: null } } catch (error) { const errorMessage = error instanceof Error ? error.message : '未知错误' return { data: null, error: `JSON 解析失败: ${errorMessage}` } } } describe('R44: 安全 JSON 解析测试', () => { describe('safeJsonParse', () => { test('有效 JSON 应该正确解析', () => { const result = safeJsonParse('{"name": "test"}', {}) expect(result).toEqual({ name: 'test' }) }) test('无效 JSON 应该返回默认值', () => { const result = safeJsonParse('invalid json', { default: true }) expect(result).toEqual({ default: true }) }) test('空字符串应该返回默认值', () => { const result = safeJsonParse('', []) expect(result).toEqual([]) }) test('数组 JSON 应该正确解析', () => { const result = safeJsonParse('[1, 2, 3]', []) expect(result).toEqual([1, 2, 3]) }) test('null JSON 应该正确解析', () => { const result = safeJsonParse('null', 'default') expect(result).toBeNull() }) test('不完整的 JSON 应该返回默认值', () => { const result = safeJsonParse('{"name": ', {}) expect(result).toEqual({}) }) }) describe('safeJsonParseWithError', () => { test('有效 JSON 应该返回数据和 null 错误', () => { const result = safeJsonParseWithError('{"name": "test"}') expect(result.data).toEqual({ name: 'test' }) expect(result.error).toBeNull() }) test('无效 JSON 应该返回 null 数据和错误信息', () => { const result = safeJsonParseWithError('invalid json') expect(result.data).toBeNull() expect(result.error).toContain('JSON 解析失败') }) test('空字符串应该返回错误', () => { const result = safeJsonParseWithError('') expect(result.data).toBeNull() expect(result.error).not.toBeNull() }) }) describe('API 路由应该有 try-catch 包裹 request.json()', () => { test('检查关键 API 路由是否有 try-catch', async () => { const fs = require('fs') const path = require('path') const criticalRoutes = [ 'app/api/materials/like/route.ts', 'app/api/danmaku/route.ts', 'app/api/materials/favorite/route.ts', ] for (const routePath of criticalRoutes) { const filePath = path.join(__dirname, '../..', routePath) if (!fs.existsSync(filePath)) { console.log(`跳过测试:文件不存在 ${routePath}`) continue } const content = fs.readFileSync(filePath, 'utf-8') // 检查是否有 try 块 expect(content).toContain('try {') // 检查是否有 catch 块 expect(content).toContain('catch') // 检查 request.json() 是否存在 if (content.includes('request.json()')) { // 确保有 try-catch 结构 const hasTryCatch = /try\s*\{[\s\S]*?request\.json\(\)[\s\S]*?\}\s*catch/.test(content) expect(hasTryCatch).toBe(true) } } }) }) })