- Expand batch upload list area and optimize preview image layout - Improve upload speed tracking and display (server-side & client-side) - Reduce network detection log noise - Optimize Docker build process (caching, env validation) - Add shadow environment deployment support
124 lines
3.6 KiB
TypeScript
124 lines
3.6 KiB
TypeScript
/**
|
||
* R44修复测试:安全的 JSON 解析工具函数
|
||
*/
|
||
|
||
// 直接复制纯 JS 函数进行测试(避免 Next.js 依赖问题)
|
||
function safeJsonParse<T>(
|
||
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<T>(
|
||
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)
|
||
}
|
||
}
|
||
})
|
||
})
|
||
})
|