mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACA-2643] Upload new version - refactoring (#1138)
* refactor upload version effect * subscriber noop fn * move logic to subscribe * tests
This commit is contained in:
parent
9b74063032
commit
9e0e50d57d
@ -34,13 +34,34 @@ import {
|
|||||||
FileUploadCompleteEvent,
|
FileUploadCompleteEvent,
|
||||||
FileModel
|
FileModel
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { UnlockWriteAction } from '@alfresco/aca-shared/store';
|
import {
|
||||||
|
UnlockWriteAction,
|
||||||
|
SnackbarErrorAction
|
||||||
|
} from '@alfresco/aca-shared/store';
|
||||||
|
import { ContentManagementService } from '../../services/content-management.service';
|
||||||
|
import { of, throwError } from 'rxjs';
|
||||||
|
|
||||||
|
function createFileList(fileName, type = 'text/plain') {
|
||||||
|
const data = new Blob([''], { type });
|
||||||
|
const arrayOfBlob = new Array<Blob>();
|
||||||
|
arrayOfBlob.push(data);
|
||||||
|
const file = new File(arrayOfBlob, fileName);
|
||||||
|
const files = [file];
|
||||||
|
|
||||||
|
const reducer = (dataTransfer, currentFile) => {
|
||||||
|
dataTransfer.items.add(currentFile);
|
||||||
|
return dataTransfer;
|
||||||
|
};
|
||||||
|
return files.reduce(reducer, new DataTransfer()).files;
|
||||||
|
}
|
||||||
|
|
||||||
describe('UploadEffects', () => {
|
describe('UploadEffects', () => {
|
||||||
let store: Store<any>;
|
let store: Store<any>;
|
||||||
let uploadService: UploadService;
|
let uploadService: UploadService;
|
||||||
let effects: UploadEffects;
|
let effects: UploadEffects;
|
||||||
let zone: NgZone;
|
let zone: NgZone;
|
||||||
|
let contentManagementService: ContentManagementService;
|
||||||
|
let uploadVersionInput: HTMLInputElement;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@ -52,121 +73,165 @@ describe('UploadEffects', () => {
|
|||||||
return fn();
|
return fn();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
contentManagementService = TestBed.get(ContentManagementService);
|
||||||
store = TestBed.get(Store);
|
store = TestBed.get(Store);
|
||||||
uploadService = TestBed.get(UploadService);
|
uploadService = TestBed.get(UploadService);
|
||||||
effects = TestBed.get(UploadEffects);
|
effects = TestBed.get(UploadEffects);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', () => {
|
beforeEach(() => {
|
||||||
expect(store).toBeDefined();
|
uploadVersionInput = document.querySelector('#app-upload-file-version');
|
||||||
expect(uploadService).toBeDefined();
|
|
||||||
expect(effects).toBeDefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not upload and unlock file if param not provided', () => {
|
afterEach(() => {
|
||||||
effects.uploadAndUnlock(null);
|
uploadVersionInput.remove();
|
||||||
expect(zone.run).not.toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should upload the file before unlocking', () => {
|
describe('uploadAndUnlock()', () => {
|
||||||
const file: any = {};
|
it('should not upload and unlock file if param not provided', () => {
|
||||||
|
effects.uploadAndUnlock(null);
|
||||||
|
expect(zone.run).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
spyOn(uploadService, 'addToQueue').and.stub();
|
it('should upload the file before unlocking', () => {
|
||||||
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
const file: any = {};
|
||||||
|
|
||||||
effects.uploadAndUnlock(file);
|
spyOn(uploadService, 'addToQueue').and.stub();
|
||||||
|
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
||||||
|
|
||||||
expect(uploadService.addToQueue).toHaveBeenCalled();
|
effects.uploadAndUnlock(file);
|
||||||
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should dispatch the unlock write action for a locked file', () => {
|
expect(uploadService.addToQueue).toHaveBeenCalled();
|
||||||
const file: FileModel = new FileModel(
|
expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled();
|
||||||
<File>{ name: 'file1.png', size: 10 },
|
});
|
||||||
null,
|
|
||||||
'file1'
|
|
||||||
);
|
|
||||||
|
|
||||||
file.data = {
|
it('should dispatch the unlock write action for a locked file', () => {
|
||||||
entry: {
|
const file: FileModel = new FileModel(
|
||||||
id: 'file1',
|
<File>{ name: 'file1.png', size: 10 },
|
||||||
properties: {
|
null,
|
||||||
'cm:lockType': 'WRITE_LOCK'
|
'file1'
|
||||||
|
);
|
||||||
|
|
||||||
|
file.data = {
|
||||||
|
entry: {
|
||||||
|
id: 'file1',
|
||||||
|
properties: {
|
||||||
|
'cm:lockType': 'WRITE_LOCK'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
spyOn(uploadService, 'addToQueue').and.stub();
|
spyOn(uploadService, 'addToQueue').and.stub();
|
||||||
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
||||||
spyOn(store, 'dispatch').and.stub();
|
spyOn(store, 'dispatch').and.stub();
|
||||||
|
|
||||||
effects.uploadAndUnlock(file);
|
effects.uploadAndUnlock(file);
|
||||||
uploadService.fileUploadComplete.next(
|
uploadService.fileUploadComplete.next(
|
||||||
new FileUploadCompleteEvent(file, 100, file.data)
|
new FileUploadCompleteEvent(file, 100, file.data)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(
|
expect(store.dispatch).toHaveBeenCalledWith(
|
||||||
new UnlockWriteAction(file.data)
|
new UnlockWriteAction(file.data)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should dispatch only one unlock action for a locked file', () => {
|
it('should dispatch only one unlock action for a locked file', () => {
|
||||||
const file: FileModel = new FileModel(
|
const file: FileModel = new FileModel(
|
||||||
<File>{ name: 'file1.png', size: 10 },
|
<File>{ name: 'file1.png', size: 10 },
|
||||||
null,
|
null,
|
||||||
'file1'
|
'file1'
|
||||||
);
|
);
|
||||||
|
|
||||||
file.data = {
|
file.data = {
|
||||||
entry: {
|
entry: {
|
||||||
id: 'file1',
|
id: 'file1',
|
||||||
properties: {
|
properties: {
|
||||||
'cm:lockType': 'WRITE_LOCK'
|
'cm:lockType': 'WRITE_LOCK'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
spyOn(uploadService, 'addToQueue').and.stub();
|
spyOn(uploadService, 'addToQueue').and.stub();
|
||||||
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
||||||
spyOn(store, 'dispatch').and.stub();
|
spyOn(store, 'dispatch').and.stub();
|
||||||
|
|
||||||
effects.uploadAndUnlock(file);
|
effects.uploadAndUnlock(file);
|
||||||
|
|
||||||
const completeEvent = new FileUploadCompleteEvent(file, 100, file.data);
|
const completeEvent = new FileUploadCompleteEvent(file, 100, file.data);
|
||||||
uploadService.fileUploadComplete.next(completeEvent);
|
uploadService.fileUploadComplete.next(completeEvent);
|
||||||
uploadService.fileUploadComplete.next(completeEvent);
|
uploadService.fileUploadComplete.next(completeEvent);
|
||||||
uploadService.fileUploadComplete.next(completeEvent);
|
uploadService.fileUploadComplete.next(completeEvent);
|
||||||
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(
|
expect(store.dispatch).toHaveBeenCalledWith(
|
||||||
new UnlockWriteAction(file.data)
|
new UnlockWriteAction(file.data)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(store.dispatch).toHaveBeenCalledTimes(1);
|
expect(store.dispatch).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should dispatch no actions if file is not locked', () => {
|
||||||
|
const file: FileModel = new FileModel(
|
||||||
|
<File>{ name: 'file1.png', size: 10 },
|
||||||
|
null,
|
||||||
|
'file1'
|
||||||
|
);
|
||||||
|
|
||||||
|
file.data = {
|
||||||
|
entry: {
|
||||||
|
id: 'file1',
|
||||||
|
properties: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(uploadService, 'addToQueue').and.stub();
|
||||||
|
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
||||||
|
spyOn(store, 'dispatch').and.stub();
|
||||||
|
|
||||||
|
effects.uploadAndUnlock(file);
|
||||||
|
uploadService.fileUploadComplete.next(
|
||||||
|
new FileUploadCompleteEvent(file, 100, file.data)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(store.dispatch).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should dispatch no actions if file is not locked', () => {
|
describe('upload file version', () => {
|
||||||
const file: FileModel = new FileModel(
|
beforeEach(() => {
|
||||||
<File>{ name: 'file1.png', size: 10 },
|
const dialog = { afterClosed: () => of({}) };
|
||||||
null,
|
spyOn(contentManagementService, 'versionUploadDialog').and.returnValue(
|
||||||
'file1'
|
dialog
|
||||||
);
|
);
|
||||||
|
spyOn(effects, 'uploadAndUnlock').and.stub();
|
||||||
|
});
|
||||||
|
|
||||||
file.data = {
|
it('should upload file', () => {
|
||||||
entry: {
|
spyOn(contentManagementService, 'getNodeInfo').and.returnValue(
|
||||||
id: 'file1',
|
of({
|
||||||
properties: {}
|
entry: {
|
||||||
}
|
id: 'file1',
|
||||||
};
|
properties: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(uploadService, 'addToQueue').and.stub();
|
uploadVersionInput.files = createFileList('bogus.txt');
|
||||||
spyOn(uploadService, 'uploadFilesInTheQueue').and.stub();
|
uploadVersionInput.dispatchEvent(new CustomEvent('change'));
|
||||||
spyOn(store, 'dispatch').and.stub();
|
expect(effects.uploadAndUnlock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
effects.uploadAndUnlock(file);
|
it('should raise error when getNodeInfo fails', () => {
|
||||||
uploadService.fileUploadComplete.next(
|
spyOn(store, 'dispatch').and.stub();
|
||||||
new FileUploadCompleteEvent(file, 100, file.data)
|
spyOn(contentManagementService, 'getNodeInfo').and.returnValue(
|
||||||
);
|
throwError('error')
|
||||||
|
);
|
||||||
|
|
||||||
expect(store.dispatch).not.toHaveBeenCalled();
|
uploadVersionInput.files = createFileList('bogus.txt');
|
||||||
|
uploadVersionInput.dispatchEvent(new CustomEvent('change'));
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith(
|
||||||
|
new SnackbarErrorAction('VERSION.ERROR.GENERIC')
|
||||||
|
);
|
||||||
|
expect(effects.uploadAndUnlock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -37,17 +37,8 @@ import { FileModel, FileUtils, UploadService } from '@alfresco/adf-core';
|
|||||||
import { Injectable, NgZone, RendererFactory2 } from '@angular/core';
|
import { Injectable, NgZone, RendererFactory2 } from '@angular/core';
|
||||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
import { Actions, Effect, ofType } from '@ngrx/effects';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { forkJoin, fromEvent, of } from 'rxjs';
|
import { forkJoin, of } from 'rxjs';
|
||||||
import {
|
import { tap, filter, catchError, flatMap, map, take } from 'rxjs/operators';
|
||||||
catchError,
|
|
||||||
distinctUntilChanged,
|
|
||||||
filter,
|
|
||||||
flatMap,
|
|
||||||
map,
|
|
||||||
switchMap,
|
|
||||||
take,
|
|
||||||
tap
|
|
||||||
} from 'rxjs/operators';
|
|
||||||
import { ContentManagementService } from '../../services/content-management.service';
|
import { ContentManagementService } from '../../services/content-management.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -78,7 +69,9 @@ export class UploadEffects {
|
|||||||
this.fileVersionInput.id = 'app-upload-file-version';
|
this.fileVersionInput.id = 'app-upload-file-version';
|
||||||
this.fileVersionInput.type = 'file';
|
this.fileVersionInput.type = 'file';
|
||||||
this.fileVersionInput.style.display = 'none';
|
this.fileVersionInput.style.display = 'none';
|
||||||
this.fileVersionInput.addEventListener('change', event => event);
|
this.fileVersionInput.addEventListener('change', () =>
|
||||||
|
this.uploadVersion()
|
||||||
|
);
|
||||||
renderer.appendChild(document.body, this.fileVersionInput);
|
renderer.appendChild(document.body, this.fileVersionInput);
|
||||||
|
|
||||||
this.folderInput = renderer.createElement('input') as HTMLInputElement;
|
this.folderInput = renderer.createElement('input') as HTMLInputElement;
|
||||||
@ -110,19 +103,38 @@ export class UploadEffects {
|
|||||||
@Effect({ dispatch: false })
|
@Effect({ dispatch: false })
|
||||||
uploadVersion$ = this.actions$.pipe(
|
uploadVersion$ = this.actions$.pipe(
|
||||||
ofType<UploadFileVersionAction>(UploadActionTypes.UploadFileVersion),
|
ofType<UploadFileVersionAction>(UploadActionTypes.UploadFileVersion),
|
||||||
switchMap(() => {
|
map(() => {
|
||||||
this.fileVersionInput.click();
|
this.fileVersionInput.click();
|
||||||
return fromEvent(this.fileVersionInput, 'change').pipe(
|
})
|
||||||
distinctUntilChanged(),
|
);
|
||||||
flatMap(() => this.contentService.versionUploadDialog().afterClosed()),
|
|
||||||
|
private uploadVersion() {
|
||||||
|
this.contentService
|
||||||
|
.versionUploadDialog()
|
||||||
|
.afterClosed()
|
||||||
|
.pipe(
|
||||||
tap(form => {
|
tap(form => {
|
||||||
if (!form) {
|
if (!form) {
|
||||||
this.fileVersionInput.value = '';
|
this.fileVersionInput.value = '';
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
filter(form => !!form),
|
filter(form => !!form),
|
||||||
flatMap(form => forkJoin(of(form), this.contentService.getNodeInfo())),
|
flatMap(form =>
|
||||||
map(([form, node]) => {
|
forkJoin(
|
||||||
|
of(form),
|
||||||
|
this.contentService.getNodeInfo().pipe(
|
||||||
|
catchError(_ => {
|
||||||
|
this.store.dispatch(
|
||||||
|
new SnackbarErrorAction('VERSION.ERROR.GENERIC')
|
||||||
|
);
|
||||||
|
return of(null);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.subscribe(([form, node]) => {
|
||||||
|
if (form && node) {
|
||||||
const file = this.fileVersionInput.files[0];
|
const file = this.fileVersionInput.files[0];
|
||||||
const fileModel = new FileModel(
|
const fileModel = new FileModel(
|
||||||
file,
|
file,
|
||||||
@ -139,17 +151,12 @@ export class UploadEffects {
|
|||||||
},
|
},
|
||||||
node.id
|
node.id
|
||||||
);
|
);
|
||||||
|
|
||||||
this.fileVersionInput.value = '';
|
|
||||||
this.uploadAndUnlock(fileModel);
|
this.uploadAndUnlock(fileModel);
|
||||||
}),
|
}
|
||||||
catchError(_ => {
|
|
||||||
this.fileVersionInput.value = '';
|
this.fileVersionInput.value = '';
|
||||||
return of(new SnackbarErrorAction('VERSION.ERROR.GENERIC'));
|
});
|
||||||
})
|
}
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
private upload(event: any): void {
|
private upload(event: any): void {
|
||||||
this.store
|
this.store
|
||||||
|
Loading…
x
Reference in New Issue
Block a user