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() }) })