flnxi-Wu/app/api/materials/__tests__/materials-list-auth.test.ts

142 lines
4.2 KiB
TypeScript

import { NextRequest } from 'next/server'
import { GET } from '../route'
jest.mock('@/lib/auth', () => ({
authOptions: {},
}))
jest.mock('next-auth', () => ({
getServerSession: jest.fn(),
}))
jest.mock('@/lib/prisma', () => ({
prisma: {
material: {
count: jest.fn(),
findMany: jest.fn(),
},
uploadField: {
findMany: jest.fn(),
},
fieldDefinition: {
findMany: jest.fn(),
},
$queryRaw: jest.fn(),
materialLike: {
findMany: jest.fn(),
},
materialFavorite: {
findMany: jest.fn(),
},
},
}))
jest.mock('@/lib/url-rewrite', () => ({
rewriteMaterialStorageUrlsForClient: jest.fn((material) => material),
}))
jest.mock('@/lib/material-log', () => ({
createMaterialLog: jest.fn(),
}))
jest.mock('@/lib/s3', () => ({
deleteFromS3: jest.fn(),
isS3Url: jest.fn(() => false),
}))
const { getServerSession } = require('next-auth')
const { prisma } = require('@/lib/prisma')
describe('GET /api/materials 权限边界', () => {
beforeEach(() => {
jest.resetAllMocks()
})
it('未登录时拒绝读取素材列表', async () => {
getServerSession.mockResolvedValue(null)
const response = await GET(new NextRequest('http://localhost/api/materials?pageSize=1'))
const data = await response.json()
expect(response.status).toBe(401)
expect(data.error).toBe('请先登录')
expect(prisma.material.count).not.toHaveBeenCalled()
expect(prisma.material.findMany).not.toHaveBeenCalled()
})
it('已登录时正常读取素材列表', async () => {
getServerSession.mockResolvedValue({
user: { id: 'user-1', role: 'USER' },
})
prisma.material.count.mockResolvedValue(0)
prisma.material.findMany.mockResolvedValue([])
prisma.uploadField.findMany.mockResolvedValue([])
prisma.fieldDefinition.findMany.mockResolvedValue([])
const response = await GET(new NextRequest('http://localhost/api/materials?pageSize=1'))
const data = await response.json()
expect(response.status).toBe(200)
expect(data.materials).toEqual([])
expect(data.totalCount).toBe(0)
expect(prisma.material.count).toHaveBeenCalled()
expect(prisma.material.findMany).toHaveBeenCalled()
})
it('搜索时会把可搜索自定义字段纳入查询', async () => {
getServerSession.mockResolvedValue({
user: { id: 'user-1', role: 'USER' },
})
prisma.uploadField.findMany.mockResolvedValue([
{ key: 'customCode' },
{ key: 'productModel' },
])
prisma.$queryRaw.mockResolvedValue([{ id: 'material-custom-1' }])
prisma.fieldDefinition.findMany.mockResolvedValue([])
prisma.material.count.mockResolvedValue(1)
prisma.material.findMany.mockResolvedValue([])
const response = await GET(new NextRequest('http://localhost/api/materials?search=CODE-001&pageSize=1'))
expect(response.status).toBe(200)
expect(prisma.uploadField.findMany).toHaveBeenCalledWith({
where: { isSearchable: true },
select: { key: true },
})
expect(prisma.$queryRaw).toHaveBeenCalled()
expect(prisma.material.count.mock.calls[0][0].where.AND).toEqual(
expect.arrayContaining([
expect.objectContaining({
OR: expect.arrayContaining([{ id: { in: ['material-custom-1'] } }]),
}),
])
)
})
it('首页自定义字段筛选会按 metadata 字段值过滤素材', async () => {
getServerSession.mockResolvedValue({
user: { id: 'user-1', role: 'USER' },
})
prisma.fieldDefinition.findMany.mockResolvedValue([{ key: 'customCode' }])
prisma.$queryRaw.mockResolvedValue([{ id: 'material-custom-1' }])
prisma.material.count.mockResolvedValue(1)
prisma.material.findMany.mockResolvedValue([])
const response = await GET(
new NextRequest('http://localhost/api/materials?homeField_customCode=CODE-001&pageSize=1')
)
expect(response.status).toBe(200)
expect(prisma.fieldDefinition.findMany).toHaveBeenCalledWith({
where: {
key: { in: ['customCode'] },
isFilterEnabled: true,
},
select: { key: true },
})
expect(prisma.material.count.mock.calls[0][0].where.AND).toEqual(
expect.arrayContaining([{ id: { in: ['material-custom-1'] } }])
)
})
})