import { describe, expect, it } from 'vitest' import { createRolePermissionDraft, mergeRoleDraft, rebaseRoleDraft, updateRolePermission, validateRolePermissionDraft, visiblePatch, type RolePermissionValue, } from '../src/rolePermissions' const initial: Record = { 'project.create': { allowed: false, capAllowed: true }, 'document.read': { allowed: true, capAllowed: true }, 'document.author': { allowed: false, capAllowed: true }, } describe('role permission draft', () => { it('retains hidden edits and patches only explicit visible actions', () => { let draft = createRolePermissionDraft(initial) draft = updateRolePermission(draft, 'project.create', { allowed: true, capAllowed: true }) draft = updateRolePermission(draft, 'document.author', { allowed: true, capAllowed: true }) expect(visiblePatch(draft, ['project.create'])).toEqual([ { actionId: 'project.create', allowed: true, capAllowed: true }, ]) expect(draft.values['document.author']).toEqual({ allowed: true, capAllowed: true }) }) it('produces the same patch for single-role and matrix edits', () => { const single = updateRolePermission(createRolePermissionDraft(initial), 'document.read', { allowed: false, capAllowed: true }) const matrix = updateRolePermission(createRolePermissionDraft(initial), 'document.read', { allowed: false, capAllowed: true }) expect(visiblePatch(single, Object.keys(initial))).toEqual(visiblePatch(matrix, Object.keys(initial))) }) it('discards a stale server refresh without replacing newer edits', () => { const edited = updateRolePermission(createRolePermissionDraft(initial), 'project.create', { allowed: true, capAllowed: true }) const merged = mergeRoleDraft(edited, initial, edited.generation - 1) expect(merged).toBe(edited) }) it('rejects defaults that exceed the role cap', () => { const invalid = updateRolePermission(createRolePermissionDraft(initial), 'document.read', { allowed: true, capAllowed: false }) expect(validateRolePermissionDraft(invalid)).toEqual({ actionId: 'document.read', reason: 'default-exceeds-cap' }) }) it('rebases local changes on a newer role version without losing the draft', () => { const edited = updateRolePermission(createRolePermissionDraft(initial), 'project.create', { allowed: true, capAllowed: true }) const server = { ...initial, 'document.read': { allowed: false, capAllowed: true } } const rebased = rebaseRoleDraft(edited, server) expect(rebased.baseline['document.read']).toEqual({ allowed: false, capAllowed: true }) expect(rebased.values['project.create']).toEqual({ allowed: true, capAllowed: true }) expect(rebased.values['document.read']).toEqual({ allowed: false, capAllowed: true }) }) })