mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
Merge pull request #299 from Alfresco/dev-denys-testing
Additional unit tests for Document List
This commit is contained in:
@@ -1,23 +0,0 @@
|
|||||||
var browserSync = require("browser-sync").create();
|
|
||||||
var historyApiFallback = require('connect-history-api-fallback');
|
|
||||||
|
|
||||||
browserSync.init({
|
|
||||||
|
|
||||||
server: {
|
|
||||||
baseDir: './',
|
|
||||||
middleware: [ historyApiFallback() ]
|
|
||||||
},
|
|
||||||
|
|
||||||
files: [
|
|
||||||
'index.html',
|
|
||||||
'dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-core/dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-datatable/dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-documentlist/dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-login/dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-search/dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-upload/dist/**/*.{html,htm,css,js}',
|
|
||||||
'node_modules/ng2-alfresco-viewer/dist/**/*.{html,htm,css,js}'],
|
|
||||||
|
|
||||||
reloadDelay: 1000
|
|
||||||
});
|
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
"clean": "rimraf dist node_modules typings",
|
"clean": "rimraf dist node_modules typings",
|
||||||
"typings": "typings install",
|
"typings": "typings install",
|
||||||
"postinstall": "npm run typings && npm run build",
|
"postinstall": "npm run typings && npm run build",
|
||||||
"start": "npm install && npm run typings && concurrently \"npm run build:w\" \"npm run server\" ",
|
"start": "concurrently \"npm run build:w\" \"npm run server\" ",
|
||||||
"server": "node browser-sync-config.js",
|
"server": "wsrv -o -s",
|
||||||
"build": "npm run tslint && rimraf dist && tsc",
|
"build": "npm run tslint && rimraf dist && tsc",
|
||||||
"build:w": "npm run tslint && rimraf dist && tsc -w",
|
"build:w": "npm run tslint && rimraf dist && tsc -w",
|
||||||
"tslint": "npm run tslint-src && npm run tslint-root",
|
"tslint": "npm run tslint-src && npm run tslint-root",
|
||||||
@@ -44,12 +44,11 @@
|
|||||||
"ng2-alfresco-documentlist": "0.1.34"
|
"ng2-alfresco-documentlist": "0.1.34"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browser-sync": "2.10.0",
|
|
||||||
"connect-history-api-fallback": "1.2.0",
|
|
||||||
"concurrently": "2.0.0",
|
"concurrently": "2.0.0",
|
||||||
"tslint": "3.8.1",
|
"tslint": "3.8.1",
|
||||||
"typescript": "1.8.10",
|
"typescript": "1.8.10",
|
||||||
"typings": "1.0.4"
|
"typings": "1.0.4",
|
||||||
|
"wsrv": "0.1.3"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"angular2",
|
"angular2",
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rimraf dist node_modules typings",
|
"clean": "rimraf dist node_modules typings",
|
||||||
"typings": "typings install",
|
"typings": "typings install",
|
||||||
"server": "http-server -c-1 -o -p 8875 .",
|
|
||||||
"build": "npm run tslint && typings install && rimraf dist && tsc && npm run copytemplates && license-check",
|
"build": "npm run tslint && typings install && rimraf dist && tsc && npm run copytemplates && license-check",
|
||||||
"build:w": "npm run tslint && typings install && rimraf dist && npm run watch-task",
|
"build:w": "npm run tslint && typings install && rimraf dist && npm run watch-task",
|
||||||
"watch-task": "concurrently \"npm run tsc:w\" \"npm run copytemplates:w\" \"license-check\"",
|
"watch-task": "concurrently \"npm run tsc:w\" \"npm run copytemplates:w\" \"license-check\"",
|
||||||
@@ -27,7 +26,7 @@
|
|||||||
"test": "karma start karma.conf.js --reporters mocha,coverage --single-run",
|
"test": "karma start karma.conf.js --reporters mocha,coverage --single-run",
|
||||||
"test-browser": "concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"",
|
"test-browser": "concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"",
|
||||||
"posttest": "node_modules/.bin/remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html",
|
"posttest": "node_modules/.bin/remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html",
|
||||||
"coverage": "npm run test && http-server -c-1 -o -p 9875 ./coverage/report",
|
"coverage": "npm run test && wsrv -o -p 9875 ./coverage/report",
|
||||||
"prepublish": "npm run build"
|
"prepublish": "npm run build"
|
||||||
},
|
},
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
@@ -85,7 +84,6 @@
|
|||||||
"concurrently": "2.1.0",
|
"concurrently": "2.1.0",
|
||||||
"coveralls": "2.11.9",
|
"coveralls": "2.11.9",
|
||||||
"cpx": "1.3.1",
|
"cpx": "1.3.1",
|
||||||
"http-server": "0.8.5",
|
|
||||||
"jasmine-core": "2.4.1",
|
"jasmine-core": "2.4.1",
|
||||||
"karma": "0.13.22",
|
"karma": "0.13.22",
|
||||||
"karma-chrome-launcher": "1.0.1",
|
"karma-chrome-launcher": "1.0.1",
|
||||||
@@ -98,7 +96,8 @@
|
|||||||
"traceur": "0.0.91",
|
"traceur": "0.0.91",
|
||||||
"tslint": "3.8.1",
|
"tslint": "3.8.1",
|
||||||
"typescript": "1.8.10",
|
"typescript": "1.8.10",
|
||||||
"typings": "1.0.4"
|
"typings": "1.0.4",
|
||||||
|
"wsrv": "0.1.3"
|
||||||
},
|
},
|
||||||
"license-check-config": {
|
"license-check-config": {
|
||||||
"src": [
|
"src": [
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import { MinimalNodeEntity } from '../models/document-library.model';
|
|
||||||
import {AlfrescoService} from '../../src/services/alfresco.service';
|
import {AlfrescoService} from '../../src/services/alfresco.service';
|
||||||
import {
|
import {
|
||||||
AlfrescoSettingsService,
|
AlfrescoSettingsService,
|
||||||
@@ -29,9 +28,9 @@ export class AlfrescoServiceMock extends AlfrescoService {
|
|||||||
_folderToReturn: any = {};
|
_folderToReturn: any = {};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
settings: AlfrescoSettingsService = null,
|
settings?: AlfrescoSettingsService,
|
||||||
authService: AlfrescoAuthenticationService = null,
|
authService?: AlfrescoAuthenticationService,
|
||||||
contentService: AlfrescoContentService = null
|
contentService?: AlfrescoContentService
|
||||||
) {
|
) {
|
||||||
super(settings, authService, contentService);
|
super(settings, authService, contentService);
|
||||||
}
|
}
|
||||||
@@ -42,8 +41,4 @@ export class AlfrescoServiceMock extends AlfrescoService {
|
|||||||
observer.complete();
|
observer.complete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getDocumentThumbnailUrl(folder: MinimalNodeEntity) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*!
|
||||||
|
* @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 {
|
||||||
|
NodePaging,
|
||||||
|
MinimalNodeEntity,
|
||||||
|
MinimalNodeEntryEntity,
|
||||||
|
PathInfoEntity,
|
||||||
|
ContentInfo
|
||||||
|
} from '../models/document-library.model';
|
||||||
|
|
||||||
|
export class PageNode extends NodePaging {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FileNode extends MinimalNodeEntity {
|
||||||
|
constructor(name?: string) {
|
||||||
|
super();
|
||||||
|
this.entry = new MinimalNodeEntryEntity();
|
||||||
|
this.entry.isFile = true;
|
||||||
|
this.entry.isFolder = false;
|
||||||
|
this.entry.name = name;
|
||||||
|
this.entry.path = new PathInfoEntity();
|
||||||
|
this.entry.content = new ContentInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FolderNode extends MinimalNodeEntity {
|
||||||
|
constructor(name?: string) {
|
||||||
|
super();
|
||||||
|
this.entry = new MinimalNodeEntryEntity();
|
||||||
|
this.entry.isFile = false;
|
||||||
|
this.entry.isFolder = true;
|
||||||
|
this.entry.name = name;
|
||||||
|
this.entry.path = new PathInfoEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,23 +21,28 @@ import {
|
|||||||
expect,
|
expect,
|
||||||
beforeEach
|
beforeEach
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
import {EventEmitter} from '@angular/core';
|
import { EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
import {DocumentList} from './document-list';
|
import { DocumentList } from './document-list';
|
||||||
import {AlfrescoServiceMock} from '../assets/alfresco.service.mock';
|
import { AlfrescoServiceMock } from '../assets/alfresco.service.mock';
|
||||||
|
import { ContentActionList } from './content-action-list';
|
||||||
import {ContentActionList} from './content-action-list';
|
import { ContentAction } from './content-action';
|
||||||
import {ContentAction} from './content-action';
|
import { DocumentActionsService } from '../services/document-actions.service';
|
||||||
import {DocumentActionsService} from '../services/document-actions.service';
|
import { FolderActionsService } from '../services/folder-actions.service';
|
||||||
import {FolderActionsService} from '../services/folder-actions.service';
|
import { ContentActionHandler } from '../models/content-action.model';
|
||||||
|
|
||||||
describe('ContentAction', () => {
|
describe('ContentAction', () => {
|
||||||
|
|
||||||
let documentList: DocumentList;
|
let documentList: DocumentList;
|
||||||
let actionList: ContentActionList;
|
let actionList: ContentActionList;
|
||||||
|
let documentActions: DocumentActionsService;
|
||||||
|
let folderActions: FolderActionsService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
let alfrescoServiceMock = new AlfrescoServiceMock();
|
let alfrescoServiceMock = new AlfrescoServiceMock();
|
||||||
|
documentActions = new DocumentActionsService(null, null);
|
||||||
|
folderActions = new FolderActionsService(null);
|
||||||
|
|
||||||
documentList = new DocumentList(alfrescoServiceMock, null);
|
documentList = new DocumentList(alfrescoServiceMock, null);
|
||||||
actionList = new ContentActionList(documentList);
|
actionList = new ContentActionList(documentList);
|
||||||
});
|
});
|
||||||
@@ -73,7 +78,6 @@ describe('ContentAction', () => {
|
|||||||
it('should get action handler from document actions service', () => {
|
it('should get action handler from document actions service', () => {
|
||||||
|
|
||||||
let handler = function() {};
|
let handler = function() {};
|
||||||
let documentActions = new DocumentActionsService(null);
|
|
||||||
spyOn(documentActions, 'getHandler').and.returnValue(handler);
|
spyOn(documentActions, 'getHandler').and.returnValue(handler);
|
||||||
|
|
||||||
let action = new ContentAction(actionList, documentActions, null);
|
let action = new ContentAction(actionList, documentActions, null);
|
||||||
@@ -91,7 +95,6 @@ describe('ContentAction', () => {
|
|||||||
|
|
||||||
it('should get action handler from folder actions service', () => {
|
it('should get action handler from folder actions service', () => {
|
||||||
let handler = function() {};
|
let handler = function() {};
|
||||||
let folderActions = new FolderActionsService();
|
|
||||||
spyOn(folderActions, 'getHandler').and.returnValue(handler);
|
spyOn(folderActions, 'getHandler').and.returnValue(handler);
|
||||||
|
|
||||||
let action = new ContentAction(actionList, null, folderActions);
|
let action = new ContentAction(actionList, null, folderActions);
|
||||||
@@ -108,10 +111,7 @@ describe('ContentAction', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should require target to get system handler', () => {
|
it('should require target to get system handler', () => {
|
||||||
let folderActions = new FolderActionsService();
|
|
||||||
spyOn(folderActions, 'getHandler').and.stub();
|
spyOn(folderActions, 'getHandler').and.stub();
|
||||||
|
|
||||||
let documentActions = new DocumentActionsService(null);
|
|
||||||
spyOn(documentActions, 'getHandler').and.stub();
|
spyOn(documentActions, 'getHandler').and.stub();
|
||||||
|
|
||||||
let action = new ContentAction(actionList, documentActions, folderActions);
|
let action = new ContentAction(actionList, documentActions, folderActions);
|
||||||
@@ -133,7 +133,6 @@ describe('ContentAction', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should be case insensitive for document target', () => {
|
it('should be case insensitive for document target', () => {
|
||||||
let documentActions = new DocumentActionsService(null);
|
|
||||||
spyOn(documentActions, 'getHandler').and.stub();
|
spyOn(documentActions, 'getHandler').and.stub();
|
||||||
|
|
||||||
let action = new ContentAction(actionList, documentActions, null);
|
let action = new ContentAction(actionList, documentActions, null);
|
||||||
@@ -146,7 +145,6 @@ describe('ContentAction', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should be case insensitive for folder target', () => {
|
it('should be case insensitive for folder target', () => {
|
||||||
let folderActions = new FolderActionsService();
|
|
||||||
spyOn(folderActions, 'getHandler').and.stub();
|
spyOn(folderActions, 'getHandler').and.stub();
|
||||||
|
|
||||||
let action = new ContentAction(actionList, null, folderActions);
|
let action = new ContentAction(actionList, null, folderActions);
|
||||||
@@ -177,4 +175,54 @@ describe('ContentAction', () => {
|
|||||||
let model = documentList.actions[0];
|
let model = documentList.actions[0];
|
||||||
model.handler('<obj>');
|
model.handler('<obj>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should sync localizable fields with model', () => {
|
||||||
|
|
||||||
|
let action = new ContentAction(actionList, null, null);
|
||||||
|
action.title = 'title1';
|
||||||
|
action.ngOnInit();
|
||||||
|
|
||||||
|
expect(action.model.title).toBe(action.title);
|
||||||
|
|
||||||
|
action.title = 'title2';
|
||||||
|
action.ngOnChanges(null);
|
||||||
|
|
||||||
|
expect(action.model.title).toBe('title2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not find document action handler with missing service', () => {
|
||||||
|
let action = new ContentAction(actionList, null, null);
|
||||||
|
expect(action.getSystemHandler('document', 'name')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not find folder action handler with missing service', () => {
|
||||||
|
let action = new ContentAction(actionList, null, null);
|
||||||
|
expect(action.getSystemHandler('folder', 'name')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find document action handler via service', () => {
|
||||||
|
let handler = <ContentActionHandler> function (obj: any, target?: any) {};
|
||||||
|
let action = new ContentAction(actionList, documentActions, null);
|
||||||
|
spyOn(documentActions, 'getHandler').and.returnValue(handler);
|
||||||
|
expect(action.getSystemHandler('document', 'name')).toBe(handler);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find folder action handler via service', () => {
|
||||||
|
let handler = <ContentActionHandler> function (obj: any, target?: any) {};
|
||||||
|
let action = new ContentAction(actionList, null, folderActions);
|
||||||
|
spyOn(folderActions, 'getHandler').and.returnValue(handler);
|
||||||
|
expect(action.getSystemHandler('folder', 'name')).toBe(handler);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not find actions for unknown target type', () => {
|
||||||
|
spyOn(folderActions, 'getHandler').and.stub();
|
||||||
|
spyOn(documentActions, 'getHandler').and.stub();
|
||||||
|
|
||||||
|
let action = new ContentAction(actionList, documentActions, folderActions);
|
||||||
|
|
||||||
|
expect(action.getSystemHandler('unknown', 'name')).toBeNull();
|
||||||
|
expect(folderActions.getHandler).not.toHaveBeenCalled();
|
||||||
|
expect(documentActions.getHandler).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -76,12 +76,12 @@ export class ContentAction implements OnInit, OnChanges {
|
|||||||
this.list.registerAction(this.model);
|
this.list.registerAction(this.model);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges(changes) {
|
||||||
// update localizable properties
|
// update localizable properties
|
||||||
this.model.title = this.title;
|
this.model.title = this.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSystemHandler(target: string, name: string): ContentActionHandler {
|
getSystemHandler(target: string, name: string): ContentActionHandler {
|
||||||
if (target) {
|
if (target) {
|
||||||
let ltarget = target.toLowerCase();
|
let ltarget = target.toLowerCase();
|
||||||
|
|
||||||
|
|||||||
@@ -77,4 +77,20 @@ describe('ContentColumn', () => {
|
|||||||
expect(model.srTitle).toBe('Thumbnail');
|
expect(model.srTitle).toBe('Thumbnail');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should sync localizable fields with model', () => {
|
||||||
|
|
||||||
|
let column = new ContentColumn(columnList);
|
||||||
|
column.title = 'title1';
|
||||||
|
column.srTitle = 'srTitle1';
|
||||||
|
column.ngOnInit();
|
||||||
|
|
||||||
|
expect(column.model.title).toBe(column.title);
|
||||||
|
expect(column.model.srTitle).toBe(column.srTitle);
|
||||||
|
|
||||||
|
column.title = 'title2';
|
||||||
|
column.ngOnChanges(null);
|
||||||
|
|
||||||
|
expect(column.model.title).toBe('title2');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
/*!
|
||||||
|
* @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,
|
||||||
|
beforeEach,
|
||||||
|
expect
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import {
|
||||||
|
DocumentListBreadcrumb,
|
||||||
|
PathNode
|
||||||
|
} from './document-list-breadcrumb.component';
|
||||||
|
import { DocumentList } from './document-list';
|
||||||
|
|
||||||
|
describe('DocumentListBreadcrumb', () => {
|
||||||
|
|
||||||
|
let component;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
component = new DocumentListBreadcrumb();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set current path', () => {
|
||||||
|
let path = '/some/path';
|
||||||
|
component.currentFolderPath = path;
|
||||||
|
expect(component.currentFolderPath).toBe(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should init with root folder by default', () => {
|
||||||
|
expect(component.route.length).toBe(1);
|
||||||
|
expect(component.route[0]).toEqual(
|
||||||
|
jasmine.objectContaining({
|
||||||
|
name: 'Root',
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to default root for invalid path', () => {
|
||||||
|
component.currentFolderPath = null;
|
||||||
|
expect(component.currentFolderPath).toBe('/');
|
||||||
|
|
||||||
|
expect(component.route.length).toBe(1);
|
||||||
|
expect(component.route[0]).toEqual(
|
||||||
|
jasmine.objectContaining({
|
||||||
|
name: 'Root',
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the route', () => {
|
||||||
|
component.currentFolderPath = '/some/path';
|
||||||
|
|
||||||
|
expect(component.route.length).toBe(3);
|
||||||
|
expect(component.route).toEqual(
|
||||||
|
jasmine.objectContaining([
|
||||||
|
{ name: 'Root', path: '/' },
|
||||||
|
{ name: 'some', path: '/some' },
|
||||||
|
{ name: 'path', path: '/some/path' }
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should prevent default click behavior', () => {
|
||||||
|
let event = jasmine.createSpyObj('event', ['preventDefault']);
|
||||||
|
component.onRoutePathClick(null, event);
|
||||||
|
expect(event.preventDefault).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit navigation event', (done) => {
|
||||||
|
let node = <PathNode> { name: 'name', path: '/path' };
|
||||||
|
component.navigate.subscribe(val => {
|
||||||
|
expect(val.value.name).toBe(node.name);
|
||||||
|
expect(val.value.path).toBe(node.path);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
component.onRoutePathClick(node, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update document list on click', () => {
|
||||||
|
let documentList = new DocumentList(null, null);
|
||||||
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
|
||||||
|
let node = <PathNode> { name: 'name', path: '/path' };
|
||||||
|
component.target = documentList;
|
||||||
|
|
||||||
|
component.onRoutePathClick(node, null);
|
||||||
|
expect(documentList.currentFolderPath).toBe(node.path);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
+2
-2
@@ -42,11 +42,11 @@ export class DocumentListBreadcrumb {
|
|||||||
@Input()
|
@Input()
|
||||||
set currentFolderPath(val: string) {
|
set currentFolderPath(val: string) {
|
||||||
if (this._currentFolderPath !== val) {
|
if (this._currentFolderPath !== val) {
|
||||||
this._currentFolderPath = val;
|
|
||||||
|
|
||||||
if (val) {
|
if (val) {
|
||||||
|
this._currentFolderPath = val;
|
||||||
this.route = this.parsePath(val);
|
this.route = this.parsePath(val);
|
||||||
} else {
|
} else {
|
||||||
|
this._currentFolderPath = this.rootFolder.path;
|
||||||
this.route = [ this.rootFolder ];
|
this.route = [ this.rootFolder ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,28 +21,40 @@ import {
|
|||||||
expect,
|
expect,
|
||||||
beforeEach
|
beforeEach
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
|
import { NgZone } from '@angular/core';
|
||||||
import { DocumentList } from './document-list';
|
import { DocumentList } from './document-list';
|
||||||
import { ContentColumnModel } from '../models/content-column.model';
|
import { ContentColumnModel } from '../models/content-column.model';
|
||||||
import { AlfrescoServiceMock } from '../assets/alfresco.service.mock';
|
import { AlfrescoServiceMock } from '../assets/alfresco.service.mock';
|
||||||
import { MinimalNodeEntity, MinimalNodeEntryEntity } from '../models/document-library.model';
|
|
||||||
import { ContentActionModel } from '../models/content-action.model';
|
import { ContentActionModel } from '../models/content-action.model';
|
||||||
|
import {
|
||||||
|
PageNode,
|
||||||
|
FileNode,
|
||||||
|
FolderNode
|
||||||
|
} from '../assets/document-library.model.mock';
|
||||||
|
import { ColumnSortingModel } from '../models/column-sorting.model';
|
||||||
|
|
||||||
describe('DocumentList', () => {
|
describe('DocumentList', () => {
|
||||||
|
|
||||||
let alfrescoServiceMock: AlfrescoServiceMock;
|
let alfrescoServiceMock: AlfrescoServiceMock;
|
||||||
let documentList: DocumentList;
|
let documentList: DocumentList;
|
||||||
let eventMock: any;
|
let eventMock: any;
|
||||||
|
let componentHandler;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
alfrescoServiceMock = new AlfrescoServiceMock();
|
alfrescoServiceMock = new AlfrescoServiceMock();
|
||||||
documentList = new DocumentList(alfrescoServiceMock, null);
|
let zone = new NgZone(false);
|
||||||
|
documentList = new DocumentList(alfrescoServiceMock, zone);
|
||||||
|
|
||||||
eventMock = {
|
eventMock = {
|
||||||
preventDefault: function () {
|
preventDefault: function () {
|
||||||
console.log('mock preventDefault');
|
console.log('mock preventDefault');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||||
|
'upgradeAllRegistered'
|
||||||
|
]);
|
||||||
|
window['componentHandler'] = componentHandler;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should setup default columns', () => {
|
it('should setup default columns', () => {
|
||||||
@@ -84,9 +96,7 @@ describe('DocumentList', () => {
|
|||||||
let url = 'URL';
|
let url = 'URL';
|
||||||
spyOn(alfrescoServiceMock, 'getDocumentThumbnailUrl').and.returnValue(url);
|
spyOn(alfrescoServiceMock, 'getDocumentThumbnailUrl').and.returnValue(url);
|
||||||
|
|
||||||
let node = new MinimalNodeEntity();
|
let node = new FileNode();
|
||||||
node.entry = new MinimalNodeEntryEntity();
|
|
||||||
node.entry.isFile = true;
|
|
||||||
documentList.thumbnails = true;
|
documentList.thumbnails = true;
|
||||||
let result = documentList.getThumbnailUrl(node);
|
let result = documentList.getThumbnailUrl(node);
|
||||||
|
|
||||||
@@ -104,15 +114,8 @@ describe('DocumentList', () => {
|
|||||||
expect(alfrescoServiceMock.getDocumentThumbnailUrl).not.toHaveBeenCalled();
|
expect(alfrescoServiceMock.getDocumentThumbnailUrl).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return no thumbnail url without service', () => {
|
|
||||||
let list = new DocumentList(null, null);
|
|
||||||
let node = new MinimalNodeEntity();
|
|
||||||
expect(list.getThumbnailUrl(node)).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should execute action with node', () => {
|
it('should execute action with node', () => {
|
||||||
let node = new MinimalNodeEntity();
|
let node = new FileNode();
|
||||||
node.entry = new MinimalNodeEntryEntity();
|
|
||||||
let action = new ContentActionModel();
|
let action = new ContentActionModel();
|
||||||
action.handler = function () {
|
action.handler = function () {
|
||||||
console.log('mock handler');
|
console.log('mock handler');
|
||||||
@@ -211,7 +214,7 @@ describe('DocumentList', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should emit itemClick event', (done) => {
|
it('should emit itemClick event', (done) => {
|
||||||
let node: MinimalNodeEntity = new MinimalNodeEntity();
|
let node = new FileNode();
|
||||||
documentList.itemClick.subscribe(e => {
|
documentList.itemClick.subscribe(e => {
|
||||||
expect(e.value).toBe(node);
|
expect(e.value).toBe(node);
|
||||||
done();
|
done();
|
||||||
@@ -219,25 +222,28 @@ describe('DocumentList', () => {
|
|||||||
documentList.onItemClick(node);
|
documentList.onItemClick(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should prevent default events for item click', () => {
|
it('should prevent default item single click event', () => {
|
||||||
spyOn(eventMock, 'preventDefault').and.stub();
|
spyOn(eventMock, 'preventDefault').and.stub();
|
||||||
|
|
||||||
documentList.onItemClick(null, eventMock);
|
documentList.onItemClick(null, eventMock);
|
||||||
expect(eventMock.preventDefault).toHaveBeenCalled();
|
expect(eventMock.preventDefault).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should prevent default item double click event', () => {
|
||||||
|
spyOn(eventMock, 'preventDefault').and.stub();
|
||||||
|
documentList.onItemDblClick(null, eventMock);
|
||||||
|
expect(eventMock.preventDefault).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('should display folder content on click', () => {
|
it('should display folder content on click', () => {
|
||||||
let path = '/';
|
let path = '/';
|
||||||
|
|
||||||
let node = new MinimalNodeEntity();
|
let node = new FolderNode('<display name>');
|
||||||
node.entry = new MinimalNodeEntryEntity();
|
|
||||||
node.entry.isFolder = true;
|
|
||||||
node.entry.name = '<display name>';
|
|
||||||
|
|
||||||
spyOn(documentList, 'getNodePath').and.returnValue(path);
|
spyOn(documentList, 'getNodePath').and.returnValue(path);
|
||||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
|
||||||
documentList.navigationMode = 'click';
|
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||||
documentList.onItemClick(node);
|
documentList.onItemClick(node);
|
||||||
|
|
||||||
expect(documentList.currentFolderPath).toBe(path);
|
expect(documentList.currentFolderPath).toBe(path);
|
||||||
@@ -256,10 +262,7 @@ describe('DocumentList', () => {
|
|||||||
expect(documentList.navigate).toBe(true);
|
expect(documentList.navigate).toBe(true);
|
||||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
|
||||||
let node = new MinimalNodeEntity();
|
let node = new FileNode();
|
||||||
node.entry = new MinimalNodeEntryEntity();
|
|
||||||
node.entry.isFolder = false;
|
|
||||||
|
|
||||||
documentList.onItemClick(node);
|
documentList.onItemClick(node);
|
||||||
|
|
||||||
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
|
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
|
||||||
@@ -268,11 +271,7 @@ describe('DocumentList', () => {
|
|||||||
it('should not display folder content on click when navigation is off', () => {
|
it('should not display folder content on click when navigation is off', () => {
|
||||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
|
||||||
let node = new MinimalNodeEntity();
|
let node = new FolderNode('<display name>');
|
||||||
node.entry = new MinimalNodeEntryEntity();
|
|
||||||
node.entry.isFolder = true;
|
|
||||||
node.entry.name = '<display name>';
|
|
||||||
|
|
||||||
documentList.navigate = false;
|
documentList.navigate = false;
|
||||||
documentList.onItemClick(node);
|
documentList.onItemClick(node);
|
||||||
|
|
||||||
@@ -310,4 +309,398 @@ describe('DocumentList', () => {
|
|||||||
expect(documentList.getObjectValue(target, 'key1.key2.key3')).toBe('value1');
|
expect(documentList.getObjectValue(target, 'key1.key2.key3')).toBe('value1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should display folder content for new folder path', () => {
|
||||||
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
let newPath = '/some/new/path';
|
||||||
|
documentList.currentFolderPath = newPath;
|
||||||
|
expect(documentList.displayFolderContent).toHaveBeenCalledWith(newPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not display folder content for same path', () => {
|
||||||
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
documentList.currentFolderPath = '/test';
|
||||||
|
expect(documentList.displayFolderContent).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
documentList.currentFolderPath = '/test';
|
||||||
|
expect(documentList.displayFolderContent).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset to default path', () => {
|
||||||
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
documentList.currentFolderPath = null;
|
||||||
|
|
||||||
|
expect(documentList.currentFolderPath).toBe(documentList.DEFAULT_ROOT_FOLDER);
|
||||||
|
expect(documentList.displayFolderContent).toHaveBeenCalledWith(documentList.DEFAULT_ROOT_FOLDER);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit folder changed event', (done) => {
|
||||||
|
documentList.folderChange.subscribe(e => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
documentList.folder = new PageNode();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit folder changed event with folder details', (done) => {
|
||||||
|
let folder = new PageNode();
|
||||||
|
let path = '/path';
|
||||||
|
|
||||||
|
documentList.folderChange.subscribe(e => {
|
||||||
|
expect(e.value).toBe(folder);
|
||||||
|
expect(e.path).toBe(path);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||||
|
documentList.currentFolderPath = path;
|
||||||
|
documentList.folder = folder;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit folder changed event', () => {
|
||||||
|
let folder = new PageNode();
|
||||||
|
let calls = 0;
|
||||||
|
documentList.folderChange.subscribe(e => {
|
||||||
|
calls++;
|
||||||
|
});
|
||||||
|
|
||||||
|
documentList.folder = folder;
|
||||||
|
documentList.folder = folder;
|
||||||
|
expect(calls).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reload on binding changes', () => {
|
||||||
|
spyOn(documentList, 'reload').and.stub();
|
||||||
|
documentList.ngOnChanges(null);
|
||||||
|
expect(documentList.reload).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute context action on callback', () => {
|
||||||
|
let action = {
|
||||||
|
node: {},
|
||||||
|
model: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(documentList, 'executeContentAction').and.stub();
|
||||||
|
documentList.contextActionCallback(action);
|
||||||
|
expect(documentList.executeContentAction).toHaveBeenCalledWith(action.node, action.model);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not execute context action on callback', () => {
|
||||||
|
spyOn(documentList, 'executeContentAction').and.stub();
|
||||||
|
documentList.contextActionCallback(null);
|
||||||
|
expect(documentList.executeContentAction).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should upgrade material design components', () => {
|
||||||
|
documentList.ngAfterViewChecked();
|
||||||
|
expect(componentHandler.upgradeAllRegistered).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should subscribe to context action handler', () => {
|
||||||
|
let value = {};
|
||||||
|
spyOn(documentList, 'contextActionCallback').and.stub();
|
||||||
|
documentList.ngOnInit();
|
||||||
|
documentList.contextActionHandler.next(value);
|
||||||
|
expect(documentList.contextActionCallback).toHaveBeenCalledWith(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should suppress default context menu', () => {
|
||||||
|
spyOn(eventMock, 'preventDefault').and.stub();
|
||||||
|
documentList.onShowContextMenu(eventMock);
|
||||||
|
expect(eventMock.preventDefault).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit file preview event on single click', (done) => {
|
||||||
|
let file = new FileNode();
|
||||||
|
documentList.preview.subscribe(e => {
|
||||||
|
expect(e.value).toBe(file);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemClick(file, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit file preview event on double click', (done) => {
|
||||||
|
let file = new FileNode();
|
||||||
|
documentList.preview.subscribe(e => {
|
||||||
|
expect(e.value).toBe(file);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
documentList.navigationMode = DocumentList.DOUBLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemDblClick(file, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should perform folder navigation on single click', () => {
|
||||||
|
let folder = new FolderNode();
|
||||||
|
spyOn(documentList, 'performNavigation').and.stub();
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemClick(folder, null);
|
||||||
|
expect(documentList.performNavigation).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should perform folder navigation on double click', () => {
|
||||||
|
let folder = new FolderNode();
|
||||||
|
spyOn(documentList, 'performNavigation').and.stub();
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.DOUBLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemDblClick(folder, null);
|
||||||
|
expect(documentList.performNavigation).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not perform folder navigation on double click when single mode', () => {
|
||||||
|
let folder = new FolderNode();
|
||||||
|
spyOn(documentList, 'performNavigation').and.stub();
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemDblClick(folder, null);
|
||||||
|
|
||||||
|
expect(documentList.performNavigation).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not perform folder navigation on double click when navigation off', () => {
|
||||||
|
let folder = new FolderNode();
|
||||||
|
spyOn(documentList, 'performNavigation').and.stub();
|
||||||
|
|
||||||
|
documentList.navigate = false;
|
||||||
|
documentList.navigationMode = DocumentList.DOUBLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemDblClick(folder, null);
|
||||||
|
|
||||||
|
expect(documentList.performNavigation).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should perform navigation for folder node only', () => {
|
||||||
|
let folder = new FolderNode();
|
||||||
|
let file = new FileNode();
|
||||||
|
spyOn(documentList, 'getNodePath').and.returnValue('/path');
|
||||||
|
|
||||||
|
expect(documentList.performNavigation(folder)).toBeTruthy();
|
||||||
|
expect(documentList.performNavigation(file)).toBeFalsy();
|
||||||
|
expect(documentList.performNavigation(null)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not get node path for null node', () => {
|
||||||
|
expect(documentList.getNodePath(null)).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trim company home from node path', () => {
|
||||||
|
let file = new FileNode('file.txt');
|
||||||
|
file.entry.path.name = '/Company Home/folder1';
|
||||||
|
expect(documentList.getNodePath(file)).toBe('/folder1/file.txt');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should require valid node for file preview', () => {
|
||||||
|
let file = new FileNode();
|
||||||
|
file.entry = null;
|
||||||
|
let called = false;
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||||
|
documentList.preview.subscribe(val => called = true);
|
||||||
|
|
||||||
|
documentList.onItemClick(file, null);
|
||||||
|
expect(called).toBeFalsy();
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.DOUBLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemDblClick(file, null);
|
||||||
|
expect(called).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should require valid node for folder navigation', () => {
|
||||||
|
let folder = new FolderNode();
|
||||||
|
folder.entry = null;
|
||||||
|
spyOn(documentList, 'performNavigation').and.stub();
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemClick(folder, null);
|
||||||
|
|
||||||
|
documentList.navigationMode = DocumentList.DOUBLE_CLICK_NAVIGATION;
|
||||||
|
documentList.onItemDblClick(folder, null);
|
||||||
|
|
||||||
|
expect(documentList.performNavigation).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display folder content on reload', () => {
|
||||||
|
spyOn(documentList, 'displayFolderContent').and.callThrough();
|
||||||
|
documentList.reload();
|
||||||
|
expect(documentList.displayFolderContent).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate folder icon path', () => {
|
||||||
|
documentList.baseComponentPath = '/root';
|
||||||
|
let folder = new FolderNode();
|
||||||
|
expect(documentList.getThumbnailUrl(folder)).toBe('/root/img/ft_ic_folder.svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate file icon path based on mime type', () => {
|
||||||
|
let fileName = 'custom-icon.svg';
|
||||||
|
spyOn(alfrescoServiceMock, 'getMimeTypeIcon').and.returnValue(fileName);
|
||||||
|
documentList.baseComponentPath = '/root';
|
||||||
|
|
||||||
|
let file = new FileNode();
|
||||||
|
file.entry.content.mimeType = 'text/plain';
|
||||||
|
|
||||||
|
expect(documentList.getThumbnailUrl(file)).toBe(`/root/img/${fileName}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to default icon for missing mime type', () => {
|
||||||
|
spyOn(alfrescoServiceMock, 'getMimeTypeIcon').and.returnValue(null);
|
||||||
|
documentList.baseComponentPath = '/root';
|
||||||
|
|
||||||
|
let file = new FileNode();
|
||||||
|
file.entry.content.mimeType = null;
|
||||||
|
|
||||||
|
expect(documentList.getThumbnailUrl(file)).toBe('/root/img/ft_ic_miscellaneous.svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to default icon for unknown mime type', () => {
|
||||||
|
spyOn(alfrescoServiceMock, 'getMimeTypeIcon').and.returnValue(null);
|
||||||
|
documentList.baseComponentPath = '/root';
|
||||||
|
|
||||||
|
let file = new FileNode();
|
||||||
|
file.entry.content.mimeType = 'text/plain';
|
||||||
|
|
||||||
|
expect(documentList.getThumbnailUrl(file)).toBe('/root/img/ft_ic_miscellaneous.svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve thumbnail url for a file', () => {
|
||||||
|
let url = 'http://<some url>';
|
||||||
|
spyOn(alfrescoServiceMock, 'getDocumentThumbnailUrl').and.returnValue(url);
|
||||||
|
|
||||||
|
documentList.thumbnails = true;
|
||||||
|
|
||||||
|
let file = new FileNode();
|
||||||
|
expect(documentList.getThumbnailUrl(file)).toBe(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return no thumbnail url with missing service', () => {
|
||||||
|
let list = new DocumentList(null, null);
|
||||||
|
list.thumbnails = true;
|
||||||
|
|
||||||
|
let file = new FileNode();
|
||||||
|
expect(list.getThumbnailUrl(file)).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sort on column header click', () => {
|
||||||
|
let col = new ContentColumnModel();
|
||||||
|
col.source = 'id';
|
||||||
|
|
||||||
|
spyOn(documentList, 'sort').and.callThrough();
|
||||||
|
|
||||||
|
documentList.onColumnHeaderClick(col);
|
||||||
|
|
||||||
|
expect(documentList.sorting).toEqual(
|
||||||
|
jasmine.objectContaining({
|
||||||
|
key: 'id',
|
||||||
|
direction: 'asc'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(documentList.sort).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should invert sorting on column header click', () => {
|
||||||
|
let col = new ContentColumnModel();
|
||||||
|
col.source = 'id';
|
||||||
|
|
||||||
|
spyOn(documentList, 'sort').and.callThrough();
|
||||||
|
|
||||||
|
documentList.sorting = <ColumnSortingModel> { key: 'id', direction: 'asc' };
|
||||||
|
documentList.onColumnHeaderClick(col);
|
||||||
|
|
||||||
|
expect(documentList.sorting).toEqual(
|
||||||
|
jasmine.objectContaining({
|
||||||
|
key: 'id',
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
documentList.onColumnHeaderClick(col);
|
||||||
|
expect(documentList.sorting).toEqual(
|
||||||
|
jasmine.objectContaining({
|
||||||
|
key: 'id',
|
||||||
|
direction: 'asc'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(documentList.sort).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use ascending direction for different column header click', () => {
|
||||||
|
let col = new ContentColumnModel();
|
||||||
|
col.source = 'id';
|
||||||
|
|
||||||
|
spyOn(documentList, 'sort').and.callThrough();
|
||||||
|
|
||||||
|
documentList.sorting = <ColumnSortingModel> { key: 'col1', direction: 'desc' };
|
||||||
|
documentList.onColumnHeaderClick(col);
|
||||||
|
|
||||||
|
expect(documentList.sorting).toEqual(
|
||||||
|
jasmine.objectContaining({
|
||||||
|
key: 'id',
|
||||||
|
direction: 'asc'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(documentList.sort).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not sort by column header when instance is missing', () => {
|
||||||
|
spyOn(documentList, 'sort').and.callThrough();
|
||||||
|
documentList.onColumnHeaderClick(null);
|
||||||
|
expect(documentList.sort).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert cell value to thumbnail', () => {
|
||||||
|
let url = 'http://<address>';
|
||||||
|
spyOn(documentList, 'getThumbnailUrl').and.returnValue(url);
|
||||||
|
|
||||||
|
let file = new FileNode();
|
||||||
|
|
||||||
|
let col = new ContentColumnModel();
|
||||||
|
col.source = '$thumbnail';
|
||||||
|
col.type = 'image';
|
||||||
|
|
||||||
|
let value = documentList.getCellValue(file, col);
|
||||||
|
expect(value).toBe(url);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ declare let __moduleName: string;
|
|||||||
})
|
})
|
||||||
export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit, OnChanges {
|
export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit, OnChanges {
|
||||||
|
|
||||||
|
static SINGLE_CLICK_NAVIGATION: string = 'click';
|
||||||
|
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
|
||||||
|
|
||||||
DEFAULT_ROOT_FOLDER: string = '/';
|
DEFAULT_ROOT_FOLDER: string = '/';
|
||||||
|
|
||||||
baseComponentPath = __moduleName.replace('/components/document-list.js', '');
|
baseComponentPath = __moduleName.replace('/components/document-list.js', '');
|
||||||
@@ -216,7 +219,7 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
|||||||
value: item
|
value: item
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.navigate && this.navigationMode === 'click') {
|
if (this.navigate && this.navigationMode === DocumentList.SINGLE_CLICK_NAVIGATION) {
|
||||||
if (item && item.entry) {
|
if (item && item.entry) {
|
||||||
if (item.entry.isFile) {
|
if (item.entry.isFile) {
|
||||||
this.preview.emit({
|
this.preview.emit({
|
||||||
@@ -240,7 +243,7 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
|||||||
value: item
|
value: item
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.navigate && this.navigationMode === 'dblclick') {
|
if (this.navigate && this.navigationMode === DocumentList.DOUBLE_CLICK_NAVIGATION) {
|
||||||
if (item && item.entry) {
|
if (item && item.entry) {
|
||||||
if (item.entry.isFile) {
|
if (item.entry.isFile) {
|
||||||
this.preview.emit({
|
this.preview.emit({
|
||||||
@@ -261,10 +264,12 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private performNavigation(node: MinimalNodeEntity) {
|
performNavigation(node: MinimalNodeEntity): boolean {
|
||||||
if (node && node.entry && node.entry.isFolder) {
|
if (node && node.entry && node.entry.isFolder) {
|
||||||
this.currentFolderPath = this.getNodePath(node);
|
this.currentFolderPath = this.getNodePath(node);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -290,7 +295,9 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
|||||||
|
|
||||||
if (entry.content && entry.content.mimeType) {
|
if (entry.content && entry.content.mimeType) {
|
||||||
let icon = this.alfrescoService.getMimeTypeIcon(entry.content.mimeType);
|
let icon = this.alfrescoService.getMimeTypeIcon(entry.content.mimeType);
|
||||||
return `${this.baseComponentPath}/img/${icon}`;
|
if (icon) {
|
||||||
|
return `${this.baseComponentPath}/img/${icon}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*!
|
||||||
|
* @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
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ContentColumnModel } from './content-column.model';
|
||||||
|
|
||||||
|
describe('ContentColumnModel', () => {
|
||||||
|
|
||||||
|
it('should init with text type from config object', () => {
|
||||||
|
let model = new ContentColumnModel({});
|
||||||
|
expect(model.type).toBe(ContentColumnModel.TYPE_TEXT);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return supported types', () => {
|
||||||
|
expect(ContentColumnModel.getSupportedTypes().length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -16,11 +16,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export class ContentColumnModel {
|
export class ContentColumnModel {
|
||||||
|
|
||||||
|
static TYPE_TEXT: string = 'text';
|
||||||
|
static TYPE_DATE: string = 'date';
|
||||||
|
static TYPE_IMAGE: string = 'image';
|
||||||
|
// static TYPE_NUMBER: string = 'number';
|
||||||
|
|
||||||
title: string;
|
title: string;
|
||||||
srTitle: string;
|
srTitle: string;
|
||||||
source: string;
|
source: string;
|
||||||
cssClass: string;
|
cssClass: string;
|
||||||
type: string = 'text'; // text|date|image|number
|
type: string = ContentColumnModel.TYPE_TEXT;
|
||||||
format: string = 'medium';
|
format: string = 'medium';
|
||||||
|
|
||||||
constructor(obj?: any) {
|
constructor(obj?: any) {
|
||||||
@@ -29,8 +35,17 @@ export class ContentColumnModel {
|
|||||||
this.srTitle = obj.srTitle;
|
this.srTitle = obj.srTitle;
|
||||||
this.source = obj.source;
|
this.source = obj.source;
|
||||||
this.cssClass = obj.cssClass;
|
this.cssClass = obj.cssClass;
|
||||||
this.type = obj.type || 'text';
|
this.type = obj.type || ContentColumnModel.TYPE_TEXT;
|
||||||
this.format = obj.format;
|
this.format = obj.format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getSupportedTypes(): string[] {
|
||||||
|
return [
|
||||||
|
ContentColumnModel.TYPE_TEXT,
|
||||||
|
ContentColumnModel.TYPE_DATE,
|
||||||
|
ContentColumnModel.TYPE_IMAGE
|
||||||
|
// ContentColumnModel.TYPE_NUMBER
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,59 +17,6 @@
|
|||||||
|
|
||||||
// note: contains only limited subset of available fields
|
// note: contains only limited subset of available fields
|
||||||
|
|
||||||
// TODO: deprecated
|
|
||||||
export class FolderEntity {
|
|
||||||
items: DocumentEntity[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: deprecated
|
|
||||||
export class DocumentEntity {
|
|
||||||
nodeRef: string;
|
|
||||||
nodeType: string;
|
|
||||||
type: string;
|
|
||||||
mimetype: string;
|
|
||||||
isFolder: boolean;
|
|
||||||
isLink: boolean;
|
|
||||||
fileName: string;
|
|
||||||
displayName: string;
|
|
||||||
status: string;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
author: string;
|
|
||||||
createdOn: string;
|
|
||||||
createdBy: string;
|
|
||||||
createdByUser: string;
|
|
||||||
modifiedOn: string;
|
|
||||||
modifiedBy: string;
|
|
||||||
modifiedByUser: string;
|
|
||||||
lockedBy: string;
|
|
||||||
lockedByUser: string;
|
|
||||||
size: number;
|
|
||||||
version: string;
|
|
||||||
contentUrl: string;
|
|
||||||
webdavUrl: string;
|
|
||||||
actionSet: string;
|
|
||||||
tags: string[];
|
|
||||||
activeWorkflows: string;
|
|
||||||
location: LocationEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: deprecated
|
|
||||||
export class LocationEntity {
|
|
||||||
repositoryId: string;
|
|
||||||
site: string;
|
|
||||||
siteTitle: string;
|
|
||||||
container: string;
|
|
||||||
path: string;
|
|
||||||
file: string;
|
|
||||||
parent: LocationParentEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: deprecated
|
|
||||||
export class LocationParentEntity {
|
|
||||||
nodeRef: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class NodePaging {
|
export class NodePaging {
|
||||||
list: NodePagingList;
|
list: NodePagingList;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user