Unit tests for document list component

This commit is contained in:
Denys Vuika
2016-06-30 13:39:52 +01:00
parent 8632013231
commit 258148cc1c
9 changed files with 289 additions and 11 deletions

View File

@@ -25,7 +25,9 @@ import {
export class AlfrescoServiceMock extends AlfrescoService { export class AlfrescoServiceMock extends AlfrescoService {
_folderToReturn: any = {}; folderToReturn: any = {};
getFolderReject: boolean = false;
getFolderRejectError: string = 'Error';
constructor( constructor(
settings?: AlfrescoSettingsService, settings?: AlfrescoSettingsService,
@@ -36,8 +38,11 @@ export class AlfrescoServiceMock extends AlfrescoService {
} }
getFolder(folder: string) { getFolder(folder: string) {
if (this.getFolderReject) {
return Observable.throw(this.getFolderRejectError);
}
return Observable.create(observer => { return Observable.create(observer => {
observer.next(this._folderToReturn); observer.next(this.folderToReturn);
observer.complete(); observer.complete();
}); });
} }

View File

@@ -20,12 +20,15 @@ import {
MinimalNodeEntity, MinimalNodeEntity,
MinimalNodeEntryEntity, MinimalNodeEntryEntity,
PathInfoEntity, PathInfoEntity,
ContentInfo ContentInfo,
NodePagingList
} from '../models/document-library.model'; } from '../models/document-library.model';
export class PageNode extends NodePaging { export class PageNode extends NodePaging {
constructor() { constructor(entries?: MinimalNodeEntity[]) {
super(); super();
this.list = new NodePagingList();
this.list.entries = entries || [];
} }
} }

View File

@@ -0,0 +1,67 @@
/*!
* @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.
*/
import {
it,
describe,
expect,
beforeEach
} from '@angular/core/testing';
import { DocumentList } from './document-list';
import { AlfrescoServiceMock } from '../assets/alfresco.service.mock';
import { ContentActionModel } from './../models/content-action.model';
import { ContentActionList } from './content-action-list';
describe('ContentColumnList', () => {
let documentList: DocumentList;
let actionList: ContentActionList;
beforeEach(() => {
let alfrescoServiceMock = new AlfrescoServiceMock();
documentList = new DocumentList(alfrescoServiceMock, null);
actionList = new ContentActionList(documentList);
});
it('should register action', () => {
spyOn(documentList.actions, 'push').and.callThrough();
let action = new ContentActionModel();
let result = actionList.registerAction(action);
expect(result).toBeTruthy();
expect(documentList.actions.push).toHaveBeenCalledWith(action);
});
it('should require document list instance to register action', () => {
actionList = new ContentActionList(null);
let action = new ContentActionModel();
expect(actionList.registerAction(action)).toBeFalsy();
});
it('should require action instance to register', () => {
spyOn(documentList.actions, 'push').and.callThrough();
let result = actionList.registerAction(null);
expect(result).toBeFalsy();
expect(documentList.actions.push).not.toHaveBeenCalled();
});
});

View File

@@ -33,9 +33,11 @@ export class ContentActionList {
* Registers action handler within the parent document list component. * Registers action handler within the parent document list component.
* @param action Action model to register. * @param action Action model to register.
*/ */
registerAction(action: ContentActionModel): void { registerAction(action: ContentActionModel): boolean {
if (this.documentList && action) { if (this.documentList && action) {
this.documentList.actions.push(action); this.documentList.actions.push(action);
} return true;
}
return false;
} }
} }

View File

@@ -41,9 +41,24 @@ describe('ContentColumnList', () => {
it('should register column within parent document list', () => { it('should register column within parent document list', () => {
expect(documentList.columns.length).toBe(0); expect(documentList.columns.length).toBe(0);
columnList.registerColumn(new ContentColumnModel()); let result = columnList.registerColumn(new ContentColumnModel());
expect(result).toBeTruthy();
expect(documentList.columns.length).toBe(1); expect(documentList.columns.length).toBe(1);
}); });
it('should require document list instance to register action', () => {
columnList = new ContentColumnList(null);
let col = new ContentColumnModel();
expect(columnList.registerColumn(col)).toBeFalsy();
});
it('should require action instance to register', () => {
spyOn(documentList.actions, 'push').and.callThrough();
let result = columnList.registerColumn(null);
expect(result).toBeFalsy();
expect(documentList.actions.push).not.toHaveBeenCalled();
});
}); });

View File

@@ -33,9 +33,11 @@ export class ContentColumnList {
* Registers column model within the parent document list component. * Registers column model within the parent document list component.
* @param column Column definition model to register. * @param column Column definition model to register.
*/ */
registerColumn(column: ContentColumnModel): void { registerColumn(column: ContentColumnModel): boolean {
if (this.documentList && column) { if (this.documentList && column) {
this.documentList.columns.push(column); this.documentList.columns.push(column);
} return true;
}
return false;
} }
} }

View File

@@ -86,7 +86,7 @@ describe('DocumentList', () => {
let folder = { let folder = {
'nodeRef': 'workspace://SpacesStore/8bb36efb-c26d-4d2b-9199-ab6922f53c28' 'nodeRef': 'workspace://SpacesStore/8bb36efb-c26d-4d2b-9199-ab6922f53c28'
}; };
alfrescoServiceMock._folderToReturn = folder; alfrescoServiceMock.folderToReturn = folder;
documentList.ngOnInit(); documentList.ngOnInit();
expect(documentList.folder).toBe(folder); expect(documentList.folder).toBe(folder);
@@ -672,7 +672,6 @@ describe('DocumentList', () => {
let value = documentList.getCellValue(file, col); let value = documentList.getCellValue(file, col);
expect(value).toBe(dateValue); expect(value).toBe(dateValue);
}); });
it('should return date value as string', () => { it('should return date value as string', () => {
@@ -703,4 +702,179 @@ describe('DocumentList', () => {
expect(value).toBe(url); expect(value).toBe(url);
}); });
it('should require path to display folder content', () => {
spyOn(alfrescoServiceMock, 'getFolder').and.callThrough();
documentList.displayFolderContent(null);
documentList.displayFolderContent('');
expect(alfrescoServiceMock.getFolder).not.toHaveBeenCalled();
});
it('should require node to resolve context menu actions', () => {
expect(documentList.getContextActions(null)).toBeNull();
let file = new FileNode();
file.entry = null;
expect(documentList.getContextActions(file)).toBeNull();
});
it('should fetch context menu actions for a file node', () => {
let actionModel = {};
spyOn(documentList, 'getContentActions').and.returnValue([actionModel]);
let file = new FileNode();
let actions = documentList.getContextActions(file);
expect(documentList.getContentActions).toHaveBeenCalledWith('document', 'menu');
expect(actions.length).toBe(1);
expect(actions[0].model).toBe(actionModel);
expect(actions[0].node).toBe(file);
expect(actions[0].subject).toBe(documentList.contextActionHandler);
});
it('should fetch context menu actions for a folder node', () => {
let actionModel = {};
spyOn(documentList, 'getContentActions').and.returnValue([actionModel]);
let folder = new FolderNode();
let actions = documentList.getContextActions(folder);
expect(documentList.getContentActions).toHaveBeenCalledWith('folder', 'menu');
expect(actions.length).toBe(1);
expect(actions[0].model).toBe(actionModel);
expect(actions[0].node).toBe(folder);
expect(actions[0].subject).toBe(documentList.contextActionHandler);
});
it('should fetch no context menu actions for unknown type', () => {
spyOn(documentList, 'getContentActions').and.stub();
let node = new FileNode();
node.entry.isFile = false;
node.entry.isFolder = false;
let actions = documentList.getContextActions(node);
expect(documentList.getContentActions).not.toHaveBeenCalled();
expect(actions).toBeNull();
});
it('should return null value when no content actions found', () => {
spyOn(documentList, 'getContentActions').and.returnValue([]);
let file = new FileNode();
let actions = documentList.getContextActions(file);
expect(actions).toBeNull();
expect(documentList.getContentActions).toHaveBeenCalled();
});
it('should update error message when folder content display fails', () => {
let error = 'My Error';
alfrescoServiceMock.getFolderReject = true;
alfrescoServiceMock.getFolderRejectError = error;
documentList.displayFolderContent('/some/path');
expect(documentList.errorMessage).toBe(error);
});
it('should get object value via property path', () => {
let obj = {
name: {
firstName: '<name>'
}
};
expect(documentList.getObjectValue(obj, 'name.firstName')).toBe('<name>');
});
it('should not get object value via invalid path', () => {
expect(documentList.getObjectValue({}, 'some.missing.path')).toBeUndefined();
});
it('should log error when having date conversion issues', () => {
let value = '<wrong-date>';
let file = new FileNode();
file.entry.createdAt = value;
let col = new ContentColumnModel({
source: 'createdAt',
type: 'date',
format: 'medium'
});
spyOn(console, 'error').and.stub();
let result = documentList.getCellValue(file, col);
expect(result).toBe(value);
expect(console.error).toHaveBeenCalledWith(`DocumentList: error parsing date ${value} to format ${col.format}`);
});
it('should convert thumbnail if column source defined', () => {
let file = new FileNode();
let col = new ContentColumnModel({
source: 'name',
type: 'image'
});
expect(documentList.getCellValue(file, col)).toBe(file.entry.name);
});
it('should require current folder path to reload', () => {
// Redefine 'currentFolderPath' to disable native setter validation
Object.defineProperty(documentList, 'currentFolderPath', {
value: null
});
expect(documentList.currentFolderPath).toBeNull();
spyOn(documentList, 'displayFolderContent').and.stub();
documentList.reload();
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
});
it('should not sort empty page', () => {
let page = new PageNode();
spyOn(page.list.entries, 'sort').and.stub();
documentList.sort(page, null);
expect(page.list.entries.sort).not.toHaveBeenCalled();
});
it('should put folders to top on sort', () => {
let folder = new FolderNode();
let file = new FileNode();
let page = new PageNode([file, folder]);
documentList.sort(page, new ColumnSortingModel({
key: 'name'
}));
expect(page.list.entries[0]).toBe(folder);
expect(page.list.entries[1]).toBe(file);
});
it('should sort by dates up to ms', () => {
let file1 = new FileNode();
file1.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 1);
let file2 = new FileNode();
file2.entry['dateProp'] = new Date(2016, 6, 30, 13, 14, 2);
let page = new PageNode([file1, file2]);
documentList.sort(page, new ColumnSortingModel({
key: 'dateProp',
direction: 'desc'
}));
expect(page.list.entries[0]).toBe(file2);
expect(page.list.entries[1]).toBe(file1);
});
}); });

View File

@@ -319,7 +319,7 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
} }
displayFolderContent(path: string) { displayFolderContent(path: string) {
if (path !== null) { if (path) {
this.alfrescoService this.alfrescoService
.getFolder(path) .getFolder(path)
.subscribe( .subscribe(

View File

@@ -16,6 +16,16 @@
*/ */
export class ColumnSortingModel { export class ColumnSortingModel {
static DEFAULT_DIRECTION: string = 'asc';
key: string; key: string;
direction: string = 'asc'; direction: string = ColumnSortingModel.DEFAULT_DIRECTION;
constructor(opts?: any) {
if (opts) {
this.key = opts.key;
this.direction = opts.direction || ColumnSortingModel.DEFAULT_DIRECTION;
}
}
} }