gongxiangp2/lib/__tests__/material-query.test.ts
2026-07-30 18:00:28 +08:00

117 lines
3.7 KiB
TypeScript

import { prisma } from '@/lib/prisma'
import {
buildMaterialSearchOrConditions,
buildMaterialWhereFromSearchParams,
createMaterialQueryContext,
} from '@/lib/material-query'
import {
getUserViewableMaterialTypes,
isSuperAdmin,
isSystemAdmin,
} from '@/lib/department-permission'
jest.mock('@/lib/prisma', () => ({
prisma: {
materialSku: {
findMany: jest.fn(),
},
user: {
findMany: jest.fn(),
},
},
}))
jest.mock('@/lib/department-permission', () => ({
getUserViewableMaterialTypes: jest.fn(),
isSuperAdmin: jest.fn(),
isSystemAdmin: jest.fn(),
}))
describe('material search conditions', () => {
beforeEach(() => {
jest.clearAllMocks()
;(prisma.materialSku.findMany as jest.Mock).mockResolvedValue([])
;(prisma.user.findMany as jest.Mock).mockResolvedValue([])
;(getUserViewableMaterialTypes as jest.Mock).mockResolvedValue(['任务-详情'])
;(isSuperAdmin as jest.Mock).mockResolvedValue(false)
;(isSystemAdmin as unknown as jest.Mock).mockReturnValue(false)
})
test('完整素材 UUID 应使用精确匹配', async () => {
const materialId = '954554fb-50b4-45c4-9234-9e94b6948953'
const conditions = await buildMaterialSearchOrConditions(materialId)
expect(conditions).toEqual(expect.arrayContaining([{ id: materialId }]))
})
test('非 UUID 的历史素材 ID 也应使用精确匹配', async () => {
const materialId = 'legacy-material-1'
const conditions = await buildMaterialSearchOrConditions(materialId)
expect(conditions).toEqual(expect.arrayContaining([{ id: materialId }]))
})
test('同一请求的多组筛选条件复用权限和搜索上下文', async () => {
const searchParams = new URLSearchParams('search=GBGJ-BG0070&category=顾家')
const user = {
id: 'user-1',
role: 'USER',
department: '品牌创意部',
}
const context = await createMaterialQueryContext(searchParams, user)
const first = await buildMaterialWhereFromSearchParams(searchParams, user, { context })
const second = await buildMaterialWhereFromSearchParams(searchParams, user, {
context,
exclude: 'category',
})
expect(first.empty).toBe(false)
expect(first.where.categoryName).toBe('顾家')
expect(second.where.categoryName).toBeUndefined()
expect(getUserViewableMaterialTypes).toHaveBeenCalledTimes(1)
expect(isSuperAdmin).toHaveBeenCalledTimes(1)
expect(prisma.materialSku.findMany).toHaveBeenCalledTimes(1)
expect(prisma.user.findMany).toHaveBeenCalledTimes(1)
})
test('复用上下文后仍拒绝普通用户查看回收站素材', async () => {
await expect(
createMaterialQueryContext(
new URLSearchParams('showDeleted=true'),
{ id: 'user-1', role: 'USER', department: '品牌创意部' },
),
).rejects.toMatchObject({
code: 'FORBIDDEN_DELETED_MATERIALS',
status: 403,
})
})
test('复用上下文后仍拦截用户无权查看的素材类型', async () => {
const searchParams = new URLSearchParams('materialType=3D场景')
const user = {
id: 'user-1',
role: 'USER',
department: '品牌创意部',
}
const context = await createMaterialQueryContext(searchParams, user)
const result = await buildMaterialWhereFromSearchParams(searchParams, user, { context })
expect(result.empty).toBe(true)
})
test('超级管理员不读取部门素材权限', async () => {
;(isSuperAdmin as jest.Mock).mockResolvedValue(true)
const context = await createMaterialQueryContext(
new URLSearchParams(),
{ id: 'super-admin', role: 'ADMIN' },
)
expect(context.isSuperAdmin).toBe(true)
expect(getUserViewableMaterialTypes).not.toHaveBeenCalled()
})
})