59 lines
3.3 KiB
TypeScript
59 lines
3.3 KiB
TypeScript
/** @jest-environment node */
|
|
import { NextRequest } from 'next/server'
|
|
import { getServerSession } from 'next-auth'
|
|
import { resolveBrandCenterAccessForUser } from '@/lib/brand-center-access'
|
|
import { isSuperAdmin } from '@/lib/department-permission'
|
|
import { getTeamFunctions, saveTeamFunction, TeamFunctionError } from '@/lib/team-functions'
|
|
import { GET, PUT } from './route'
|
|
jest.mock('next-auth', () => ({ getServerSession: jest.fn() }))
|
|
jest.mock('@/lib/auth', () => ({ authOptions: {} }))
|
|
jest.mock('@/lib/brand-center-access', () => ({ resolveBrandCenterAccessForUser: jest.fn() }))
|
|
jest.mock('@/lib/department-permission', () => ({ isSuperAdmin: jest.fn() }))
|
|
jest.mock('@/lib/team-functions', () => ({ ...jest.requireActual('@/lib/team-functions'), getTeamFunctions: jest.fn(), saveTeamFunction: jest.fn() }))
|
|
jest.mock('@/lib/prisma', () => ({ prisma: {} }))
|
|
const input = { organizationUnitId: 'team', revision: 0, leadEmployeeProfileId: null, description: '说明', branches: [] }
|
|
const request = (body: unknown) => new NextRequest('http://local/api/organization/team-functions', { method: 'PUT', body: JSON.stringify(body) })
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
;(getServerSession as jest.Mock).mockResolvedValue({ user: { id: 'actor', role: 'USER' } })
|
|
;(resolveBrandCenterAccessForUser as jest.Mock).mockResolvedValue(true)
|
|
;(isSuperAdmin as jest.Mock).mockResolvedValue(false)
|
|
;(getTeamFunctions as jest.Mock).mockResolvedValue({ teams: [], canEdit: false })
|
|
;(saveTeamFunction as jest.Mock).mockResolvedValue({ revision: 1 })
|
|
})
|
|
test('品牌中心成员可读,不取得维护权限或候选人员', async () => {
|
|
const response = await GET()
|
|
expect(response.status).toBe(200)
|
|
expect(response.headers.get('Cache-Control')).toBe('private, no-store')
|
|
expect(getTeamFunctions).toHaveBeenCalledWith(false)
|
|
})
|
|
test('未登录及非品牌中心成员拒绝读取', async () => {
|
|
;(getServerSession as jest.Mock).mockResolvedValue(null)
|
|
expect((await GET()).status).toBe(403)
|
|
;(getServerSession as jest.Mock).mockResolvedValue({ user: { id: 'actor' } })
|
|
;(resolveBrandCenterAccessForUser as jest.Mock).mockResolvedValue(false)
|
|
expect((await GET()).status).toBe(403)
|
|
expect(getTeamFunctions).not.toHaveBeenCalled()
|
|
})
|
|
test('客户端提交的管理员身份不能绕过数据库检查', async () => {
|
|
expect((await PUT(request({ ...input, isSuperAdmin: true }))).status).toBe(403)
|
|
expect(saveTeamFunction).not.toHaveBeenCalled()
|
|
})
|
|
test('超级管理员使用服务端身份保存', async () => {
|
|
;(isSuperAdmin as jest.Mock).mockResolvedValue(true)
|
|
expect((await PUT(request(input))).status).toBe(200)
|
|
expect(saveTeamFunction).toHaveBeenCalledWith(input, 'actor')
|
|
})
|
|
test('空分组、超长条目及错误修订号拒绝写入', async () => {
|
|
;(isSuperAdmin as jest.Mock).mockResolvedValue(true)
|
|
for (const body of [{ ...input, revision: -1 }, { ...input, branches: [{ label: '', items: ['职责'] }] }, { ...input, description: 'x'.repeat(2001) }]) {
|
|
expect((await PUT(request(body))).status).toBe(400)
|
|
}
|
|
expect(saveTeamFunction).not.toHaveBeenCalled()
|
|
})
|
|
test('版本冲突返回可恢复的错误', async () => {
|
|
;(isSuperAdmin as jest.Mock).mockResolvedValue(true)
|
|
;(saveTeamFunction as jest.Mock).mockRejectedValue(new TeamFunctionError('配置已更新', 409))
|
|
expect((await PUT(request(input))).status).toBe(409)
|
|
})
|