Skip to content

Commit

Permalink
[ADF-5369] HTTP 500 response in adf-upload-button is emitted as a suc…
Browse files Browse the repository at this point in the history
…cess event (#7087)

* [ADF-5369] HTTP 500 response in adf-upload-button is emitted as a success event

* [ci:force] unit test fixed
  • Loading branch information
dhrn committed Jun 8, 2021
1 parent acf4b26 commit 9a2a622
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 49 deletions.
4 changes: 2 additions & 2 deletions demo-shell/src/app/components/files/files.component.ts
Expand Up @@ -404,8 +404,8 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
});
}

openSnackMessageError(message: string) {
this.notificationService.showError(message);
openSnackMessageError(error: any) {
this.notificationService.showError(error.value || error);
}

openSnackMessageInfo(message: string) {
Expand Down
58 changes: 58 additions & 0 deletions lib/content-services/src/lib/mock/upload.service.mock.ts
@@ -0,0 +1,58 @@
/*!
* @license
* Copyright 2019 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 mockUploadSuccessPromise = {
on: function (event, callback) {
if (event === 'success') {
callback();
}
return this;
},
catch: function (callback) {
callback();
return this;
},
then: function (callback) {
callback();
return this;
},
next: function (callback) {
callback();
return this;
}
};

export const mockUploadErrorPromise = {
on: function (event, callback) {
if (event === 'error') {
callback();
}
return this;
},
catch: function (callback) {
callback();
return this;
},
then: function (callback) {
callback();
return this;
},
next: function (callback) {
callback();
return this;
}
};
Expand Up @@ -126,14 +126,15 @@ export abstract class UploadBase implements OnInit, OnDestroy {
const event = new UploadFilesEvent(
[...filteredFiles],
this.uploadService,
this.success
this.success,
this.error
);
this.beginUpload.emit(event);

if (!event.defaultPrevented) {
if (filteredFiles.length > 0) {
this.uploadService.addToQueue(...filteredFiles);
this.uploadService.uploadFilesInTheQueue(this.success);
this.uploadService.uploadFilesInTheQueue(this.success, this.error);
}
}
});
Expand Down
Expand Up @@ -23,6 +23,7 @@ import { UploadButtonComponent } from './upload-button.component';
import { NodeEntry } from '@alfresco/js-api';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { mockUploadErrorPromise, mockUploadSuccessPromise } from '../../mock/upload.service.mock';

describe('UploadButtonComponent', () => {

Expand Down Expand Up @@ -124,40 +125,32 @@ describe('UploadButtonComponent', () => {

it('should call uploadFile with the default root folder', () => {
component.rootFolderId = '-root-';
component.success = null;

spyOn(contentService, 'getNode').and.returnValue(of(fakeFolderNodeWithPermission));
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();

component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });
uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');

fixture.detectChanges();

component.onFilesAdded(fakeEvent);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled();
});

it('should call uploadFile with a custom root folder', () => {
component.rootFolderId = '-my-';
component.success = null;

spyOn(contentService, 'getNode').and.returnValue(of(fakeFolderNodeWithPermission));
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });

uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();

component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });
fixture.detectChanges();

component.onFilesAdded(fakeEvent);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled();
});

it('should not call uploadFiles if rootFolderId is null', () => {
component.rootFolderId = null;
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
component.ngOnChanges({ rootFolderId: new SimpleChange(null, null, true) });

uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');

fixture.detectChanges();

component.onFilesAdded(fakeEvent);
Expand Down Expand Up @@ -351,6 +344,7 @@ describe('UploadButtonComponent', () => {
let fakeNodeWithNoPermission;

beforeEach(() => {
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
fakeNodeWithNoPermission = {
entry: {}
};
Expand All @@ -361,9 +355,6 @@ describe('UploadButtonComponent', () => {

spyOn(contentService, 'getNode').and.returnValue(of(fakeNodeWithNoPermission));
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });

uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');

fixture.detectChanges();

component.onFilesAdded(fakeEvent);
Expand All @@ -375,9 +366,6 @@ describe('UploadButtonComponent', () => {

spyOn(contentService, 'getNode').and.returnValue(throwError('error'));
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });

uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');

fixture.detectChanges();

component.onFilesAdded(fakeEvent);
Expand Down Expand Up @@ -407,9 +395,6 @@ describe('UploadButtonComponent', () => {

spyOn(contentService, 'getNode').and.returnValue(of(fakeNodeWithNoPermission));
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });

uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');

fixture.detectChanges();

component.onFilesAdded(fakeEvent);
Expand All @@ -421,13 +406,40 @@ describe('UploadButtonComponent', () => {

spyOn(contentService, 'getNode').and.returnValue(of(fakeFolderNodeWithPermission));
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });
fixture.detectChanges();

uploadService.uploadFilesInTheQueue = jasmine.createSpy('uploadFilesInTheQueue');
component.onFilesAdded(fakeEvent);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled();
});
});

describe('Events', () => {
beforeEach(() => {
spyOn(contentService, 'getNode').and.returnValue(of(fakeFolderNodeWithPermission));
component.rootFolderId = 'nodeId';
component.ngOnChanges({ rootFolderId: new SimpleChange(null, component.rootFolderId, true) });
fixture.detectChanges();
});

it('should emit an success for successful upload of a file', (done) => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadSuccessPromise);

component.success.subscribe((success) => {
expect(success).not.toBeNull();
done();
});

component.onFilesAdded(fakeEvent);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled();
});

it('should emit error if upload errored', (done) => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise);

component.error.subscribe((error) => {
expect(error).not.toBeNull();
done();
});
component.onFilesAdded(fakeEvent);
});
});
});
Expand Up @@ -20,6 +20,7 @@ import { FileModel, UploadService, setupTestBed } from '@alfresco/adf-core';
import { UploadDragAreaComponent } from './upload-drag-area.component';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { mockUploadSuccessPromise, mockUploadErrorPromise } from '../../mock/upload.service.mock';

function getFakeShareDataRow(allowableOperations = ['delete', 'update', 'create']) {
return {
Expand Down Expand Up @@ -222,6 +223,7 @@ describe('UploadDragAreaComponent', () => {
it('should only upload those files whose fileTypes are in acceptedFilesType', async(() => {
spyOn(uploadService, 'uploadFilesInTheQueue');
component.success = null;
component.error = null;
component.acceptedFilesType = '.jpg,.pdf';
fixture.detectChanges();
const files: File[] = [
Expand All @@ -231,7 +233,7 @@ describe('UploadDragAreaComponent', () => {
];
component.onFilesDropped(files);
fixture.whenStable().then(() => {
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null, null);
const filesCalledWith = addToQueueSpy.calls.mostRecent().args;
expect(filesCalledWith.length).toBe(2, 'Files should contain two elements');
expect(filesCalledWith[0].name).toBe('phobos.jpg');
Expand All @@ -242,12 +244,13 @@ describe('UploadDragAreaComponent', () => {
it('should upload a file if fileType is in acceptedFilesType', async(() => {
spyOn(uploadService, 'uploadFilesInTheQueue');
component.success = null;
component.error = null;
component.acceptedFilesType = '.png';
fixture.detectChanges();

fixture.whenStable().then(() => {
component.onFilesDropped([new File(['fakefake'], 'file-fake.png', { type: 'image/png' })]);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null, null);
});
}));

Expand Down Expand Up @@ -281,23 +284,25 @@ describe('UploadDragAreaComponent', () => {

it('should not upload a file if fileType is not in acceptedFilesType', async(() => {
component.success = null;
component.error = null;
component.acceptedFilesType = '.pdf';
fixture.detectChanges();
spyOn(uploadService, 'uploadFilesInTheQueue');

fixture.whenStable().then(() => {
component.onFilesDropped([new File(['fakefake'], 'file-fake.png', { type: 'image/png' })]);
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalledWith(null);
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalledWith(null, null);
});
}));

it('should upload a file with a custom root folder ID when dropped', async(() => {
component.success = null;
component.error = null;
fixture.detectChanges();
spyOn(uploadService, 'uploadFilesInTheQueue');

component.onFilesDropped([new File(['fakefake'], 'file-fake.png', { type: 'image/png' })]);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null);
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalledWith(null, null);
}));

it('should upload a file when user has create permission on target folder', async(() => {
Expand Down Expand Up @@ -446,5 +451,67 @@ describe('UploadDragAreaComponent', () => {

component.onUploadFiles(fakeCustomEvent);
});

it('should emit success if successful of upload a file', (done) => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadSuccessPromise);
const fakeItem = {
fullPath: '/folder-fake/file-fake.png',
isDirectory: false,
isFile: true,
relativeFolder: '/',
name: 'file-fake.png',
file: (callbackFile) => {
const fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
callbackFile(fileFake);
}
};

fixture.detectChanges();

component.success.subscribe((success) => {
expect(success).not.toBeNull();
done();
});

const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
detail: {
data: getFakeShareDataRow(),
files: [fakeItem]
}
});

component.onUploadFiles(fakeCustomEvent);
});

it('should emit error if upload errored', (done) => {
spyOn(uploadService, 'getUploadPromise').and.returnValue(mockUploadErrorPromise);
const fakeItem = {
fullPath: '/folder-fake/file-fake.png',
isDirectory: false,
isFile: true,
relativeFolder: '/',
name: 'file-fake.png',
file: (callbackFile) => {
const fileFake = new File(['fakefake'], 'file-fake.png', { type: 'image/png' });
callbackFile(fileFake);
}
};

fixture.detectChanges();

component.error.subscribe((error) => {
expect(error).not.toBeNull();
done();
});

const fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
detail: {
data: getFakeShareDataRow(),
files: [fakeItem]
}
});

component.onUploadFiles(fakeCustomEvent);
});
});
});
Expand Up @@ -32,7 +32,8 @@ export class UploadFilesEvent {
constructor(
public files: Array<FileModel>,
private uploadService: UploadService,
private callback: EventEmitter<any>
private successEmitter: EventEmitter<any>,
private errorEmitter: EventEmitter<any>
) {}

pauseUpload() {
Expand All @@ -42,7 +43,7 @@ export class UploadFilesEvent {
resumeUpload() {
if (this.files && this.files.length > 0) {
this.uploadService.addToQueue(...this.files);
this.uploadService.uploadFilesInTheQueue(this.callback);
this.uploadService.uploadFilesInTheQueue(this.successEmitter, this.errorEmitter);
}
}
}
2 changes: 1 addition & 1 deletion lib/core/services/upload.service.spec.ts
Expand Up @@ -195,7 +195,7 @@ describe('UploadService', () => {
<FileUploadOptions> { parentId: '-root-' }
);
service.addToQueue(fileFake);
service.uploadFilesInTheQueue(emitter);
service.uploadFilesInTheQueue(null, emitter);
expect(jasmine.Ajax.requests.mostRecent().url)
.toBe('http://localhost:9876/ecm/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children?autoRename=true&include=allowableOperations');

Expand Down

0 comments on commit 9a2a622

Please sign in to comment.