chenpei 4712175cb0 feat(素材链路): 发布白底图双轨与AI生图回传能力
- 完成白底图 WebP 双轨接口、上传链路与预览缓存改造
- 新增 AI 生图平台成品回传接口、任务状态与表单规则
- 补齐 AI 生成标签、任务详情补全、相关测试与对接文档
2026-03-25 10:28:02 +08:00

110 lines
2.9 KiB
TypeScript

/** @jest-environment node */
import { POST } from '@/app/api/materials/upload/init/route'
import { getServerSession } from 'next-auth'
import { saveUploadSession } from '@/lib/upload-sessions'
import { mkdir, writeFile } from 'fs/promises'
jest.mock('next-auth', () => ({
getServerSession: jest.fn(),
}))
jest.mock('@/lib/auth', () => ({
authOptions: {},
}))
jest.mock('@/lib/upload-sessions', () => ({
saveUploadSession: jest.fn().mockResolvedValue(undefined),
}))
jest.mock('fs/promises', () => ({
mkdir: jest.fn().mockResolvedValue(undefined),
writeFile: jest.fn().mockResolvedValue(undefined),
}))
jest.mock('crypto', () => ({
randomBytes: jest.fn(() => ({
toString: () => 'fixed-upload-id',
})),
}))
function createRequest(body: unknown, options?: { jsonReject?: boolean }) {
return {
json: jest.fn().mockImplementation(() => {
if (options?.jsonReject) {
return Promise.reject(new Error('invalid json'))
}
return Promise.resolve(body)
}),
} as any
}
describe('/api/materials/upload/init', () => {
beforeEach(() => {
jest.clearAllMocks()
;(getServerSession as jest.Mock).mockResolvedValue({
user: { id: 'user-1' },
})
process.env.UPLOAD_DIR = 'D:/temp/uploads'
})
test('缺少文件名时返回明确错误', async () => {
const response = await POST(createRequest({
fileName: ' ',
fileSize: 1,
totalChunks: 1,
}))
const body = await response.json()
expect(response.status).toBe(400)
expect(body).toEqual({ error: '文件名不能为空' })
})
test('空文件时返回明确错误', async () => {
const response = await POST(createRequest({
fileName: 'source.psd',
fileSize: 0,
totalChunks: 1,
}))
const body = await response.json()
expect(response.status).toBe(400)
expect(body).toEqual({ error: '上传文件不能为空' })
})
test('无效分片参数时返回明确错误', async () => {
const response = await POST(createRequest({
fileName: 'source.psd',
fileSize: 1024,
totalChunks: 0,
}))
const body = await response.json()
expect(response.status).toBe(400)
expect(body).toEqual({ error: '上传分片参数无效' })
})
test('有效请求会保存标准化后的上传会话', async () => {
const response = await POST(createRequest({
fileName: ' source.psb ',
fileSize: '2048',
totalChunks: '2',
}))
const body = await response.json()
expect(response.status).toBe(200)
expect(body).toEqual({ uploadId: expect.stringContaining('upload-') })
expect(mkdir).toHaveBeenCalled()
expect(writeFile).toHaveBeenCalled()
expect(saveUploadSession).toHaveBeenCalledWith(
expect.stringContaining('upload-'),
expect.objectContaining({
fileName: 'source.psb',
fileSize: 2048,
totalChunks: 2,
userId: 'user-1',
}),
)
})
})