2026-04-17 12:50:06 +08:00

192 lines
4.7 KiB
TypeScript

export {}
import { beforeEach, describe, expect, it, jest } from '@jest/globals'
import { AppError, ErrorCode } from '@/server/core/errors'
const mockHandleRequest: any = jest.fn()
const mockJsonSuccess: any = jest.fn()
const mockJsonError: any = jest.fn()
const mockGetUserDetail: any = jest.fn()
const mockUpdateUser: any = jest.fn()
const mockDeleteUser: any = jest.fn()
jest.mock('@/server/core/response', () => ({
handleRequest: (...args: unknown[]) => mockHandleRequest(...args),
jsonSuccess: (...args: unknown[]) => mockJsonSuccess(...args),
jsonError: (...args: unknown[]) => mockJsonError(...args),
}))
jest.mock('@/server/services/user-management.service', () => ({
userManagementService: {
getUserDetail: (...args: unknown[]) => mockGetUserDetail(...args),
updateUser: (...args: unknown[]) => mockUpdateUser(...args),
deleteUser: (...args: unknown[]) => mockDeleteUser(...args),
},
}))
const { GET, PUT, DELETE } = require('./route')
function createRequest(body?: unknown) {
return {
json: jest.fn(async () => body),
} as any
}
describe('GET/PUT/DELETE /api/users/[id]', () => {
beforeEach(() => {
jest.clearAllMocks()
mockHandleRequest.mockImplementation(async (_request: unknown, handler: any) =>
handler({
requestId: 'req-test',
user: {
id: 'admin-1',
email: 'admin@example.com',
name: '管理员',
role: 'ADMIN',
status: 'ACTIVE',
},
}),
)
mockJsonSuccess.mockImplementation((data, status, requestId) => ({
success: true,
data,
status,
requestId,
}))
mockJsonError.mockImplementation((code, message, status, requestId) => ({
success: false,
code,
message,
status,
requestId,
}))
})
it('GET 会返回单个用户详情', async () => {
mockGetUserDetail.mockResolvedValue({
id: 'user-1',
name: '测试用户',
role: 'DESIGNER',
})
const response = await GET(createRequest(), {
params: Promise.resolve({ id: 'user-1' }),
})
expect(mockGetUserDetail).toHaveBeenCalledWith(
'user-1',
expect.objectContaining({ id: 'admin-1' }),
)
expect(response).toEqual(
expect.objectContaining({
success: true,
status: 200,
data: {
user: expect.objectContaining({
id: 'user-1',
name: '测试用户',
}),
},
}),
)
})
it('PUT 会透传更新字段并返回更新结果', async () => {
mockUpdateUser.mockResolvedValue({
id: 'user-1',
name: '新名字',
role: 'SUPERVISOR',
departmentId: 'dept-2',
teamId: null,
status: 'ACTIVE',
})
const response = await PUT(
createRequest({
name: '新名字',
role: 'SUPERVISOR',
departmentId: 'dept-2',
teamId: null,
phone: null,
status: 'ACTIVE',
}),
{
params: Promise.resolve({ id: 'user-1' }),
},
)
expect(mockUpdateUser).toHaveBeenCalledWith(
'user-1',
{
email: undefined,
name: '新名字',
password: undefined,
role: 'SUPERVISOR',
departmentId: 'dept-2',
teamId: null,
phone: null,
status: 'ACTIVE',
},
expect.objectContaining({ id: 'admin-1' }),
)
expect(response).toEqual(
expect.objectContaining({
success: true,
status: 200,
data: expect.objectContaining({
message: '用户更新成功',
}),
}),
)
})
it('DELETE 会调用删除服务并返回成功消息', async () => {
mockDeleteUser.mockResolvedValue(undefined)
const response = await DELETE(createRequest(), {
params: Promise.resolve({ id: 'user-1' }),
})
expect(mockDeleteUser).toHaveBeenCalledWith(
'user-1',
expect.objectContaining({ id: 'admin-1' }),
)
expect(response).toEqual(
expect.objectContaining({
success: true,
status: 200,
data: {
message: '用户删除成功',
},
}),
)
})
it('服务抛出应用错误时会走标准错误响应', async () => {
mockGetUserDetail.mockRejectedValue(
new AppError(ErrorCode.AUTH_PERMISSION_DENIED, '无权限查看此用户'),
)
const response = await GET(createRequest(), {
params: Promise.resolve({ id: 'user-2' }),
})
expect(mockJsonError).toHaveBeenCalledWith(
ErrorCode.AUTH_PERMISSION_DENIED,
'无权限查看此用户',
403,
'req-test',
)
expect(response).toEqual(
expect.objectContaining({
success: false,
code: ErrorCode.AUTH_PERMISSION_DENIED,
status: 403,
}),
)
})
})