From 45f14fa506becb66986b6199d6e8e4044a8546e9 Mon Sep 17 00:00:00 2001 From: Vito Date: Fri, 16 Jun 2017 09:03:50 -0700 Subject: [PATCH] [ADF-510] Drag&Drop check permission to allow user to upload a file (#1948) * [ADF-510] added permission check for drag&drop * Improved code for drag and drop side * Added test for drag and drop upload area changes * Added test for document list permissions check * [ADF-510] rebased branch after changes applied to upload * [ADF-510] rebased branch and fixed tests --- demo-shell-ng2/app/app.component.html | 3 +- demo-shell-ng2/app/app.component.ts | 13 +- .../app/components/files/files.component.html | 5 +- .../assets/document-list.component.mock.ts | 117 ++++++++++++++++ .../document-list.component.spec.ts | 125 +++++++++--------- .../src/components/document-list.component.ts | 29 +++- .../src/data/share-datatable-adapter.spec.ts | 22 +++ .../src/data/share-datatable-adapter.ts | 25 +++- .../upload-drag-area.component.spec.ts | 68 ++++++++++ .../components/upload-drag-area.component.ts | 45 +++++-- 10 files changed, 363 insertions(+), 89 deletions(-) create mode 100644 ng2-components/ng2-alfresco-documentlist/src/assets/document-list.component.mock.ts diff --git a/demo-shell-ng2/app/app.component.html b/demo-shell-ng2/app/app.component.html index d052ae1f88..4d860b8bcd 100644 --- a/demo-shell-ng2/app/app.component.html +++ b/demo-shell-ng2/app/app.component.html @@ -63,7 +63,8 @@ Settings -
+
diff --git a/demo-shell-ng2/app/app.component.ts b/demo-shell-ng2/app/app.component.ts index 53d7dbb042..79a019a44d 100644 --- a/demo-shell-ng2/app/app.component.ts +++ b/demo-shell-ng2/app/app.component.ts @@ -17,7 +17,13 @@ import { Component } from '@angular/core'; import { Router } from '@angular/router'; -import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoSettingsService, StorageService, LogService } from 'ng2-alfresco-core'; +import { + AlfrescoTranslationService, + AlfrescoAuthenticationService, + AlfrescoSettingsService, + StorageService, + LogService +} from 'ng2-alfresco-core'; declare var document: any; @@ -117,4 +123,9 @@ export class AppComponent { this.settingsService.setProviders(this.storage.getItem(`providers`)); } } + + onDragOverMainPage(event: any): boolean { + event.preventDefault(); + return false; + } } diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html index 09424ed0b8..2df82cd6d9 100644 --- a/demo-shell-ng2/app/components/files/files.component.html +++ b/demo-shell-ng2/app/components/files/files.component.html @@ -1,7 +1,8 @@
+ [rootFolderId]="documentList.currentFolderId" + [versioning]="versioning" + [enabled]="documentList.hasCreatePermission()"> diff --git a/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.component.mock.ts b/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.component.mock.ts new file mode 100644 index 0000000000..4b00a0df14 --- /dev/null +++ b/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.component.mock.ts @@ -0,0 +1,117 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const fakeNodeWithCreatePermission = { + isFile: false, + createdByUser: { id: 'admin', displayName: 'Administrator' }, + modifiedAt: '2017-06-08T13:53:46.495Z', + nodeType: 'cm:folder', + parentId: '55052317-7e59-4058-8e07-769f41e615e1', + createdAt: '2017-05-22T11:36:11.270Z', + path: { + name: '/Company Home/User Homes', + isComplete: true, + elements: [{ + id: '94acfc73-7014-4475-9bd9-93a2162f0f8c', + name: 'Company Home' + }, { id: '55052317-7e59-4058-8e07-769f41e615e1', name: 'User Homes' }] + }, + isFolder: true, + modifiedByUser: { id: 'Test', displayName: 'Test' }, + name: 'Test', + id: '70e1cc6a-6918-468a-b84a-1048093b06fd', + properties: {}, + allowableOperations: ['delete', 'update', 'create'] +}; + +export const fakeNodeWithNoPermission = { + isFile: false, + createdByUser: { id: 'admin', displayName: 'Administrator' }, + modifiedAt: '2017-06-08T13:53:46.495Z', + nodeType: 'cm:folder', + parentId: '55052317-7e59-4058-8e07-769f41e615e1', + aspectNames: ['cm:ownable', 'cm:auditable'], + createdAt: '2017-05-22T11:36:11.270Z', + path: { + name: '/Company Home/User Homes', + isComplete: true, + elements: [{ + id: '94acfc73-7014-4475-9bd9-93a2162f0f8c', + name: 'Company Home' + }, { id: '55052317-7e59-4058-8e07-769f41e615e1', name: 'User Homes' }] + }, + isFolder: true, + modifiedByUser: { id: 'Test', displayName: 'Test' }, + name: 'Test', + id: '70e1cc6a-6918-468a-b84a-1048093b06fd', + properties: {} +}; + +export const fakeNodeAnswerWithEntries = { + 'list': { + 'pagination': { + 'count': 4, + 'hasMoreItems': false, + 'totalItems': 14, + 'skipCount': 10, + 'maxItems': 10 + }, + 'entries': [{ + 'entry': { + 'isFile': true, + 'createdByUser': { 'id': 'admin', 'displayName': 'Administrator' }, + 'modifiedAt': '2017-05-24T15:08:55.640Z', + 'nodeType': 'cm:content', + 'content': { + 'mimeType': 'application/rtf', + 'mimeTypeName': 'Rich Text Format', + 'sizeInBytes': 14530, + 'encoding': 'UTF-8' + }, + 'parentId': 'd124de26-6ba0-4f40-8d98-4907da2d337a', + 'createdAt': '2017-05-24T15:08:55.640Z', + 'path': { + 'name': '/Company Home/Guest Home', + 'isComplete': true, + 'elements': [{ + 'id': '94acfc73-7014-4475-9bd9-93a2162f0f8c', + 'name': 'Company Home' + }, { 'id': 'd124de26-6ba0-4f40-8d98-4907da2d337a', 'name': 'Guest Home' }] + }, + 'isFolder': false, + 'modifiedByUser': { 'id': 'admin', 'displayName': 'Administrator' }, + 'name': 'b_txt_file.rtf', + 'id': '67b80f77-dbca-4f58-be6c-71b9dd61ea53', + 'properties': { 'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR' }, + 'allowableOperations': ['delete', 'update'] + } + }] + } +}; + +export const fakeNodeAnswerWithNOEntries = { + 'list': { + 'pagination': { + 'count': 4, + 'hasMoreItems': false, + 'totalItems': 14, + 'skipCount': 10, + 'maxItems': 10 + }, + 'entries': [] + } +}; diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts index 9224ce51aa..a63328432d 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.spec.ts @@ -28,68 +28,20 @@ import { ShareDataRow, RowFilter, ImageResolver } from './../data/share-datatabl import { DataTableModule } from 'ng2-alfresco-datatable'; import { DocumentMenuActionComponent } from './document-menu-action.component'; import { Observable } from 'rxjs/Rx'; +import { + fakeNodeAnswerWithNOEntries, + fakeNodeAnswerWithEntries, + fakeNodeWithCreatePermission, + fakeNodeWithNoPermission +} from '../assets/document-list.component.mock'; import { MdProgressSpinnerModule } from '@angular/material'; declare let jasmine: any; -let fakeNodeAnswerWithEntries = { - 'list': { - 'pagination': { - 'count': 4, - 'hasMoreItems': false, - 'totalItems': 14, - 'skipCount': 10, - 'maxItems': 10 - }, - 'entries': [{ - 'entry': { - 'isFile': true, - 'createdByUser': {'id': 'admin', 'displayName': 'Administrator'}, - 'modifiedAt': '2017-05-24T15:08:55.640Z', - 'nodeType': 'cm:content', - 'content': { - 'mimeType': 'application/rtf', - 'mimeTypeName': 'Rich Text Format', - 'sizeInBytes': 14530, - 'encoding': 'UTF-8' - }, - 'parentId': 'd124de26-6ba0-4f40-8d98-4907da2d337a', - 'createdAt': '2017-05-24T15:08:55.640Z', - 'path': { - 'name': '/Company Home/Guest Home', - 'isComplete': true, - 'elements': [{ - 'id': '94acfc73-7014-4475-9bd9-93a2162f0f8c', - 'name': 'Company Home' - }, {'id': 'd124de26-6ba0-4f40-8d98-4907da2d337a', 'name': 'Guest Home'}] - }, - 'isFolder': false, - 'modifiedByUser': {'id': 'admin', 'displayName': 'Administrator'}, - 'name': 'b_txt_file.rtf', - 'id': '67b80f77-dbca-4f58-be6c-71b9dd61ea53', - 'properties': {'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR'}, - 'allowableOperations': ['delete', 'update'] - } - }] - } -}; - -let fakeNodeAnswerWithNOEntries = { - 'list': { - 'pagination': { - 'count': 4, - 'hasMoreItems': false, - 'totalItems': 14, - 'skipCount': 10, - 'maxItems': 10 - }, - 'entries': [] - } -}; - describe('DocumentList', () => { let documentList: DocumentListComponent; + let documentListService: DocumentListService; let fixture: ComponentFixture; let element: HTMLElement; let eventMock: any; @@ -110,7 +62,7 @@ describe('DocumentList', () => { ], providers: [ DocumentListService, - {provide: NgZone, useValue: zone} + { provide: NgZone, useValue: zone } ] }).compileComponents(); })); @@ -137,6 +89,7 @@ describe('DocumentList', () => { element = fixture.nativeElement; documentList = fixture.componentInstance; + documentListService = TestBed.get(DocumentListService); fixture.detectChanges(); }); @@ -263,7 +216,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFile: true, name: 'xyz', allowableOperations: ['create', 'update']}}; + let nodeFile = { entry: { isFile: true, name: 'xyz', allowableOperations: ['create', 'update'] } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -284,7 +237,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFolder: true, name: 'xyz', allowableOperations: ['create', 'update']}}; + let nodeFile = { entry: { isFolder: true, name: 'xyz', allowableOperations: ['create', 'update'] } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -305,7 +258,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFile: true, name: 'xyz', allowableOperations: ['create', 'update']}}; + let nodeFile = { entry: { isFile: true, name: 'xyz', allowableOperations: ['create', 'update'] } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -325,7 +278,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFolder: true, name: 'xyz', allowableOperations: ['create', 'update']}}; + let nodeFile = { entry: { isFolder: true, name: 'xyz', allowableOperations: ['create', 'update'] } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -345,7 +298,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFile: true, name: 'xyz', allowableOperations: ['create', 'update', 'delete']}}; + let nodeFile = { entry: { isFile: true, name: 'xyz', allowableOperations: ['create', 'update', 'delete'] } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -365,7 +318,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFolder: true, name: 'xyz', allowableOperations: ['create', 'update', 'delete']}}; + let nodeFile = { entry: { isFolder: true, name: 'xyz', allowableOperations: ['create', 'update', 'delete'] } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -384,7 +337,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFile: true, name: 'xyz', allowableOperations: null}}; + let nodeFile = { entry: { isFile: true, name: 'xyz', allowableOperations: null } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -403,7 +356,7 @@ describe('DocumentList', () => { documentMenu ]; - let nodeFile = {entry: {isFolder: true, name: 'xyz', allowableOperations: null}}; + let nodeFile = { entry: { isFolder: true, name: 'xyz', allowableOperations: null } }; let actions = documentList.getNodeActions(nodeFile); expect(actions.length).toBe(1); @@ -707,7 +660,7 @@ describe('DocumentList', () => { }); documentList.currentFolderId = 'wrong-id'; - documentList.ngOnChanges({currentFolderId: new SimpleChange(null, documentList.currentFolderId, true)}); + documentList.ngOnChanges({ currentFolderId: new SimpleChange(null, documentList.currentFolderId, true) }); }); it('should require dataTable to check empty template', () => { @@ -799,7 +752,7 @@ describe('DocumentList', () => { it('should load folder by ID on init', () => { documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692'; spyOn(documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.resolve()); - documentList.ngOnChanges({folderNode: new SimpleChange(null, documentList.currentFolderId, true)}); + documentList.ngOnChanges({ folderNode: new SimpleChange(null, documentList.currentFolderId, true) }); expect(documentList.loadFolderNodesByFolderNodeId).toHaveBeenCalled(); }); @@ -834,4 +787,44 @@ describe('DocumentList', () => { responseText: JSON.stringify(fakeNodeAnswerWithEntries) }); }); + + it('should return true if current folder node has create permission', (done) => { + documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692'; + documentList.folderNode = new NodeMinimal(); + documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692'; + documentList.skipCount = 5; + documentList.pageSize = 5; + spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithCreatePermission)); + spyOn(documentListService, 'getFolder').and.returnValue(Promise.resolve(fakeNodeAnswerWithNOEntries)); + + let change = new SimpleChange(null, '1d26e465-dea3-42f3-b415-faa8364b9692', true); + documentList.ngOnChanges({ 'currentFolderId': change }); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(documentList.hasCreatePermission()).toBeTruthy(); + done(); + }); + }); + + it('should return false if navigate to a folder with no create permission', (done) => { + documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692'; + documentList.folderNode = new NodeMinimal(); + documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692'; + documentList.skipCount = 5; + documentList.pageSize = 5; + spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithNoPermission)); + spyOn(documentListService, 'getFolder').and.returnValue(Promise.resolve(fakeNodeAnswerWithNOEntries)); + + documentList.loadFolder(); + let clickedFolderNode = new FolderNode('fake-folder-node'); + documentList.onNodeDblClick(clickedFolderNode); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + expect(documentList.hasCreatePermission()).toBeFalsy(); + done(); + }); + }); }); diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts index 0e658d787b..966f9d3e06 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.component.ts @@ -165,6 +165,8 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni data: ShareDataTableAdapter; loading: boolean = false; + private currentNodeAllowableOperations: string[] = []; + private CREATE_PERMISSION = 'create'; constructor(private documentListService: DocumentListService, private ngZone: NgZone, @@ -329,6 +331,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.currentFolderId = node.entry.id; this.folderNode = node.entry; this.skipCount = 0; + this.currentNodeAllowableOperations = node.entry['allowableOperations'] ? node.entry['allowableOperations'] : []; this.loadFolder(); this.folderChange.emit(new NodeEntryEvent(node.entry)); return true; @@ -359,11 +362,12 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni loadFolderByNodeId(nodeId: string) { this.loading = true; this.documentListService.getFolderNode(nodeId).then(node => { - this.folderNode = node; - this.currentFolderId = node.id; - this.skipCount = 0; - this.loadFolderNodesByFolderNodeId(node.id, this.pageSize, this.skipCount).catch(err => this.error.emit(err)); - }) + this.folderNode = node; + this.currentFolderId = node.id; + this.skipCount = 0; + this.currentNodeAllowableOperations = node['allowableOperations'] ? node['allowableOperations'] : []; + this.loadFolderNodesByFolderNodeId(node.id, this.pageSize, this.skipCount).catch(err => this.error.emit(err)); + }) .catch(err => this.error.emit(err)); } @@ -381,7 +385,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.updateSkipCount(skipCount - maxItems); this.loadFolderNodesByFolderNodeId(id, maxItems, skipCount - maxItems).then(() => { resolve(true); - }, () => { + }, (error) => { reject(error); }); } else { @@ -581,4 +585,17 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni this.skipCount = newSkipCount; } + hasCurrentNodePermission(permission: string): boolean { + let hasPermission: boolean = false; + if (this.currentNodeAllowableOperations.length > 0) { + let permFound = this.currentNodeAllowableOperations.find(element => element === permission); + hasPermission = permFound ? true : false; + } + return hasPermission; + } + + hasCreatePermission() { + return this.hasCurrentNodePermission(this.CREATE_PERMISSION); + } + } diff --git a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.spec.ts index 9e8cb43ed5..b958d8c6bc 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.spec.ts @@ -405,4 +405,26 @@ describe('ShareDataRow', () => { expect(row.hasValue('missing')).toBeFalsy(); }); + it('should be set as drop target when user has permission for that node', () => { + let file = new FolderNode('test'); + file.entry['allowableOperations'] = ['create']; + let row = new ShareDataRow(file); + + expect(row.isDropTarget).toBeTruthy(); + }); + + it('should not be set as drop target when user has permission for that node', () => { + let file = new FolderNode('test'); + let row = new ShareDataRow(file); + + expect(row.isDropTarget).toBeFalsy(); + }); + + it('should not be set as drop target when element is not a Folder', () => { + let file = new FileNode('test'); + let row = new ShareDataRow(file); + + expect(row.isDropTarget).toBeFalsy(); + }); + }); diff --git a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts index e8964b1a1e..0708bd685d 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/data/share-datatable-adapter.ts @@ -236,7 +236,7 @@ export class ShareDataRow implements DataRow { cache: { [key: string]: any } = {}; isSelected: boolean = false; - readonly isDropTarget; + isDropTarget: boolean; get node(): NodeMinimalEntry { return this.obj; @@ -247,7 +247,28 @@ export class ShareDataRow implements DataRow { throw new Error(ShareDataRow.ERR_OBJECT_NOT_FOUND); } - this.isDropTarget = obj.entry && obj.entry.isFolder; + this.isDropTarget = this.isFolderAndHasPermissionToUpload(obj); + } + + isFolderAndHasPermissionToUpload(obj: NodeMinimalEntry): boolean { + return this.isFolder(obj) && this.hasCreatePermission(obj); + } + + hasCreatePermission(obj: NodeMinimalEntry): boolean { + return this.hasPermission(obj, 'create'); + } + + private hasPermission(obj: NodeMinimalEntry, permission: string): boolean { + let hasPermission: boolean = false; + if (obj.entry && obj.entry['allowableOperations']) { + let permFound = obj.entry['allowableOperations'].find(element => element === permission); + hasPermission = permFound ? true : false; + } + return hasPermission; + } + + isFolder(obj: NodeMinimalEntry): boolean { + return obj.entry && obj.entry.isFolder; } cacheValue(key: string, value: any): any { diff --git a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.spec.ts b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.spec.ts index 29db41972d..3df8abfbc0 100644 --- a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.spec.ts +++ b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.spec.ts @@ -25,6 +25,41 @@ import { TranslationMock } from '../assets/translation.service.mock'; import { UploadService } from '../services/upload.service'; import { FileModel } from '../models/file.model'; +let fakeShareDataRow = { + obj: { + entry: { + createdAt: '2017-06-04T04:32:15.597Z', + path: { + name: '/Company Home/User Homes/Test', + isComplete: true, + elements: [ + { + id: '94acfc73-7014-4475-9bd9-93a2162f0f8c', + name: 'Company Home' + }, + { + id: '55052317-7e59-4058-8e07-769f41e615e1', + name: 'User Homes' + }, + { + id: '70e1cc6a-6918-468a-b84a-1048093b06fd', + name: 'Test' + } + ] + }, + isFolder: true, + name: 'pippo', + id: '7462d28e-bd43-4b91-9e7b-0d71598680ac', + nodeType: 'cm:folder', + allowableOperations: [ + 'delete', + 'update', + 'create' + ] + } + } +}; + describe('UploadDragAreaComponent', () => { let component: UploadDragAreaComponent; @@ -145,4 +180,37 @@ describe('UploadDragAreaComponent', () => { component.onFilesEntityDropped(itemEntity); expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null); }); + + it('should upload a file when user has create permission on target folder', async(() => { + component.currentFolderPath = '/root-fake-/sites-fake/document-library-fake'; + component.rootFolderId = '-my-'; + component.enabled = false; + + let fakeItem = { + fullPath: '/folder-fake/file-fake.png', + isDirectory: false, + isFile: true, + name: 'file-fake.png', + file: (callbackFile) => { + let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'}); + callbackFile(fileFake); + } + }; + + fixture.detectChanges(); + spyOn(uploadService, 'uploadFilesInTheQueue').and.returnValue(Promise.resolve(fakeItem)); + component.onSuccess.subscribe((val) => { + expect(val).not.toBeNull(); + }); + + let fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', { + detail: { + data: fakeShareDataRow, + files: [fakeItem] + } + }); + + component.onUploadFiles(fakeCustomEvent); + })); + }); diff --git a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts index 5ae8f614fb..c4589a6c51 100644 --- a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts +++ b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts @@ -67,24 +67,25 @@ export class UploadDragAreaComponent { /** * Handles 'upload-files' events raised by child components. - * @param e DOM event + * @param event DOM event */ - onUploadFiles(e: CustomEvent) { - e.stopPropagation(); - e.preventDefault(); - if (this.enabled) { - let files: FileInfo[] = e.detail.files; + onUploadFiles(event: CustomEvent) { + event.stopPropagation(); + event.preventDefault(); + let isAllowed: boolean = this.isAllowed(event.detail.data.obj.entry); + if (isAllowed) { + let files: FileInfo[] = event.detail.files; if (files && files.length > 0) { let parentId = this.rootFolderId; - if (e.detail.data && e.detail.data.obj.entry.isFolder) { - parentId = e.detail.data.obj.entry.id || this.rootFolderId; + if (event.detail.data && event.detail.data.obj.entry.isFolder) { + parentId = event.detail.data.obj.entry.id || this.rootFolderId; } const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, { newVersion: this.versioning, path: fileInfo.relativeFolder, parentId: parentId })); - this.uploadFiles(fileModels); + this.uploadFiles(fileModels, isAllowed); } } } @@ -168,8 +169,17 @@ export class UploadDragAreaComponent { }); } - private uploadFiles(files: FileModel[]): void { - if (this.enabled && files.length) { + /** + * Show the error inside Notification bar + * @param Error message + * @private + */ + showErrorNotificationBar(errorMessage: string) { + this.notificationService.openSnackMessage(errorMessage, 3000); + } + + private uploadFiles(files: FileModel[], isAllowed: boolean): void { + if (isAllowed && files.length) { this.uploadService.addToQueue(...files); this.uploadService.uploadFilesInTheQueue(this.onSuccess); let latestFilesAdded = this.uploadService.getQueue(); @@ -178,4 +188,17 @@ export class UploadDragAreaComponent { } } } + + private hasCreatePermission(node: any): boolean { + let isPermitted = false; + if (node && node['allowableOperations']) { + let permFound = node['allowableOperations'].find(element => element === 'create'); + isPermitted = permFound ? true : false; + } + return isPermitted; + } + + private isAllowed(node: any) { + return this.enabled || this.hasCreatePermission(node); + } }