mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +00:00
[MNT-24923] legal hold hold capabilities are not verified properly (#4616)
* [MNT-24923] Added possibility to configure readonly for metadata sidebar by json config * [MNT-24923] Unit tests * [MNT-24923] Fixed sonar issues
This commit is contained in:
@@ -883,6 +883,20 @@
|
||||
"description": "Sidebar extensions",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"rules": {
|
||||
"description": "Element rules",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Rule to evaluate the enabled state",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"description": "Toolbar entries",
|
||||
"type": "array",
|
||||
|
@@ -32,7 +32,7 @@ import { By } from '@angular/platform-browser';
|
||||
import { AppExtensionService, NodePermissionService } from '@alfresco/aca-shared';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { ContentActionType } from '@alfresco/adf-extensions';
|
||||
import { ContentActionType, ExtensionService } from '@alfresco/adf-extensions';
|
||||
import { CategoryService, ContentMetadataComponent, ContentMetadataService, TagService } from '@alfresco/adf-content-services';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
|
||||
@@ -70,6 +70,7 @@ describe('MetadataTabComponent', () => {
|
||||
return permissions.some((permission) => source.allowableOperations.includes(permission));
|
||||
});
|
||||
spyOn(contentMetadataService, 'getGroupedProperties').and.returnValue(of());
|
||||
extensions = TestBed.inject(AppExtensionService);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -79,7 +80,6 @@ describe('MetadataTabComponent', () => {
|
||||
describe('content-metadata configuration', () => {
|
||||
beforeEach(() => {
|
||||
appConfig = TestBed.inject(AppConfigService);
|
||||
extensions = TestBed.inject(AppExtensionService);
|
||||
appConfig.config['content-metadata'] = { presets };
|
||||
});
|
||||
|
||||
@@ -102,9 +102,12 @@ describe('MetadataTabComponent', () => {
|
||||
});
|
||||
|
||||
describe('readOnly', () => {
|
||||
let extensionService: ExtensionService;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MetadataTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
extensionService = TestBed.inject(ExtensionService);
|
||||
});
|
||||
|
||||
it('should return false if node is not locked and has update permission', async () => {
|
||||
@@ -146,6 +149,170 @@ describe('MetadataTabComponent', () => {
|
||||
expect(component.readOnly).toBe(true);
|
||||
});
|
||||
|
||||
it('should set readOnly to false if node is defined, is not locked and enabled rule for sidebar returns true, has update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: false,
|
||||
allowableOperations: ['update']
|
||||
} as Node;
|
||||
const rule = 'someRule';
|
||||
spyOn(extensionService, 'getFeature').and.returnValue({
|
||||
rules: {
|
||||
enabled: [rule]
|
||||
}
|
||||
});
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeFalse();
|
||||
expect(extensionService.getFeature).toHaveBeenCalledWith('sidebar');
|
||||
expect(extensionService.evaluateRule).toHaveBeenCalledWith(rule, extensions);
|
||||
});
|
||||
|
||||
it('should set readOnly to false if node is defined, is not locked and there is nothing for sidebar in configuration, has update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: false,
|
||||
allowableOperations: ['update']
|
||||
} as Node;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue(undefined);
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeFalse();
|
||||
expect(extensionService.getFeature).toHaveBeenCalledWith('sidebar');
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is undefined and enabled rule for sidebar returns true, has update permission for node', () => {
|
||||
component.node = undefined;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue({
|
||||
rules: {
|
||||
enabled: ['someRule']
|
||||
}
|
||||
});
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).not.toHaveBeenCalled();
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is undefined and there is nothing for sidebar in configuration, has update permission for node', () => {
|
||||
component.node = undefined;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue(undefined);
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).not.toHaveBeenCalled();
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is defined, is locked and enabled rule for sidebar returns true, has update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: true,
|
||||
allowableOperations: ['update']
|
||||
} as Node;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue({
|
||||
rules: {
|
||||
enabled: ['someRule']
|
||||
}
|
||||
});
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).not.toHaveBeenCalled();
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is defined, is locked and there is nothing for sidebar in configuration, has update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: true,
|
||||
allowableOperations: ['update']
|
||||
} as Node;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue(undefined);
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).not.toHaveBeenCalled();
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is defined, is not locked and enabled rule for sidebar returns true, has not update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: false,
|
||||
allowableOperations: []
|
||||
} as Node;
|
||||
const rule = 'someRule';
|
||||
spyOn(extensionService, 'getFeature').and.returnValue({
|
||||
rules: {
|
||||
enabled: [rule]
|
||||
}
|
||||
});
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).toHaveBeenCalledWith('sidebar');
|
||||
expect(extensionService.evaluateRule).toHaveBeenCalledWith(rule, extensions);
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is defined, is not locked and there is nothing for sidebar in configuration, has not update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: false,
|
||||
allowableOperations: ['']
|
||||
} as Node;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue(undefined);
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).toHaveBeenCalledWith('sidebar');
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is defined, is locked and enabled rule for sidebar returns true, has not update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: true,
|
||||
allowableOperations: []
|
||||
} as Node;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue({
|
||||
rules: {
|
||||
enabled: ['someRule']
|
||||
}
|
||||
});
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).not.toHaveBeenCalled();
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set readOnly to true if node is defined, is locked and there is nothing for sidebar in configuration, has not update permission for node', () => {
|
||||
component.node = {
|
||||
id: 'some id',
|
||||
isLocked: true,
|
||||
allowableOperations: []
|
||||
} as Node;
|
||||
spyOn(extensionService, 'getFeature').and.returnValue(undefined);
|
||||
spyOn(extensionService, 'evaluateRule').and.returnValue(true);
|
||||
|
||||
component.ngOnInit();
|
||||
expect(component.readOnly).toBeTrue();
|
||||
expect(extensionService.getFeature).not.toHaveBeenCalled();
|
||||
expect(extensionService.evaluateRule).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('set by triggering EditOfflineAction', () => {
|
||||
let editOfflineAction: EditOfflineAction;
|
||||
|
||||
|
@@ -40,6 +40,7 @@ import { CommonModule } from '@angular/common';
|
||||
import { Actions, ofType } from '@ngrx/effects';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { ExtensionService } from '@alfresco/adf-extensions';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -81,15 +82,16 @@ export class MetadataTabComponent implements OnInit {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private permission: NodePermissionService,
|
||||
protected extensions: AppExtensionService,
|
||||
private appConfig: AppConfigService,
|
||||
private notificationService: NotificationService,
|
||||
private contentMetadataService: ContentMetadataService,
|
||||
private actions$: Actions,
|
||||
private tagService: TagService,
|
||||
private categoryService: CategoryService,
|
||||
private store: Store<AppStore>
|
||||
private readonly permission: NodePermissionService,
|
||||
protected readonly extensions: AppExtensionService,
|
||||
private readonly appConfig: AppConfigService,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly contentMetadataService: ContentMetadataService,
|
||||
private readonly actions$: Actions,
|
||||
private readonly tagService: TagService,
|
||||
private readonly categoryService: CategoryService,
|
||||
private readonly store: Store<AppStore>,
|
||||
private readonly extensionService: ExtensionService
|
||||
) {
|
||||
if (this.extensions.contentMetadata) {
|
||||
this.appConfig.config['content-metadata'].presets = this.extensions.contentMetadata.presets;
|
||||
@@ -128,6 +130,12 @@ export class MetadataTabComponent implements OnInit {
|
||||
}
|
||||
|
||||
private checkIfNodeIsUpdatable(node: Node) {
|
||||
this.readOnly = !(node && !isLocked({ entry: node }) ? this.permission.check(node, ['update']) : false);
|
||||
this.readOnly = !(node &&
|
||||
!isLocked({ entry: node }) &&
|
||||
(this.extensionService.getFeature('sidebar')?.['rules']?.enabled ?? []).every((rule: string) =>
|
||||
this.extensionService.evaluateRule(rule, this.extensions)
|
||||
)
|
||||
? this.permission.check(node, ['update'])
|
||||
: false);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user