- 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
92 lines
3.0 KiB
TypeScript
92 lines
3.0 KiB
TypeScript
/**
|
||
* N6修复测试:文件流错误时正确清理
|
||
*
|
||
* 验证:
|
||
* 1. 所有 fileStream.on('error') 回调中都调用了 fileStream.destroy()
|
||
* 2. 确保文件描述符不会泄漏
|
||
*/
|
||
|
||
describe('N6: 文件流错误清理测试', () => {
|
||
|
||
test('所有下载路由的文件流错误处理应该包含 destroy() 调用', async () => {
|
||
const fs = require('fs')
|
||
const path = require('path')
|
||
|
||
const downloadRoutes = [
|
||
'app/api/materials/download/route.ts',
|
||
'app/api/materials/[id]/skus/[skuId]/download/route.ts',
|
||
'app/api/external/download/route.ts',
|
||
]
|
||
|
||
for (const routePath of downloadRoutes) {
|
||
const filePath = path.join(__dirname, '../..', routePath)
|
||
|
||
if (!fs.existsSync(filePath)) {
|
||
console.log(`跳过测试:文件不存在 ${routePath}`)
|
||
continue
|
||
}
|
||
|
||
const content = fs.readFileSync(filePath, 'utf-8')
|
||
|
||
// 查找所有 fileStream.on('error' 模式
|
||
const errorHandlerPattern = /fileStream\.on\('error',\s*\(err\)\s*=>\s*\{[^}]*\}/g
|
||
const matches = content.match(errorHandlerPattern)
|
||
|
||
if (matches) {
|
||
for (const match of matches) {
|
||
// 每个错误处理回调中都应该有 destroy() 调用
|
||
expect(match).toContain('destroy()')
|
||
}
|
||
}
|
||
}
|
||
})
|
||
|
||
test('不应该有只调用 controller.error 而不调用 destroy 的错误处理', async () => {
|
||
const fs = require('fs')
|
||
const path = require('path')
|
||
|
||
const downloadRoutes = [
|
||
'app/api/materials/download/route.ts',
|
||
'app/api/materials/[id]/skus/[skuId]/download/route.ts',
|
||
'app/api/external/download/route.ts',
|
||
]
|
||
|
||
for (const routePath of downloadRoutes) {
|
||
const filePath = path.join(__dirname, '../..', routePath)
|
||
|
||
if (!fs.existsSync(filePath)) {
|
||
console.log(`跳过测试:文件不存在 ${routePath}`)
|
||
continue
|
||
}
|
||
|
||
const content = fs.readFileSync(filePath, 'utf-8')
|
||
|
||
// 查找简单的错误处理模式(只有 controller.error,没有 destroy)
|
||
// 这种模式是有问题的:fileStream.on('error', (err) => controller.error(err))
|
||
const badPattern = /fileStream\.on\('error',\s*\(err\)\s*=>\s*controller\.error\(err\)\)/g
|
||
const badMatches = content.match(badPattern)
|
||
|
||
// 不应该有这种简单的错误处理
|
||
expect(badMatches).toBeNull()
|
||
}
|
||
})
|
||
|
||
test('所有错误处理应该先调用 destroy 再调用 controller.error', async () => {
|
||
const fs = require('fs')
|
||
const path = require('path')
|
||
|
||
const filePath = path.join(__dirname, '../../app/api/materials/download/route.ts')
|
||
|
||
if (!fs.existsSync(filePath)) {
|
||
console.log('跳过测试:文件不存在')
|
||
return
|
||
}
|
||
|
||
const content = fs.readFileSync(filePath, 'utf-8')
|
||
|
||
// 检查错误处理的顺序:先 destroy() 再 controller.error()
|
||
const correctPattern = /fileStream\.destroy\(\)[\s\S]*?controller\.error\(err\)/
|
||
expect(correctPattern.test(content)).toBe(true)
|
||
})
|
||
})
|