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

169 lines
4.5 KiB
TypeScript

/** @jest-environment node */
import { NextRequest } from 'next/server'
import { getServerSession } from 'next-auth'
import { GET } from '@/app/api/materials/route'
import { prisma } from '@/lib/prisma'
import { getUserViewableMaterialTypes, isShareLinkAccess, isSuperAdmin } from '@/lib/department-permission'
jest.mock('next-auth', () => ({
getServerSession: jest.fn(),
}))
jest.mock('@/lib/auth', () => ({
authOptions: {},
}))
jest.mock('@/lib/prisma', () => ({
prisma: {
material: {
count: jest.fn(),
findMany: jest.fn(),
},
materialLike: {
findMany: jest.fn(),
},
materialFavorite: {
findMany: jest.fn(),
},
materialAsset: {
findMany: jest.fn(),
},
materialSku: {
findMany: jest.fn(),
},
user: {
findMany: jest.fn(),
},
},
}))
jest.mock('@/lib/department-permission', () => ({
isSystemAdmin: jest.fn(),
getUserViewableMaterialTypes: jest.fn(),
isShareLinkAccess: jest.fn(),
isSuperAdmin: jest.fn(),
}))
jest.mock('@/lib/s3', () => ({
deleteFromS3: jest.fn(),
isS3Url: jest.fn(() => false),
}))
jest.mock('@/lib/file-cleanup', () => ({
deleteFiles: jest.fn(),
}))
jest.mock('@/lib/material-cleanup', () => ({
collectMaterialFiles: jest.fn(),
deleteMaterialRelatedRecords: jest.fn(),
}))
jest.mock('@/lib/material-log', () => ({
createMaterialLog: jest.fn(),
}))
jest.mock('@/lib/material-download-log', () => ({
ensureMaterialDownloadLogsTable: jest.fn(),
}))
jest.mock('@/lib/url-rewrite', () => ({
rewriteMaterialStorageUrlsForClient: jest.fn((value) => value),
rewriteMediaUrlForClient: jest.fn((value) => value),
}))
jest.mock('@/lib/network-detection', () => ({
detectIsIntranet: jest.fn(() => false),
}))
jest.mock('@/lib/product-package', () => ({
getMaterialCoverUrl: jest.fn(),
}))
jest.mock('@/lib/material-type-mapper', () => ({
isProductPackageType: jest.fn((materialType: string) => materialType === '任务-详情'),
}))
describe('materials route ai generated', () => {
beforeEach(() => {
jest.clearAllMocks()
;(getServerSession as jest.Mock).mockResolvedValue({
user: {
id: 'user-1',
role: 'USER',
department: '设计部',
managedDepartment: null,
isSuperAdmin: false,
},
})
;(isShareLinkAccess as jest.Mock).mockReturnValue(false)
;(isSuperAdmin as jest.Mock).mockResolvedValue(false)
;(getUserViewableMaterialTypes as jest.Mock).mockResolvedValue(['任务-详情'])
;(prisma.material.count as jest.Mock).mockResolvedValue(1)
;(prisma.material.findMany as jest.Mock).mockResolvedValue([
{
id: 'material-1',
userId: 'user-1',
previewUrl: 'https://example.com/preview.jpg',
productModel: 'SPU-001',
categoryName: '旗舰店',
sceneName: '客厅',
platformName: '天猫',
productCategoryName: '沙发',
materialType: '任务-详情',
renderer: '',
authorName: '张三',
zipFileName: 'sample.zip',
zipFileSize: BigInt(1024),
downloadCount: 0,
likeCount: 0,
createdAt: new Date('2026-03-25T08:00:00.000Z'),
videoSourceUrl: null,
displayImages: [],
videoPreview540Url: null,
videoPreviewClipUrl: null,
videoCoverUrl: null,
videoDuration: null,
videoProcessingStatus: null,
transcodeLastError: null,
transcodeAttempts: 0,
isAiGenerated: true,
user: {
username: 'zhangsan',
realName: '张三',
avatar: null,
},
assets: [],
},
])
;(prisma.materialLike.findMany as jest.Mock).mockResolvedValue([])
;(prisma.materialFavorite.findMany as jest.Mock).mockResolvedValue([])
;(prisma.materialAsset.findMany as jest.Mock).mockResolvedValue([])
})
test('列表接口应返回 isAiGenerated 标记,供首页展示 AI生成 标签', async () => {
const request = new NextRequest('http://localhost/api/materials?page=1&pageSize=20')
const response = await GET(request)
const body = await response.json()
expect(response.status).toBe(200)
expect(prisma.material.findMany).toHaveBeenCalledWith(
expect.objectContaining({
select: expect.objectContaining({
isAiGenerated: true,
}),
}),
)
expect(body.materials).toHaveLength(1)
expect(body.materials[0]).toEqual(
expect.objectContaining({
id: 'material-1',
isAiGenerated: true,
}),
)
})
})