117 lines
3.7 KiB
TypeScript
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()
|
|
})
|
|
})
|