From 32c00b7e996890a907bffde9bfb4277c9b05ad20 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 7 Jul 2016 17:05:03 +0100 Subject: [PATCH] Unit tests --- .../src/assets/document-list.service.mock.ts | 6 +- .../src/components/document-list.spec.ts | 145 ---------- .../src/data/share-datatable-adapter.spec.ts | 258 +++++++++++++++++- .../src/data/share-datatable-adapter.ts | 33 ++- 4 files changed, 278 insertions(+), 164 deletions(-) diff --git a/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.service.mock.ts b/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.service.mock.ts index a18b386d2e..83ec9eeb63 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.service.mock.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/assets/document-list.service.mock.ts @@ -16,6 +16,8 @@ */ import { Observable } from 'rxjs/Observable'; +import { NodePaging } from './../models/document-library.model'; +import { PageNode } from './document-library.model.mock'; import { DocumentListService } from './../services/document-list.service'; import { AlfrescoSettingsService, @@ -25,7 +27,7 @@ import { export class DocumentListServiceMock extends DocumentListService { - folderToReturn: any = {}; + getFolderResult: NodePaging = new PageNode(); getFolderReject: boolean = false; getFolderRejectError: string = 'Error'; @@ -42,7 +44,7 @@ export class DocumentListServiceMock extends DocumentListService { return Observable.throw(this.getFolderRejectError); } return Observable.create(observer => { - observer.next(this.folderToReturn); + observer.next(this.getFolderResult); observer.complete(); }); } diff --git a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.spec.ts b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.spec.ts index c9e373536b..bb0a485fde 100644 --- a/ng2-components/ng2-alfresco-documentlist/src/components/document-list.spec.ts +++ b/ng2-components/ng2-alfresco-documentlist/src/components/document-list.spec.ts @@ -75,47 +75,6 @@ describe('DocumentList', () => { expect(columns[0]).toBe(column); }); - // TODO: move to data adapter - /* - it('should fetch folder', () => { - let folder = { - 'nodeRef': 'workspace://SpacesStore/8bb36efb-c26d-4d2b-9199-ab6922f53c28' - }; - documentListService.folderToReturn = folder; - documentList.ngOnInit(); - - expect(documentList.folder).toBe(folder); - }); - */ - - // TODO: move to data adapter - /* - it('should return thumbnail url for a file when thumbnails turned on', () => { - let url = 'URL'; - spyOn(documentListService, 'getDocumentThumbnailUrl').and.returnValue(url); - - let node = new FileNode(); - documentList.thumbnails = true; - let result = documentList.getThumbnailUrl(node); - - expect(result).toBe(url); - expect(documentListService.getDocumentThumbnailUrl).toHaveBeenCalled(); - }); - */ - - // TODO: move to data adapter - /* - it('should return a null thumbnail url for a null item', () => { - let url = 'URL'; - spyOn(documentListService, 'getDocumentThumbnailUrl').and.returnValue(url); - - let result = documentList.getThumbnailUrl(null); - - expect(result).toBeNull(); - expect(documentListService.getDocumentThumbnailUrl).not.toHaveBeenCalled(); - }); - */ - it('should execute action with node', () => { let node = new FileNode(); let action = new ContentActionModel(); @@ -457,26 +416,6 @@ describe('DocumentList', () => { expect(documentList.displayFolderContent).toHaveBeenCalled(); }); - // TODO: move to data adapter - /* - it('should generate thumbnail for unknown content', () => { - documentList.baseComponentPath = '/root'; - let node = new FileNode(); - node.entry.isFile = false; - - expect(documentList.getThumbnailUrl(node)).toBe('/root/img/ft_ic_miscellaneous.svg'); - }); - */ - - // TODO: move to data adapter - /* - it('should generate folder icon path', () => { - documentList.baseComponentPath = '/root'; - let folder = new FolderNode(); - expect(documentList.getThumbnailUrl(folder)).toBe('/root/img/ft_ic_folder.svg'); - }); - */ - // TODO: move to data adapter /* it('should generate file icon path based on mime type', () => { @@ -541,43 +480,6 @@ describe('DocumentList', () => { }); */ - // TODO: move to DataTable - /* - it('should convert cell value to formatted date', () => { - - let rawValue = new Date(2015, 6, 15, 21, 43, 11).toString(); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST); - let dateValue = 'Jul 15, 2015, 9:43:11 PM'; - - let file = new FileNode(); - file.entry.createdAt = rawValue; - - let col = new ContentColumnModel(); - col.source = 'createdAt'; - col.type = 'date'; - col.format = 'medium'; // Jul 15, 2015, 9:43:11 PM - - let value = documentList.getCellValue(file, col); - expect(value).toBe(dateValue); - }); - */ - - // TODO: move to DataTable - /* - it('should return date value as string', () => { - let rawValue = new Date(2015, 6, 15, 21, 43, 11).toString(); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST); - - let file = new FileNode(); - file.entry.createdAt = rawValue; - - let col = new ContentColumnModel(); - col.source = 'createdAt'; - col.type = 'string'; - - let value = documentList.getCellValue(file, col); - expect(value).toBe(rawValue); - }); - */ - // TODO: move to data adapter /* it('should convert cell value to thumbnail', () => { @@ -662,53 +564,6 @@ describe('DocumentList', () => { expect(documentList.getNodeActions).toHaveBeenCalled(); }); - /* - it('should update error message when folder content display fails', () => { - let error = 'My Error'; - documentListService.getFolderReject = true; - documentListService.getFolderRejectError = error; - - documentList.displayFolderContent('/some/path'); - expect(documentList.errorMessage).toBe(error); - }); - */ - - // TODO: move to data adapter - /* - it('should log error when having date conversion issues', () => { - - let value = ''; - 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}`); - }); - */ - - // TODO: move to data adapter - /* - 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 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 e7fccf355f..40714e06be 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 @@ -15,16 +15,23 @@ * limitations under the License. */ -import { - it, - describe, - expect -} from '@angular/core/testing'; +import { it, describe, expect, beforeEach } from '@angular/core/testing'; import { DataColumn, DataRow } from 'ng2-alfresco-datatable'; -import { ShareDataTableAdapter } from './share-datatable-adapter'; + +import { DocumentListServiceMock } from './../assets/document-list.service.mock'; +import { ShareDataTableAdapter, ShareDataRow } from './share-datatable-adapter'; +import { FileNode, FolderNode, PageNode } from './../assets/document-library.model.mock'; describe('ShareDataTableAdapter', () => { + let basePath: string; + let documentListService: DocumentListServiceMock; + + beforeEach(() => { + basePath = '/root'; + documentListService = new DocumentListServiceMock(); + }); + it('should setup rows and columns with constructor', () => { let schema = [ {}]; let adapter = new ShareDataTableAdapter(null, null, schema); @@ -85,4 +92,243 @@ describe('ShareDataTableAdapter', () => { expect(adapter.sort).toHaveBeenCalled(); }); + it('should fail when getting value for missing row', () => { + let adapter = new ShareDataTableAdapter(null, null, null); + let check = () => { return adapter.getValue(null, {}); }; + expect(check).toThrowError(ShareDataTableAdapter.ERR_ROW_NOT_FOUND); + }); + + it('should fail when getting value for missing column', () => { + let adapter = new ShareDataTableAdapter(null, null, null); + let check = () => { return adapter.getValue({}, null); }; + expect(check).toThrowError(ShareDataTableAdapter.ERR_COL_NOT_FOUND); + }); + + it('should require path to load data', () => { + spyOn(documentListService, 'getFolder').and.callThrough(); + + let adapter = new ShareDataTableAdapter(documentListService, null, null); + adapter.loadPath(null); + + expect(documentListService.getFolder).not.toHaveBeenCalled(); + }); + + it('should load data for path', () => { + let folder = new FolderNode(); + let path = '/some/path'; + let page = new PageNode([folder]); + + spyOn(documentListService, 'getFolder').and.callThrough(); + documentListService.getFolderResult = page; + + let adapter = new ShareDataTableAdapter(documentListService, null, null); + adapter.loadPath(path); + + expect(documentListService.getFolder).toHaveBeenCalledWith(path); + + let rows = adapter.getRows(); + expect(rows.length).toBe(1); + expect((rows[0]).node).toBe(folder); + }); + + it('should covert cell value to formatted date', () => { + let rawValue = new Date(2015, 6, 15, 21, 43, 11).toString(); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST); + let dateValue = 'Jul 15, 2015, 9:43:11 PM'; + + let file = new FileNode(); + file.entry.createdAt = rawValue; + + let col = { + key: 'createdAt', + type: 'date', + format: 'medium' // Jul 15, 2015, 9:43:11 PM + }; + + let row = new ShareDataRow(file); + let adapter = new ShareDataTableAdapter(null, null, null); + + let value = adapter.getValue(row, col); + expect(value).toBe(dateValue); + }); + + it('should use default date format as fallback', () => { + let rawValue = new Date(2015, 6, 15, 21, 43, 11).toString(); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST); + let dateValue = 'Jul 15, 2015, 9:43:11 PM'; + + let file = new FileNode(); + file.entry.createdAt = rawValue; + + let col = { + key: 'createdAt', + type: 'date', + format: null + }; + + let row = new ShareDataRow(file); + let adapter = new ShareDataTableAdapter(null, null, null); + + let value = adapter.getValue(row, col); + expect(value).toBe(dateValue); + }); + + it('should return date value as string', () => { + let rawValue = new Date(2015, 6, 15, 21, 43, 11).toString(); // Wed Jul 15 2015 21:43:11 GMT+0100 (BST); + + let file = new FileNode(); + file.entry.createdAt = rawValue; + + let col = { + key: 'createdAt', + type: 'string' + }; + + let row = new ShareDataRow(file); + let adapter = new ShareDataTableAdapter(null, null, null); + + let value = adapter.getValue(row, col); + expect(value).toBe(rawValue); + }); + + it('should log error when having date conversion issues', () => { + let dateValue = '[wrong-date]'; + let file = new FileNode(); + file.entry.createdAt = dateValue; + + let col = { + key: 'createdAt', + type: 'date', + format: 'medium' + }; + + let row = new ShareDataRow(file); + let adapter = new ShareDataTableAdapter(null, null, null); + spyOn(console, 'error').and.stub(); + + let value = adapter.getValue(row, col); + expect(value).toBe(dateValue); + expect(console.error).toHaveBeenCalledWith(`Error parsing date ${value} to format ${col.format}`); + }); + + it('should generate fallback icon for a file thumbnail', () => { + let adapter = new ShareDataTableAdapter(null, basePath, null); + + let row = new ShareDataRow(new FileNode()); + let col = { type: 'image', key: '$thumbnail' }; + + let value = adapter.getValue(row, col); + expect(value).toBe(`${basePath}/img/ft_ic_miscellaneous.svg`); + }); + + it('should return image value unmodified', () => { + let imageUrl = 'http://
'; + + let file = new FileNode(); + file.entry['icon'] = imageUrl; + + + let adapter = new ShareDataTableAdapter(null, basePath, null); + let row = new ShareDataRow(file); + let col = { type: 'image', key: 'icon' }; + + let value = adapter.getValue(row, col); + expect(value).toBe(imageUrl); + }); + + it('should resolve folder icon', () => { + let adapter = new ShareDataTableAdapter(null, basePath, null); + + let row = new ShareDataRow(new FolderNode()); + let col = { type: 'image', key: '$thumbnail' }; + + let value = adapter.getValue(row, col); + expect(value).toBe(`${basePath}/img/ft_ic_folder.svg`); + }); + + it('should resolve file thumbnail', () => { + let imageUrl: 'http://'; + spyOn(documentListService, 'getDocumentThumbnailUrl').and.returnValue(imageUrl); + + let adapter = new ShareDataTableAdapter(documentListService, basePath, null); + adapter.thumbnails = true; + + let file = new FileNode(); + let row = new ShareDataRow(file); + let col = { type: 'image', key: '$thumbnail' }; + + let value = adapter.getValue(row, col); + expect(value).toBe(imageUrl); + expect(documentListService.getDocumentThumbnailUrl).toHaveBeenCalledWith(file); + }); + + it('should resolve fallback file icon for unknown node', () => { + let adapter = new ShareDataTableAdapter(null, basePath, null); + + let file = new FileNode(); + file.entry.isFile = false; + file.entry.isFolder = false; + + let row = new ShareDataRow(file); + let col = { type: 'image', key: '$thumbnail' }; + + let value = adapter.getValue(row, col); + expect(value).toBe(`${basePath}/img/ft_ic_miscellaneous.svg`); + }); + + it('should require document service to resolve thumbnail', () => { + let adapter = new ShareDataTableAdapter(null, basePath, null); + adapter.thumbnails = true; + + let file = new FileNode(); + let row = new ShareDataRow(file); + let col = { type: 'image', key: '$thumbnail' }; + + let value = adapter.getValue(row, col); + expect(value).toBeNull(); + }); + + it('should log load error', () => { + let error = 'My Error'; + documentListService.getFolderReject = true; + documentListService.getFolderRejectError = error; + + spyOn(console, 'error').and.stub(); + spyOn(documentListService, 'getFolder').and.callThrough(); + + let adapter = new ShareDataTableAdapter(documentListService, null, null); + adapter.loadPath('/some/path'); + + expect(documentListService.getFolder).toHaveBeenCalled(); + expect(console.error).toHaveBeenCalledWith(error); + }); + + +}); + + +describe('ShareDataRow', () => { + + it('should wrap node', () => { + let file = new FileNode(); + let row = new ShareDataRow(file); + expect(row.node).toBe(file); + }); + + it('should require object source', () => { + expect(() => { return new ShareDataRow(null); }).toThrowError(ShareDataRow.ERR_OBJECT_NOT_FOUND); + }); + + it('should resolve value from node entry', () => { + let file = new FileNode('test'); + let row = new ShareDataRow(file); + expect(row.getValue('name')).toBe('test'); + }); + + it('should check value', () => { + let file = new FileNode('test'); + let row = new ShareDataRow(file); + + expect(row.hasValue('name')).toBeTruthy(); + expect(row.hasValue('missing')).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 31b30e03e9..d8735c9658 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 @@ -27,6 +27,11 @@ import { DocumentListService } from './../services/document-list.service'; export class ShareDataTableAdapter implements DataTableAdapter { + static ERR_ROW_NOT_FOUND: string = 'Row not found'; + static ERR_COL_NOT_FOUND: string = 'Column not found'; + + static DEFAULT_DATE_FORMAT: string = 'medium'; + private sorting: DataSorting; private rows: DataRow[]; private columns: DataColumn[]; @@ -59,20 +64,20 @@ export class ShareDataTableAdapter implements DataTableAdapter { getValue(row: DataRow, col: DataColumn): any { if (!row) { - throw new Error('Row not found'); + throw new Error(ShareDataTableAdapter.ERR_ROW_NOT_FOUND); } if (!col) { - throw new Error('Column not found'); + throw new Error(ShareDataTableAdapter.ERR_COL_NOT_FOUND); } let value = row.getValue(col.key); if (col.type === 'date') { let datePipe = new DatePipe(); - let format = col.format || 'medium'; + let format = col.format || ShareDataTableAdapter.DEFAULT_DATE_FORMAT; try { return datePipe.transform(value, format); } catch (err) { - console.error(`DocumentList: error parsing date ${value} to format ${format}`); + console.error(`Error parsing date ${value} to format ${format}`); } } @@ -168,25 +173,31 @@ export class ShareDataTableAdapter implements DataTableAdapter { let data = page.list.entries; if (data && data.length > 0) { rows = data.map(item => new ShareDataRow(item)); + // Sort by first sortable or just first column - let sortable = this.columns.filter(c => c.sortable); - if (sortable.length > 0) { - this.sort(sortable[0].key, 'asc'); - } else { - this.sort(this.columns[0].key, 'asc'); + if (this.columns && this.columns.length > 0) { + let sortable = this.columns.filter(c => c.sortable); + if (sortable.length > 0) { + this.sort(sortable[0].key, 'asc'); + } else { + this.sort(this.columns[0].key, 'asc'); + } } } } this.rows = rows; }, - error => console.log(error)); + error => console.error(error)); } } } export class ShareDataRow implements DataRow { + + static ERR_OBJECT_NOT_FOUND: string = 'Object source not found'; + isSelected: boolean = false; get node(): MinimalNodeEntity { @@ -195,7 +206,7 @@ export class ShareDataRow implements DataRow { constructor(private obj: MinimalNodeEntity) { if (!obj) { - throw new Error('Object source not found'); + throw new Error(ShareDataRow.ERR_OBJECT_NOT_FOUND); } }