[ACS-6196] await-thenable rule for ESLint, fix issues (#9027)

* fix issues for core lib

* fix content services lib

* fix and cleanup process services

* [ci:force] process services cloud

* [ci:force] align coverage with all libs

* [ci:force] fix the insights
This commit is contained in:
Denys Vuika
2023-10-26 14:33:48 +01:00
committed by GitHub
parent 7ebdce7875
commit ba96ed14b2
45 changed files with 638 additions and 1224 deletions

View File

@@ -78,6 +78,7 @@ module.exports = {
accessibility: 'explicit' accessibility: 'explicit'
} }
], ],
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/prefer-optional-chain': 'warn', '@typescript-eslint/prefer-optional-chain': 'warn',
'@typescript-eslint/no-inferrable-types': 'off', '@typescript-eslint/no-inferrable-types': 'off',
'@typescript-eslint/no-require-imports': 'off', '@typescript-eslint/no-require-imports': 'off',

View File

@@ -133,7 +133,7 @@ describe('Process Task - Attach content file', () => {
await taskFormCloudComponent.formFields().checkFormIsDisplayed(); await taskFormCloudComponent.formFields().checkFormIsDisplayed();
await taskFormCloudComponent.formFields().checkWidgetIsVisible(uploadWidgetId); await taskFormCloudComponent.formFields().checkWidgetIsVisible(uploadWidgetId);
const contentUploadFileWidget = await processCloudWidget.attachFileWidgetCloud(uploadWidgetId); const contentUploadFileWidget = processCloudWidget.attachFileWidgetCloud(uploadWidgetId);
await contentUploadFileWidget.clickAttachContentFile(uploadWidgetId); await contentUploadFileWidget.clickAttachContentFile(uploadWidgetId);
await contentNodeSelectorDialog.attachFileFromContentNode(folderName, pdfFileOne.name); await contentNodeSelectorDialog.attachFileFromContentNode(folderName, pdfFileOne.name);

View File

@@ -311,7 +311,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
await taskFormCloudComponent.clickClaimButton(); await taskFormCloudComponent.clickClaimButton();
const localFileWidget = await widget.attachFileWidgetCloud('Attachlocalfile'); const localFileWidget = widget.attachFileWidgetCloud('Attachlocalfile');
await localFileWidget.clickAttachContentFile('Attachlocalfile'); await localFileWidget.clickAttachContentFile('Attachlocalfile');
await contentNodeSelectorDialogPage.attachFilesFromLocal([pdfFile]); await contentNodeSelectorDialogPage.attachFilesFromLocal([pdfFile]);
await localFileWidget.checkFileIsAttached(pdfFile.name); await localFileWidget.checkFileIsAttached(pdfFile.name);
@@ -326,7 +326,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask'); await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask');
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name); await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name);
@@ -344,7 +344,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
await taskFormCloudComponent.clickClaimButton(); await taskFormCloudComponent.clickClaimButton();
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.checkDialogIsDisplayed(); await contentNodeSelectorDialogPage.checkDialogIsDisplayed();
await expect(await breadCrumbDropdownPage.getTextOfCurrentFolder()).toBe(testUser.username); await expect(await breadCrumbDropdownPage.getTextOfCurrentFolder()).toBe(testUser.username);
@@ -369,7 +369,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
await taskFormCloudComponent.clickClaimButton(); await taskFormCloudComponent.clickClaimButton();
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.checkDialogIsDisplayed(); await contentNodeSelectorDialogPage.checkDialogIsDisplayed();
await contentNodeSelectorDialogPage.contentListPage().dataTablePage().waitTillContentLoaded(); await contentNodeSelectorDialogPage.contentListPage().dataTablePage().waitTillContentLoaded();
@@ -391,7 +391,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask'); await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask');
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name); await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name);
@@ -406,7 +406,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask'); await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask');
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name); await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name);
@@ -426,7 +426,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask'); await processDetailsCloudDemoPage.checkTaskIsDisplayed('UploadFileTask');
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name); await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name);
@@ -448,7 +448,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
await taskFormCloudComponent.clickClaimButton(); await taskFormCloudComponent.clickClaimButton();
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name); await contentNodeSelectorDialogPage.attachFileFromContentNode(folderName, testFileModel.name);
@@ -478,7 +478,7 @@ describe('Start Task Form', () => {
await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask'); await processDetailsCloudDemoPage.selectProcessTaskByName('UploadFileTask');
await taskFormCloudComponent.clickClaimButton(); await taskFormCloudComponent.clickClaimButton();
const contentFileWidget = await widget.attachFileWidgetCloud('Attachsinglecontentfile'); const contentFileWidget = widget.attachFileWidgetCloud('Attachsinglecontentfile');
await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile'); await contentFileWidget.clickAttachContentFile('Attachsinglecontentfile');
await contentNodeSelectorDialogPage.checkDialogIsDisplayed(); await contentNodeSelectorDialogPage.checkDialogIsDisplayed();
await contentNodeSelectorDialogPage.contentListPage().dataTablePage().doubleClickRowByContent(folderName); await contentNodeSelectorDialogPage.contentListPage().dataTablePage().doubleClickRowByContent(folderName);

View File

@@ -96,7 +96,7 @@ describe('Checklist component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
await taskPage.tasksListPage().selectRow(tasks[0]); await taskPage.tasksListPage().selectRow(tasks[0]);
await await taskPage.clickOnAddChecklistButton(); await taskPage.clickOnAddChecklistButton();
await taskPage.checkChecklistDialogIsDisplayed(); await taskPage.checkChecklistDialogIsDisplayed();
await expect(await taskPage.usingCheckListDialog().getDialogTitle()).toEqual('New Check'); await expect(await taskPage.usingCheckListDialog().getDialogTitle()).toEqual('New Check');
await expect(await taskPage.usingCheckListDialog().getNameFieldPlaceholder()).toEqual('Name'); await expect(await taskPage.usingCheckListDialog().getNameFieldPlaceholder()).toEqual('Name');
@@ -125,7 +125,7 @@ describe('Checklist component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[2]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[2]);
await taskPage.tasksListPage().selectRow(tasks[2]); await taskPage.tasksListPage().selectRow(tasks[2]);
await await taskPage.clickOnAddChecklistButton(); await taskPage.clickOnAddChecklistButton();
await taskPage.checkChecklistDialogIsDisplayed(); await taskPage.checkChecklistDialogIsDisplayed();
await checklistDialog.addName(removeChecklist[0]); await checklistDialog.addName(removeChecklist[0]);
await checklistDialog.clickCreateChecklistButton(); await checklistDialog.clickCreateChecklistButton();

View File

@@ -84,7 +84,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
await taskPage.tasksListPage().selectRow(tasks[0]); await taskPage.tasksListPage().selectRow(tasks[0]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
@@ -99,7 +99,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
await taskPage.tasksListPage().selectRow(tasks[0]); await taskPage.tasksListPage().selectRow(tasks[0]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await expect(await taskPage.taskDetails().getInvolvePeopleHeader()).toEqual('Add people and groups'); await expect(await taskPage.taskDetails().getInvolvePeopleHeader()).toEqual('Add people and groups');
@@ -114,7 +114,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
await taskPage.tasksListPage().selectRow(tasks[0]); await taskPage.tasksListPage().selectRow(tasks[0]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(processUserModel.firstName + ' ' + processUserModel.lastName); await taskDetails.typeUser(processUserModel.firstName + ' ' + processUserModel.lastName);
await taskDetails.noUserIsDisplayedInSearchInvolvePeople(processUserModel.firstName + ' ' + processUserModel.lastName); await taskDetails.noUserIsDisplayedInSearchInvolvePeople(processUserModel.firstName + ' ' + processUserModel.lastName);
@@ -126,7 +126,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
await taskPage.tasksListPage().selectRow(tasks[0]); await taskPage.tasksListPage().selectRow(tasks[0]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
@@ -144,7 +144,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[1]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[1]);
await taskPage.tasksListPage().selectRow(tasks[1]); await taskPage.tasksListPage().selectRow(tasks[1]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
@@ -168,7 +168,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[2]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[2]);
await taskPage.tasksListPage().selectRow(tasks[2]); await taskPage.tasksListPage().selectRow(tasks[2]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskPage.taskDetails().clickInvolvePeopleButton(); await taskPage.taskDetails().clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
@@ -179,7 +179,7 @@ describe('People component', () => {
.toEqual(assigneeUserModel.email); .toEqual(assigneeUserModel.email);
await expect(await taskPage.taskDetails().getInvolvedPeopleTitle()).toEqual(peopleTitle + '(1)'); await expect(await taskPage.taskDetails().getInvolvedPeopleTitle()).toEqual(peopleTitle + '(1)');
const taskDetails2 = await taskPage.taskDetails(); const taskDetails2 = taskPage.taskDetails();
await taskDetails2.clickInvolvePeopleButton(); await taskDetails2.clickInvolvePeopleButton();
await taskDetails2.typeUser(secondAssigneeUserModel.firstName + ' ' + secondAssigneeUserModel.lastName); await taskDetails2.typeUser(secondAssigneeUserModel.firstName + ' ' + secondAssigneeUserModel.lastName);
await taskDetails2.selectUserToInvolve(secondAssigneeUserModel.firstName + ' ' + secondAssigneeUserModel.lastName); await taskDetails2.selectUserToInvolve(secondAssigneeUserModel.firstName + ' ' + secondAssigneeUserModel.lastName);
@@ -196,7 +196,7 @@ describe('People component', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[3]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[3]);
await taskPage.tasksListPage().selectRow(tasks[3]); await taskPage.tasksListPage().selectRow(tasks[3]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.selectUserToInvolve(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);

View File

@@ -463,7 +463,7 @@ describe('Start Process Component', () => {
await processInstanceTasksPage.clickOnStartForm(); await processInstanceTasksPage.clickOnStartForm();
await processInstanceTasksPage.checkStartProcessDialogIsDisplayed(); await processInstanceTasksPage.checkStartProcessDialogIsDisplayed();
await expect(await processInstanceTasksPage.getTitle()).toBe('Start Form'); await expect(await processInstanceTasksPage.getTitle()).toBe('Start Form');
await expect(await (await widget.dateWidget()).getDateInput('testdate')).toBe('15-7-2019'); await expect(await widget.dateWidget().getDateInput('testdate')).toBe('15-7-2019');
await processInstanceTasksPage.clickCloseButton(); await processInstanceTasksPage.clickCloseButton();
await processInstanceTasksPage.checkStartProcessDialogIsNotDisplayed(); await processInstanceTasksPage.checkStartProcessDialogIsNotDisplayed();
}); });

View File

@@ -75,7 +75,7 @@ describe('Start Task - Task App', () => {
await taskPage.tasksListPage().checkContentIsDisplayed('Standalone task'); await taskPage.tasksListPage().checkContentIsDisplayed('Standalone task');
await taskPage.taskDetails().noFormIsDisplayed(); await taskPage.taskDetails().noFormIsDisplayed();
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.checkCompleteTaskButtonIsDisplayed(); await taskDetails.checkCompleteTaskButtonIsDisplayed();
await taskDetails.checkCompleteTaskButtonIsEnabled(); await taskDetails.checkCompleteTaskButtonIsEnabled();
await taskPage.taskDetails().checkAttachFormButtonIsDisplayed(); await taskPage.taskDetails().checkAttachFormButtonIsDisplayed();
@@ -110,7 +110,7 @@ describe('Start Task - Task App', () => {
await taskPage.formFields().noFormIsDisplayed(); await taskPage.formFields().noFormIsDisplayed();
await taskPage.taskDetails().clickAttachFormButton(); await taskPage.taskDetails().clickAttachFormButton();
const formFields = await taskPage.formFields(); const formFields = taskPage.formFields();
await formFields.selectForm(app.formName); await formFields.selectForm(app.formName);
await formFields.clickOnAttachFormButton(); await formFields.clickOnAttachFormButton();
@@ -122,7 +122,7 @@ describe('Start Task - Task App', () => {
it('[C268912] Should a standalone task be displayed when removing the form from APS', async () => { it('[C268912] Should a standalone task be displayed when removing the form from APS', async () => {
const task = await taskPage.createNewTask(); const task = await taskPage.createNewTask();
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await task.addName('Remove form'); await task.addName('Remove form');
await task.selectForm(app.formName); await task.selectForm(app.formName);
await task.clickStartButton(); await task.clickStartButton();

View File

@@ -73,7 +73,7 @@ describe('Start Task - Custom App', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);

View File

@@ -80,7 +80,7 @@ describe('Start Task - Task App', () => {
await task.selectForm(app.formName); await task.selectForm(app.formName);
await task.clickStartButton(); await task.clickStartButton();
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[0]);
const taskDetails = await taskPage.taskDetails(); const taskDetails = taskPage.taskDetails();
await taskDetails.clickInvolvePeopleButton(); await taskDetails.clickInvolvePeopleButton();
await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName); await taskDetails.typeUser(assigneeUserModel.firstName + ' ' + assigneeUserModel.lastName);
@@ -126,7 +126,7 @@ describe('Start Task - Task App', () => {
await taskPage.tasksListPage().checkContentIsDisplayed(tasks[4]); await taskPage.tasksListPage().checkContentIsDisplayed(tasks[4]);
const formFields = await taskPage.formFields(); const formFields = taskPage.formFields();
const formFieldValue = 'First value '; const formFieldValue = 'First value ';
await formFields.setFieldValue(formTextField, formFieldValue); await formFields.setFieldValue(formTextField, formFieldValue);

View File

@@ -72,26 +72,27 @@ describe('NodeAspectService', () => {
expect(nodeApiService.updateNode).toHaveBeenCalledWith('fake-node-id', expectedParameters); expect(nodeApiService.updateNode).toHaveBeenCalledWith('fake-node-id', expectedParameters);
}); });
it('should send and update node event once the node has been updated', async () => { it('should send and update node event once the node has been updated', () => {
await nodeApiService.nodeUpdated.subscribe((nodeUpdated) => { let lastValue: Node;
expect(nodeUpdated.id).toBe('fake-node-id'); nodeApiService.nodeUpdated.subscribe((nodeUpdated) => lastValue = nodeUpdated);
expect(nodeUpdated.aspectNames).toEqual(['a', 'b', 'c']);
});
const fakeNode = new Node({ id: 'fake-node-id', aspectNames: ['a', 'b', 'c'] }); const fakeNode = new Node({ id: 'fake-node-id', aspectNames: ['a', 'b', 'c'] });
spyOn(dialogAspectListService, 'openAspectListDialog').and.returnValue(of(['a', 'b', 'c'])); spyOn(dialogAspectListService, 'openAspectListDialog').and.returnValue(of(['a', 'b', 'c']));
spyOn(nodeApiService, 'updateNode').and.returnValue(of(fakeNode)); spyOn(nodeApiService, 'updateNode').and.returnValue(of(fakeNode));
nodeAspectService.updateNodeAspects('fake-node-id'); nodeAspectService.updateNodeAspects('fake-node-id');
expect(lastValue.id).toBe('fake-node-id');
expect(lastValue.aspectNames).toEqual(['a', 'b', 'c']);
}); });
it('should send and update node aspect once the node has been updated', async () => { it('should send and update node aspect once the node has been updated', () => {
await cardViewContentUpdateService.updatedAspect$.subscribe((nodeUpdated) => { let lastValue: Node;
expect(nodeUpdated.id).toBe('fake-node-id'); cardViewContentUpdateService.updatedAspect$.subscribe((nodeUpdated) => lastValue = nodeUpdated);
expect(nodeUpdated.aspectNames).toEqual(['a', 'b', 'c']);
});
const fakeNode = new Node({ id: 'fake-node-id', aspectNames: ['a', 'b', 'c'] }); const fakeNode = new Node({ id: 'fake-node-id', aspectNames: ['a', 'b', 'c'] });
spyOn(dialogAspectListService, 'openAspectListDialog').and.returnValue(of(['a', 'b', 'c'])); spyOn(dialogAspectListService, 'openAspectListDialog').and.returnValue(of(['a', 'b', 'c']));
spyOn(nodeApiService, 'updateNode').and.returnValue(of(fakeNode)); spyOn(nodeApiService, 'updateNode').and.returnValue(of(fakeNode));
nodeAspectService.updateNodeAspects('fake-node-id'); nodeAspectService.updateNodeAspects('fake-node-id');
expect(lastValue.id).toBe('fake-node-id');
expect(lastValue.aspectNames).toEqual(['a', 'b', 'c']);
}); });
it('should call emit on refresh from TagService', () => { it('should call emit on refresh from TagService', () => {

View File

@@ -126,7 +126,7 @@ describe('PeopleContentService', () => {
await peopleContentService.getCurrentUserInfo().toPromise(); await peopleContentService.getCurrentUserInfo().toPromise();
expect(await peopleContentService.isCurrentUserAdmin()).toBe(true); expect(peopleContentService.isCurrentUserAdmin()).toBe(true);
expect(getCurrentPersonSpy.calls.count()).toEqual(1); expect(getCurrentPersonSpy.calls.count()).toEqual(1);
}); });

View File

@@ -127,14 +127,14 @@ describe('ContentNodeSelectorPanelComponent', () => {
component.currentFolderId = 'fake-starting-folder'; component.currentFolderId = 'fake-starting-folder';
}); });
it('should trigger siteChange event on init with parent site Title of start folder', async () => { it('should trigger siteChange event on init with parent site Title of start folder', () => {
await component.siteChange.subscribe((siteTitle: string) => { let lastValue: string;
expect(siteTitle).toBe('fake-site'); component.siteChange.subscribe((siteTitle: string) => lastValue = siteTitle);
});
component.ngOnInit(); component.ngOnInit();
fixture.detectChanges(); fixture.detectChanges();
expect(component.startSiteGuid).toBe('fake-site'); expect(component.startSiteGuid).toBe('fake-site');
expect(lastValue).toBe('fake-site');
}); });
it('should trigger siteChange event when a site is selected in sites-dropdown', async () => { it('should trigger siteChange event when a site is selected in sites-dropdown', async () => {
@@ -142,12 +142,12 @@ describe('ContentNodeSelectorPanelComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
await component.siteChange.subscribe((siteTitle: string) => { let lastValue: string;
expect(siteTitle).toBe('fake-new-site'); component.siteChange.subscribe((siteTitle: string) => lastValue = siteTitle);
});
const sitesDropdown = fixture.debugElement.query(By.directive(DropdownSitesComponent)); const sitesDropdown = fixture.debugElement.query(By.directive(DropdownSitesComponent));
sitesDropdown.componentInstance.selectedSite({ value: fakeSiteEntry }); sitesDropdown.componentInstance.selectedSite({ value: fakeSiteEntry });
expect(lastValue).toBe('fake-new-site');
}); });
}); });
@@ -177,14 +177,14 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(component.documentList.sortingMode).toBe('server'); expect(component.documentList.sortingMode).toBe('server');
}); });
it('should trigger the select event when selection has been made', async () => { it('should trigger the select event when selection has been made', () => {
const expectedNode = { id: 'fakeid' } as Node; const expectedNode = { id: 'fakeid' } as Node;
await component.select.subscribe((nodes) => { let lastValue: Node[];
expect(nodes.length).toBe(1); component.select.subscribe((nodes) => lastValue = nodes);
expect(nodes[0]).toBe(expectedNode);
});
component.chosenNode = [expectedNode]; component.chosenNode = [expectedNode];
expect(lastValue.length).toBe(1);
expect(lastValue[0]).toBe(expectedNode);
}); });
it('should be able to filter out the exclude site content', () => { it('should be able to filter out the exclude site content', () => {

View File

@@ -56,7 +56,7 @@ describe('FileAutoDownloadComponent', () => {
const waitButton = getButton('#cancelButton'); const waitButton = getButton('#cancelButton');
waitButton.dispatchEvent(new Event('click')); waitButton.dispatchEvent(new Event('click'));
await fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
expect(matDialogRef.close).toHaveBeenCalled(); expect(matDialogRef.close).toHaveBeenCalled();
@@ -66,7 +66,7 @@ describe('FileAutoDownloadComponent', () => {
const waitButton = getButton('#downloadButton'); const waitButton = getButton('#downloadButton');
waitButton.dispatchEvent(new Event('click')); waitButton.dispatchEvent(new Event('click'));
await fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
expect(matDialogRef.close).toHaveBeenCalled(); expect(matDialogRef.close).toHaveBeenCalled();

View File

@@ -23,6 +23,7 @@ import { of } from 'rxjs';
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { ContentTestingModule } from '../../testing/content.testing.module'; import { ContentTestingModule } from '../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { PermissionModel } from '../models/permissions.model';
describe('DocumentActionsService', () => { describe('DocumentActionsService', () => {
@@ -94,17 +95,18 @@ describe('DocumentActionsService', () => {
expect(service.getHandler('delete')).toBeDefined(); expect(service.getHandler('delete')).toBeDefined();
}); });
it('should not delete the file node if there are no permissions', async () => { it('should not delete the file node if there are no permissions', () => {
spyOn(documentListService, 'deleteNode').and.returnValue(of(true)); spyOn(documentListService, 'deleteNode').and.returnValue(of(true));
await service.permissionEvent.subscribe((permission) => { let lastValue: PermissionModel;
expect(permission).toBeDefined(); service.permissionEvent.subscribe((permission) => lastValue = permission);
expect(permission.type).toEqual('content');
expect(permission.action).toEqual('delete');
});
const file = new FileNode(); const file = new FileNode();
service.getHandler('delete')(file); service.getHandler('delete')(file);
expect(lastValue).toBeDefined();
expect(lastValue.type).toEqual('content');
expect(lastValue.action).toEqual('delete');
}); });
it('should call the error on the returned Observable if there are no permissions', async () => { it('should call the error on the returned Observable if there are no permissions', async () => {
@@ -132,20 +134,21 @@ describe('DocumentActionsService', () => {
expect(documentListService.deleteNode).toHaveBeenCalledWith(file.entry.id); expect(documentListService.deleteNode).toHaveBeenCalledWith(file.entry.id);
}); });
it('should not delete the file node if there is no delete permission', async () => { it('should not delete the file node if there is no delete permission', () => {
spyOn(documentListService, 'deleteNode').and.callThrough(); spyOn(documentListService, 'deleteNode').and.callThrough();
await service.permissionEvent.subscribe((permissionBack) => { let lastValue: PermissionModel;
expect(permissionBack).toBeDefined(); service.permissionEvent.subscribe((permissionBack) => lastValue = permissionBack);
expect(permissionBack.type).toEqual('content');
expect(permissionBack.action).toEqual('delete');
});
const permission = 'delete'; const permission = 'delete';
const file = new FileNode(); const file = new FileNode();
const fileWithPermission: any = file; const fileWithPermission: any = file;
fileWithPermission.entry.allowableOperations = ['create', 'update']; fileWithPermission.entry.allowableOperations = ['create', 'update'];
service.getHandler('delete')(fileWithPermission, null, permission); service.getHandler('delete')(fileWithPermission, null, permission);
expect(lastValue).toBeDefined();
expect(lastValue.type).toEqual('content');
expect(lastValue.action).toEqual('delete');
}); });
it('should delete the file node if there is the delete and others permission ', () => { it('should delete the file node if there is the delete and others permission ', () => {
@@ -202,10 +205,9 @@ describe('DocumentActionsService', () => {
expect(documentListService.deleteNode).not.toHaveBeenCalled(); expect(documentListService.deleteNode).not.toHaveBeenCalled();
}); });
it('should emit success event upon node deletion', async () => { it('should emit success event upon node deletion', () => {
await service.success.subscribe((message) => { let lastValue: string;
expect(message).toEqual('CORE.DELETE_NODE.SINGULAR'); service.success.subscribe((message) => lastValue = message);
});
spyOn(documentListService, 'deleteNode').and.returnValue(of(true)); spyOn(documentListService, 'deleteNode').and.returnValue(of(true));
const target = jasmine.createSpyObj('obj', ['reload']); const target = jasmine.createSpyObj('obj', ['reload']);
@@ -214,5 +216,6 @@ describe('DocumentActionsService', () => {
const fileWithPermission: any = file; const fileWithPermission: any = file;
fileWithPermission.entry.allowableOperations = [permission]; fileWithPermission.entry.allowableOperations = [permission];
service.getHandler('delete')(fileWithPermission, target, permission); service.getHandler('delete')(fileWithPermission, target, permission);
expect(lastValue).toEqual('CORE.DELETE_NODE.SINGULAR');
}); });
}); });

View File

@@ -31,9 +31,9 @@ import { ContentNodeDialogService } from '../../content-node-selector/content-no
}) })
export class DocumentActionsService { export class DocumentActionsService {
permissionEvent: Subject<PermissionModel> = new Subject<PermissionModel>(); permissionEvent = new Subject<PermissionModel>();
error: Subject<Error> = new Subject<Error>(); error = new Subject<Error>();
success: Subject<string> = new Subject<string>(); success = new Subject<string>();
private handlers: { [id: string]: ContentActionHandler } = {}; private handlers: { [id: string]: ContentActionHandler } = {};
@@ -113,7 +113,7 @@ export class DocumentActionsService {
return actionObservable; return actionObservable;
} }
private prepareHandlers(actionObservable): void { private prepareHandlers(actionObservable: Subject<string>): void {
actionObservable.subscribe( actionObservable.subscribe(
(fileOperationMessage) => { (fileOperationMessage) => {
this.success.next(fileOperationMessage); this.success.next(fileOperationMessage);

View File

@@ -24,6 +24,7 @@ import { DocumentListService } from './document-list.service';
import { FolderActionsService } from './folder-actions.service'; import { FolderActionsService } from './folder-actions.service';
import { ContentTestingModule } from '../../testing/content.testing.module'; import { ContentTestingModule } from '../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { PermissionModel } from '../models/permissions.model';
describe('FolderActionsService', () => { describe('FolderActionsService', () => {
@@ -87,17 +88,17 @@ describe('FolderActionsService', () => {
expect(service.getHandler('delete')).toBeDefined(); expect(service.getHandler('delete')).toBeDefined();
}); });
it('should not delete the folder node if there are no permissions', async () => { it('should not delete the folder node if there are no permissions', () => {
spyOn(documentListService, 'deleteNode').and.callThrough(); spyOn(documentListService, 'deleteNode').and.callThrough();
await service.permissionEvent.subscribe((permission) => { let lastValue: PermissionModel;
expect(permission).toBeDefined(); service.permissionEvent.subscribe((permission) => lastValue = permission);
expect(permission.type).toEqual('folder');
expect(permission.action).toEqual('delete');
});
const folder = new FolderNode(); const folder = new FolderNode();
service.getHandler('delete')(folder); service.getHandler('delete')(folder);
expect(lastValue).toBeDefined();
expect(lastValue.type).toEqual('folder');
expect(lastValue.action).toEqual('delete');
}); });
it('should delete the folder node if there is the delete permission', () => { it('should delete the folder node if there is the delete permission', () => {
@@ -116,22 +117,22 @@ describe('FolderActionsService', () => {
expect(deleteObservable.subscribe).toBeDefined(); expect(deleteObservable.subscribe).toBeDefined();
}); });
it('should not delete the folder node if there is no delete permission', async () => { it('should not delete the folder node if there is no delete permission', () => {
spyOn(documentListService, 'deleteNode').and.callFake(() => new Observable<any>((observer) => { spyOn(documentListService, 'deleteNode').and.callFake(() => new Observable<any>((observer) => {
observer.next(); observer.next();
observer.complete(); observer.complete();
})); }));
await service.permissionEvent.subscribe((permission) => { let lastValue: PermissionModel;
expect(permission).toBeDefined(); service.permissionEvent.subscribe((permission) => lastValue = permission);
expect(permission.type).toEqual('folder');
expect(permission.action).toEqual('delete');
});
const folder = new FolderNode(); const folder = new FolderNode();
const folderWithPermission: any = folder; const folderWithPermission: any = folder;
folderWithPermission.entry.allowableOperations = ['create', 'update']; folderWithPermission.entry.allowableOperations = ['create', 'update'];
service.getHandler('delete')(folderWithPermission); service.getHandler('delete')(folderWithPermission);
expect(lastValue).toBeDefined();
expect(lastValue.type).toEqual('folder');
expect(lastValue.action).toEqual('delete');
}); });
it('should call the error on the returned Observable if there is no delete permission', async () => { it('should call the error on the returned Observable if there is no delete permission', async () => {
@@ -219,15 +220,14 @@ describe('FolderActionsService', () => {
expect(documentListService.deleteNode).toHaveBeenCalled(); expect(documentListService.deleteNode).toHaveBeenCalled();
}); });
it('should emit success event upon node deletion', async () => { it('should emit success event upon node deletion', () => {
spyOn(documentListService, 'deleteNode').and.callFake(() => new Observable<any>((observer) => { spyOn(documentListService, 'deleteNode').and.callFake(() => new Observable<any>((observer) => {
observer.next(); observer.next();
observer.complete(); observer.complete();
})); }));
await service.success.subscribe((nodeId) => { let lastValue: string;
expect(nodeId).not.toBeNull(); service.success.subscribe((nodeId) => lastValue = nodeId);
});
const permission = 'delete'; const permission = 'delete';
const target = jasmine.createSpyObj('obj', ['reload']); const target = jasmine.createSpyObj('obj', ['reload']);
@@ -236,5 +236,6 @@ describe('FolderActionsService', () => {
folderWithPermission.entry.allowableOperations = [permission]; folderWithPermission.entry.allowableOperations = [permission];
service.getHandler('delete')(folderWithPermission, target, permission); service.getHandler('delete')(folderWithPermission, target, permission);
expect(lastValue).not.toBeNull();
}); });
}); });

View File

@@ -30,9 +30,9 @@ import { NodeActionsService } from './node-actions.service';
}) })
export class FolderActionsService { export class FolderActionsService {
permissionEvent: Subject<PermissionModel> = new Subject<PermissionModel>(); permissionEvent = new Subject<PermissionModel>();
error: Subject<Error> = new Subject<Error>(); error = new Subject<Error>();
success: Subject<string> = new Subject<string>(); success = new Subject<string>();
private handlers: { [id: string]: ContentActionHandler } = {}; private handlers: { [id: string]: ContentActionHandler } = {};

View File

@@ -86,15 +86,15 @@ describe('AddPermissionComponent', () => {
fixture.componentInstance.selectedItems = fakeAuthorityResults; fixture.componentInstance.selectedItems = fakeAuthorityResults;
spyOn(nodePermissionService, 'updateNodePermissions').and.returnValue(of(new Node({ id: 'fake-node-id'}))); spyOn(nodePermissionService, 'updateNodePermissions').and.returnValue(of(new Node({ id: 'fake-node-id'})));
await fixture.componentInstance.success.subscribe((node) => { let lastValue: Node;
expect(node.id).toBe('fake-node-id'); fixture.componentInstance.success.subscribe((node) => lastValue = node);
});
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
const addButton = element.querySelector<HTMLButtonElement>('#adf-add-permission-action-button'); const addButton = element.querySelector<HTMLButtonElement>('#adf-add-permission-action-button');
addButton.click(); addButton.click();
expect(lastValue.id).toBe('fake-node-id');
}); });
it('should NOT emit a success event when the user does not have permission to update the node', () => { it('should NOT emit a success event when the user does not have permission to update the node', () => {
@@ -111,13 +111,15 @@ describe('AddPermissionComponent', () => {
fixture.componentInstance.selectedItems = fakeAuthorityResults; fixture.componentInstance.selectedItems = fakeAuthorityResults;
spyOn(nodePermissionService, 'updateNodePermissions').and.returnValue(throwError({ error: 'err'})); spyOn(nodePermissionService, 'updateNodePermissions').and.returnValue(throwError({ error: 'err'}));
await fixture.componentInstance.error.subscribe((error) => { let lastValue: any;
expect(error.error).toBe('err'); fixture.componentInstance.error.subscribe((error) => lastValue = error);
});
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
const addButton = element.querySelector<HTMLButtonElement>('#adf-add-permission-action-button'); const addButton = element.querySelector<HTMLButtonElement>('#adf-add-permission-action-button');
addButton.click(); addButton.click();
expect(lastValue.error).toBe('err');
}); });
}); });

View File

@@ -39,11 +39,11 @@ export class AddPermissionComponent implements OnInit {
/** Emitted when the node is updated successfully. */ /** Emitted when the node is updated successfully. */
@Output() @Output()
success: EventEmitter<Node> = new EventEmitter(); success = new EventEmitter<Node>();
/** Emitted when an error occurs during the update. */ /** Emitted when an error occurs during the update. */
@Output() @Output()
error: EventEmitter<any> = new EventEmitter(); error = new EventEmitter<any>();
selectedItems: NodeEntry[] = []; selectedItems: NodeEntry[] = [];
currentNode: Node; currentNode: Node;

View File

@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { LogService, UserPreferencesService } from '@alfresco/adf-core'; import { UserPreferencesService } from '@alfresco/adf-core';
import { TagService } from './tag.service'; import { TagService } from './tag.service';
import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { ContentTestingModule } from '../../testing/content.testing.module'; import { ContentTestingModule } from '../../testing/content.testing.module';
@@ -25,8 +25,8 @@ import { Pagination, Tag, TagBody, TagEntry, TagPaging, TagPagingList } from '@a
describe('TagService', () => { describe('TagService', () => {
let service: TagService; let service: TagService;
let logService: LogService;
let userPreferencesService: UserPreferencesService; let userPreferencesService: UserPreferencesService;
let tagEntry: TagEntry;
const mockTagPaging = (): TagPaging => { const mockTagPaging = (): TagPaging => {
const tagPaging = new TagPaging(); const tagPaging = new TagPaging();
@@ -45,17 +45,19 @@ describe('TagService', () => {
imports: [TranslateModule.forRoot(), ContentTestingModule] imports: [TranslateModule.forRoot(), ContentTestingModule]
}); });
service = TestBed.inject(TagService); service = TestBed.inject(TagService);
logService = TestBed.inject(LogService);
userPreferencesService = TestBed.inject(UserPreferencesService); userPreferencesService = TestBed.inject(UserPreferencesService);
tagEntry = new TagEntry({ entry: { id: '1', tag: 'test-tag' } });
spyOn(service.tagsApi, 'deleteTagFromNode').and.returnValue(Promise.resolve()); spyOn(service.tagsApi, 'deleteTagFromNode').and.returnValue(Promise.resolve());
spyOn(service.tagsApi, 'createTagForNode').and.returnValue(Promise.resolve(new TagEntry({}))); spyOn(service.tagsApi, 'createTagForNode').and.returnValue(Promise.resolve(tagEntry));
spyOn(service.tagsApi, 'deleteTag').and.returnValue(Promise.resolve());
}); });
describe('Content tests', () => { describe('Content tests', () => {
it('should catch errors on getTagsByNodeId call', async () => { it('should catch errors on getTagsByNodeId call', async () => {
spyOn(service, 'getTagsByNodeId').and.returnValue(throwError({ error: 'error' })); spyOn(service, 'getTagsByNodeId').and.returnValue(throwError({ error: 'error' }));
await service.getTagsByNodeId('fake-node-id').subscribe( service.getTagsByNodeId('fake-node-id').subscribe(
() => { () => {
throwError('This call should fail'); throwError('This call should fail');
}, },
@@ -66,31 +68,28 @@ describe('TagService', () => {
}); });
it('should trigger a refresh event on removeTag() call', async () => { it('should trigger a refresh event on removeTag() call', async () => {
await service.refresh.subscribe(() => {
expect(service.tagsApi.deleteTagFromNode).toHaveBeenCalledWith('fake-node-id', 'fake-tag');
});
service.removeTag('fake-node-id', 'fake-tag'); service.removeTag('fake-node-id', 'fake-tag');
expect(service.tagsApi.deleteTagFromNode).toHaveBeenCalledWith('fake-node-id', 'fake-tag');
}); });
it('should trigger a refresh event on addTag() call', async () => { it('should trigger a refresh event on addTag() call', async () => {
await service.refresh.subscribe((res) => { let lastValue: any;
expect(res).toBeDefined(); service.refresh.subscribe((res) => lastValue = res);
});
service.addTag('fake-node-id', 'fake-tag'); await service.addTag('fake-node-id', 'fake-tag').toPromise();
expect(lastValue).toBe(tagEntry);
}); });
it('should trigger a refresh event on deleteTag() call', async () => { it('should trigger a refresh event on deleteTag() call', async () => {
await service.refresh.subscribe((res) => { let lastValue = false;
expect(res).toBeDefined(); service.refresh.subscribe(() => lastValue = true);
});
service.deleteTag('fake-tag-id'); await service.deleteTag('fake-tag-id').toPromise();
expect(lastValue).toBeTrue();
}); });
describe('createTags', () => { describe('createTags', () => {
it('should call createTags on tagsApi', (done) => { it('should call createTags on tagsApi', () => {
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve([])); spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve([]));
const tag1 = new TagBody(); const tag1 = new TagBody();
tag1.tag = 'Some tag 1'; tag1.tag = 'Some tag 1';
@@ -100,10 +99,9 @@ describe('TagService', () => {
service.createTags(tags); service.createTags(tags);
expect(service.tagsApi.createTags).toHaveBeenCalledWith(tags); expect(service.tagsApi.createTags).toHaveBeenCalledWith(tags);
done();
}); });
it('should emit refresh when tags creation is success', fakeAsync(() => { it('should emit refresh when tags creation is success', async () => {
const tags: TagEntry[] = [ const tags: TagEntry[] = [
{ {
entry: { entry: {
@@ -114,19 +112,10 @@ describe('TagService', () => {
]; ];
spyOn(service.refresh, 'emit'); spyOn(service.refresh, 'emit');
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve(tags)); spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve(tags));
service.createTags([]);
tick();
expect(service.refresh.emit).toHaveBeenCalledWith(tags);
}));
it('should call error on logService when error occurs during tags creation', fakeAsync(() => { await service.createTags([]).toPromise();
spyOn(logService, 'error'); expect(service.refresh.emit).toHaveBeenCalledWith(tags);
const error = 'Some error'; });
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.reject(error));
service.createTags([]);
tick();
expect(logService.error).toHaveBeenCalledWith(error);
}));
}); });
describe('getAllTheTags', () => { describe('getAllTheTags', () => {
@@ -176,18 +165,6 @@ describe('TagService', () => {
}); });
tick(); tick();
})); }));
it('should call error on logService when error occurs during fetching paging object for tags', fakeAsync(() => {
spyOn(logService, 'error');
const error: string = 'Some error';
spyOn(service.tagsApi, 'listTags').and.returnValue(Promise.reject(error));
service.getAllTheTags().subscribe({
error: () => {
expect(logService.error).toHaveBeenCalledWith(error);
}
});
tick();
}));
}); });
describe('searchTags', () => { describe('searchTags', () => {
@@ -247,18 +224,6 @@ describe('TagService', () => {
}); });
tick(); tick();
})); }));
it('should call error on logService when error occurs during fetching paging object for tags', fakeAsync(() => {
spyOn(logService, 'error');
const error: string = 'Some error';
spyOn(service.tagsApi, 'listTags').and.returnValue(Promise.reject(error));
service.searchTags('test').subscribe({
error: () => {
expect(logService.error).toHaveBeenCalledWith(error);
}
});
tick();
}));
}); });
describe('updateTag', () => { describe('updateTag', () => {
@@ -283,22 +248,12 @@ describe('TagService', () => {
expect(service.tagsApi.updateTag).toHaveBeenCalledWith(tag.entry.id, tagBody); expect(service.tagsApi.updateTag).toHaveBeenCalledWith(tag.entry.id, tagBody);
}); });
it('should emit refresh when tag updated successfully', fakeAsync(() => { it('should emit refresh when tag updated successfully', async () => {
spyOn(service.refresh, 'emit'); spyOn(service.refresh, 'emit');
spyOn(service.tagsApi, 'updateTag').and.returnValue(Promise.resolve(updatedTag)); spyOn(service.tagsApi, 'updateTag').and.returnValue(Promise.resolve(updatedTag));
service.updateTag(tag.entry.id, tagBody); await service.updateTag(tag.entry.id, tagBody).toPromise();
tick();
expect(service.refresh.emit).toHaveBeenCalledWith(updatedTag); expect(service.refresh.emit).toHaveBeenCalledWith(updatedTag);
})); });
it('should call error on logService when error occurs during tag update', fakeAsync(() => {
spyOn(logService, 'error');
const error = 'Some error';
spyOn(service.tagsApi, 'updateTag').and.returnValue(Promise.reject(error));
service.updateTag(tag.entry.id, tagBody);
tick();
expect(logService.error).toHaveBeenCalledWith(error);
}));
}); });
describe('findTagByName', () => { describe('findTagByName', () => {
@@ -334,19 +289,6 @@ describe('TagService', () => {
done(); done();
}); });
}); });
it('should call error on logService when error occurs during fetching tag for name', fakeAsync(() => {
spyOn(logService, 'error');
const error = 'Some error';
spyOn(service.tagsApi, 'listTags').and.returnValue(Promise.reject(error));
service.findTagByName(tagName).subscribe({
error: () => {
expect(logService.error).toHaveBeenCalledWith(error);
}
});
tick();
}));
}); });
describe('assignTagsToNode', () => { describe('assignTagsToNode', () => {

View File

@@ -15,17 +15,16 @@
* limitations under the License. * limitations under the License.
*/ */
import { AlfrescoApiService, LogService, UserPreferencesService } from '@alfresco/adf-core'; import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core';
import { EventEmitter, Injectable, Output } from '@angular/core'; import { EventEmitter, Injectable, Output } from '@angular/core';
import { from, Observable, throwError } from 'rxjs'; import { from, Observable } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators'; import { map, tap } from 'rxjs/operators';
import { TagBody, TagEntry, TagPaging, TagsApi } from '@alfresco/js-api'; import { TagBody, TagEntry, TagPaging, TagsApi } from '@alfresco/js-api';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class TagService { export class TagService {
private _tagsApi: TagsApi; private _tagsApi: TagsApi;
get tagsApi(): TagsApi { get tagsApi(): TagsApi {
this._tagsApi = this._tagsApi ?? new TagsApi(this.apiService.getInstance()); this._tagsApi = this._tagsApi ?? new TagsApi(this.apiService.getInstance());
@@ -36,10 +35,7 @@ export class TagService {
@Output() @Output()
refresh = new EventEmitter(); refresh = new EventEmitter();
constructor(private apiService: AlfrescoApiService, constructor(private apiService: AlfrescoApiService, private userPreferencesService: UserPreferencesService) {}
private logService: LogService,
private userPreferencesService: UserPreferencesService) {
}
/** /**
* Gets a list of tags added to a node. * Gets a list of tags added to a node.
@@ -48,9 +44,7 @@ export class TagService {
* @returns TagPaging object (defined in JS-API) containing the tags * @returns TagPaging object (defined in JS-API) containing the tags
*/ */
getTagsByNodeId(nodeId: string): Observable<TagPaging> { getTagsByNodeId(nodeId: string): Observable<TagPaging> {
return from(this.tagsApi.listTagsForNode(nodeId)).pipe( return from(this.tagsApi.listTagsForNode(nodeId));
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -61,10 +55,12 @@ export class TagService {
* @returns TagPaging object (defined in JS-API) containing the tags * @returns TagPaging object (defined in JS-API) containing the tags
*/ */
getAllTheTags(opts?: any, includedCounts?: boolean): Observable<TagPaging> { getAllTheTags(opts?: any, includedCounts?: boolean): Observable<TagPaging> {
return from(this.tagsApi.listTags({ return from(
include: includedCounts ? ['count'] : undefined, this.tagsApi.listTags({
...opts include: includedCounts ? ['count'] : undefined,
})).pipe(catchError((err) => this.handleError(err))); ...opts
})
);
} }
/** /**
@@ -78,15 +74,7 @@ export class TagService {
const tagBody = new TagBody(); const tagBody = new TagBody();
tagBody.tag = tagName; tagBody.tag = tagName;
const observableAdd = from(this.tagsApi.createTagForNode(nodeId, [tagBody])); return from(this.tagsApi.createTagForNode(nodeId, [tagBody])).pipe(tap((tagEntry) => this.refresh.emit(tagEntry)));
observableAdd.subscribe((tagEntry: TagEntry) => {
this.refresh.emit(tagEntry);
}, (err) => {
this.handleError(err);
});
return observableAdd;
} }
/** /**
@@ -97,15 +85,7 @@ export class TagService {
* @returns Null object when the operation completes * @returns Null object when the operation completes
*/ */
removeTag(nodeId: string, tag: string): Observable<void> { removeTag(nodeId: string, tag: string): Observable<void> {
const observableRemove = from(this.tagsApi.deleteTagFromNode(nodeId, tag)); return from(this.tagsApi.deleteTagFromNode(nodeId, tag)).pipe(tap(() => this.refresh.emit()));
observableRemove.subscribe(() => {
this.refresh.emit();
}, (err) => {
this.handleError(err);
});
return observableRemove;
} }
/** /**
@@ -115,12 +95,7 @@ export class TagService {
* @returns Created tags. * @returns Created tags.
*/ */
createTags(tags: TagBody[]): Observable<TagEntry[]> { createTags(tags: TagBody[]): Observable<TagEntry[]> {
const observableAdd$: Observable<TagEntry[]> = from(this.tagsApi.createTags(tags)); return from(this.tagsApi.createTags(tags)).pipe(tap((tagEntries) => this.refresh.emit(tagEntries)));
observableAdd$.subscribe(
(tagsEntries: TagEntry[]) => this.refresh.emit(tagsEntries),
(err) => this.handleError(err)
);
return observableAdd$;
} }
/** /**
@@ -131,12 +106,7 @@ export class TagService {
* @returns Updated tag. * @returns Updated tag.
*/ */
updateTag(tagId: string, tagBody: TagBody): Observable<TagEntry> { updateTag(tagId: string, tagBody: TagBody): Observable<TagEntry> {
const observableUpdate$: Observable<TagEntry> = from(this.tagsApi.updateTag(tagId, tagBody)); return from(this.tagsApi.updateTag(tagId, tagBody)).pipe(tap((tagEntry) => this.refresh.emit(tagEntry)));
observableUpdate$.subscribe(
(tagEntry: TagEntry) => this.refresh.emit(tagEntry),
(err) => this.handleError(err)
);
return observableUpdate$;
} }
/** /**
@@ -150,16 +120,24 @@ export class TagService {
* @param maxItems Specify max number of returned tags. Default is specified by UserPreferencesService. * @param maxItems Specify max number of returned tags. Default is specified by UserPreferencesService.
* @returns Found tags which name contains searched name. * @returns Found tags which name contains searched name.
*/ */
searchTags(name: string, sorting = { orderBy: 'tag', direction: 'asc' }, searchTags(
includedCounts?: boolean, skipCount = 0, maxItems?: number): Observable<TagPaging> { name: string,
sorting = { orderBy: 'tag', direction: 'asc' },
includedCounts?: boolean,
skipCount = 0,
maxItems?: number
): Observable<TagPaging> {
maxItems = maxItems || this.userPreferencesService.paginationSize; maxItems = maxItems || this.userPreferencesService.paginationSize;
return this.getAllTheTags({ return this.getAllTheTags(
tag: `*${name}*`, {
skipCount, tag: `*${name}*`,
maxItems, skipCount,
sorting, maxItems,
matching: true sorting,
}, includedCounts).pipe(catchError((err) => this.handleError(err))); matching: true
},
includedCounts
);
} }
/** /**
@@ -169,10 +147,7 @@ export class TagService {
* @returns Found tag which name matches exactly to passed name. * @returns Found tag which name matches exactly to passed name.
*/ */
findTagByName(name: string): Observable<TagEntry> { findTagByName(name: string): Observable<TagEntry> {
return this.getAllTheTags({ tag: name }).pipe( return this.getAllTheTags({ tag: name }).pipe(map((result) => result.list.entries[0]));
map((result) => result.list.entries[0]),
catchError((error) => this.handleError(error))
);
} }
/** /**
@@ -184,9 +159,7 @@ export class TagService {
* @returns Null object when the operation completes * @returns Null object when the operation completes
*/ */
deleteTag(tagId: string): Observable<void> { deleteTag(tagId: string): Observable<void> {
return from(this.tagsApi.deleteTag(tagId)).pipe( return from(this.tagsApi.deleteTag(tagId)).pipe(tap(() => this.refresh.emit()));
tap((data) => this.refresh.emit(data))
);
} }
/** /**
@@ -197,13 +170,6 @@ export class TagService {
* @returns Just linked tags to node or single tag if linked only one tag. * @returns Just linked tags to node or single tag if linked only one tag.
*/ */
assignTagsToNode(nodeId: string, tags: TagBody[]): Observable<TagPaging | TagEntry> { assignTagsToNode(nodeId: string, tags: TagBody[]): Observable<TagPaging | TagEntry> {
return from(this.tagsApi.assignTagsToNode(nodeId, tags)).pipe( return from(this.tagsApi.assignTagsToNode(nodeId, tags)).pipe(tap((data) => this.refresh.emit(data)));
tap((data) => this.refresh.emit(data))
);
}
private handleError(error: any) {
this.logService.error(error);
return throwError(error || 'Server error');
} }
} }

View File

@@ -146,7 +146,7 @@ describe('UploadButtonComponent', () => {
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled(); expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
}); });
it('should create a folder and emit an File uploaded event', async () => { it('should create a folder and emit an File uploaded event', () => {
component.rootFolderId = '-my-'; component.rootFolderId = '-my-';
spyOn(nodesApiService, 'getNode').and.returnValue(of(fakeFolderNodeWithPermission.entry)); spyOn(nodesApiService, 'getNode').and.returnValue(of(fakeFolderNodeWithPermission.entry));
@@ -154,9 +154,8 @@ describe('UploadButtonComponent', () => {
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) }); component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });
fixture.detectChanges(); fixture.detectChanges();
await component.success.subscribe((e) => { let lastValue: any;
expect(e.value).toEqual('File uploaded'); component.success.subscribe((res) => lastValue = res);
});
spyOn(component, 'uploadFiles').and.callFake(() => { spyOn(component, 'uploadFiles').and.callFake(() => {
component.success.emit({ component.success.emit({
@@ -164,6 +163,7 @@ describe('UploadButtonComponent', () => {
}); });
}); });
component.onDirectoryAdded(fakeEvent); component.onDirectoryAdded(fakeEvent);
expect(lastValue.value).toEqual('File uploaded');
}); });
it('should by default the title of the button get from the JSON file', () => { it('should by default the title of the button get from the JSON file', () => {
@@ -245,14 +245,14 @@ describe('UploadButtonComponent', () => {
expect(addToQueueSpy.calls.mostRecent()).toBeUndefined(); expect(addToQueueSpy.calls.mostRecent()).toBeUndefined();
}); });
it('should output an error when you try to upload a file too big', async () => { it('should output an error when you try to upload a file too big', () => {
component.maxFilesSize = 100; component.maxFilesSize = 100;
await component.error.subscribe((res) => { let lastValue: FileUploadErrorEvent;
expect(res).toBeDefined(); component.error.subscribe((res) => lastValue = res);
});
component.uploadFiles(files); component.uploadFiles(files);
expect(lastValue).toBeDefined();
}); });
it('should not filter out files if max file size is not set', () => { it('should not filter out files if max file size is not set', () => {
@@ -346,19 +346,19 @@ describe('UploadButtonComponent', () => {
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled(); expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
}); });
it('should emit an error message when getNode fails', async () => { it('should emit an error message when getNode fails', () => {
component.rootFolderId = 'nodeId'; component.rootFolderId = 'nodeId';
spyOn(nodesApiService, 'getNode').and.returnValue(throwError('error')); spyOn(nodesApiService, 'getNode').and.returnValue(throwError('error'));
await component.error.subscribe((value: FileUploadErrorEvent) => { let lastValue: FileUploadErrorEvent;
expect(value.error).toBe('FILE_UPLOAD.BUTTON.PERMISSION_CHECK_ERROR'); component.error.subscribe((value) => lastValue = value);
});
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) }); component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });
fixture.detectChanges(); fixture.detectChanges();
component.onFilesAdded(fakeEvent); component.onFilesAdded(fakeEvent);
expect(lastValue.error).toBe('FILE_UPLOAD.BUTTON.PERMISSION_CHECK_ERROR');
}); });
it('should not call uploadFiles for node with other permissions', () => { it('should not call uploadFiles for node with other permissions', () => {
@@ -394,13 +394,13 @@ describe('UploadButtonComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should emit error if upload errored', async () => { it('should emit error if upload errored', () => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise); spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise);
await component.error.subscribe((error) => { let lastValue: FileUploadErrorEvent;
expect(error).not.toBeNull(); component.error.subscribe((error) => lastValue = error);
});
component.onFilesAdded(fakeEvent); component.onFilesAdded(fakeEvent);
expect(lastValue).not.toBeNull();
}); });
}); });
}); });

View File

@@ -22,6 +22,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { mockUploadSuccessPromise, mockUploadErrorPromise } from '../../mock/upload.service.mock'; import { mockUploadSuccessPromise, mockUploadErrorPromise } from '../../mock/upload.service.mock';
import { UploadService } from '../../common/services/upload.service'; import { UploadService } from '../../common/services/upload.service';
import { FileModel } from '../../common/models/file.model'; import { FileModel } from '../../common/models/file.model';
import { FileUploadErrorEvent } from '../../common/events/file.event';
const getFakeShareDataRow = (allowableOperations = ['delete', 'update', 'create']) => ({ const getFakeShareDataRow = (allowableOperations = ['delete', 'update', 'create']) => ({
obj: { obj: {
@@ -180,7 +181,7 @@ describe('UploadDragAreaComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { data: getFakeShareDataRow([]), files: [fakeItem] } detail: { data: getFakeShareDataRow([]), files: [fakeItem] }
}); });
component.onUploadFiles(fakeCustomEvent); component.onUploadFiles(fakeCustomEvent);
@@ -255,7 +256,7 @@ describe('UploadDragAreaComponent', () => {
expect(fileList.options.path).toBe('pippo/'); expect(fileList.options.path).toBe('pippo/');
}); });
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakeItem] files: [fakeItem]
@@ -294,7 +295,7 @@ describe('UploadDragAreaComponent', () => {
it('should upload a file when user has create permission on target folder', () => { it('should upload a file when user has create permission on target folder', () => {
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakeItem] files: [fakeItem]
@@ -318,7 +319,7 @@ describe('UploadDragAreaComponent', () => {
} }
}; };
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakePngItem] files: [fakePngItem]
@@ -348,7 +349,7 @@ describe('UploadDragAreaComponent', () => {
} }
}; };
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakeSuperItem] files: [fakeSuperItem]
@@ -368,7 +369,7 @@ describe('UploadDragAreaComponent', () => {
it('should trigger updating the file version when we drop a file over another file', async () => { it('should trigger updating the file version when we drop a file over another file', async () => {
spyOn(component.updateFileVersion, 'emit'); spyOn(component.updateFileVersion, 'emit');
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeFileShareRow(), data: getFakeFileShareRow(),
files: [fakeItem] files: [fakeItem]
@@ -388,32 +389,33 @@ describe('UploadDragAreaComponent', () => {
it('should raise an error if upload a file goes wrong', async () => { it('should raise an error if upload a file goes wrong', async () => {
spyOn(uploadService, 'getUploadPromise').and.callThrough(); spyOn(uploadService, 'getUploadPromise').and.callThrough();
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakeItem] files: [fakeItem]
} }
}); });
component.error.subscribe((error) => { let lastValue: FileUploadErrorEvent;
expect(error).not.toBeNull(); component.error.subscribe((error) => lastValue = error);
});
component.onUploadFiles(fakeCustomEvent); component.onUploadFiles(fakeCustomEvent);
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
expect(lastValue).not.toBeNull();
}); });
it('should emit success if successful of upload a file', async () => { it('should emit success if successful of upload a file', () => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadSuccessPromise); spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadSuccessPromise);
fixture.detectChanges(); fixture.detectChanges();
await component.success.subscribe((success) => { let lastValue: any;
expect(success).not.toBeNull(); component.success.subscribe((success) => lastValue = success);
});
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakeItem] files: [fakeItem]
@@ -421,18 +423,18 @@ describe('UploadDragAreaComponent', () => {
}); });
component.onUploadFiles(fakeCustomEvent); component.onUploadFiles(fakeCustomEvent);
expect(lastValue).not.toBeNull();
}); });
it('should emit error if upload errored', async () => { it('should emit error if upload errored', () => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise); spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise);
fixture.detectChanges(); fixture.detectChanges();
await component.error.subscribe((error) => { let lastValue: FileUploadErrorEvent;
expect(error).not.toBeNull(); component.error.subscribe((error) => lastValue = error);
});
const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { const fakeCustomEvent = new CustomEvent('CustomEvent', {
detail: { detail: {
data: getFakeShareDataRow(), data: getFakeShareDataRow(),
files: [fakeItem] files: [fakeItem]
@@ -440,6 +442,7 @@ describe('UploadDragAreaComponent', () => {
}); });
component.onUploadFiles(fakeCustomEvent); component.onUploadFiles(fakeCustomEvent);
expect(lastValue).not.toBeNull();
}); });
}); });
}); });

View File

@@ -48,7 +48,7 @@ describe('VersionManagerComponent', () => {
component.node = node; component.node = node;
nodesApiService = TestBed.inject(NodesApiService); nodesApiService = TestBed.inject(NodesApiService);
spyOnListVersionHistory = spyOn(component.versionListComponent['versionsApi'], 'listVersionHistory').and.callFake(() => spyOnListVersionHistory = spyOn(component.versionListComponent.versionsApi, 'listVersionHistory').and.callFake(() =>
Promise.resolve(new VersionPaging({ list: { entries: [versionEntry] } })) Promise.resolve(new VersionPaging({ list: { entries: [versionEntry] } }))
); );
}); });
@@ -81,24 +81,25 @@ describe('VersionManagerComponent', () => {
expect(versionCommentEl).toBeNull(); expect(versionCommentEl).toBeNull();
}); });
it('should emit success event upon successful upload of a new version', async () => { it('should emit success event upon successful upload of a new version', () => {
fixture.detectChanges(); fixture.detectChanges();
const emittedData = { value: { entry: node } }; const emittedData = { value: { entry: node } };
await component.uploadSuccess.subscribe((event) => { let lastValue: Node;
expect(event).toBe(node); component.uploadSuccess.subscribe((event) => lastValue = event);
});
component.onUploadSuccess(emittedData); component.onUploadSuccess(emittedData);
expect(lastValue).toBe(node);
}); });
it('should emit nodeUpdated event upon successful upload of a new version', () => { it('should emit nodeUpdated event upon successful upload of a new version', () => {
fixture.detectChanges(); fixture.detectChanges();
nodesApiService.nodeUpdated.subscribe((res) => {
expect(res).toEqual(node); let lastValue: Node;
}); nodesApiService.nodeUpdated.subscribe((res) => lastValue = res);
const emittedData = { value: { entry: node } }; const emittedData = { value: { entry: node } };
component.onUploadSuccess(emittedData); component.onUploadSuccess(emittedData);
expect(lastValue).toEqual(node);
}); });
describe('Animation', () => { describe('Animation', () => {

View File

@@ -61,7 +61,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(router)).toBeTruthy(); expect(authGuard.canActivate(router)).toBeTruthy();
}); });
it('Should canActivate be true if case of empty roles to check', async () => { it('Should canActivate be true if case of empty roles to check', async () => {
@@ -69,7 +69,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: [] }; router.data = { roles: [] };
expect(await authGuard.canActivate(router)).toBeTruthy(); expect(authGuard.canActivate(router)).toBeTruthy();
}); });
it('Should canActivate be false if the Role is not present int the JWT token', async () => { it('Should canActivate be false if the Role is not present int the JWT token', async () => {
@@ -77,7 +77,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(router)).toBeFalsy(); expect(authGuard.canActivate(router)).toBeFalsy();
}); });
it('Should not redirect if canActivate is', async () => { it('Should not redirect if canActivate is', async () => {
@@ -87,7 +87,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(router)).toBeTruthy(); expect(authGuard.canActivate(router)).toBeTruthy();
expect(routerService.navigate).not.toHaveBeenCalled(); expect(routerService.navigate).not.toHaveBeenCalled();
}); });
@@ -95,7 +95,7 @@ describe('Auth Guard SSO role service', () => {
spyUserAccess(['MOCK_USER_ROLE', 'MOCK_ROOT_USER_ROLE'], {}); spyUserAccess(['MOCK_USER_ROLE', 'MOCK_ROOT_USER_ROLE'], {});
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
expect(await authGuard.canActivate(router)).toBeFalsy(); expect(authGuard.canActivate(router)).toBeFalsy();
}); });
it('Should redirect to the redirectURL if canActivate is false and redirectUrl is in data', async () => { it('Should redirect to the redirectURL if canActivate is false and redirectUrl is in data', async () => {
@@ -105,7 +105,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], redirectUrl: 'no-role-url' }; router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], redirectUrl: 'no-role-url' };
expect(await authGuard.canActivate(router)).toBeFalsy(); expect(authGuard.canActivate(router)).toBeFalsy();
expect(routerService.navigate).toHaveBeenCalledWith(['/no-role-url']); expect(routerService.navigate).toHaveBeenCalledWith(['/no-role-url']);
}); });
@@ -116,7 +116,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(router)).toBeFalsy(); expect(authGuard.canActivate(router)).toBeFalsy();
expect(routerService.navigate).not.toHaveBeenCalled(); expect(routerService.navigate).not.toHaveBeenCalled();
}); });
@@ -127,7 +127,7 @@ describe('Auth Guard SSO role service', () => {
route.params = { appName: 'mockApp' }; route.params = { appName: 'mockApp' };
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(route)).toBeFalsy(); expect(authGuard.canActivate(route)).toBeFalsy();
}); });
it('Should canActivate be false if hasRealm is false and hasClientRole is true', async () => { it('Should canActivate be false if hasRealm is false and hasClientRole is true', async () => {
@@ -137,7 +137,7 @@ describe('Auth Guard SSO role service', () => {
route.params = { appName: 'mockApp' }; route.params = { appName: 'mockApp' };
route.data = { clientRoles: ['mockApp'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; route.data = { clientRoles: ['mockApp'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(route)).toBeFalsy(); expect(authGuard.canActivate(route)).toBeFalsy();
}); });
it('Should canActivate be true if both Real Role and Client Role are present int the JWT token', async () => { it('Should canActivate be true if both Real Role and Client Role are present int the JWT token', async () => {
@@ -147,7 +147,7 @@ describe('Auth Guard SSO role service', () => {
route.params = { appName: 'mockApp' }; route.params = { appName: 'mockApp' };
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(route)).toBeTruthy(); expect(authGuard.canActivate(route)).toBeTruthy();
}); });
it('Should canActivate be false if the Client Role is not present int the JWT token with the correct role', async () => { it('Should canActivate be false if the Client Role is not present int the JWT token with the correct role', async () => {
@@ -157,7 +157,7 @@ describe('Auth Guard SSO role service', () => {
route.params = { appName: 'mockApp' }; route.params = { appName: 'mockApp' };
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(route)).toBeFalsy(); expect(authGuard.canActivate(route)).toBeFalsy();
}); });
it('Should canActivate be false hasRealm is true and hasClientRole is false', async () => { it('Should canActivate be false hasRealm is true and hasClientRole is false', async () => {
@@ -171,7 +171,7 @@ describe('Auth Guard SSO role service', () => {
route.params = { appName: 'mockApp' }; route.params = { appName: 'mockApp' };
route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] }; route.data = { clientRoles: ['appName'], roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'] };
expect(await authGuard.canActivate(route)).toBeFalsy(); expect(authGuard.canActivate(route)).toBeFalsy();
expect(materialDialog.closeAll).toHaveBeenCalled(); expect(materialDialog.closeAll).toHaveBeenCalled();
}); });
@@ -182,7 +182,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_ANOTHER_ROLE'], excludedRoles: ['MOCK_USER_ROLE'] }; router.data = { roles: ['MOCK_ANOTHER_ROLE'], excludedRoles: ['MOCK_USER_ROLE'] };
expect(await authGuard.canActivate(router)).toBe(false); expect(authGuard.canActivate(router)).toBe(false);
}); });
it('Should canActivate be true when the user has none of the excluded roles', async () => { it('Should canActivate be true when the user has none of the excluded roles', async () => {
@@ -190,8 +190,7 @@ describe('Auth Guard SSO role service', () => {
const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot(); const router: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], excludedRoles: ['MOCK_ROOT_USER_ROLE'] }; router.data = { roles: ['MOCK_USER_ROLE', 'MOCK_ADMIN_ROLE'], excludedRoles: ['MOCK_ROOT_USER_ROLE'] };
const result = await authGuard.canActivate(router); expect(authGuard.canActivate(router)).toBeTruthy();
expect(result).toBeTruthy();
}); });
}); });

View File

@@ -22,6 +22,7 @@ import { WidgetComponent } from './widget.component';
import { CoreTestingModule } from '../../../testing'; import { CoreTestingModule } from '../../../testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { filter } from 'rxjs/operators'; import { filter } from 'rxjs/operators';
import { FormRulesEvent } from '../../events/form-rules.event';
describe('WidgetComponent', () => { describe('WidgetComponent', () => {
@@ -69,40 +70,43 @@ describe('WidgetComponent', () => {
expect(widget.hasField()).toBeTruthy(); expect(widget.hasField()).toBeTruthy();
}); });
it('should send an event after view init', async () => { it('should send an event after view init', () => {
const fakeForm = new FormModel(); const fakeForm = new FormModel();
const fakeField = new FormFieldModel(fakeForm, { id: 'fakeField', value: 'fakeValue' }); const fakeField = new FormFieldModel(fakeForm, { id: 'fakeField', value: 'fakeValue' });
widget.field = fakeField; widget.field = fakeField;
await widget.fieldChanged.subscribe((field) => { let lastValue: FormFieldModel;
expect(field).not.toBe(null);
expect(field.id).toBe('fakeField');
expect(field.value).toBe('fakeValue');
});
widget.fieldChanged.subscribe((field) => lastValue = field);
widget.ngAfterViewInit(); widget.ngAfterViewInit();
expect(lastValue).not.toBe(null);
expect(lastValue.id).toBe('fakeField');
expect(lastValue.value).toBe('fakeValue');
}); });
it('should send an event when a field is changed', async () => { it('should send an event when a field is changed', () => {
const fakeForm = new FormModel(); const fakeForm = new FormModel();
const fakeField = new FormFieldModel(fakeForm, { id: 'fakeField', value: 'fakeValue' }); const fakeField = new FormFieldModel(fakeForm, { id: 'fakeField', value: 'fakeValue' });
await widget.fieldChanged.subscribe((field) => {
expect(field).not.toBe(null);
expect(field.id).toBe('fakeField');
expect(field.value).toBe('fakeValue');
});
let lastValue: FormFieldModel;
widget.fieldChanged.subscribe((field) => lastValue = field);
widget.onFieldChanged(fakeField); widget.onFieldChanged(fakeField);
expect(lastValue).not.toBe(null);
expect(lastValue.id).toBe('fakeField');
expect(lastValue.value).toBe('fakeValue');
}); });
it('should send a rule event when a field is changed', async () => { it('should send a rule event when a field is changed', () => {
const fakeForm = new FormModel(); const fakeForm = new FormModel();
const fakeField = new FormFieldModel(fakeForm, { id: 'fakeField', value: 'fakeValue' }); const fakeField = new FormFieldModel(fakeForm, { id: 'fakeField', value: 'fakeValue' });
await widget.formService.formRulesEvent.subscribe((event) => {
expect(event.type).toEqual('fieldValueChanged'); let lastValue: FormRulesEvent;
}); widget.formService.formRulesEvent.subscribe((event) => lastValue = event);
widget.onFieldChanged(fakeField); widget.onFieldChanged(fakeField);
expect(lastValue.type).toEqual('fieldValueChanged');
}); });
it('should eval isRequired state of the field', () => { it('should eval isRequired state of the field', () => {

View File

@@ -53,7 +53,7 @@ describe('DownloadPromptDialogComponent', () => {
const waitButton = getButton('#waitButton'); const waitButton = getButton('#waitButton');
waitButton.dispatchEvent(new Event('click')); waitButton.dispatchEvent(new Event('click'));
await fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
expect(matDialogRef.close).toHaveBeenCalledWith(DownloadPromptActions.WAIT); expect(matDialogRef.close).toHaveBeenCalledWith(DownloadPromptActions.WAIT);
@@ -63,7 +63,7 @@ describe('DownloadPromptDialogComponent', () => {
const waitButton = getButton('#downloadButton'); const waitButton = getButton('#downloadButton');
waitButton.dispatchEvent(new Event('click')); waitButton.dispatchEvent(new Event('click'));
await fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
expect(matDialogRef.close).toHaveBeenCalledWith(DownloadPromptActions.DOWNLOAD); expect(matDialogRef.close).toHaveBeenCalledWith(DownloadPromptActions.DOWNLOAD);

View File

@@ -92,7 +92,7 @@ describe('ViewerComponent', () => {
it('should not reload the content of all the viewer after type change', async () => { it('should not reload the content of all the viewer after type change', async () => {
const fixtureDouble = TestBed.createComponent(DoubleViewerComponent); const fixtureDouble = TestBed.createComponent(DoubleViewerComponent);
await fixtureDouble.detectChanges(); fixtureDouble.detectChanges();
await fixtureDouble.whenStable(); await fixtureDouble.whenStable();
fixtureDouble.componentInstance.urlFileViewer1 = 'fake-test-file.pdf'; fixtureDouble.componentInstance.urlFileViewer1 = 'fake-test-file.pdf';
@@ -101,7 +101,7 @@ describe('ViewerComponent', () => {
fixtureDouble.componentInstance.viewer1.ngOnChanges(); fixtureDouble.componentInstance.viewer1.ngOnChanges();
fixtureDouble.componentInstance.viewer2.ngOnChanges(); fixtureDouble.componentInstance.viewer2.ngOnChanges();
await fixtureDouble.detectChanges(); fixtureDouble.detectChanges();
await fixtureDouble.whenStable(); await fixtureDouble.whenStable();
expect(fixtureDouble.componentInstance.viewer1.viewerType).toBe('pdf'); expect(fixtureDouble.componentInstance.viewer1.viewerType).toBe('pdf');
@@ -110,7 +110,7 @@ describe('ViewerComponent', () => {
fixtureDouble.componentInstance.urlFileViewer1 = 'fake-test-file.pdf'; fixtureDouble.componentInstance.urlFileViewer1 = 'fake-test-file.pdf';
fixtureDouble.componentInstance.urlFileViewer2 = 'fake-test-file-two.png'; fixtureDouble.componentInstance.urlFileViewer2 = 'fake-test-file-two.png';
await fixtureDouble.detectChanges(); fixtureDouble.detectChanges();
await fixtureDouble.whenStable(); await fixtureDouble.whenStable();
fixtureDouble.componentInstance.viewer1.ngOnChanges(); fixtureDouble.componentInstance.viewer1.ngOnChanges();

View File

@@ -71,7 +71,7 @@ describe('AnalyticsReportListComponent', () => {
expect(component.isReportsEmpty()).toBeTruthy(); expect(component.isReportsEmpty()).toBeTruthy();
}); });
it('should return the default reports when the report list is empty', async () => { it('should return the default reports when the report list is empty', (done) => {
jasmine.Ajax.stubRequest('http://localhost:9876/bpm/activiti-app/app/rest/reporting/reports').andReturn({ jasmine.Ajax.stubRequest('http://localhost:9876/bpm/activiti-app/app/rest/reporting/reports').andReturn({
status: 200, status: 200,
contentType: 'json', contentType: 'json',
@@ -92,7 +92,7 @@ describe('AnalyticsReportListComponent', () => {
responseText: reportList responseText: reportList
}); });
await component.success.subscribe(() => { component.success.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(element.querySelector('#report-list-0 .adf-activiti-filters__entry-icon').innerHTML).toBe('assignment'); expect(element.querySelector('#report-list-0 .adf-activiti-filters__entry-icon').innerHTML).toBe('assignment');
expect(element.querySelector('#report-list-0 > span').innerHTML).toBe('Fake Test Process definition heat map'); expect(element.querySelector('#report-list-0 > span').innerHTML).toBe('Fake Test Process definition heat map');
@@ -101,13 +101,14 @@ describe('AnalyticsReportListComponent', () => {
expect(element.querySelector('#report-list-3 > span').innerHTML).toBe('Fake Test Task overview'); expect(element.querySelector('#report-list-3 > span').innerHTML).toBe('Fake Test Task overview');
expect(element.querySelector('#report-list-4 > span').innerHTML).toBe('Fake Test Task service level agreement'); expect(element.querySelector('#report-list-4 > span').innerHTML).toBe('Fake Test Task service level agreement');
expect(component.isReportsEmpty()).toBeFalsy(); expect(component.isReportsEmpty()).toBeFalsy();
done();
}); });
}); });
it('Report render the report list relative to a single app', async () => { it('Report render the report list relative to a single app', (done) => {
fixture.detectChanges(); fixture.detectChanges();
await component.success.subscribe(() => { component.success.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(element.querySelector('#report-list-0 .adf-activiti-filters__entry-icon').innerHTML).toBe('assignment'); expect(element.querySelector('#report-list-0 .adf-activiti-filters__entry-icon').innerHTML).toBe('assignment');
expect(element.querySelector('#report-list-0 > span').innerHTML).toBe('Fake Test Process definition heat map'); expect(element.querySelector('#report-list-0 > span').innerHTML).toBe('Fake Test Process definition heat map');
@@ -116,6 +117,7 @@ describe('AnalyticsReportListComponent', () => {
expect(element.querySelector('#report-list-3 > span').innerHTML).toBe('Fake Test Task overview'); expect(element.querySelector('#report-list-3 > span').innerHTML).toBe('Fake Test Task overview');
expect(element.querySelector('#report-list-4 > span').innerHTML).toBe('Fake Test Task service level agreement'); expect(element.querySelector('#report-list-4 > span').innerHTML).toBe('Fake Test Task service level agreement');
expect(component.isReportsEmpty()).toBeFalsy(); expect(component.isReportsEmpty()).toBeFalsy();
done();
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.requests.mostRecent().respondWith({
@@ -125,11 +127,12 @@ describe('AnalyticsReportListComponent', () => {
}); });
}); });
it('Report emit an error with a empty response', async () => { it('Report emit an error with a empty response', (done) => {
fixture.detectChanges(); fixture.detectChanges();
await component.error.subscribe((err) => { component.error.subscribe((err) => {
expect(err).toBeDefined(); expect(err).toBeDefined();
done();
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.requests.mostRecent().respondWith({
@@ -158,15 +161,16 @@ describe('AnalyticsReportListComponent', () => {
expect(component.isSelected(anotherReport)).toBe(false); expect(component.isSelected(anotherReport)).toBe(false);
}); });
it('Should reload the report list', async () => { it('Should reload the report list', (done) => {
component.initObserver(); component.initObserver();
const report = new ReportParametersModel({ id: 2002, name: 'Fake Test Process definition heat map' }); const report = new ReportParametersModel({ id: 2002, name: 'Fake Test Process definition heat map' });
component.reports = [report]; component.reports = [report];
expect(component.reports.length).toEqual(1); expect(component.reports.length).toEqual(1);
component.reload(); component.reload();
await component.success.subscribe(() => { component.success.subscribe(() => {
expect(component.reports.length).toEqual(5); expect(component.reports.length).toEqual(5);
done();
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.requests.mostRecent().respondWith({
@@ -176,17 +180,18 @@ describe('AnalyticsReportListComponent', () => {
}); });
}); });
it('Should reload the report list and select the report with the given id', async () => { it('Should reload the report list and select the report with the given id', (done) => {
component.initObserver(); component.initObserver();
expect(component.reports.length).toEqual(0); expect(component.reports.length).toEqual(0);
component.reload(2002); component.reload(2002);
await component.success.subscribe(() => { component.success.subscribe(() => {
expect(component.reports.length).toEqual(5); expect(component.reports.length).toEqual(5);
expect(component.currentReport).toBeDefined(); expect(component.currentReport).toBeDefined();
expect(component.currentReport).not.toBeNull(); expect(component.currentReport).not.toBeNull();
expect(component.currentReport.id).toEqual(2002); expect(component.currentReport.id).toEqual(2002);
done();
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.requests.mostRecent().respondWith({

View File

@@ -15,9 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
import { AlfrescoApiService, LogService } from '@alfresco/adf-core'; import { AlfrescoApiService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, from, throwError, of } from 'rxjs'; import { Observable, from, of } from 'rxjs';
import { ParameterValueModel } from '../../diagram/models/report/parameter-value.model'; import { ParameterValueModel } from '../../diagram/models/report/parameter-value.model';
import { ReportParametersModel } from '../../diagram/models/report/report-parameters.model'; import { ReportParametersModel } from '../../diagram/models/report/report-parameters.model';
import { BarChart } from '../../diagram/models/chart/bar-chart.model'; import { BarChart } from '../../diagram/models/chart/bar-chart.model';
@@ -27,12 +27,11 @@ import { HeatMapChart } from '../../diagram/models/chart/heat-map-chart.model';
import { MultiBarChart } from '../../diagram/models/chart/multi-bar-chart.model'; import { MultiBarChart } from '../../diagram/models/chart/multi-bar-chart.model';
import { PieChart } from '../../diagram/models/chart/pie-chart.model'; import { PieChart } from '../../diagram/models/chart/pie-chart.model';
import { TableChart } from '../../diagram/models/chart/table-chart.model'; import { TableChart } from '../../diagram/models/chart/table-chart.model';
import { map, catchError } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ProcessDefinitionsApi, ReportApi } from '@alfresco/js-api'; import { ProcessDefinitionsApi, ReportApi } from '@alfresco/js-api';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AnalyticsService { export class AnalyticsService {
private _reportApi: ReportApi; private _reportApi: ReportApi;
get reportApi(): ReportApi { get reportApi(): ReportApi {
this._reportApi = this._reportApi ?? new ReportApi(this.apiService.getInstance()); this._reportApi = this._reportApi ?? new ReportApi(this.apiService.getInstance());
@@ -45,9 +44,7 @@ export class AnalyticsService {
return this._processDefinitionsApi; return this._processDefinitionsApi;
} }
constructor(private apiService: AlfrescoApiService, constructor(private apiService: AlfrescoApiService) {}
private logService: LogService) {
}
/** /**
* Retrieve all the Deployed app * Retrieve all the Deployed app
@@ -56,20 +53,18 @@ export class AnalyticsService {
* @returns list or report parameter models * @returns list or report parameter models
*/ */
getReportList(appId: number): Observable<ReportParametersModel[]> { getReportList(appId: number): Observable<ReportParametersModel[]> {
return from(this.reportApi.getReportList()) return from(this.reportApi.getReportList()).pipe(
.pipe( map((res) => {
map((res: any) => { const reports: ReportParametersModel[] = [];
const reports: ReportParametersModel[] = []; res.forEach((report: ReportParametersModel) => {
res.forEach((report: ReportParametersModel) => { const reportModel = new ReportParametersModel(report);
const reportModel = new ReportParametersModel(report); if (this.isReportValid(appId, report)) {
if (this.isReportValid(appId, report)) { reports.push(reportModel);
reports.push(reportModel); }
} });
}); return reports;
return reports; })
}), );
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -79,19 +74,11 @@ export class AnalyticsService {
* @returns report model * @returns report model
*/ */
getReportByName(reportName: string): Observable<any> { getReportByName(reportName: string): Observable<any> {
return from(this.reportApi.getReportList()) return from(this.reportApi.getReportList()).pipe(map((response) => response.find((report) => report.name === reportName)));
.pipe(
map((response: any) => response.find((report) => report.name === reportName)),
catchError((err) => this.handleError(err))
);
} }
getReportParams(reportId: string): Observable<ReportParametersModel> { getReportParams(reportId: string): Observable<ReportParametersModel> {
return from(this.reportApi.getReportParams(reportId)) return from(this.reportApi.getReportParams(reportId)).pipe(map((res) => new ReportParametersModel(res)));
.pipe(
map((res: any) => new ReportParametersModel(res)),
catchError((err) => this.handleError(err))
);
} }
getParamValuesByType(type: string, appId: number, reportId?: string, processDefinitionId?: string): Observable<ParameterValueModel[]> { getParamValuesByType(type: string, appId: number, reportId?: string, processDefinitionId?: string): Observable<ParameterValueModel[]> {
@@ -145,125 +132,85 @@ export class AnalyticsService {
} }
getProcessDefinitionsValuesNoApp(): Observable<ParameterValueModel[]> { getProcessDefinitionsValuesNoApp(): Observable<ParameterValueModel[]> {
return from(this.reportApi.getProcessDefinitions()) return from(this.reportApi.getProcessDefinitions()).pipe(
.pipe( map((res) => {
map((res: any) => { const paramOptions: ParameterValueModel[] = [];
const paramOptions: ParameterValueModel[] = []; res.forEach((opt) => {
res.forEach((opt) => { paramOptions.push(new ParameterValueModel(opt));
paramOptions.push(new ParameterValueModel(opt)); });
}); return paramOptions;
return paramOptions; })
}), );
catchError((err) => this.handleError(err))
);
} }
getProcessDefinitionsValues(appId: number): Observable<ParameterValueModel[]> { getProcessDefinitionsValues(appId: number): Observable<ParameterValueModel[]> {
const options = { appDefinitionId: appId }; const options = { appDefinitionId: appId };
return from(this.processDefinitionsApi.getProcessDefinitions(options)) return from(this.processDefinitionsApi.getProcessDefinitions(options)).pipe(
.pipe( map((res) => {
map((res: any) => { const paramOptions: ParameterValueModel[] = [];
const paramOptions: ParameterValueModel[] = []; res.data.forEach((opt) => {
res.data.forEach((opt) => { paramOptions.push(new ParameterValueModel(opt));
paramOptions.push(new ParameterValueModel(opt)); });
}); return paramOptions;
return paramOptions; })
}), );
catchError((err) => this.handleError(err))
);
} }
getTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): Observable<ParameterValueModel[]> { getTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): Observable<ParameterValueModel[]> {
return from(this.reportApi.getTasksByProcessDefinitionId(reportId, processDefinitionId)) return from(this.reportApi.getTasksByProcessDefinitionId(reportId, processDefinitionId)).pipe(
.pipe( map((res) => {
map((res: any) => { const paramOptions: ParameterValueModel[] = [];
const paramOptions: ParameterValueModel[] = []; res.forEach((opt) => {
res.forEach((opt) => { paramOptions.push(new ParameterValueModel({ id: opt, name: opt }));
paramOptions.push(new ParameterValueModel({ id: opt, name: opt })); });
}); return paramOptions;
return paramOptions; })
}), );
catchError((err) => this.handleError(err))
);
} }
getReportsByParams(reportId: string, paramsQuery: any): Observable<Chart[]> { getReportsByParams(reportId: string, paramsQuery: any): Observable<Chart[]> {
return from(this.reportApi.getReportsByParams(reportId, paramsQuery)) return from(this.reportApi.getReportsByParams(reportId, paramsQuery)).pipe(
.pipe( map((res: any) => {
map((res: any) => { const elements: Chart[] = [];
const elements: Chart[] = []; res.elements.forEach((chartData) => {
res.elements.forEach((chartData) => { if (chartData.type === 'pieChart') {
if (chartData.type === 'pieChart') { elements.push(new PieChart(chartData));
elements.push(new PieChart(chartData)); } else if (chartData.type === 'table') {
} else if (chartData.type === 'table') { elements.push(new TableChart(chartData));
elements.push(new TableChart(chartData)); } else if (chartData.type === 'processDefinitionHeatMap') {
} else if (chartData.type === 'processDefinitionHeatMap') { elements.push(new HeatMapChart(chartData));
elements.push(new HeatMapChart(chartData)); } else if (chartData.type === 'masterDetailTable') {
} else if (chartData.type === 'masterDetailTable') { elements.push(new DetailsTableChart(chartData));
elements.push(new DetailsTableChart(chartData)); } else if (chartData.type === 'barChart') {
} else if (chartData.type === 'barChart') { elements.push(new BarChart(chartData));
elements.push(new BarChart(chartData)); } else if (chartData.type === 'multiBarChart') {
} else if (chartData.type === 'multiBarChart') { elements.push(new MultiBarChart(chartData));
elements.push(new MultiBarChart(chartData)); }
} });
});
return elements; return elements;
}), })
catchError((err) => this.handleError(err)) );
);
} }
createDefaultReports(): Observable<any> { createDefaultReports(): Observable<any> {
return from(this.reportApi.createDefaultReports()) return from(this.reportApi.createDefaultReports()).pipe(map((res) => res || {}));
.pipe(
map(res => res || {}),
catchError((err) => this.handleError(err))
);
} }
updateReport(reportId: string, name: string): Observable<any> { updateReport(reportId: string, name: string): Observable<any> {
return from(this.reportApi.updateReport(reportId, name)) return from(this.reportApi.updateReport(reportId, name));
.pipe(
map(() => this.logService.info('upload')),
catchError((err) => this.handleError(err))
);
} }
exportReportToCsv(reportId: string, paramsQuery: any): Observable<any> { exportReportToCsv(reportId: string, paramsQuery: any): Observable<any> {
return from(this.reportApi.exportToCsv(reportId, paramsQuery)) return from(this.reportApi.exportToCsv(reportId, paramsQuery));
.pipe(
map((res: any) => {
this.logService.info('export');
return res;
}),
catchError((err) => this.handleError(err))
);
} }
saveReport(reportId: string, paramsQuery: any): Observable<any> { saveReport(reportId: string, paramsQuery: any): Observable<any> {
return from(this.reportApi.saveReport(reportId, paramsQuery)) return from(this.reportApi.saveReport(reportId, paramsQuery));
.pipe(
map(() => {
this.logService.info('save');
}),
catchError((err) => this.handleError(err))
);
} }
deleteReport(reportId: string): Observable<any> { deleteReport(reportId: string): Observable<any> {
return from(this.reportApi.deleteReport(reportId)) return from(this.reportApi.deleteReport(reportId));
.pipe(
map(() => {
this.logService.info('delete');
}),
catchError((err) => this.handleError(err))
);
}
private handleError(error: any) {
this.logService.error(error);
return throwError(error || 'Server error');
} }
private isReportValid(appId: number, report: ReportParametersModel) { private isReportValid(appId: number, report: ReportParametersModel) {

View File

@@ -29,7 +29,8 @@ import {
AppConfigService, AppConfigService,
UploadWidgetContentLinkModel, UploadWidgetContentLinkModel,
LocalizedDatePipe, LocalizedDatePipe,
NotificationService NotificationService,
ContentLinkModel
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { import {
allSourceParams, allSourceParams,
@@ -578,11 +579,10 @@ describe('AttachFileCloudWidgetComponent', () => {
}); });
}); });
it('should preview file when show is clicked', async () => { it('should preview file when show is clicked', () => {
spyOn(processCloudContentService, 'getRawContentNode').and.returnValue(of(new Blob())); spyOn(processCloudContentService, 'getRawContentNode').and.returnValue(of(new Blob()));
await formService.formContentClicked.subscribe((fileClicked: any) => { let lastValue: ContentLinkModel;
expect(fileClicked.nodeId).toBe('fake-properties'); formService.formContentClicked.subscribe((fileClicked) => lastValue = fileClicked);
});
fixture.detectChanges(); fixture.detectChanges();
const menuButton = fixture.debugElement.query(By.css('#file-fake-properties-option-menu')).nativeElement as HTMLButtonElement; const menuButton = fixture.debugElement.query(By.css('#file-fake-properties-option-menu')).nativeElement as HTMLButtonElement;
@@ -590,6 +590,8 @@ describe('AttachFileCloudWidgetComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
const showOption = fixture.debugElement.query(By.css('#file-fake-properties-show-file')).nativeElement as HTMLButtonElement; const showOption = fixture.debugElement.query(By.css('#file-fake-properties-show-file')).nativeElement as HTMLButtonElement;
showOption.click(); showOption.click();
expect(lastValue.nodeId).toBe('fake-properties');
}); });
it('should request form to be updated with metadata when retrieve is clicked', async () => { it('should request form to be updated with metadata when retrieve is clicked', async () => {

View File

@@ -148,7 +148,7 @@ describe('ContentCloudNodeSelectorService', () => {
expect(service.sourceNodeNotFound).toBe(true); expect(service.sourceNodeNotFound).toBe(true);
} }
await service.openUploadFileDialog('nodeId', 'single', true, true); service.openUploadFileDialog('nodeId', 'single', true, true);
expect(openDialogSpy).toHaveBeenCalled(); expect(openDialogSpy).toHaveBeenCalled();
expect(showWarningSpy).toHaveBeenCalledWith('ADF_CLOUD_TASK_FORM.ERROR.DESTINATION_FOLDER_PATH_ERROR'); expect(showWarningSpy).toHaveBeenCalledWith('ADF_CLOUD_TASK_FORM.ERROR.DESTINATION_FOLDER_PATH_ERROR');
@@ -167,7 +167,7 @@ describe('ContentCloudNodeSelectorService', () => {
expect(service.sourceNodeNotFound).toBe(true); expect(service.sourceNodeNotFound).toBe(true);
} }
await service.openUploadFileDialog('nodeId', 'single', true, true); service.openUploadFileDialog('nodeId', 'single', true, true);
expect(openDialogSpy).toHaveBeenCalled(); expect(openDialogSpy).toHaveBeenCalled();
expect(showWarningSpy).toHaveBeenCalledWith('ADF_CLOUD_TASK_FORM.ERROR.DESTINATION_FOLDER_PATH_ERROR'); expect(showWarningSpy).toHaveBeenCalledWith('ADF_CLOUD_TASK_FORM.ERROR.DESTINATION_FOLDER_PATH_ERROR');

View File

@@ -108,21 +108,18 @@ describe('ProcessFiltersCloudComponent', () => {
expect(filters[2].nativeElement.innerText).toContain('FakeCompletedProcesses'); expect(filters[2].nativeElement.innerText).toContain('FakeCompletedProcesses');
}); });
it('should emit an error with a bad response', async () => { it('should emit an error with a bad response', () => {
const mockErrorFilterList = { getProcessFiltersSpy.and.returnValue(throwError('wrong request'));
error: 'wrong request'
};
getProcessFiltersSpy.and.returnValue(throwError(mockErrorFilterList));
const appName = 'my-app-1'; const appName = 'my-app-1';
const change = new SimpleChange(null, appName, true); const change = new SimpleChange(null, appName, true);
await component.error.subscribe((err) => { let lastValue: any;
expect(err).toBeDefined(); component.error.subscribe((err) => lastValue = err);
});
component.ngOnChanges({appName: change}); component.ngOnChanges({appName: change});
fixture.detectChanges(); fixture.detectChanges();
expect(lastValue).toBeDefined();
}); });
it('should emit success with the filters when filters are loaded', async () => { it('should emit success with the filters when filters are loaded', async () => {

View File

@@ -63,16 +63,17 @@ describe('ProcessFilterCloudService', () => {
getCurrentUserInfoSpy = spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue(identityUserMock); getCurrentUserInfoSpy = spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue(identityUserMock);
}); });
it('should create processfilter key by using appName and the username', async () => { it('should create processfilter key by using appName and the username', (done) => {
await service.getProcessFilters('mock-appName').subscribe((res: any) => { service.getProcessFilters('mock-appName').subscribe((res: any) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(getCurrentUserInfoSpy).toHaveBeenCalled(); expect(getCurrentUserInfoSpy).toHaveBeenCalled();
done();
}); });
}); });
it('should create default process filters', async () => { it('should create default process filters', (done) => {
getPreferencesSpy.and.returnValue(of(fakeEmptyProcessCloudFilterEntries)); getPreferencesSpy.and.returnValue(of(fakeEmptyProcessCloudFilterEntries));
await service.getProcessFilters('mock-appName').subscribe((res: any) => { service.getProcessFilters('mock-appName').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
@@ -91,12 +92,14 @@ describe('ProcessFilterCloudService', () => {
expect(res[2].id).toBe('3'); expect(res[2].id).toBe('3');
expect(res[2].name).toBe('MOCK_PROCESS_NAME_3'); expect(res[2].name).toBe('MOCK_PROCESS_NAME_3');
expect(res[2].status).toBe('MOCK-COMPLETED'); expect(res[2].status).toBe('MOCK-COMPLETED');
expect(createPreferenceSpy).toHaveBeenCalled();
done();
}); });
expect(createPreferenceSpy).toHaveBeenCalled();
}); });
it('should fetch the process filters if filters are available', async () => { it('should fetch the process filters if filters are available', (done) => {
await service.getProcessFilters('mock-appName').subscribe((res: any) => { service.getProcessFilters('mock-appName').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
@@ -115,13 +118,16 @@ describe('ProcessFilterCloudService', () => {
expect(res[2].id).toBe('3'); expect(res[2].id).toBe('3');
expect(res[2].name).toBe('MOCK_PROCESS_NAME_3'); expect(res[2].name).toBe('MOCK_PROCESS_NAME_3');
expect(res[2].status).toBe('MOCK-COMPLETED'); expect(res[2].status).toBe('MOCK-COMPLETED');
expect(getPreferencesSpy).toHaveBeenCalled();
done();
}); });
expect(getPreferencesSpy).toHaveBeenCalled();
}); });
it('should create the process filters in case the filters are not exist in the user preferences', async () => { it('should create the process filters in case the filters are not exist in the user preferences', (done) => {
getPreferencesSpy.and.returnValue(of(fakeProcessCloudFilterWithDifferentEntries)); getPreferencesSpy.and.returnValue(of(fakeProcessCloudFilterWithDifferentEntries));
await service.getProcessFilters('mock-appName').subscribe((res: any) => {
service.getProcessFilters('mock-appName').subscribe((res: any) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
@@ -140,64 +146,77 @@ describe('ProcessFilterCloudService', () => {
expect(res[2].id).toBe('3'); expect(res[2].id).toBe('3');
expect(res[2].name).toBe('MOCK_PROCESS_NAME_3'); expect(res[2].name).toBe('MOCK_PROCESS_NAME_3');
expect(res[2].status).toBe('MOCK-COMPLETED'); expect(res[2].status).toBe('MOCK-COMPLETED');
expect(getPreferencesSpy).toHaveBeenCalled();
expect(createPreferenceSpy).toHaveBeenCalled();
done();
}); });
expect(getPreferencesSpy).toHaveBeenCalled();
expect(createPreferenceSpy).toHaveBeenCalled();
}); });
it('should return filter by process filter id', async () => { it('should return filter by process filter id', (done) => {
await service.getFilterById('mock-appName', '2').subscribe((res: any) => { service.getFilterById('mock-appName', '2').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.appName).toBe('mock-appName'); expect(res.appName).toBe('mock-appName');
expect(res.id).toBe('2'); expect(res.id).toBe('2');
expect(res.name).toBe('MOCK_PROCESS_NAME_2'); expect(res.name).toBe('MOCK_PROCESS_NAME_2');
expect(res.status).toBe('MOCK-RUNNING'); expect(res.status).toBe('MOCK-RUNNING');
expect(getPreferenceByKeySpy).toHaveBeenCalled();
done();
}); });
expect(getPreferenceByKeySpy).toHaveBeenCalled();
}); });
it('should add process filter if filter is not exist in the filters', async () => { it('should add process filter if filter is not exist in the filters', (done) => {
getPreferenceByKeySpy.and.returnValue(of([])); getPreferenceByKeySpy.and.returnValue(of([]));
await service.getFilterById('mock-appName', '2').subscribe((res: any) => {
service.getFilterById('mock-appName', '2').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.appName).toBe('mock-appName'); expect(res.appName).toBe('mock-appName');
expect(res.id).toBe('2'); expect(res.id).toBe('2');
expect(res.name).toBe('MOCK_PROCESS_NAME_2'); expect(res.name).toBe('MOCK_PROCESS_NAME_2');
expect(res.status).toBe('MOCK-RUNNING'); expect(res.status).toBe('MOCK-RUNNING');
done();
}); });
}); });
it('should update filter', async () => { it('should update filter', (done) => {
await service.updateFilter(fakeProcessFilter).subscribe((res: any) => { service.updateFilter(fakeProcessFilter).subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
expect(res[0].appName).toBe('mock-appName'); expect(res[0].appName).toBe('mock-appName');
expect(res[1].appName).toBe('mock-appName'); expect(res[1].appName).toBe('mock-appName');
expect(res[2].appName).toBe('mock-appName'); expect(res[2].appName).toBe('mock-appName');
done();
}); });
}); });
it('should create process filter when trying to update in case filter is not exist in the filters', async () => { it('should create process filter when trying to update in case filter is not exist in the filters', (done) => {
getPreferenceByKeySpy.and.returnValue(of([])); getPreferenceByKeySpy.and.returnValue(of([]));
await service.updateFilter(fakeProcessFilter).subscribe((res: any) => {
service.updateFilter(fakeProcessFilter).subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
expect(res[0].appName).toBe('mock-appName'); expect(res[0].appName).toBe('mock-appName');
expect(res[1].appName).toBe('mock-appName'); expect(res[1].appName).toBe('mock-appName');
expect(res[2].appName).toBe('mock-appName'); expect(res[2].appName).toBe('mock-appName');
expect(createPreferenceSpy).toHaveBeenCalled();
done();
}); });
expect(createPreferenceSpy).toHaveBeenCalled();
}); });
it('should delete filter', async () => { it('should delete filter', (done) => {
await service.deleteFilter(fakeProcessFilter).subscribe((res: any) => { service.deleteFilter(fakeProcessFilter).subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(updatePreferenceSpy).toHaveBeenCalled();
done();
}); });
expect(updatePreferenceSpy).toHaveBeenCalled();
}); });
it('should check if given filter is a default filter', () => { it('should check if given filter is a default filter', () => {

View File

@@ -16,9 +16,9 @@
*/ */
import { Injectable, Inject } from '@angular/core'; import { Injectable, Inject } from '@angular/core';
import { Observable, of, BehaviorSubject, throwError } from 'rxjs'; import { Observable, of, BehaviorSubject } from 'rxjs';
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model'; import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
import { switchMap, map, catchError } from 'rxjs/operators'; import { switchMap, map } from 'rxjs/operators';
import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service'; import { PROCESS_FILTERS_SERVICE_TOKEN } from '../../../services/cloud-token.service';
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface'; import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
import { IdentityUserService } from '../../../people/services/identity-user.service'; import { IdentityUserService } from '../../../people/services/identity-user.service';
@@ -100,7 +100,7 @@ export class ProcessFilterCloudService {
this.preferenceService this.preferenceService
.getPreferences(appName, key) .getPreferences(appName, key)
.pipe( .pipe(
switchMap((response: any) => { switchMap((response) => {
const preferences = response?.list?.entries ? response.list.entries : []; const preferences = response?.list?.entries ? response.list.entries : [];
if (!this.hasPreferences(preferences)) { if (!this.hasPreferences(preferences)) {
return this.createProcessFilters(appName, key, this.defaultProcessFilters(appName)); return this.createProcessFilters(appName, key, this.defaultProcessFilters(appName));
@@ -109,8 +109,7 @@ export class ProcessFilterCloudService {
} else { } else {
return of(this.findFiltersByKeyInPreferences(preferences, key)); return of(this.findFiltersByKeyInPreferences(preferences, key));
} }
}), })
catchError((err) => this.handleProcessError(err))
) )
.subscribe((filters) => { .subscribe((filters) => {
this.addFiltersToStream(filters); this.addFiltersToStream(filters);
@@ -138,15 +137,14 @@ export class ProcessFilterCloudService {
getFilterById(appName: string, id: string): Observable<ProcessFilterCloudModel> { getFilterById(appName: string, id: string): Observable<ProcessFilterCloudModel> {
const key: string = this.prepareKey(appName); const key: string = this.prepareKey(appName);
return this.getProcessFiltersByKey(appName, key).pipe( return this.getProcessFiltersByKey(appName, key).pipe(
switchMap((filters: ProcessFilterCloudModel[]) => { switchMap((filters) => {
if (filters?.length === 0) { if (filters?.length === 0) {
return this.createProcessFilters(appName, key, this.defaultProcessFilters(appName)); return this.createProcessFilters(appName, key, this.defaultProcessFilters(appName));
} else { } else {
return of(filters); return of(filters);
} }
}), }),
map((filters) => filters.filter((filter) => filter.id === id)[0]), map((filters) => filters.filter((filter) => filter.id === id)[0])
catchError((err) => this.handleProcessError(err))
); );
} }
@@ -158,7 +156,7 @@ export class ProcessFilterCloudService {
*/ */
addFilter(newFilter: ProcessFilterCloudModel): Observable<ProcessFilterCloudModel[]> { addFilter(newFilter: ProcessFilterCloudModel): Observable<ProcessFilterCloudModel[]> {
const { appName, name } = newFilter; const { appName, name } = newFilter;
const key: string = this.prepareKey(appName); const key = this.prepareKey(appName);
return this.getProcessFiltersByKey(appName, key).pipe( return this.getProcessFiltersByKey(appName, key).pipe(
switchMap((filters) => { switchMap((filters) => {
@@ -174,11 +172,10 @@ export class ProcessFilterCloudService {
return this.preferenceService.updatePreference(appName, key, filters); return this.preferenceService.updatePreference(appName, key, filters);
} }
}), }),
map((filters: ProcessFilterCloudModel[]) => { map((filters) => {
this.addFiltersToStream(filters); this.addFiltersToStream(filters);
return filters; return filters;
}), })
catchError((err) => this.handleProcessError(err))
); );
} }
@@ -189,7 +186,7 @@ export class ProcessFilterCloudService {
* @returns Observable of process instance filters with updated filter * @returns Observable of process instance filters with updated filter
*/ */
updateFilter(updatedFilter: ProcessFilterCloudModel): Observable<ProcessFilterCloudModel[]> { updateFilter(updatedFilter: ProcessFilterCloudModel): Observable<ProcessFilterCloudModel[]> {
const key: string = this.prepareKey(updatedFilter.appName); const key = this.prepareKey(updatedFilter.appName);
return this.getProcessFiltersByKey(updatedFilter.appName, key).pipe( return this.getProcessFiltersByKey(updatedFilter.appName, key).pipe(
switchMap((filters) => { switchMap((filters) => {
if (filters?.length === 0) { if (filters?.length === 0) {
@@ -203,8 +200,7 @@ export class ProcessFilterCloudService {
map((updatedFilters) => { map((updatedFilters) => {
this.addFiltersToStream(updatedFilters); this.addFiltersToStream(updatedFilters);
return updatedFilters; return updatedFilters;
}), })
catchError((err) => this.handleProcessError(err))
); );
} }
@@ -226,11 +222,10 @@ export class ProcessFilterCloudService {
return of([]); return of([]);
} }
}), }),
map((filters: ProcessFilterCloudModel[]) => { map((filters) => {
this.addFiltersToStream(filters); this.addFiltersToStream(filters);
return filters; return filters;
}), })
catchError((err) => this.handleProcessError(err))
); );
} }
@@ -345,10 +340,6 @@ export class ProcessFilterCloudService {
this.filtersSubject.next(filters); this.filtersSubject.next(filters);
} }
private handleProcessError(error: any) {
return throwError(error || 'Server error');
}
/** /**
* Creates and returns the default filters for a process app. * Creates and returns the default filters for a process app.
* *

View File

@@ -112,21 +112,18 @@ describe('ServiceTaskFiltersCloudComponent', () => {
expect(filters[2].nativeElement.innerText).toContain('FakeMyServiceTasks2'); expect(filters[2].nativeElement.innerText).toContain('FakeMyServiceTasks2');
}); });
it('should emit an error with a bad response', async () => { it('should emit an error with a bad response', () => {
const mockErrorFilterList = { getTaskListFiltersSpy.and.returnValue(throwError('wrong request'));
error: 'wrong request'
};
getTaskListFiltersSpy.and.returnValue(throwError(mockErrorFilterList));
const appName = 'my-app-1'; const appName = 'my-app-1';
const change = new SimpleChange(null, appName, true); const change = new SimpleChange(null, appName, true);
await component.error.subscribe((err) => { let lastValue: any;
expect(err).toBeDefined(); component.error.subscribe((err) => lastValue = err);
});
component.ngOnChanges({ appName: change }); component.ngOnChanges({ appName: change });
fixture.detectChanges(); fixture.detectChanges();
expect(lastValue).toBeDefined();
}); });
it('should not select any filter as default', async () => { it('should not select any filter as default', async () => {

View File

@@ -31,9 +31,7 @@ import {
import { UserPreferenceCloudService } from '../../../services/user-preference-cloud.service'; import { UserPreferenceCloudService } from '../../../services/user-preference-cloud.service';
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface'; import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TaskFilterCloudModel } from '../models/filter-cloud.model';
import { NotificationCloudService } from '../../../services/notification-cloud.service'; import { NotificationCloudService } from '../../../services/notification-cloud.service';
import { TaskCloudEngineEvent } from './../../../models/engine-event-cloud.model';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
import { IdentityUserService } from '../../../people/services/identity-user.service'; import { IdentityUserService } from '../../../people/services/identity-user.service';
import { ApolloModule } from 'apollo-angular'; import { ApolloModule } from 'apollo-angular';
@@ -72,16 +70,18 @@ describe('TaskFilterCloudService', () => {
getCurrentUserInfoSpy = spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue(identityUserMock); getCurrentUserInfoSpy = spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue(identityUserMock);
}); });
it('should create task filter key by using appName and the username', async () => { it('should create task filter key by using appName and the username', (done) => {
await service.getTaskListFilters('fakeAppName').subscribe((res: any) => { service.getTaskListFilters('fakeAppName').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(getCurrentUserInfoSpy).toHaveBeenCalled(); expect(getCurrentUserInfoSpy).toHaveBeenCalled();
done();
}); });
}); });
it('should create default task filters if there are no task filter preferences', async () => { it('should create default task filters if there are no task filter preferences', (done) => {
getPreferencesSpy.and.returnValue(of(fakeEmptyTaskCloudPreferenceList)); getPreferencesSpy.and.returnValue(of(fakeEmptyTaskCloudPreferenceList));
await service.getTaskListFilters('fakeAppName').subscribe((res: any) => {
service.getTaskListFilters('fakeAppName').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
@@ -100,12 +100,14 @@ describe('TaskFilterCloudService', () => {
expect(res[2].id).toBe('3'); expect(res[2].id).toBe('3');
expect(res[2].name).toBe('FAKE_TASK_3'); expect(res[2].name).toBe('FAKE_TASK_3');
expect(res[2].status).toBe('COMPLETED'); expect(res[2].status).toBe('COMPLETED');
expect(createPreferenceSpy).toHaveBeenCalled();
done();
}); });
expect(createPreferenceSpy).toHaveBeenCalled();
}); });
it('should return the task filters if filters available', async () => { it('should return the task filters if filters available', (done) => {
await service.getTaskListFilters('fakeAppName').subscribe((res: any) => { service.getTaskListFilters('fakeAppName').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
@@ -124,14 +126,16 @@ describe('TaskFilterCloudService', () => {
expect(res[2].id).toBe('3'); expect(res[2].id).toBe('3');
expect(res[2].name).toBe('FAKE_TASK_3'); expect(res[2].name).toBe('FAKE_TASK_3');
expect(res[2].status).toBe('COMPLETED'); expect(res[2].status).toBe('COMPLETED');
expect(getPreferencesSpy).toHaveBeenCalled();
done();
}); });
expect(getPreferencesSpy).toHaveBeenCalled();
}); });
it('should create the task filters if the user preference does not have task filters', async () => { it('should create the task filters if the user preference does not have task filters', (done) => {
getPreferencesSpy.and.returnValue(of(fakePreferenceWithNoTaskFilterPreference)); getPreferencesSpy.and.returnValue(of(fakePreferenceWithNoTaskFilterPreference));
await service.getTaskListFilters('fakeAppName').subscribe((res) => { service.getTaskListFilters('fakeAppName').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
@@ -150,57 +154,67 @@ describe('TaskFilterCloudService', () => {
expect(res[2].id).toBe('3'); expect(res[2].id).toBe('3');
expect(res[2].name).toBe('FAKE_TASK_3'); expect(res[2].name).toBe('FAKE_TASK_3');
expect(res[2].status).toBe('COMPLETED'); expect(res[2].status).toBe('COMPLETED');
});
done();
});
}); });
it('should return filter by task filter id', async () => { it('should return filter by task filter id', (done) => {
await service.getTaskFilterById('fakeAppName', '2').subscribe((res: any) => { service.getTaskFilterById('fakeAppName', '2').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.appName).toBe('fakeAppName'); expect(res.appName).toBe('fakeAppName');
expect(res.id).toBe('2'); expect(res.id).toBe('2');
expect(res.name).toBe('FAKE_TASK_2'); expect(res.name).toBe('FAKE_TASK_2');
expect(res.status).toBe('RUNNING'); expect(res.status).toBe('RUNNING');
expect(getPreferenceByKeySpy).toHaveBeenCalled();
done();
}); });
expect(getPreferenceByKeySpy).toHaveBeenCalled();
}); });
it('should add task filter if filter is not exist in the filters', async () => { it('should add task filter if filter is not exist in the filters', (done) => {
getPreferenceByKeySpy.and.returnValue(of([])); getPreferenceByKeySpy.and.returnValue(of([]));
await service.getTaskFilterById('fakeAppName', '2').subscribe((res: any) => {
service.getTaskFilterById('fakeAppName', '2').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.appName).toBe('fakeAppName'); expect(res.appName).toBe('fakeAppName');
expect(res.id).toBe('2'); expect(res.id).toBe('2');
expect(res.name).toBe('FAKE_TASK_2'); expect(res.name).toBe('FAKE_TASK_2');
expect(res.status).toBe('RUNNING'); expect(res.status).toBe('RUNNING');
done();
}); });
}); });
it('should update filter', async () => { it('should update filter', (done) => {
createPreferenceSpy.and.returnValue(of(fakeTaskCloudFilters)); createPreferenceSpy.and.returnValue(of(fakeTaskCloudFilters));
await service.updateFilter(fakeTaskFilter).subscribe((res: any) => {
service.updateFilter(fakeTaskFilter).subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
expect(res[0].appName).toBe('fakeAppName'); expect(res[0].appName).toBe('fakeAppName');
expect(res[1].appName).toBe('fakeAppName'); expect(res[1].appName).toBe('fakeAppName');
expect(res[2].appName).toBe('fakeAppName'); expect(res[2].appName).toBe('fakeAppName');
done();
}); });
}); });
it('should create task filter when trying to update in case filter is not exist in the filters', async () => { it('should create task filter when trying to update in case filter is not exist in the filters', (done) => {
getPreferenceByKeySpy.and.returnValue(of([])); getPreferenceByKeySpy.and.returnValue(of([]));
await service.updateFilter(fakeTaskFilter).subscribe((res: any) => {
service.updateFilter(fakeTaskFilter).subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).not.toBeNull(); expect(res).not.toBeNull();
expect(res.length).toBe(3); expect(res.length).toBe(3);
expect(res[0].appName).toBe('fakeAppName'); expect(res[0].appName).toBe('fakeAppName');
expect(res[1].appName).toBe('fakeAppName'); expect(res[1].appName).toBe('fakeAppName');
expect(res[2].appName).toBe('fakeAppName'); expect(res[2].appName).toBe('fakeAppName');
expect(createPreferenceSpy).toHaveBeenCalled();
done();
}); });
expect(createPreferenceSpy).toHaveBeenCalled();
}); });
it('should check if given filter is a default filter', () => { it('should check if given filter is a default filter', () => {
@@ -211,13 +225,14 @@ describe('TaskFilterCloudService', () => {
expect(service.isDefaultFilter(fakeFilterName)).toBe(false); expect(service.isDefaultFilter(fakeFilterName)).toBe(false);
}); });
it('should return engine event task subscription', async () => { it('should return engine event task subscription', (done) => {
spyOn(notificationCloudService, 'makeGQLQuery').and.returnValue(of(taskCloudEngineEventsMock)); spyOn(notificationCloudService, 'makeGQLQuery').and.returnValue(of(taskCloudEngineEventsMock));
await service.getTaskNotificationSubscription('myAppName').subscribe((res: TaskCloudEngineEvent[]) => { service.getTaskNotificationSubscription('myAppName').subscribe((res) => {
expect(res.length).toBe(1); expect(res.length).toBe(1);
expect(res[0].eventType).toBe('TASK_ASSIGNED'); expect(res[0].eventType).toBe('TASK_ASSIGNED');
expect(res[0].entity.name).toBe('This is a new task'); expect(res[0].entity.name).toBe('This is a new task');
done();
}); });
}); });
}); });
@@ -244,9 +259,10 @@ describe('Inject [LocalPreferenceCloudService] into the TaskFilterCloudService',
spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue(identityUserMock); spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue(identityUserMock);
}); });
it('should create default task filters if there are no task filter preferences', async () => { it('should create default task filters if there are no task filter preferences', (done) => {
const appName = 'fakeAppName'; const appName = 'fakeAppName';
await service.getTaskListFilters(appName).subscribe((res: TaskFilterCloudModel[]) => {
service.getTaskListFilters(appName).subscribe((res) => {
expect(res.length).toEqual(3); expect(res.length).toEqual(3);
expect(res[0].name).toEqual('ADF_CLOUD_TASK_FILTERS.MY_TASKS'); expect(res[0].name).toEqual('ADF_CLOUD_TASK_FILTERS.MY_TASKS');
@@ -267,29 +283,31 @@ describe('Inject [LocalPreferenceCloudService] into the TaskFilterCloudService',
expect(res[2].appName).toEqual(appName); expect(res[2].appName).toEqual(appName);
expect(res[2].icon).toEqual('done'); expect(res[2].icon).toEqual('done');
expect(res[2].status).toEqual('COMPLETED'); expect(res[2].status).toEqual('COMPLETED');
expect(getPreferencesSpy).toHaveBeenCalled();
const localData = JSON.parse(localStorage.getItem(`task-filters-${appName}-${identityUserMock.username}`));
expect(localData.length).toEqual(3);
expect(localData[0].name).toEqual('ADF_CLOUD_TASK_FILTERS.MY_TASKS');
expect(localData[0].key).toEqual('my-tasks');
expect(localData[0].appName).toEqual(appName);
expect(localData[0].icon).toEqual('inbox');
expect(localData[0].status).toEqual('ASSIGNED');
expect(localData[0].assignee).toEqual(identityUserMock.username);
expect(localData[1].name).toEqual('ADF_CLOUD_TASK_FILTERS.QUEUED_TASKS');
expect(localData[1].key).toEqual('queued-tasks');
expect(localData[1].appName).toEqual(appName);
expect(localData[1].icon).toEqual('queue');
expect(localData[1].status).toEqual('CREATED');
expect(localData[2].name).toEqual('ADF_CLOUD_TASK_FILTERS.COMPLETED_TASKS');
expect(localData[2].key).toEqual('completed-tasks');
expect(localData[2].appName).toEqual(appName);
expect(localData[2].icon).toEqual('done');
expect(localData[2].status).toEqual('COMPLETED');
done();
}); });
expect(getPreferencesSpy).toHaveBeenCalled();
const localData = JSON.parse(localStorage.getItem(`task-filters-${appName}-${identityUserMock.username}`));
expect(localData.length).toEqual(3);
expect(localData[0].name).toEqual('ADF_CLOUD_TASK_FILTERS.MY_TASKS');
expect(localData[0].key).toEqual('my-tasks');
expect(localData[0].appName).toEqual(appName);
expect(localData[0].icon).toEqual('inbox');
expect(localData[0].status).toEqual('ASSIGNED');
expect(localData[0].assignee).toEqual(identityUserMock.username);
expect(localData[1].name).toEqual('ADF_CLOUD_TASK_FILTERS.QUEUED_TASKS');
expect(localData[1].key).toEqual('queued-tasks');
expect(localData[1].appName).toEqual(appName);
expect(localData[1].icon).toEqual('queue');
expect(localData[1].status).toEqual('CREATED');
expect(localData[2].name).toEqual('ADF_CLOUD_TASK_FILTERS.COMPLETED_TASKS');
expect(localData[2].key).toEqual('completed-tasks');
expect(localData[2].appName).toEqual(appName);
expect(localData[2].icon).toEqual('done');
expect(localData[2].status).toEqual('COMPLETED');
}); });
}); });

View File

@@ -56,7 +56,7 @@ module.exports = function (config) {
reporters: [{ type: 'html' }, { type: 'text-summary' }], reporters: [{ type: 'html' }, { type: 'text-summary' }],
check: { check: {
global: { global: {
statements: 80, statements: 75,
branches: 67, branches: 67,
functions: 70, functions: 70,
lines: 75 lines: 75

View File

@@ -16,22 +16,17 @@
*/ */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, from, throwError, of } from 'rxjs'; import { Observable, from, of } from 'rxjs';
import { AlfrescoApiService, LogService, GroupModel } from '@alfresco/adf-core'; import { AlfrescoApiService, GroupModel } from '@alfresco/adf-core';
import { BpmUserModel } from '../models/bpm-user.model'; import { BpmUserModel } from '../models/bpm-user.model';
import { UserProcessModel } from '../models/user-process.model'; import { UserProcessModel } from '../models/user-process.model';
import { catchError, combineAll, defaultIfEmpty, map, switchMap } from 'rxjs/operators'; import { combineAll, defaultIfEmpty, map, switchMap } from 'rxjs/operators';
import { import { TaskActionsApi, UsersApi, ResultListDataRepresentationLightUserRepresentation, ActivitiGroupsApi, UserProfileApi } from '@alfresco/js-api';
TaskActionsApi,
UsersApi,
ResultListDataRepresentationLightUserRepresentation, ActivitiGroupsApi, UserProfileApi
} from '@alfresco/js-api';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class PeopleProcessService { export class PeopleProcessService {
private _taskActionsApi: TaskActionsApi; private _taskActionsApi: TaskActionsApi;
get taskActionsApi(): TaskActionsApi { get taskActionsApi(): TaskActionsApi {
this._taskActionsApi = this._taskActionsApi ?? new TaskActionsApi(this.apiService.getInstance()); this._taskActionsApi = this._taskActionsApi ?? new TaskActionsApi(this.apiService.getInstance());
@@ -56,9 +51,7 @@ export class PeopleProcessService {
return this._profileApi; return this._profileApi;
} }
constructor(private apiService: AlfrescoApiService, constructor(private apiService: AlfrescoApiService) {}
private logService: LogService) {
}
/** /**
* Gets information about the current user. * Gets information about the current user.
@@ -66,11 +59,7 @@ export class PeopleProcessService {
* @returns User information object * @returns User information object
*/ */
getCurrentUserInfo(): Observable<BpmUserModel> { getCurrentUserInfo(): Observable<BpmUserModel> {
return from(this.profileApi.getProfile()) return from(this.profileApi.getProfile()).pipe(map((userRepresentation) => new BpmUserModel(userRepresentation)));
.pipe(
map((userRepresentation) => new BpmUserModel(userRepresentation)),
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -94,11 +83,7 @@ export class PeopleProcessService {
if (groupId) { if (groupId) {
option.groupId = groupId; option.groupId = groupId;
} }
return from(this.groupsApi.getGroups(option)) return from(this.groupsApi.getGroups(option)).pipe(map((response: any) => response.data || []));
.pipe(
map((response: any) => response.data || []),
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -112,17 +97,15 @@ export class PeopleProcessService {
getWorkflowUsers(taskId?: string, searchWord?: string, groupId?: string): Observable<UserProcessModel[]> { getWorkflowUsers(taskId?: string, searchWord?: string, groupId?: string): Observable<UserProcessModel[]> {
const option = { excludeTaskId: taskId, filter: searchWord, groupId }; const option = { excludeTaskId: taskId, filter: searchWord, groupId };
return from(this.getWorkflowUserApi(option)) return from(this.getWorkflowUserApi(option)).pipe(
.pipe( switchMap((response) => (response.data as UserProcessModel[]) || []),
switchMap(response => response.data as UserProcessModel[] || []), map((user) => {
map((user) => { user.userImage = this.getUserProfileImageApi(user.id.toString());
user.userImage = this.getUserProfileImageApi(user.id.toString()); return of(user);
return of(user); }),
}), combineAll(),
combineAll(), defaultIfEmpty([])
defaultIfEmpty([]), );
catchError((err) => this.handleError(err))
);
} }
/** /**
* Gets the profile picture URL for the specified user. * Gets the profile picture URL for the specified user.
@@ -142,11 +125,7 @@ export class PeopleProcessService {
* @returns Empty response when the update completes * @returns Empty response when the update completes
*/ */
involveUserWithTask(taskId: string, idToInvolve: string): Observable<UserProcessModel[]> { involveUserWithTask(taskId: string, idToInvolve: string): Observable<UserProcessModel[]> {
const node = { userId: idToInvolve }; return from(this.involveUserToTaskApi(taskId, { userId: idToInvolve }));
return from(this.involveUserToTaskApi(taskId, node))
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -157,11 +136,7 @@ export class PeopleProcessService {
* @returns Empty response when the update completes * @returns Empty response when the update completes
*/ */
removeInvolvedUser(taskId: string, idToRemove: string): Observable<UserProcessModel[]> { removeInvolvedUser(taskId: string, idToRemove: string): Observable<UserProcessModel[]> {
const node = { userId: idToRemove }; return from(this.removeInvolvedUserFromTaskApi(taskId, { userId: idToRemove }));
return from(this.removeInvolvedUserFromTaskApi(taskId, node))
.pipe(
catchError((err) => this.handleError(err))
);
} }
private getWorkflowUserApi(options: any): Promise<ResultListDataRepresentationLightUserRepresentation> { private getWorkflowUserApi(options: any): Promise<ResultListDataRepresentationLightUserRepresentation> {
@@ -179,9 +154,4 @@ export class PeopleProcessService {
private getUserProfileImageApi(userId: string): string { private getUserProfileImageApi(userId: string): string {
return this.userApi.getUserProfilePictureUrl(userId); return this.userApi.getUserProfilePictureUrl(userId);
} }
private handleError(error: any) {
this.logService.error(error);
return throwError(error || 'Server error');
}
} }

View File

@@ -16,7 +16,7 @@
*/ */
import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core';
import { from, of } from 'rxjs'; import { from, of, throwError } from 'rxjs';
import { FilterProcessRepresentationModel } from '../models/filter-process.model'; import { FilterProcessRepresentationModel } from '../models/filter-process.model';
import { AppsProcessService } from '../../app-list/services/apps-process.service'; import { AppsProcessService } from '../../app-list/services/apps-process.service';
import { ProcessFilterService } from '../services/process-filter.service'; import { ProcessFilterService } from '../services/process-filter.service';
@@ -28,6 +28,7 @@ import { ProcessTestingModule } from '../../testing/process.testing.module';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { NavigationStart, Router } from '@angular/router'; import { NavigationStart, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
describe('ProcessFiltersComponent', () => { describe('ProcessFiltersComponent', () => {
@@ -62,14 +63,8 @@ describe('ProcessFiltersComponent', () => {
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
await filterList.success.subscribe((res) => { let lastValue: ProcessInstanceFilterRepresentation[];
expect(res).toBeDefined(); filterList.success.subscribe((res) => lastValue = res);
expect(filterList.filters).toBeDefined();
expect(filterList.filters.length).toEqual(3);
expect(filterList.filters[0].name).toEqual('FakeCompleted');
expect(filterList.filters[1].name).toEqual('FakeAll');
expect(filterList.filters[2].name).toEqual('Running');
});
spyOn(filterList, 'getFiltersByAppId').and.callThrough(); spyOn(filterList, 'getFiltersByAppId').and.callThrough();
@@ -79,6 +74,14 @@ describe('ProcessFiltersComponent', () => {
await fixture.whenStable(); await fixture.whenStable();
expect(filterList.getFiltersByAppId).toHaveBeenCalled(); expect(filterList.getFiltersByAppId).toHaveBeenCalled();
expect(lastValue).toBeDefined();
expect(lastValue).toEqual(filterList.filters);
expect(filterList.filters).toBeDefined();
expect(filterList.filters.length).toEqual(3);
expect(filterList.filters[0].name).toEqual('FakeCompleted');
expect(filterList.filters[1].name).toEqual('FakeAll');
expect(filterList.filters[2].name).toEqual('Running');
}); });
it('should select the Running process filter', async () => { it('should select the Running process filter', async () => {
@@ -87,15 +90,13 @@ describe('ProcessFiltersComponent', () => {
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
await filterList.success.subscribe(() => {
filterList.selectRunningFilter();
expect(filterList.currentFilter.name).toEqual('Running');
});
filterList.ngOnChanges({ appId: change }); filterList.ngOnChanges({ appId: change });
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
filterList.selectRunningFilter();
expect(filterList.currentFilter.name).toEqual('Running');
}); });
it('should emit the selected filter based on the filterParam input', async () => { it('should emit the selected filter based on the filterParam input', async () => {
@@ -104,13 +105,14 @@ describe('ProcessFiltersComponent', () => {
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
await filterList.filterSelected.subscribe((filter) => { let lastValue: UserProcessInstanceFilterRepresentation;
expect(filter.name).toEqual('FakeCompleted'); filterList.filterSelected.subscribe((filter) => lastValue = filter);
});
filterList.ngOnChanges({ appId: change }); filterList.ngOnChanges({ appId: change });
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
expect(lastValue.name).toEqual('FakeCompleted');
}); });
it('should filterClicked emit when a filter is clicked from the UI', async () => { it('should filterClicked emit when a filter is clicked from the UI', async () => {
@@ -143,50 +145,44 @@ describe('ProcessFiltersComponent', () => {
expect(filterList.currentFilter).toBe(undefined); expect(filterList.currentFilter).toBe(undefined);
}); });
it('should return the filter task list, filtered By Name', async () => { it('should return the filter task list, filtered By Name', () => {
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(from(Promise.resolve({ id: 1 }))); const deployApp = spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(from(Promise.resolve({ id: 1 })));
spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(fakeProcessFilters)); spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(fakeProcessFilters));
const change = new SimpleChange(null, 'test', true); const change = new SimpleChange(null, 'test', true);
filterList.ngOnChanges({ appName: change }); filterList.ngOnChanges({ appName: change });
await filterList.success.subscribe((res) => {
const deployApp: any = appsProcessService.getDeployedApplicationsByName;
expect(deployApp.calls.count()).toEqual(1);
expect(res).toBeDefined();
});
fixture.detectChanges(); fixture.detectChanges();
expect(deployApp.calls.count()).toEqual(1);
}); });
it('should emit an error with a bad response of getProcessFilters', async () => { it('should emit an error with a bad response of getProcessFilters', () => {
const mockErrorFilterPromise = Promise.reject(new Error('wrong request')); spyOn(processFilterService, 'getProcessFilters').and.returnValue(throwError('error'));
spyOn(processFilterService, 'getProcessFilters').and.returnValue(from(mockErrorFilterPromise));
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
let lastValue: any;
filterList.error.subscribe((err) => lastValue = err);
filterList.ngOnChanges({ appId: change }); filterList.ngOnChanges({ appId: change });
await filterList.error.subscribe((err) => { expect(lastValue).toBeDefined();
expect(err).toBeDefined();
});
fixture.detectChanges();
}); });
it('should emit an error with a bad response of getDeployedApplicationsByName', async () => { it('should emit an error with a bad response of getDeployedApplicationsByName', () => {
const mockErrorFilterPromise = Promise.reject(new Error('wrong request')); spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(throwError('wrong request'));
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(from(mockErrorFilterPromise));
const appId = 'fake-app'; const appId = 'fake-app';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
let lastValue: any;
filterList.error.subscribe((err) => lastValue = err);
filterList.ngOnChanges({ appName: change }); filterList.ngOnChanges({ appName: change });
await filterList.error.subscribe((err) => {
expect(err).toBeDefined();
});
fixture.detectChanges(); fixture.detectChanges();
expect(lastValue).toBeDefined();
}); });
it('should emit an event when a filter is selected', async () => { it('should emit an event when a filter is selected', async () => {
@@ -196,13 +192,13 @@ describe('ProcessFiltersComponent', () => {
filter: { state: 'open', assignment: 'fake-involved' } filter: { state: 'open', assignment: 'fake-involved' }
}); });
await filterList.filterClicked.subscribe((filter) => { let lastValue: UserProcessInstanceFilterRepresentation;
expect(filter).toBeDefined(); filterList.filterClicked.subscribe((filter) => lastValue = filter);
expect(filter).toEqual(currentFilter);
expect(filterList.currentFilter).toEqual(currentFilter);
});
filterList.selectFilter(currentFilter); filterList.selectFilter(currentFilter);
expect(lastValue).toBeDefined();
expect(lastValue).toEqual(currentFilter);
expect(filterList.currentFilter).toEqual(currentFilter);
}); });
it('should reload filters by appId on binding changes', () => { it('should reload filters by appId on binding changes', () => {

View File

@@ -127,16 +127,16 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
*/ */
getFiltersByAppId(appId?: number) { getFiltersByAppId(appId?: number) {
this.processFilterService.getProcessFilters(appId).subscribe( this.processFilterService.getProcessFilters(appId).subscribe(
(res: ProcessInstanceFilterRepresentation[]) => { (res) => {
if (res.length === 0 && this.isFilterListEmpty()) { if (res.length === 0 && this.isFilterListEmpty()) {
this.processFilterService.createDefaultFilters(appId).subscribe( this.processFilterService.createDefaultFilters(appId).subscribe(
(resDefault: ProcessInstanceFilterRepresentation[]) => { (resDefault) => {
this.resetFilter(); this.resetFilter();
this.filters = resDefault; this.filters = resDefault;
this.selectProcessFilter(this.filterParam); this.selectProcessFilter(this.filterParam);
this.success.emit(resDefault); this.success.emit(resDefault);
}, },
(errDefault: any) => { (errDefault) => {
this.error.emit(errDefault); this.error.emit(errDefault);
} }
); );
@@ -147,7 +147,7 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
this.success.emit(res); this.success.emit(res);
} }
}, },
(err: any) => { (err) => {
this.error.emit(err); this.error.emit(err);
} }
); );

View File

@@ -19,14 +19,7 @@ import { NO_ERRORS_SCHEMA, SimpleChange } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { of, throwError } from 'rxjs'; import { of, throwError } from 'rxjs';
import { import { FormModel, FormOutcomeEvent, FormOutcomeModel, CommentModel, User } from '@alfresco/adf-core';
FormModel,
FormOutcomeEvent,
FormOutcomeModel,
LogService,
CommentModel,
User
} from '@alfresco/adf-core';
import { TaskDetailsModel } from '../models/task-details.model'; import { TaskDetailsModel } from '../models/task-details.model';
import { import {
noDataMock, noDataMock,
@@ -60,7 +53,6 @@ const fakeTaskAssignResponse = new TaskDetailsModel({
}); });
describe('TaskDetailsComponent', () => { describe('TaskDetailsComponent', () => {
let taskListService: TaskListService; let taskListService: TaskListService;
let taskService: TaskService; let taskService: TaskService;
let taskFormService: TaskFormService; let taskFormService: TaskFormService;
@@ -70,7 +62,6 @@ describe('TaskDetailsComponent', () => {
let getCommentsSpy: jasmine.Spy; let getCommentsSpy: jasmine.Spy;
let getTasksSpy: jasmine.Spy; let getTasksSpy: jasmine.Spy;
let assignTaskSpy: jasmine.Spy; let assignTaskSpy: jasmine.Spy;
let logService: LogService;
let taskCommentsService: TaskCommentsService; let taskCommentsService: TaskCommentsService;
let peopleProcessService: PeopleProcessService; let peopleProcessService: PeopleProcessService;
@@ -82,7 +73,6 @@ describe('TaskDetailsComponent', () => {
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}); });
logService = TestBed.inject(LogService);
peopleProcessService = TestBed.inject(PeopleProcessService); peopleProcessService = TestBed.inject(PeopleProcessService);
spyOn(peopleProcessService, 'getCurrentUserInfo').and.returnValue(of({ email: 'fake-email' } as any)); spyOn(peopleProcessService, 'getCurrentUserInfo').and.returnValue(of({ email: 'fake-email' } as any));
@@ -130,14 +120,14 @@ describe('TaskDetailsComponent', () => {
expect(getTaskDetailsSpy).not.toHaveBeenCalled(); expect(getTaskDetailsSpy).not.toHaveBeenCalled();
}); });
it('should send a claim task event when a task is claimed', async () => { it('should send a claim task event when a task is claimed', () => {
await component.claimedTask.subscribe((taskId) => { let lastValue: string;
expect(taskId).toBe('FAKE-TASK-CLAIM'); component.claimedTask.subscribe((taskId) => lastValue = taskId);
});
component.onClaimAction('FAKE-TASK-CLAIM'); component.onClaimAction('FAKE-TASK-CLAIM');
expect(lastValue).toBe('FAKE-TASK-CLAIM');
}); });
it('should send a unclaim task event when a task is unclaimed', async () => { it('should send a unclaim task event when a task is unclaimed', () => {
const taskUnclaimedSpy = spyOn(component.unClaimedTask, 'emit'); const taskUnclaimedSpy = spyOn(component.unClaimedTask, 'emit');
component.onUnclaimAction('FAKE-TASK-UNCLAIM'); component.onUnclaimAction('FAKE-TASK-UNCLAIM');
@@ -397,7 +387,7 @@ describe('TaskDetailsComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should return an observable with user search results', async () => { it('should return an observable with user search results', () => {
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([{ spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([{
id: 1, id: 1,
firstName: 'fake-test-1', firstName: 'fake-test-1',
@@ -410,32 +400,25 @@ describe('TaskDetailsComponent', () => {
email: 'fake-test-2@test.com' email: 'fake-test-2@test.com'
}])); }]));
await component.peopleSearch.subscribe((users) => { let lastValue: UserProcessModel[];
expect(users.length).toBe(2); component.peopleSearch.subscribe((users) => lastValue = users);
expect(users[0].firstName).toBe('fake-test-1');
expect(users[0].lastName).toBe('fake-last-1');
expect(users[0].email).toBe('fake-test-1@test.com');
expect(users[0].id).toBe(1);
});
component.searchUser('fake-search-word'); component.searchUser('fake-search-word');
expect(lastValue.length).toBe(2);
expect(lastValue[0].firstName).toBe('fake-test-1');
expect(lastValue[0].lastName).toBe('fake-last-1');
expect(lastValue[0].email).toBe('fake-test-1@test.com');
expect(lastValue[0].id).toBe(1);
}); });
it('should return an empty list for not valid search', async () => { it('should return an empty list for not valid search', () => {
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([])); spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([]));
await component.peopleSearch.subscribe((users) => { let lastValue: UserProcessModel[];
expect(users.length).toBe(0); component.peopleSearch.subscribe((users) => lastValue = users);
});
component.searchUser('fake-search-word'); component.searchUser('fake-search-word');
});
it('should log error message when search fails', async () => { expect(lastValue.length).toBe(0);
const logServiceErrorSpy = spyOn(logService, 'error');
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(throwError('fake-error'));
component.searchUser('fake-search');
expect(logServiceErrorSpy).toHaveBeenCalledWith('Could not load users');
}); });
it('should assign task to user', () => { it('should assign task to user', () => {

View File

@@ -19,7 +19,7 @@ import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppsProcessService } from '../../app-list/services/apps-process.service'; import { AppsProcessService } from '../../app-list/services/apps-process.service';
import { AppConfigService } from '@alfresco/adf-core'; import { AppConfigService } from '@alfresco/adf-core';
import { from, of } from 'rxjs'; import { of, throwError } from 'rxjs';
import { FilterParamsModel, FilterRepresentationModel } from '../models/filter.model'; import { FilterParamsModel, FilterRepresentationModel } from '../models/filter.model';
import { TaskListService } from '../services/tasklist.service'; import { TaskListService } from '../services/tasklist.service';
import { TaskFilterService } from '../services/task-filter.service'; import { TaskFilterService } from '../services/task-filter.service';
@@ -60,37 +60,35 @@ describe('TaskFiltersComponent', () => {
router = TestBed.inject(Router); router = TestBed.inject(Router);
}); });
it('should emit an error with a bad response', async () => { it('should emit an error with a bad response', () => {
const mockErrorFilterList = { spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(throwError('wrong request'));
error: 'wrong request'
};
const mockErrorFilterPromise = Promise.reject(mockErrorFilterList);
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(from(mockErrorFilterPromise));
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
component.ngOnChanges({ appId: change });
await component.error.subscribe((err) => { let lastError: any;
expect(err).toBeDefined(); component.error.subscribe((err) => lastError = err);
});
component.ngOnChanges({ appId: change });
expect(lastError).toBeDefined();
}); });
it('should return the filter task list', async () => { it('should return the filter task list', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
await component.success.subscribe((res) => { let lastValue: any;
expect(res).toBeDefined(); component.success.subscribe((res) => lastValue = res);
expect(component.filters).toBeDefined();
expect(component.filters.length).toEqual(3);
expect(component.filters[0].name).toEqual('FakeInvolvedTasks');
expect(component.filters[1].name).toEqual('FakeMyTasks1');
expect(component.filters[2].name).toEqual('FakeMyTasks2');
});
component.ngOnChanges({ appId: change }); component.ngOnChanges({ appId: change });
expect(lastValue).toBeDefined();
expect(component.filters).toBeDefined();
expect(component.filters.length).toEqual(3);
expect(component.filters[0].name).toEqual('FakeInvolvedTasks');
expect(component.filters[1].name).toEqual('FakeMyTasks1');
expect(component.filters[2].name).toEqual('FakeMyTasks2');
}); });
it('Should call the API to create the default task filters when no task filters exist', async () => { it('Should call the API to create the default task filters when no task filters exist', async () => {
@@ -105,52 +103,54 @@ describe('TaskFiltersComponent', () => {
expect(createDefaultFiltersSpy).toHaveBeenCalledWith(appId); expect(createDefaultFiltersSpy).toHaveBeenCalledWith(appId);
}); });
it('should return the filter task list, filtered By Name', async () => { it('should return the filter task list, filtered By Name', () => {
spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(of({} as any)); const deployApp = spyOn(appsProcessService, 'getDeployedApplicationsByName').and.returnValue(of({} as any));
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
const change = new SimpleChange(null, 'test', true); const change = new SimpleChange(null, 'test', true);
await component.success.subscribe((res) => { let lastValue: any;
const deployApp: any = appsProcessService.getDeployedApplicationsByName; component.success.subscribe((res) => lastValue = res);
expect(deployApp.calls.count()).toEqual(1);
expect(res).toBeDefined();
});
component.ngOnChanges({ appName: change }); component.ngOnChanges({ appName: change });
expect(deployApp.calls.count()).toEqual(1);
expect(lastValue).toBeDefined();
}); });
it('should select the task filter based on the input by name param', async () => { it('should select the task filter based on the input by name param', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
component.filterParam = new FilterParamsModel({ name: 'FakeMyTasks1' }); component.filterParam = new FilterParamsModel({ name: 'FakeMyTasks1' });
await component.success.subscribe((res) => { let lastValue: any;
expect(res).toBeDefined(); component.success.subscribe((res) => lastValue = res);
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeMyTasks1');
});
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
component.ngOnChanges({ appId: change }); component.ngOnChanges({ appId: change });
expect(lastValue).toBeDefined();
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeMyTasks1');
}); });
it('should select the task filter based on the input by index param', async () => { it('should select the task filter based on the input by index param', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
component.filterParam = new FilterParamsModel({ index: 2 }); component.filterParam = new FilterParamsModel({ index: 2 });
await component.success.subscribe((res) => { let lastValue: any;
expect(res).toBeDefined(); component.success.subscribe((res) => lastValue = res);
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeMyTasks2');
});
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
component.ngOnChanges({ appId: change }); component.ngOnChanges({ appId: change });
expect(lastValue).toBeDefined();
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeMyTasks2');
}); });
it('should select the task filter based on the input by id param', async () => { it('should select the task filter based on the input by id param', () => {
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters)); spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
component.filterParam = new FilterParamsModel({ id: 10 }); component.filterParam = new FilterParamsModel({ id: 10 });
@@ -158,13 +158,14 @@ describe('TaskFiltersComponent', () => {
const appId = '1'; const appId = '1';
const change = new SimpleChange(null, appId, true); const change = new SimpleChange(null, appId, true);
await component.success.subscribe((res) => { let lastValue: any;
expect(res).toBeDefined(); component.success.subscribe((res) => lastValue = res);
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeInvolvedTasks');
});
component.ngOnChanges({ appId: change }); component.ngOnChanges({ appId: change });
expect(lastValue).toBeDefined();
expect(component.currentFilter).toBeDefined();
expect(component.currentFilter.name).toEqual('FakeInvolvedTasks');
}); });
it('should emit the selected filter based on the filterParam input', () => { it('should emit the selected filter based on the filterParam input', () => {

View File

@@ -18,74 +18,27 @@
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { CoreModule } from '@alfresco/adf-core'; import { CoreModule } from '@alfresco/adf-core';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { import { fakeCompletedTaskList, fakeOpenTaskList, fakeTaskList } from '../../mock';
fakeCompletedTaskList, import { fakeFilter } from '../../mock/task/task-filters.mock';
fakeFormList,
fakeOpenTaskList,
fakeTaskDetails,
fakeTaskList,
fakeTasksChecklist,
fakeUser1,
fakeUser2,
secondFakeTaskList
} from '../../mock';
import { fakeFilter, fakeRepresentationFilter1, fakeRepresentationFilter2 } from '../../mock/task/task-filters.mock';
import { FilterRepresentationModel } from '../models/filter.model';
import { TaskDetailsModel } from '../models/task-details.model';
import { TaskListService } from './tasklist.service'; import { TaskListService } from './tasklist.service';
import { TaskRepresentation, TaskUpdateRepresentation } from '@alfresco/js-api';
import { ProcessTestingModule } from '../../testing/process.testing.module'; import { ProcessTestingModule } from '../../testing/process.testing.module';
import { UserProcessModel } from '../../common/models/user-process.model';
declare let jasmine: any;
describe('Activiti TaskList Service', () => { describe('Activiti TaskList Service', () => {
let service: TaskListService; let service: TaskListService;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [CoreModule.forRoot(), ProcessTestingModule]
CoreModule.forRoot(),
ProcessTestingModule
]
}); });
service = TestBed.inject(TaskListService); service = TestBed.inject(TaskListService);
jasmine.Ajax.install();
});
afterEach(() => {
jasmine.Ajax.uninstall();
}); });
describe('Content tests', () => { describe('Content tests', () => {
it('should return the task list filtered', (done) => {
service.getTasks(fakeFilter).subscribe((res) => {
expect(res).toBeDefined();
expect(res.size).toEqual(1);
expect(res.start).toEqual(0);
expect(res.data).toBeDefined();
expect(res.data.length).toEqual(1);
expect(res.data[0].name).toEqual('FakeNameTask');
expect(res.data[0].assignee.email).toEqual('fake-email@dom.com');
expect(res.data[0].assignee.firstName).toEqual('firstName');
expect(res.data[0].assignee.lastName).toEqual('lastName');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
});
it('should return the task list with all tasks filtered by state', (done) => { it('should return the task list with all tasks filtered by state', (done) => {
spyOn(service, 'getTasks').and.returnValue(of(fakeTaskList)); spyOn(service, 'getTasks').and.returnValue(of(fakeTaskList));
spyOn(service, 'getTotalTasks').and.returnValue(of(fakeTaskList)); spyOn(service, 'getTotalTasks').and.returnValue(of(fakeTaskList));
service.findAllTaskByState(fakeFilter, 'open').subscribe((res) => { service.findAllTaskByState(fakeFilter, 'open').subscribe((res) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res.size).toEqual(1); expect(res.size).toEqual(1);
expect(res.start).toEqual(0); expect(res.start).toEqual(0);
@@ -117,27 +70,6 @@ describe('Activiti TaskList Service', () => {
}); });
}); });
it('should return the task list filtered by state', (done) => {
service.findTasksByState(fakeFilter, 'open').subscribe((res) => {
expect(res).toBeDefined();
expect(res.size).toEqual(1);
expect(res.start).toEqual(0);
expect(res.data).toBeDefined();
expect(res.data.length).toEqual(1);
expect(res.data[0].name).toEqual('FakeNameTask');
expect(res.data[0].assignee.email).toEqual('fake-email@dom.com');
expect(res.data[0].assignee.firstName).toEqual('firstName');
expect(res.data[0].assignee.lastName).toEqual('lastName');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
});
it('should return the task list with all tasks filtered without state', (done) => { it('should return the task list with all tasks filtered without state', (done) => {
spyOn(service, 'getTasks').and.returnValue(of(fakeTaskList)); spyOn(service, 'getTasks').and.returnValue(of(fakeTaskList));
spyOn(service, 'getTotalTasks').and.returnValue(of(fakeTaskList)); spyOn(service, 'getTotalTasks').and.returnValue(of(fakeTaskList));
@@ -190,325 +122,5 @@ describe('Activiti TaskList Service', () => {
done(); done();
}); });
}); });
it('should return the task details ', (done) => {
service.getTaskDetails('999').subscribe((res: TaskDetailsModel) => {
expect(res).toBeDefined();
expect(res.id).toEqual('999');
expect(res.name).toEqual('fake-task-name');
expect(res.formKey).toEqual('99');
expect(res.assignee).toBeDefined();
expect(res.assignee.email).toEqual('fake-email@dom.com');
expect(res.assignee.firstName).toEqual('firstName');
expect(res.assignee.lastName).toEqual('lastName');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskDetails)
});
});
it('should return the tasks checklists ', (done) => {
service.getTaskChecklist('999').subscribe((res: TaskDetailsModel[]) => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].name).toEqual('FakeCheckTask1');
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
expect(res[0].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
expect(res[1].name).toEqual('FakeCheckTask2');
expect(res[1].assignee.email).toEqual('fake-email@dom.com');
expect(res[1].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTasksChecklist)
});
});
it('should add a task ', (done) => {
const taskFake = new TaskDetailsModel({
id: 123,
parentTaskId: 456,
name: 'FakeNameTask',
description: null,
category: null,
assignee: fakeUser1,
created: ''
});
service.addTask(taskFake).subscribe((res: TaskDetailsModel) => {
expect(res).toBeDefined();
expect(res.id).not.toEqual('');
expect(res.name).toEqual('FakeNameTask');
expect(res.created).not.toEqual(null);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({
id: '777', name: 'FakeNameTask', description: null, category: null,
assignee: fakeUser1,
created: '2016-07-15T11:19:17.440+0000'
})
});
});
it('should remove a checklist task ', async () => {
await service.deleteTask('999').subscribe((res) => {
expect(res).toEqual({});
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({})
});
});
it('should complete the task', async () => {
await service.completeTask('999').subscribe((res: any) => {
expect(res).toBeDefined();
expect(res).toEqual({});
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({})
});
});
it('should return the total number of tasks', async () => {
await service.getTotalTasks(fakeFilter).subscribe((res: any) => {
expect(res).toBeDefined();
expect(res.size).toEqual(1);
expect(res.total).toEqual(1);
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
});
it('should create a new standalone task ', async () => {
const taskFake = new TaskDetailsModel({
name: 'FakeNameTask',
description: 'FakeDescription',
category: '3'
});
await service.createNewTask(taskFake).subscribe((res: TaskDetailsModel) => {
expect(res).toBeDefined();
expect(res.id).not.toEqual('');
expect(res.name).toEqual('FakeNameTask');
expect(res.description).toEqual('FakeDescription');
expect(res.category).toEqual('3');
expect(res.created).not.toEqual(null);
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({
id: '777',
name: 'FakeNameTask',
description: 'FakeDescription',
category: '3',
assignee: fakeUser1,
created: '2016-07-15T11:19:17.440+0000'
})
});
});
it('should assign task to a user', async () => {
const testTaskId = '8888';
await service.assignTask(testTaskId, fakeUser2).subscribe((res: TaskDetailsModel) => {
expect(res).toBeDefined();
expect(res.id).toEqual(testTaskId);
expect(res.name).toEqual('FakeNameTask');
expect(res.description).toEqual('FakeDescription');
expect(res.category).toEqual('3');
expect(res.created).not.toEqual(null);
expect(res.adhocTaskCanBeReassigned).toBe(true);
expect(res.assignee).toEqual(new UserProcessModel(fakeUser2));
expect(res.involvedPeople[0].email).toEqual(fakeUser1.email);
expect(res.involvedPeople[0].firstName).toEqual(fakeUser1.firstName);
expect(res.involvedPeople[0].lastName).toEqual(fakeUser1.lastName);
expect(res.involvedPeople[0].id).toEqual(fakeUser1.id);
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({
id: testTaskId,
name: 'FakeNameTask',
description: 'FakeDescription',
adhocTaskCanBeReassigned: true,
category: '3',
assignee: fakeUser2,
involvedPeople: [fakeUser1],
created: '2016-07-15T11:19:17.440+0000'
})
});
});
it('should assign task to a userId', async () => {
const testTaskId = '8888';
await service.assignTaskByUserId(testTaskId, fakeUser2.id.toString()).subscribe((res: TaskDetailsModel) => {
expect(res).toBeDefined();
expect(res.id).toEqual(testTaskId);
expect(res.name).toEqual('FakeNameTask');
expect(res.description).toEqual('FakeDescription');
expect(res.category).toEqual('3');
expect(res.created).not.toEqual(null);
expect(res.adhocTaskCanBeReassigned).toBe(true);
expect(res.assignee).toEqual(new UserProcessModel(fakeUser2));
expect(res.involvedPeople[0].email).toEqual(fakeUser1.email);
expect(res.involvedPeople[0].firstName).toEqual(fakeUser1.firstName);
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({
id: testTaskId,
name: 'FakeNameTask',
description: 'FakeDescription',
adhocTaskCanBeReassigned: true,
category: '3',
assignee: fakeUser2,
involvedPeople: [fakeUser1],
created: '2016-07-15T11:19:17.440+0000'
})
});
});
it('should claim a task', async () => {
const taskId = '111';
await service.claimTask(taskId).subscribe((res) => {
expect(res).toEqual({});
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({})
});
});
it('should unclaim a task', async () => {
const taskId = '111';
await service.unclaimTask(taskId).subscribe((res) => {
expect(res).toEqual({});
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({})
});
});
it('should update a task', async () => {
const taskId = '111';
const updated: TaskUpdateRepresentation = {
name: 'someName'
};
await service.updateTask(taskId, updated).subscribe((res) => {
expect(res).toEqual(new TaskRepresentation({}));
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify({})
});
});
it('should return the filter if it contains task id', async () => {
const taskId = '1';
const filterFake = new FilterRepresentationModel({
name: 'FakeNameFilter',
assignment: 'fake-assignment',
filter: {
processDefinitionKey: '1',
assignment: 'fake',
state: 'none',
sort: 'asc'
}
});
await service.isTaskRelatedToFilter(taskId, filterFake).subscribe((res: any) => {
expect(res).toBeDefined();
expect(res).not.toBeNull();
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
});
it('should return the filters if it contains task id', async () => {
const taskId = '1';
const fakeFilterList: FilterRepresentationModel[] = [];
fakeFilterList.push(fakeRepresentationFilter1, fakeRepresentationFilter2);
let resultFilter: FilterRepresentationModel = null;
await service.getFilterForTaskById(taskId, fakeFilterList).subscribe((res: FilterRepresentationModel) => {
resultFilter = res;
}, () => {
}, () => {
expect(resultFilter).toBeDefined();
expect(resultFilter).not.toBeNull();
expect(resultFilter.name).toBe('CONTAIN FILTER');
});
jasmine.Ajax.requests.at(0).respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
jasmine.Ajax.requests.at(1).respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(secondFakeTaskList)
});
});
it('should get possible form list', async () => {
await service.getFormList().subscribe((res: any) => {
expect(res).toBeDefined();
expect(res.length).toBe(2);
expect(res[0].id).toBe(1);
expect(res[0].name).toBe('form with all widgets');
expect(res[1].id).toBe(2);
expect(res[1].name).toBe('uppy');
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeFormList)
});
});
}); });
}); });

View File

@@ -15,9 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
import { AlfrescoApiService, LogService } from '@alfresco/adf-core'; import { AlfrescoApiService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, from, forkJoin, throwError, of } from 'rxjs'; import { Observable, from, forkJoin, of } from 'rxjs';
import { map, catchError, switchMap, flatMap, filter } from 'rxjs/operators'; import { map, catchError, switchMap, flatMap, filter } from 'rxjs/operators';
import { FilterRepresentationModel, TaskQueryRequestRepresentationModel } from '../models/filter.model'; import { FilterRepresentationModel, TaskQueryRequestRepresentationModel } from '../models/filter.model';
import { Form } from '../models/form.model'; import { Form } from '../models/form.model';
@@ -57,8 +57,7 @@ export class TaskListService {
return this._checklistsApi; return this._checklistsApi;
} }
constructor(private apiService: AlfrescoApiService, constructor(private apiService: AlfrescoApiService) {
private logService: LogService) {
} }
/** /**
@@ -87,8 +86,7 @@ export class TaskListService {
const requestNodeForFilter = this.generateTaskRequestNodeFromFilter(filterModel); const requestNodeForFilter = this.generateTaskRequestNodeFromFilter(filterModel);
return from(this.callApiTasksFiltered(requestNodeForFilter)) return from(this.callApiTasksFiltered(requestNodeForFilter))
.pipe( .pipe(
map(res => res.data.find((element) => element.id === taskId) ? filterModel : null), map(res => res.data.find((element) => element.id === taskId) ? filterModel : null)
catchError((err) => this.handleError(err))
); );
} }
@@ -99,10 +97,7 @@ export class TaskListService {
* @returns List of tasks * @returns List of tasks
*/ */
getTasks(requestNode: TaskQueryRequestRepresentationModel): Observable<TaskListModel> { getTasks(requestNode: TaskQueryRequestRepresentationModel): Observable<TaskListModel> {
return from(this.callApiTasksFiltered(requestNode)) return from(this.callApiTasksFiltered(requestNode));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -168,8 +163,7 @@ export class TaskListService {
getTaskDetails(taskId: string): Observable<TaskDetailsModel> { getTaskDetails(taskId: string): Observable<TaskDetailsModel> {
return from(this.callApiTaskDetails(taskId)) return from(this.callApiTaskDetails(taskId))
.pipe( .pipe(
map(details => new TaskDetailsModel(details)), map(details => new TaskDetailsModel(details))
catchError((err) => this.handleError(err))
); );
} }
@@ -188,8 +182,7 @@ export class TaskListService {
checklists.push(new TaskDetailsModel(checklist)); checklists.push(new TaskDetailsModel(checklist));
}); });
return checklists; return checklists;
}), })
catchError((err) => this.handleError(err))
); );
} }
@@ -213,8 +206,7 @@ export class TaskListService {
forms.push(new Form(form.id, form.name)); forms.push(new Form(form.id, form.name));
}); });
return forms; return forms;
}), })
catchError((err) => this.handleError(err))
); );
} }
@@ -226,10 +218,7 @@ export class TaskListService {
* @returns Null response notifying when the operation is complete * @returns Null response notifying when the operation is complete
*/ */
attachFormToATask(taskId: string, formId: number): Observable<any> { attachFormToATask(taskId: string, formId: number): Observable<any> {
return from(this.taskActionsApi.attachForm(taskId, { formId })) return from(this.taskActionsApi.attachForm(taskId, { formId }));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -241,8 +230,7 @@ export class TaskListService {
addTask(task: TaskDetailsModel): Observable<TaskDetailsModel> { addTask(task: TaskDetailsModel): Observable<TaskDetailsModel> {
return from(this.callApiAddTask(task)) return from(this.callApiAddTask(task))
.pipe( .pipe(
map((response) => new TaskDetailsModel(response)), map((response) => new TaskDetailsModel(response))
catchError((err) => this.handleError(err))
); );
} }
@@ -253,10 +241,7 @@ export class TaskListService {
* @returns Null response notifying when the operation is complete * @returns Null response notifying when the operation is complete
*/ */
deleteTask(taskId: string): Observable<TaskDetailsModel> { deleteTask(taskId: string): Observable<TaskDetailsModel> {
return from(this.callApiDeleteTask(taskId)) return from(this.callApiDeleteTask(taskId));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -266,10 +251,7 @@ export class TaskListService {
* @returns Null response notifying when the operation is complete * @returns Null response notifying when the operation is complete
*/ */
deleteForm(taskId: string): Observable<TaskDetailsModel> { deleteForm(taskId: string): Observable<TaskDetailsModel> {
return from(this.callApiDeleteForm(taskId)) return from(this.callApiDeleteForm(taskId));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -279,10 +261,7 @@ export class TaskListService {
* @returns Null response notifying when the operation is complete * @returns Null response notifying when the operation is complete
*/ */
completeTask(taskId: string) { completeTask(taskId: string) {
return from(this.taskActionsApi.completeTask(taskId)) return from(this.taskActionsApi.completeTask(taskId));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -291,12 +270,9 @@ export class TaskListService {
* @param requestNode Query to search for tasks * @param requestNode Query to search for tasks
* @returns Number of tasks * @returns Number of tasks
*/ */
public getTotalTasks(requestNode: TaskQueryRequestRepresentationModel): Observable<any> { public getTotalTasks(requestNode: TaskQueryRequestRepresentationModel): Observable<TaskListModel> {
requestNode.size = 0; requestNode.size = 0;
return from(this.callApiTasksFiltered(requestNode)) return from(this.callApiTasksFiltered(requestNode));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -308,8 +284,7 @@ export class TaskListService {
createNewTask(task: TaskDetailsModel): Observable<TaskDetailsModel> { createNewTask(task: TaskDetailsModel): Observable<TaskDetailsModel> {
return from(this.callApiCreateTask(task)) return from(this.callApiCreateTask(task))
.pipe( .pipe(
map((response) => new TaskDetailsModel(response)), map((response) => new TaskDetailsModel(response))
catchError((err) => this.handleError(err))
); );
} }
@@ -324,8 +299,7 @@ export class TaskListService {
const assignee = { assignee: requestNode.id }; const assignee = { assignee: requestNode.id };
return from(this.callApiAssignTask(taskId, assignee)) return from(this.callApiAssignTask(taskId, assignee))
.pipe( .pipe(
map((response) => new TaskDetailsModel(response)), map((response) => new TaskDetailsModel(response))
catchError((err) => this.handleError(err))
); );
} }
@@ -341,8 +315,7 @@ export class TaskListService {
return from(this.callApiAssignTask(taskId, assignee)) return from(this.callApiAssignTask(taskId, assignee))
.pipe( .pipe(
map((response) => new TaskDetailsModel(response)), map((response) => new TaskDetailsModel(response))
catchError((err) => this.handleError(err))
); );
} }
@@ -353,10 +326,7 @@ export class TaskListService {
* @returns Details of the claimed task * @returns Details of the claimed task
*/ */
claimTask(taskId: string): Observable<TaskDetailsModel> { claimTask(taskId: string): Observable<TaskDetailsModel> {
return from(this.taskActionsApi.claimTask(taskId)) return from(this.taskActionsApi.claimTask(taskId));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -366,10 +336,7 @@ export class TaskListService {
* @returns Null response notifying when the operation is complete * @returns Null response notifying when the operation is complete
*/ */
unclaimTask(taskId: string): Observable<TaskDetailsModel> { unclaimTask(taskId: string): Observable<TaskDetailsModel> {
return from(this.taskActionsApi.unclaimTask(taskId)) return from(this.taskActionsApi.unclaimTask(taskId));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -382,8 +349,7 @@ export class TaskListService {
updateTask(taskId: string, updated: TaskUpdateRepresentation): Observable<TaskDetailsModel> { updateTask(taskId: string, updated: TaskUpdateRepresentation): Observable<TaskDetailsModel> {
return from(this.tasksApi.updateTask(taskId, updated)) return from(this.tasksApi.updateTask(taskId, updated))
.pipe( .pipe(
map((result) => result as TaskDetailsModel), map((result) => result as TaskDetailsModel)
catchError((err) => this.handleError(err))
); );
} }
@@ -394,11 +360,7 @@ export class TaskListService {
* @returns Binary PDF data * @returns Binary PDF data
*/ */
fetchTaskAuditPdfById(taskId: string): Observable<Blob> { fetchTaskAuditPdfById(taskId: string): Observable<Blob> {
return from(this.tasksApi.getTaskAuditPdf(taskId)) return from(this.tasksApi.getTaskAuditPdf(taskId));
.pipe(
map((data) => data as Blob),
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -408,10 +370,7 @@ export class TaskListService {
* @returns JSON data * @returns JSON data
*/ */
fetchTaskAuditJsonById(taskId: string): Observable<any> { fetchTaskAuditJsonById(taskId: string): Observable<any> {
return from(this.tasksApi.getTaskAuditLog(taskId)) return from(this.tasksApi.getTaskAuditLog(taskId));
.pipe(
catchError((err) => this.handleError(err))
);
} }
/** /**
@@ -461,10 +420,4 @@ export class TaskListService {
private callApiAssignTask(taskId: string, requestNode: AssigneeIdentifierRepresentation): Promise<TaskDetailsModel> { private callApiAssignTask(taskId: string, requestNode: AssigneeIdentifierRepresentation): Promise<TaskDetailsModel> {
return this.taskActionsApi.assignTask(taskId, requestNode); return this.taskActionsApi.assignTask(taskId, requestNode);
} }
private handleError(error: any) {
this.logService.error(error);
return throwError(error || 'Server error');
}
} }