diff --git a/ng2-components/ng2-activiti-processlist/README.md b/ng2-components/ng2-activiti-processlist/README.md index a0976a6038..f349a0f7cb 100644 --- a/ng2-components/ng2-activiti-processlist/README.md +++ b/ng2-components/ng2-activiti-processlist/README.md @@ -418,17 +418,17 @@ This component displays attached documents on a specified process instance #### Options - | Name | Description | | --- | --- | | `processInstanceId` | (required): The numeric ID of the process instance to display | #### Events - | Name | Description | | --- | --- | -| `attachmentClick` | Emitted when the attachment double clicked or selected view option from context menu by the user from within the component | +| `attachmentClick` | Emitted when the attachment double clicked or selected view option from context menu by the user from within the component and return a Blob obj of the object clicker| +| `success` | Emitted when the attachment list fetch all the attach and return a list of attachments | +| `error` | Emitted when the attachment list is not able to fetch the attachments for example network error | ### Create Process Attachment component diff --git a/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.html b/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.html index 3613ae89f9..f9001080a7 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.html +++ b/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.html @@ -8,8 +8,8 @@ (showRowActionsMenu)="onShowRowActionsMenu($event)" (executeRowAction)="onExecuteRowAction($event)"> - + - \ No newline at end of file + diff --git a/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.spec.ts b/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.spec.ts index 541e270b39..191165be6e 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.spec.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.spec.ts @@ -36,6 +36,7 @@ describe('Activiti Process Instance Attachment List', () => { let getProcessRelatedContentSpy: jasmine.Spy; let deleteContentSpy: jasmine.Spy; let getFileRawContentSpy: jasmine.Spy; + let mockAttachment: any; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -59,31 +60,30 @@ describe('Activiti Process Instance Attachment List', () => { component = fixture.componentInstance; service = fixture.debugElement.injector.get(ActivitiContentService); - getProcessRelatedContentSpy = spyOn(service, 'getProcessRelatedContent').and.returnValue(Observable.of( - { - 'size': 2, - 'total': 2, - 'start': 0, - 'data': [{ - 'id': 4001, - 'name': 'Invoice01.pdf', - 'created': '2017-05-12T12:50:05.522+0000', - 'createdBy': { - 'id': 1, - 'firstName': 'Apps', - 'lastName': 'Administrator', - 'email': 'admin@app.activiti.com', - 'company': 'Alfresco.com', - 'pictureId': 3003 - }, - 'relatedContent': true, - 'contentAvailable': true, - 'link': false, - 'mimeType': 'application/pdf', - 'simpleType': 'pdf', - 'previewStatus': 'created', - 'thumbnailStatus': 'created' + mockAttachment = { + 'size': 2, + 'total': 2, + 'start': 0, + 'data': [{ + 'id': 4001, + 'name': 'Invoice01.pdf', + 'created': '2017-05-12T12:50:05.522+0000', + 'createdBy': { + 'id': 1, + 'firstName': 'Apps', + 'lastName': 'Administrator', + 'email': 'admin@app.activiti.com', + 'company': 'Alfresco.com', + 'pictureId': 3003 }, + 'relatedContent': true, + 'contentAvailable': true, + 'link': false, + 'mimeType': 'application/pdf', + 'simpleType': 'pdf', + 'previewStatus': 'created', + 'thumbnailStatus': 'created' + }, { 'id': 4002, 'name': 'Invoice02.pdf', @@ -104,7 +104,9 @@ describe('Activiti Process Instance Attachment List', () => { 'previewStatus': 'created', 'thumbnailStatus': 'created' }] - })); + }; + + getProcessRelatedContentSpy = spyOn(service, 'getProcessRelatedContent').and.returnValue(Observable.of(mockAttachment)); deleteContentSpy = spyOn(service, 'deleteRelatedContent').and.returnValue(Observable.of({successCode: true})); @@ -134,6 +136,16 @@ describe('Activiti Process Instance Attachment List', () => { expect(emitSpy).toHaveBeenCalled(); }); + it('should emit a success event when the attachments are loaded', () => { + let change = new SimpleChange(null, '123', true); + component.success.subscribe((attachments) => { + expect(attachments[0].name).toEqual(mockAttachment.data[0].name); + expect(attachments[0].id).toEqual(mockAttachment.data[0].id); + }); + + component.ngOnChanges({'taskId': change}); + }); + it('should not attach when no processInstanceId is specified', () => { fixture.detectChanges(); expect(getProcessRelatedContentSpy).not.toHaveBeenCalled(); diff --git a/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.ts b/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.ts index e003afba06..1647ca5500 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/adf-process-attachment-list.component.ts @@ -32,6 +32,9 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges { @Output() attachmentClick = new EventEmitter(); + @Output() + success = new EventEmitter(); + @Output() error: EventEmitter = new EventEmitter(); @@ -42,14 +45,13 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges { private contentService: ContentService) { if (translateService) { - translateService.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/src'); + translateService.addTranslationFolder('ng2-activiti-processlist', 'assets/ng2-activiti-processlist'); } } ngOnChanges(changes: SimpleChanges) { if (changes['processInstanceId'] && changes['processInstanceId'].currentValue) { - this.processInstanceId = changes['processInstanceId'].currentValue; - this.loadAttachmentsByProcessInstanceId(this.processInstanceId); + this.loadAttachmentsByProcessInstanceId(changes['processInstanceId'].currentValue); } } @@ -71,7 +73,7 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges { icon: this.activitiContentService.getMimeTypeIcon(content.mimeType) }); }); - + this.success.emit(this.attachments); }, (err) => { this.error.emit(err); @@ -149,9 +151,6 @@ export class ActivitiProcessAttachmentListComponent implements OnChanges { ); } - /** - * Invoke content download. - */ downloadContent(content: any): void { this.activitiContentService.getFileRawContent(content.id).subscribe( (blob: Blob) => this.contentService.downloadBlob(blob, content.name), diff --git a/ng2-components/ng2-activiti-tasklist/README.md b/ng2-components/ng2-activiti-tasklist/README.md index 4f1a17d9ee..d4ca524f2a 100644 --- a/ng2-components/ng2-activiti-tasklist/README.md +++ b/ng2-components/ng2-activiti-tasklist/README.md @@ -456,7 +456,9 @@ This component displays attached documents on a specified task | Name | Description | | --- | --- | -| `attachmentClick` | Emitted when the attachment double clicked or selected view option from context menu by the user from within the component | +| `attachmentClick` | Emitted when the attachment double clicked or selected view option from context menu by the user from within the component and return a Blob obj of the object clicker| +| `success` | Emitted when the attachment list fetch all the attach and return a list of attachments | +| `error` | Emitted when the attachment list is not able to fetch the attachments for example network error | ### Create Task Attachment component diff --git a/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.spec.ts index be73ab280a..1ad70d54d8 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.spec.ts @@ -22,6 +22,7 @@ import { DataTableModule } from 'ng2-alfresco-datatable'; import { ActivitiContentService } from 'ng2-activiti-form'; import { TaskAttachmentListComponent } from './adf-task-attachment-list.component'; import { Observable } from 'rxjs/Rx'; +import { By } from '@angular/platform-browser'; declare let jasmine: any; @@ -31,14 +32,10 @@ describe('TaskAttachmentList', () => { let component: TaskAttachmentListComponent; let fixture: ComponentFixture; let service: ActivitiContentService; - - beforeEach(() => { - jasmine.Ajax.install(); - }); - - afterEach(() => { - jasmine.Ajax.uninstall(); - }); + let getTaskRelatedContentSpy: jasmine.Spy; + let deleteContentSpy: jasmine.Spy; + let getFileRawContentSpy: jasmine.Spy; + let mockAttachment: any; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -56,7 +53,9 @@ describe('TaskAttachmentList', () => { let translateService = TestBed.get(AlfrescoTranslationService); spyOn(translateService, 'addTranslationFolder').and.stub(); - spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); + spyOn(translateService, 'get').and.callFake((key) => { + return Observable.of(key); + }); })); beforeEach(() => { @@ -66,6 +65,51 @@ describe('TaskAttachmentList', () => { service = TestBed.get(ActivitiContentService); + mockAttachment = { + size: 2, + total: 2, + start: 0, + data: [ + { + id: 8, + name: 'fake.zip', + created: 1494595697381, + createdBy: {id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com'}, + relatedContent: true, + contentAvailable: true, + link: false, + mimeType: 'application/zip', + simpleType: 'content', + previewStatus: 'unsupported', + thumbnailStatus: 'unsupported' + }, + { + id: 9, + name: 'fake.jpg', + created: 1494595655381, + createdBy: {id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com'}, + relatedContent: true, + contentAvailable: true, + link: false, + mimeType: 'image/jpeg', + simpleType: 'image', + previewStatus: 'unsupported', + thumbnailStatus: 'unsupported' + } + ] + }; + + getTaskRelatedContentSpy = spyOn(service, 'getTaskRelatedContent').and.returnValue(Observable.of( + mockAttachment + )); + + deleteContentSpy = spyOn(service, 'deleteRelatedContent').and.returnValue(Observable.of({successCode: true})); + + let blobObj = new Blob(); + getFileRawContentSpy = spyOn(service, 'getFileRawContent').and.returnValue(Observable.of( + blobObj + )); + componentHandler = jasmine.createSpyObj('componentHandler', [ 'upgradeAllRegistered', 'upgradeElement' @@ -73,58 +117,100 @@ describe('TaskAttachmentList', () => { window['componentHandler'] = componentHandler; }); - it('should fetch all the attachments of a taskId', (done) => { + it('should load attachments when taskId specified', () => { + let change = new SimpleChange(null, '123', true); + component.ngOnChanges({'taskId': change}); + expect(getTaskRelatedContentSpy).toHaveBeenCalled(); + }); - component.success.subscribe((res) => { - expect(res).toBeDefined(); - expect(res.length).toBe(2); - expect(res[0].name).toBe('fake.zip'); - expect(res[0].icon).toBe('ft_ic_archive.svg'); - expect(res[1].name).toBe('fake.jpg'); - expect(res[1].icon).toBe('ft_ic_raster_image.svg'); - done(); + it('should emit an error when an error occurs loading attachments', () => { + let emitSpy = spyOn(component.error, 'emit'); + getTaskRelatedContentSpy.and.returnValue(Observable.throw({})); + let change = new SimpleChange(null, '123', true); + component.ngOnChanges({'taskId': change}); + expect(emitSpy).toHaveBeenCalled(); + }); + + it('should emit a success event when the attachments are loaded', () => { + let change = new SimpleChange(null, '123', true); + component.success.subscribe((attachments) => { + expect(attachments[0].name).toEqual(mockAttachment.data[0].name); + expect(attachments[0].id).toEqual(mockAttachment.data[0].id); }); - let taskId = '1'; - let change = new SimpleChange(null, taskId, true); - component.ngOnChanges({ 'taskId': change }); + component.ngOnChanges({'taskId': change}); + }); - jasmine.Ajax.requests.mostRecent().respondWith({ - 'status': 200, - contentType: 'application/json', - responseText: JSON.stringify({ - size: 2, - total: 2, - start: 0, - data: [ - { - id: 8, - name: 'fake.zip', - created: 1494595697381, - createdBy: {id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com'}, - relatedContent: true, - contentAvailable: true, - link: false, - mimeType: 'application/zip', - simpleType: 'content', - previewStatus: 'unsupported', - thumbnailStatus: 'unsupported' - }, - { - id: 9, - name: 'fake.jpg', - created: 1494595655381, - createdBy: {id: 2, firstName: 'user', lastName: 'user', email: 'user@user.com'}, - relatedContent: true, - contentAvailable: true, - link: false, - mimeType: 'image/jpeg', - simpleType: 'image', - previewStatus: 'unsupported', - thumbnailStatus: 'unsupported' - } - ] - }) + it('should not attach when no taskId is specified', () => { + fixture.detectChanges(); + expect(getTaskRelatedContentSpy).not.toHaveBeenCalled(); + }); + + it('should display attachments when the task has attachments', async(() => { + let change = new SimpleChange(null, '123', true); + component.ngOnChanges({'taskId': change}); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(fixture.debugElement.queryAll(By.css('alfresco-datatable tbody tr')).length).toBe(2); + }); + })); + + it('should not display attachments when the task has no attachments', async(() => { + component.taskId = '123'; + getTaskRelatedContentSpy.and.returnValue(Observable.of({ + 'size': 0, + 'total': 0, + 'start': 0, + 'data': [] + })); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(fixture.debugElement.queryAll(By.css('alfresco-datatable tbody tr')).length).toBe(0); + }); + })); + + describe('change detection', () => { + + let change = new SimpleChange('123', '456', true); + let nullChange = new SimpleChange('123', null, true); + + beforeEach(async(() => { + component.taskId = '123'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + getTaskRelatedContentSpy.calls.reset(); + }); + })); + + it('should fetch new attachments when taskId changed', () => { + component.ngOnChanges({'taskId': change}); + expect(getTaskRelatedContentSpy).toHaveBeenCalledWith('456'); + }); + + it('should NOT fetch new attachments when empty changeset made', () => { + component.ngOnChanges({}); + expect(getTaskRelatedContentSpy).not.toHaveBeenCalled(); + }); + + it('should NOT fetch new attachments when taskId changed to null', () => { + component.ngOnChanges({'taskId': nullChange}); + expect(getTaskRelatedContentSpy).not.toHaveBeenCalled(); }); }); + + describe('Delete attachments', () => { + + beforeEach(async(() => { + component.taskId = '123'; + fixture.detectChanges(); + fixture.whenStable(); + })); + + it('should display a dialog to the user when the Add button clicked', () => { + expect(true).toBe(true); + }); + + }); }); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.ts index 0abe5fcf29..ff3911dace 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/adf-task-attachment-list.component.ts @@ -78,8 +78,10 @@ export class TaskAttachmentListComponent implements OnChanges { }); }); this.success.emit(this.attachments); - }); - } + }, + (err) => { + this.error.emit(err); + }); } } private deleteAttachmentById(contentId: string) { @@ -89,6 +91,9 @@ export class TaskAttachmentListComponent implements OnChanges { this.attachments = this.attachments.filter(content => { return content.id !== contentId; }); + }, + (err) => { + this.error.emit(err); }); } }