/** * Test suite for permission utility functions */ import { AppACLPermission, DatasetACLPermission, getAppACLCapabilities, getDatasetACLCapabilities, hasOnlyAppPreviewPermission, hasOnlyDatasetPreviewPermission, hasPermission, } from './permission' describe('permission', () => { describe('hasPermissionKey', () => { const permissionKey = 'workspace.member.manage' it('returns true when the permission key exists', () => { expect(hasPermission(['workspace.role.manage', permissionKey], permissionKey)).toBe(true) }) it('returns false when the permission key does not exist', () => { expect(hasPermission(['workspace.role.manage'], permissionKey)).toBe(false) }) }) describe('getAppACLCapabilities', () => { it('allows test-and-run users to access layout without edit', () => { const capabilities = getAppACLCapabilities([AppACLPermission.TestAndRun]) expect(capabilities.canTestAndRun).toBe(true) expect(capabilities.canAccessLayout).toBe(true) expect(capabilities.canEdit).toBe(false) }) it('allows view-layout users to preview the app but not run/debug', () => { const capabilities = getAppACLCapabilities([AppACLPermission.ViewLayout]) expect(capabilities.canPreviewApp).toBe(true) expect(capabilities.canAccessLayout).toBe(true) expect(capabilities.canTestAndRun).toBe(false) }) it('keeps monitor, tracing config, and log/annotation permissions independent', () => { const monitorCapabilities = getAppACLCapabilities([AppACLPermission.Monitor]) const tracingCapabilities = getAppACLCapabilities([AppACLPermission.TracingConfig]) const logAndAnnotationCapabilities = getAppACLCapabilities([ AppACLPermission.LogAndAnnotation, ]) expect(monitorCapabilities.canMonitor).toBe(true) expect(monitorCapabilities.canConfigureTracing).toBe(false) expect(monitorCapabilities.canAccessLogAndAnnotation).toBe(false) expect(tracingCapabilities.canMonitor).toBe(false) expect(tracingCapabilities.canConfigureTracing).toBe(true) expect(tracingCapabilities.canAccessLogAndAnnotation).toBe(false) expect(logAndAnnotationCapabilities.canMonitor).toBe(false) expect(logAndAnnotationCapabilities.canConfigureTracing).toBe(false) expect(logAndAnnotationCapabilities.canAccessLogAndAnnotation).toBe(true) }) }) describe('hasOnlyAppPreviewPermission', () => { it('should return true when app ACL contains only preview permission', () => { expect(hasOnlyAppPreviewPermission([AppACLPermission.Preview])).toBe(true) }) it('should return false when app ACL contains preview permission and another permission', () => { expect( hasOnlyAppPreviewPermission([AppACLPermission.Preview, AppACLPermission.ViewLayout]), ).toBe(false) }) }) describe('hasOnlyDatasetPreviewPermission', () => { it('should return true when dataset ACL contains only preview permission', () => { expect(hasOnlyDatasetPreviewPermission([DatasetACLPermission.Preview])).toBe(true) }) it('should return false when dataset ACL contains preview permission and another permission', () => { expect( hasOnlyDatasetPreviewPermission([ DatasetACLPermission.Preview, DatasetACLPermission.Readonly, ]), ).toBe(false) }) }) describe('app maintainer capabilities', () => { it('grants all app ACL capabilities without injecting app ACL permission keys', () => { const permissionKeys: string[] = [] const capabilities = getAppACLCapabilities(permissionKeys, { currentUserId: 'user-1', resourceMaintainer: 'user-1', workspacePermissionKeys: ['app.create_and_management'], isRbacEnabled: true, }) expect(capabilities.canViewLayout).toBe(true) expect(capabilities.canTestAndRun).toBe(true) expect(capabilities.canEdit).toBe(true) expect(capabilities.canImportExportDSL).toBe(true) expect(capabilities.canDelete).toBe(true) expect(capabilities.canReleaseAndVersion).toBe(true) expect(capabilities.canMonitor).toBe(true) expect(capabilities.canConfigureTracing).toBe(true) expect(capabilities.canAccessLogAndAnnotation).toBe(true) expect(capabilities.canAccessConfig).toBe(true) expect(permissionKeys).toEqual([]) }) it('keeps app ACL capabilities unchanged when the maintainer lacks app.create_and_management permission', () => { const capabilities = getAppACLCapabilities([AppACLPermission.ViewLayout], { currentUserId: 'user-1', resourceMaintainer: 'user-1', workspacePermissionKeys: [], }) expect(capabilities.canViewLayout).toBe(true) expect(capabilities.canEdit).toBe(false) expect(capabilities.canDelete).toBe(false) }) it('does not grant app access config when RBAC is disabled', () => { const capabilities = getAppACLCapabilities([AppACLPermission.AccessConfig], { isRbacEnabled: false, }) expect(capabilities.canAccessConfig).toBe(false) }) }) describe('dataset maintainer capabilities', () => { it('grants all dataset ACL capabilities without injecting dataset ACL permission keys', () => { const permissionKeys: string[] = [] const capabilities = getDatasetACLCapabilities(permissionKeys, { currentUserId: 'user-1', resourceMaintainer: 'user-1', workspacePermissionKeys: ['dataset.create_and_management'], isRbacEnabled: true, }) expect(capabilities.canReadonly).toBe(true) expect(capabilities.canEdit).toBe(true) expect(capabilities.canImportExportDSL).toBe(true) expect(capabilities.canPipelineTest).toBe(true) expect(capabilities.canDocumentDownload).toBe(true) expect(capabilities.canRetrievalRecall).toBe(true) expect(capabilities.canUse).toBe(true) expect(capabilities.canDeleteFile).toBe(true) expect(capabilities.canPipelineRelease).toBe(true) expect(capabilities.canDelete).toBe(true) expect(capabilities.canAccessConfig).toBe(true) expect(permissionKeys).toEqual([]) }) it('keeps dataset ACL capabilities unchanged when the current user is not the maintainer', () => { const capabilities = getDatasetACLCapabilities([DatasetACLPermission.Readonly], { currentUserId: 'user-1', resourceMaintainer: 'user-2', workspacePermissionKeys: ['dataset.create_and_management'], }) expect(capabilities.canReadonly).toBe(true) expect(capabilities.canEdit).toBe(false) expect(capabilities.canDelete).toBe(false) }) it('does not grant dataset access config when RBAC is disabled', () => { const capabilities = getDatasetACLCapabilities([DatasetACLPermission.AccessConfig], { isRbacEnabled: false, }) expect(capabilities.canAccessConfig).toBe(false) }) }) })