119 lines
4.1 KiB
TypeScript
119 lines
4.1 KiB
TypeScript
/** @jest-environment node */
|
||
|
||
import { getServerSession } from 'next-auth'
|
||
|
||
import {
|
||
DELETE,
|
||
PATCH,
|
||
POST,
|
||
} from '@/app/api/materials/[id]/assets/[assetId]/route'
|
||
import {
|
||
deleteTaskDetailImage,
|
||
renameTaskDetailImage,
|
||
replaceTaskDetailImage,
|
||
} from '@/lib/task-detail-asset-edit'
|
||
|
||
jest.mock('next-auth', () => ({ getServerSession: jest.fn() }))
|
||
jest.mock('@/lib/auth', () => ({ authOptions: {} }))
|
||
jest.mock('@/lib/task-detail-asset-edit', () => ({
|
||
TaskDetailAssetEditError: class TaskDetailAssetEditError extends Error {
|
||
statusCode: number
|
||
constructor(message: string, statusCode = 400) {
|
||
super(message)
|
||
this.statusCode = statusCode
|
||
}
|
||
},
|
||
deleteTaskDetailImage: jest.fn(),
|
||
renameTaskDetailImage: jest.fn(),
|
||
replaceTaskDetailImage: jest.fn(),
|
||
}))
|
||
|
||
const mockedDelete = deleteTaskDetailImage as jest.Mock
|
||
const mockedRename = renameTaskDetailImage as jest.Mock
|
||
const mockedReplace = replaceTaskDetailImage as jest.Mock
|
||
|
||
describe('任务-详情单图编辑路由', () => {
|
||
beforeEach(() => {
|
||
jest.clearAllMocks()
|
||
})
|
||
|
||
test('未登录返回 401,不触发编辑逻辑', async () => {
|
||
;(getServerSession as jest.Mock).mockResolvedValue(null)
|
||
|
||
for (const response of [
|
||
await PATCH({ json: async () => ({ newFileName: 'x' }) } as any, { params: { id: 'm1', assetId: 'a1' } }),
|
||
await POST({ json: async () => ({ uploadId: 'u1' }) } as any, { params: { id: 'm1', assetId: 'a1' } }),
|
||
await DELETE({} as any, { params: { id: 'm1', assetId: 'a1' } }),
|
||
]) {
|
||
expect(response.status).toBe(401)
|
||
}
|
||
expect(mockedRename).not.toHaveBeenCalled()
|
||
expect(mockedReplace).not.toHaveBeenCalled()
|
||
expect(mockedDelete).not.toHaveBeenCalled()
|
||
})
|
||
|
||
test('PATCH 缺少新文件名返回 400', async () => {
|
||
;(getServerSession as jest.Mock).mockResolvedValue({ user: { id: 'u1' } })
|
||
const response = await PATCH({ json: async () => ({}) } as any, { params: { id: 'm1', assetId: 'a1' } })
|
||
expect(response.status).toBe(400)
|
||
expect(mockedRename).not.toHaveBeenCalled()
|
||
})
|
||
|
||
test('POST 缺少 uploadId 返回 400', async () => {
|
||
;(getServerSession as jest.Mock).mockResolvedValue({ user: { id: 'u1' } })
|
||
const response = await POST({ json: async () => ({}) } as any, { params: { id: 'm1', assetId: 'a1' } })
|
||
expect(response.status).toBe(400)
|
||
expect(mockedReplace).not.toHaveBeenCalled()
|
||
})
|
||
|
||
test('登录用户正常调用并透传参数', async () => {
|
||
;(getServerSession as jest.Mock).mockResolvedValue({ user: { id: 'u1', role: 'USER' } })
|
||
mockedRename.mockResolvedValue({ success: true })
|
||
mockedReplace.mockResolvedValue({ success: true })
|
||
mockedDelete.mockResolvedValue({ success: true })
|
||
|
||
await PATCH(
|
||
{ json: async () => ({ newFileName: '新名字' }) } as any,
|
||
{ params: { id: 'm1', assetId: 'a1' } },
|
||
)
|
||
expect(mockedRename).toHaveBeenCalledWith({
|
||
materialId: 'm1',
|
||
assetId: 'a1',
|
||
operatorUserId: 'u1',
|
||
operatorRole: 'USER',
|
||
newFileName: '新名字',
|
||
})
|
||
|
||
await POST(
|
||
{ json: async () => ({ uploadId: 'upload-1' }) } as any,
|
||
{ params: { id: 'm1', assetId: 'a2' } },
|
||
)
|
||
expect(mockedReplace).toHaveBeenCalledWith({
|
||
materialId: 'm1',
|
||
assetId: 'a2',
|
||
operatorUserId: 'u1',
|
||
operatorRole: 'USER',
|
||
uploadId: 'upload-1',
|
||
})
|
||
|
||
await DELETE({} as any, { params: { id: 'm1', assetId: 'a3' } })
|
||
expect(mockedDelete).toHaveBeenCalledWith({
|
||
materialId: 'm1',
|
||
assetId: 'a3',
|
||
operatorUserId: 'u1',
|
||
operatorRole: 'USER',
|
||
})
|
||
})
|
||
|
||
test('权限类业务错误透传状态码与文案', async () => {
|
||
;(getServerSession as jest.Mock).mockResolvedValue({ user: { id: 'intruder' } })
|
||
const { TaskDetailAssetEditError: MockedError } = await import('@/lib/task-detail-asset-edit')
|
||
mockedDelete.mockRejectedValue(new (MockedError as any)('您没有权限编辑此素材', 403))
|
||
|
||
const response = await DELETE({} as any, { params: { id: 'm1', assetId: 'a1' } })
|
||
expect(response.status).toBe(403)
|
||
const body = await response.json()
|
||
expect(body.error).toBe('您没有权限编辑此素材')
|
||
})
|
||
})
|