66 lines
4.3 KiB
TypeScript
66 lines
4.3 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { renderToStaticMarkup } from 'react-dom/server'
|
|
import { CapabilityChangePreview, CapabilityGroupEditor, rolePermissionSaveError } from './RolePermissionsPanel'
|
|
import {
|
|
buildCapabilityGroups, capabilityGroupChanges, createRolePermissionDraft, linkedChainBreaks, setCapabilityGroup,
|
|
type RolePermissionValue,
|
|
} from '../rolePermissions'
|
|
|
|
const catalog = [
|
|
{ actionId: 'project.create', label: '创建项目', group: '项目入口' },
|
|
{ actionId: 'project.settings', label: '项目设置', group: '项目管理' },
|
|
{ actionId: 'project.members.manage', label: '管理项目成员', group: '项目管理' },
|
|
{ actionId: 'project.permissions.manage', label: '管理项目权限', group: '项目管理' },
|
|
{ actionId: 'document.duties.assign', label: '分配文档三权', group: '文档职责' },
|
|
{ actionId: 'document.author', label: '编制文档', group: '文档动作' },
|
|
{ actionId: 'document.review', label: '审核文档', group: '文档动作' },
|
|
{ actionId: 'document.approve', label: '批准文档', group: '文档动作' },
|
|
]
|
|
const labels = Object.fromEntries(catalog.map(item => [item.actionId, item.label]))
|
|
const off: RolePermissionValue = { allowed: false, capAllowed: false }
|
|
const values = Object.fromEntries(catalog.map(item => [item.actionId, off]))
|
|
const groups = buildCapabilityGroups(catalog)
|
|
|
|
describe('CapabilityGroup role editor', () => {
|
|
it('replaces the per-capability checkbox grid with one default/cap pair per business group', () => {
|
|
const html = renderToStaticMarkup(<CapabilityGroupEditor groups={groups} values={values} labels={labels} disabled={false} onToggle={vi.fn()} />)
|
|
expect(html.match(/type="checkbox"/g)).toHaveLength(groups.length * 2)
|
|
expect(html).toContain('创建与管理本人项目 默认授予')
|
|
expect(html).toContain('文档编制与审签 角色上限')
|
|
expect(html).not.toContain('编制文档 默认允许')
|
|
expect(html).not.toContain('管理项目成员 默认授予')
|
|
})
|
|
|
|
it('shows linked own-project management as controlled items with their association source', () => {
|
|
const create = groups.find(group => group.id === 'project-create')!
|
|
const linked = setCapabilityGroup(createRolePermissionDraft(values), create, 'allowed', true).values
|
|
const html = renderToStaticMarkup(<CapabilityGroupEditor groups={groups} values={linked} labels={labels} disabled onToggle={vi.fn()} />)
|
|
expect(html).toContain('管理项目成员:已联动(来源:创建项目,仅本人创建的项目)')
|
|
expect(html).toContain('分配文档三权:已联动')
|
|
const before = renderToStaticMarkup(<CapabilityGroupEditor groups={groups} values={values} labels={labels} disabled onToggle={vi.fn()} />)
|
|
expect(before).toContain('未联动(开启创建项目后自动补齐)')
|
|
})
|
|
|
|
it('marks a partially granted group instead of hiding the difference', () => {
|
|
const partial = { ...values, 'document.author': { allowed: true, capAllowed: true } }
|
|
const html = renderToStaticMarkup(<CapabilityGroupEditor groups={groups} values={partial} labels={labels} disabled={false} onToggle={vi.fn()} />)
|
|
expect(html).toContain('默认授予(部分)')
|
|
})
|
|
|
|
it('previews the grouped difference with the affected source and affected user count', () => {
|
|
const create = groups.find(group => group.id === 'project-create')!
|
|
const draft = setCapabilityGroup(createRolePermissionDraft(values), create, 'allowed', true)
|
|
const html = renderToStaticMarkup(<CapabilityChangePreview changes={capabilityGroupChanges(draft, groups)} breaks={linkedChainBreaks(draft.values)}
|
|
labels={labels} roleName="项目经理" bindingCount={7} />)
|
|
expect(html).toContain('影响来源:职位角色「项目经理」 · 影响 7 名绑定用户')
|
|
expect(html).toContain('创建与管理本人项目:默认 拒绝 → 允许')
|
|
expect(html).toContain('联动补齐 项目设置、管理项目成员、管理项目权限、分配文档三权(仅本人创建的项目)')
|
|
})
|
|
|
|
it('keeps the draft and names a linked conflict the server rejected as a whole', () => {
|
|
expect(rolePermissionSaveError(new Error('422: linked capability conflict project.members.manage')))
|
|
.toMatch(/关联能力冲突.*整笔拒绝.*本地草稿已保留/)
|
|
expect(rolePermissionSaveError(new Error('500: boom'))).toContain('本地草稿已保留')
|
|
})
|
|
})
|