From 9e4b2e74e93b6283d1e997e509c69506df5d4184 Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Thu, 1 Feb 2018 10:08:25 +0000 Subject: [PATCH] [ADF-2159] Update angular-cli to latest version (#2874) * Update angular cli version 1.6.5 * fix tslint problems and update devdependencies using the angularcli 1.6.4 * test fixing * [ADF-2159] start fixing userinfo test * [ADF-2159] fixed userinfo tests * [ADF-2159] added async to accordion component test * [ADF-2159] testing probable failed test on CI * [ADF-2159] check removing fake destroyed view test * [ADF-2159] check viewer tests * [ADF-2159] attempt on test fix * [ADF-2159] test fix * [ADF-2159] fix test * [ADF-2159] fix test * [ADF-2159] rebased * [ADF-2159] check test * [ADF-2159] fixing test * [ADF-2159] Fix#1 * [ADF-2159] Fix#2 * [ADF-2159] Fix#3 * [ADF-2159] Fix #4 * [ADF-2159] Fix #5 * [ADF-2159] Fix #6 * [ADF-2159] fixed viewer test * [ADF-2159] fixed cast element --- .gitignore | 1 + demo-shell/.angular-cli.json | 39 +- demo-shell/config/dev-copy-watch.js | 14 + demo-shell/package.json | 30 +- .../app/components/files/files.component.ts | 4 +- .../form-node-viewer.component.ts | 2 +- .../process-service/form-viewer.component.ts | 2 +- .../process-service.component.ts | 2 +- .../components/settings/settings.component.ts | 2 +- demo-shell/src/main.ts | 2 +- demo-shell/src/polyfills.ts | 3 +- demo-shell/tslint.json | 25 +- .../content-node-selector-panel.component.ts | 2 +- .../mock/search.component.mock.ts | 2 +- .../accordion-group.component.spec.ts | 21 +- .../components/start-form.component.spec.ts | 4 +- .../widgets/dropdown/dropdown.widget.spec.ts | 28 +- .../widgets/tabs/tabs.widget.spec.ts | 33 +- .../components/user-info.component.html | 2 +- .../components/user-info.component.spec.ts | 370 +++--- .../components/user-info.component.ts | 3 +- .../viewer/components/imgViewer.component.ts | 2 +- .../components/viewer.component.spec.ts | 1172 +++++++++-------- .../viewer/components/viewer.component.ts | 199 +-- .../tooltip/diagram-tooltip.component.ts | 2 +- lib/package.json | 6 +- lib/tslint.json | 24 +- 27 files changed, 999 insertions(+), 997 deletions(-) create mode 100644 demo-shell/config/dev-copy-watch.js diff --git a/.gitignore b/.gitignore index d5e0ca95bf..e0b8c0edc6 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ src/environments/ package-lock.* /ng2-components/ng2-alfresco-core/prebuilt-themes/ .ng_pkg_build/ +/demo-shell/dist-dev-temp/ diff --git a/demo-shell/.angular-cli.json b/demo-shell/.angular-cli.json index 8103d163c5..0b378c281f 100644 --- a/demo-shell/.angular-cli.json +++ b/demo-shell/.angular-cli.json @@ -102,43 +102,8 @@ }, { "glob": "**/*", - "input": "../../lib/core/prebuilt-themes", - "output": "./assets/prebuilt-themes" - }, - { - "glob": "**/*", - "input": "../../lib/core/assets", - "output": "./assets/" - }, - { - "glob": "**/*", - "input": "../../lib/process-services/assets", - "output": "./assets/" - }, - { - "glob": "**/*", - "input": "../../lib/content-services/assets", - "output": "./assets/" - }, - { - "glob": "**/*", - "input": "../../lib/core/i18n", - "output": "./assets/adf-core/i18n" - }, - { - "glob": "**/*", - "input": "../../lib/process-services/i18n", - "output": "./assets/adf-process-services/i18n" - }, - { - "glob": "**/*", - "input": "../../lib/content-services/i18n", - "output": "./assets/adf-content-services/i18n" - }, - { - "glob": "**/*", - "input": "../../lib/insights/i18n", - "output": "./assets/adf-insights/i18n" + "input": "../dist-dev-temp/", + "output": "./" }, { "glob": "pdf.worker.js", diff --git a/demo-shell/config/dev-copy-watch.js b/demo-shell/config/dev-copy-watch.js new file mode 100644 index 0000000000..ef7a83dbde --- /dev/null +++ b/demo-shell/config/dev-copy-watch.js @@ -0,0 +1,14 @@ +const cpx = require('cpx'); + +//Workaround for https://github.com/angular/angular-cli/issues/8783 +//we copy before the files in dist-dev-temp in the demo shell and after we let the angular cli watch over them..double wathh necessary for dev mode + +cpx.watch('../lib/core/prebuilt-themes/**/*.*', './dist-dev-temp/assets/prebuilt-themes') +cpx.watch('../lib/core/assets/**/*.*', './dist-dev-temp/assets/' ) +cpx.watch('../lib/process-services/assets/**/*.*', './dist-dev-temp/assets/' ) +cpx.watch('../lib/content-services/assets/**/*.*', './dist-dev-temp/assets/' ) + +cpx.watch('../lib/core/i18n/**/*.*', './dist-dev-temp//assets/adf-core/i18n' ) +cpx.watch('../lib/process-services/i18n/**/*.*', './dist-dev-temp/assets/adf-process-services/i18n' ) +cpx.watch('../lib/content-services/i18n/**/*.*', './dist-dev-temp/assets/adf-content-services/i18n' ) +cpx.watch('../lib/insights/i18n/**/*.*', './dist-dev-temp//assets/adf-insights/i18n' ) diff --git a/demo-shell/package.json b/demo-shell/package.json index be0b656832..8a2b9fe236 100644 --- a/demo-shell/package.json +++ b/demo-shell/package.json @@ -7,12 +7,13 @@ "ng": "ng", "prestart": "npm run validate-config", "start": "npm run server-versions && rimraf dist && ng serve --host 0.0.0.0 --app dist --open --aot=false", - "start:dev": "npm run lint && npm run server-versions && rimraf dist && npm run clean-lib-angular && concurrently \"ng serve --host 0.0.0.0 --disable-host-check --app dev pp-dev --proxy-config proxy.conf.js --open\" \"npm run style:dev -- --watch\" ", + "start:dev": " npm run lint && npm run server-versions && rimraf dist && npm run clean-lib-angular && concurrently \"ng serve --host 0.0.0.0 --disable-host-check --app dev pp-dev --proxy-config proxy.conf.js --open\" \"npm run style:dev --watch\" \"npm run copy:dev\" ", "start:dist": "npm run server-versions && rimraf dist && node --max_old_space_size=30000 node_modules/.bin/ng serve --prod --build-optimizer=false --aot=false --host 0.0.0.0 --disable-host-check --app dist", "build": "npm run server-versions && rimraf dist && ng build --app dist", "build:dev": "npm run lint && npm run style:dev && npm run server-versions && rimraf dist && ng build --app dev", "build:dist": "npm run style:dev && npm run server-versions && rimraf dist && node --max_old_space_size=30000 node_modules/.bin/ng build --prod --build-optimizer=false --aot=false --app dist", "style:dev": "npm run webpack -- --config config/webpack.style.js --progress --profile --bail", + "copy:dev": "node ./config/dev-copy-watch.js", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", @@ -92,7 +93,7 @@ "moment": "2.18.1", "moment-es6": "^1.0.0", "ng2-charts": "1.6.0", - "pdfjs-dist": "1.5.404", + "pdfjs-dist": "2.0.265", "raphael": "2.2.7", "reflect-metadata": "0.1.10", "rxjs": "5.5.2", @@ -101,27 +102,28 @@ }, "devDependencies": { "@angular-devkit/core": "0.0.28", - "@angular/cli": "1.5.0", - "@angular/compiler-cli": "5.1.1", - "@angular/language-service": "5.1.1", - "@types/jasmine": "~2.5.53", + "@angular/cli": "1.6.5", + "@angular/compiler-cli": "^5.2.0", + "@angular/language-service": "^5.2.0", + "@types/jasmine": "~2.8.3", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "ajv-cli": "^3.0.0", - "codelyzer": "4.0.0", + "codelyzer": "4.1.0", "concurrently": "^3.5.1", - "jasmine-core": "~2.6.2", - "jasmine-spec-reporter": "~4.1.0", - "karma": "~1.7.0", - "karma-chrome-launcher": "~2.1.1", + "cpx": "^1.5.0", + "jasmine-core": "~2.8.0", + "jasmine-spec-reporter": "~4.2.1", + "karma": "~2.0.0", + "karma-chrome-launcher": "~2.2.0", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.2", "rimraf": "^2.6.2", - "ts-node": "~3.2.0", - "tslint": "^5.7.0", - "typescript": "2.6.2" + "ts-node": "~4.1.0", + "tslint": "~5.9.1", + "typescript": "~2.5.3" } } diff --git a/demo-shell/src/app/components/files/files.component.ts b/demo-shell/src/app/components/files/files.component.ts index 3c349d56ac..6a044deb52 100644 --- a/demo-shell/src/app/components/files/files.component.ts +++ b/demo-shell/src/app/components/files/files.component.ts @@ -34,7 +34,7 @@ import { DocumentListComponent, PermissionStyleModel, DownloadZipDialogComponent import { SelectAppsDialogComponent } from '@alfresco/adf-process-services'; import { VersionManagerDialogAdapterComponent } from './version-manager-dialog-adapter.component'; -import { Subscription } from 'rxjs/Rx'; +import { Subscription } from 'rxjs/Subscription'; const DEFAULT_FOLDER_TO_SHOW = '-my-'; @@ -272,7 +272,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { message, 4000 ); - }) + }); } handleUploadError(event: any) { diff --git a/demo-shell/src/app/components/process-service/form-node-viewer.component.ts b/demo-shell/src/app/components/process-service/form-node-viewer.component.ts index 409580ad92..7ed7af87fa 100644 --- a/demo-shell/src/app/components/process-service/form-node-viewer.component.ts +++ b/demo-shell/src/app/components/process-service/form-node-viewer.component.ts @@ -17,7 +17,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs/Rx'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'app-form-node-viewer', diff --git a/demo-shell/src/app/components/process-service/form-viewer.component.ts b/demo-shell/src/app/components/process-service/form-viewer.component.ts index 5fb3346fe0..5327761628 100644 --- a/demo-shell/src/app/components/process-service/form-viewer.component.ts +++ b/demo-shell/src/app/components/process-service/form-viewer.component.ts @@ -17,7 +17,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs/Rx'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'app-form-viewer', diff --git a/demo-shell/src/app/components/process-service/process-service.component.ts b/demo-shell/src/app/components/process-service/process-service.component.ts index 57c678f0ea..c17b66de14 100644 --- a/demo-shell/src/app/components/process-service/process-service.component.ts +++ b/demo-shell/src/app/components/process-service/process-service.component.ts @@ -58,7 +58,7 @@ import { ObjectDataRow, ObjectDataTableAdapter } from '@alfresco/adf-core'; -import { Subscription } from 'rxjs/Rx'; +import { Subscription } from 'rxjs/Subscription'; import { /*CustomEditorComponent*/ CustomStencil01 } from './custom-editor/custom-editor.component'; import { DemoFieldValidator } from './demo-field-validator'; diff --git a/demo-shell/src/app/components/settings/settings.component.ts b/demo-shell/src/app/components/settings/settings.component.ts index 1eb5d0f00f..8c82578c81 100644 --- a/demo-shell/src/app/components/settings/settings.component.ts +++ b/demo-shell/src/app/components/settings/settings.component.ts @@ -28,6 +28,6 @@ export class SettingsComponent { } onError(error: string) { - this.logService.log(error) + this.logService.log(error); } } diff --git a/demo-shell/src/main.ts b/demo-shell/src/main.ts index f8130a7f3e..8e14b4a6b5 100644 --- a/demo-shell/src/main.ts +++ b/demo-shell/src/main.ts @@ -7,7 +7,7 @@ import 'hammerjs'; import 'chart.js'; import 'ng2-charts'; -import pdfjsLib from 'pdfjs-dist'; +import * as pdfjsLib from 'pdfjs-dist'; pdfjsLib.PDFJS.workerSrc = 'pdf.worker.js'; if (environment.production) { diff --git a/demo-shell/src/polyfills.ts b/demo-shell/src/polyfills.ts index 1fbf2b074f..229e7fbf23 100644 --- a/demo-shell/src/polyfills.ts +++ b/demo-shell/src/polyfills.ts @@ -65,5 +65,6 @@ import 'intl'; // Run `npm install --save intl`. * Support custom event in IE11 * * */ -import 'custom-event-polyfill/custom-event-polyfill' // Run `npm install --save custom-event-polyfill`. + +import 'custom-event-polyfill/custom-event-polyfill'; // Run `npm install --save custom-event-polyfill`. diff --git a/demo-shell/tslint.json b/demo-shell/tslint.json index 49add5145c..71d1f7d829 100644 --- a/demo-shell/tslint.json +++ b/demo-shell/tslint.json @@ -3,6 +3,7 @@ "node_modules/codelyzer" ], "rules": { + "arrow-return-shorthand": true, "callable-types": true, "class-name": true, "comment-format": [ @@ -12,7 +13,11 @@ "curly": true, "eofline": true, "forin": true, - "import-blacklist": [true, "rxjs"], + "import-blacklist": [ + true, + "rxjs", + "rxjs/Rx" + ], "import-spacing": true, "indent": [ true, @@ -27,8 +32,14 @@ "member-access": false, "member-ordering": [ true, - "static-before-instance", - "variables-before-functions" + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } ], "no-arg": true, "no-bitwise": true, @@ -43,7 +54,7 @@ ], "no-construct": true, "no-debugger": true, - "no-duplicate-variable": true, + "no-duplicate-super": true, "no-empty": false, "no-empty-interface": true, "no-eval": true, @@ -71,6 +82,7 @@ ], "radix": true, "semicolon": [ + true, "always" ], "triple-equals": [ @@ -108,9 +120,6 @@ "use-life-cycle-interface": true, "use-pipe-transform-interface": true, "component-class-suffix": true, - "directive-class-suffix": true, - "no-access-missing-member": true, - "templates-use-public": true, - "invoke-injectable": true + "directive-class-suffix": true } } diff --git a/lib/content-services/content-node-selector/content-node-selector-panel.component.ts b/lib/content-services/content-node-selector/content-node-selector-panel.component.ts index 1a512375f4..77122bc457 100644 --- a/lib/content-services/content-node-selector/content-node-selector-panel.component.ts +++ b/lib/content-services/content-node-selector/content-node-selector-panel.component.ts @@ -91,7 +91,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit { pagination: Pagination; skipCount: number = 0; infiniteScroll: boolean = false; - debounceSearch: number= 200; + debounceSearch: number = 200; searchInput: FormControl = new FormControl(); constructor(private contentNodeSelectorService: ContentNodeSelectorService, diff --git a/lib/content-services/mock/search.component.mock.ts b/lib/content-services/mock/search.component.mock.ts index c3bc5825f5..0b30b32ccc 100644 --- a/lib/content-services/mock/search.component.mock.ts +++ b/lib/content-services/mock/search.component.mock.ts @@ -141,7 +141,7 @@ export let errorJson = { search: SearchComponent; message: string = ''; - searchedWord= ''; + searchedWord = ''; maxResults: number = 5; searchNode: QueryBody; diff --git a/lib/core/collapsable/accordion-group.component.spec.ts b/lib/core/collapsable/accordion-group.component.spec.ts index 2e6eb01976..a32fb5eee1 100644 --- a/lib/core/collapsable/accordion-group.component.spec.ts +++ b/lib/core/collapsable/accordion-group.component.spec.ts @@ -46,7 +46,7 @@ describe('AccordionGroupComponent', () => { }); - it('should be closed by default', () => { + it('should be closed by default', async(() => { component.heading = 'Fake Header'; component.headingIcon = 'fake-icon'; component.contentWrapper.nativeElement.innerHTML = 'Test'; @@ -59,9 +59,9 @@ describe('AccordionGroupComponent', () => { let headerToggle = element.querySelector('#accordion-button .material-icons'); expect(headerToggle.innerText).toEqual('expand_more'); }); - }); + })); - it('should be open when click', () => { + it('should be open when click', async(() => { component.isSelected = true; component.heading = 'Fake Header'; component.headingIcon = 'fake-icon'; @@ -77,9 +77,9 @@ describe('AccordionGroupComponent', () => { let headerToggle = element.querySelector('#accordion-button .material-icons'); expect(headerToggle.innerText).toEqual('expand_less'); }); - }); + })); - it('should show expand icon by default', () => { + it('should show expand icon by default', async(() => { component.heading = 'Fake Header'; component.headingIcon = 'fake-icon'; component.contentWrapper.nativeElement.innerHTML = 'Test'; @@ -88,9 +88,9 @@ describe('AccordionGroupComponent', () => { let headerIcon = element.querySelector('#accordion-button'); expect(headerIcon).toBeDefined(); }); - }); + })); - it('should hide expand icon', () => { + it('should hide expand icon', async(() => { component.heading = 'Fake Header'; component.headingIcon = 'fake-icon'; component.hasAccordionIcon = false; @@ -100,19 +100,18 @@ describe('AccordionGroupComponent', () => { let headerIcon = element.querySelector('#accordion-button'); expect(headerIcon).toBeNull(); }); - }); + })); - it('should emit an event when a heading clicked', (done) => { + it('should emit an event when a heading clicked', async(() => { component.heading = 'Fake Header'; fixture.detectChanges(); let heading: string = component.heading; component.headingClick.subscribe((headName: string) => { expect(headName).toBeDefined(); expect(headName).toEqual(heading); - done(); }); let header = element.querySelector('.adf-panel-heading'); header.click(); - }); + })); }); diff --git a/lib/core/form/components/start-form.component.spec.ts b/lib/core/form/components/start-form.component.spec.ts index 77a6743c2a..4cb2caddba 100644 --- a/lib/core/form/components/start-form.component.spec.ts +++ b/lib/core/form/components/start-form.component.spec.ts @@ -339,8 +339,8 @@ describe('ActivitiStartForm', () => { component.showOutcomeButtons = true; component.showRefreshButton = true; component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) }); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); const formTabs = component.form.tabs; const tabField1 = formTabs.find(tab => tab.id === 'form1'); const tabField2 = formTabs.find(tab => tab.id === 'form2'); @@ -357,8 +357,8 @@ describe('ActivitiStartForm', () => { component.showOutcomeButtons = true; component.showRefreshButton = true; component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) }); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); const titleIcon = fixture.debugElement.nativeElement.querySelector('mat-card-title>mat-icon'); const titleElement = fixture.debugElement.nativeElement.querySelector('mat-card-title>h2'); const actionButtons = fixture.debugElement.nativeElement.querySelectorAll('.mat-button'); diff --git a/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts b/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts index 8fb63854bb..9ace0bda14 100644 --- a/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts +++ b/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts @@ -43,9 +43,9 @@ describe('DropdownWidgetComponent', () => { let element: HTMLElement; let fakeOptionList: FormFieldOption[] = [ - {id: 'opt_1', name: 'option_1'}, - {id: 'opt_2', name: 'option_2'}, - {id: 'opt_3', name: 'option_3'}]; + { id: 'opt_1', name: 'option_1' }, + { id: 'opt_2', name: 'option_2' }, + { id: 'opt_3', name: 'option_3' }]; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -71,7 +71,7 @@ describe('DropdownWidgetComponent', () => { widget.ngOnInit(); expect(formService.getRestFieldValues).not.toHaveBeenCalled(); - widget.field = new FormFieldModel(null, {restUrl: null}); + widget.field = new FormFieldModel(null, { restUrl: null }); widget.ngOnInit(); expect(formService.getRestFieldValues).not.toHaveBeenCalled(); }); @@ -100,7 +100,7 @@ describe('DropdownWidgetComponent', () => { }); it('should preserve empty option when loading fields', () => { - let restFieldValue: FormFieldOption = {id: '1', name: 'Option1'}; + let restFieldValue: FormFieldOption = { id: '1', name: 'Option1' }; spyOn(formService, 'getRestFieldValues').and.callFake(() => { return Observable.create(observer => { observer.next([restFieldValue]); @@ -108,8 +108,8 @@ describe('DropdownWidgetComponent', () => { }); }); - let form = new FormModel({taskId: ''}); - let emptyOption: FormFieldOption = {id: 'empty', name: 'Empty'}; + let form = new FormModel({ taskId: '' }); + let emptyOption: FormFieldOption = { id: 'empty', name: 'Empty' }; widget.field = new FormFieldModel(form, { id: '', restUrl: '/some/url/address', @@ -133,14 +133,14 @@ describe('DropdownWidgetComponent', () => { spyOn(formService, 'getRestFieldValues').and.callFake(() => { return Observable.of(fakeOptionList); }); - widget.field = new FormFieldModel(new FormModel({taskId: 'fake-task-id'}), { + widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { id: 'dropdown-id', name: 'date-name', type: 'dropdown', readOnly: 'false', restUrl: 'fake-rest-url' }); - widget.field.emptyOption = {id: 'empty', name: 'Choose one...'}; + widget.field.emptyOption = { id: 'empty', name: 'Choose one...' }; widget.field.isVisible = true; fixture.detectChanges(); })); @@ -179,6 +179,8 @@ describe('DropdownWidgetComponent', () => { openSelect(); + fixture.detectChanges(); + fixture.whenStable() .then(() => { let dropDownElement: any = element.querySelector('#dropdown-id'); @@ -216,14 +218,14 @@ describe('DropdownWidgetComponent', () => { spyOn(formService, 'getRestFieldValuesByProcessId').and.callFake(() => { return Observable.of(fakeOptionList); }); - widget.field = new FormFieldModel(new FormModel({processDefinitionId: 'fake-process-id'}), { + widget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), { id: 'dropdown-id', name: 'date-name', type: 'dropdown', readOnly: 'false', restUrl: 'fake-rest-url' }); - widget.field.emptyOption = {id: 'empty', name: 'Choose one...'}; + widget.field.emptyOption = { id: 'empty', name: 'Choose one...' }; widget.field.isVisible = true; fixture.detectChanges(); })); @@ -262,6 +264,8 @@ describe('DropdownWidgetComponent', () => { openSelect(); + fixture.detectChanges(); + fixture.whenStable() .then(() => { let dropDownElement: any = element.querySelector('#dropdown-id'); @@ -270,7 +274,7 @@ describe('DropdownWidgetComponent', () => { })); it('should be disabled when the field is readonly', async(() => { - widget.field = new FormFieldModel(new FormModel({processDefinitionId: 'fake-process-id'}), { + widget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), { id: 'dropdown-id', name: 'date-name', type: 'dropdown', diff --git a/lib/core/form/components/widgets/tabs/tabs.widget.spec.ts b/lib/core/form/components/widgets/tabs/tabs.widget.spec.ts index c80d332650..02482eb38f 100644 --- a/lib/core/form/components/widgets/tabs/tabs.widget.spec.ts +++ b/lib/core/form/components/widgets/tabs/tabs.widget.spec.ts @@ -91,29 +91,22 @@ describe('TabsWidgetComponent', () => { fixture = TestBed.createComponent(TabsWidgetComponent); tabWidgetComponent = fixture.componentInstance; element = fixture.nativeElement; + + fakeTabVisible = new TabModel(new FormModel(fakeFormJson), { + id: 'tab-id-visible', + title: 'tab-title-visible' + }); + fakeTabVisible.isVisible = true; + fakeTabInvisible = new TabModel(new FormModel(fakeFormJson), { + id: 'tab-id-invisible', + title: 'tab-title-invisible' + }); + fakeTabInvisible.isVisible = false; + tabWidgetComponent.tabs.push(fakeTabVisible); + tabWidgetComponent.tabs.push(fakeTabInvisible); }); })); - beforeEach(() => { - fakeTabVisible = new TabModel(new FormModel(fakeFormJson), { - id: 'tab-id-visible', - title: 'tab-title-visible' - }); - fakeTabVisible.isVisible = true; - fakeTabInvisible = new TabModel(new FormModel(fakeFormJson), { - id: 'tab-id-invisible', - title: 'tab-title-invisible' - }); - fakeTabInvisible.isVisible = false; - tabWidgetComponent.tabs.push(fakeTabVisible); - tabWidgetComponent.tabs.push(fakeTabInvisible); - }); - - afterEach(() => { - fixture.destroy(); - TestBed.resetTestingModule(); - }); - it('should show only visible tabs', () => { fixture.detectChanges(); fixture.whenStable() diff --git a/lib/core/userinfo/components/user-info.component.html b/lib/core/userinfo/components/user-info.component.html index 6c19af929a..ac5907a63e 100644 --- a/lib/core/userinfo/components/user-info.component.html +++ b/lib/core/userinfo/components/user-info.component.html @@ -43,7 +43,7 @@ {{ecmUser.email}}
- + {{ 'USER_PROFILE.LABELS.ECM.JOB_TITLE' | translate }} {{ ecmUser.jobTitle ? ecmUser.jobTitle : 'N/A' }} diff --git a/lib/core/userinfo/components/user-info.component.spec.ts b/lib/core/userinfo/components/user-info.component.spec.ts index 59beb48d5a..57b4d42c66 100644 --- a/lib/core/userinfo/components/user-info.component.spec.ts +++ b/lib/core/userinfo/components/user-info.component.spec.ts @@ -26,6 +26,7 @@ import { BpmUserService } from '../services/bpm-user.service'; import { EcmUserService } from '../services/ecm-user.service'; import { BpmUserModel } from './../models/bpm-user.model'; import { UserInfoComponent } from './user-info.component'; +import { Observable } from 'rxjs/Observable'; class FakeSanitazer extends DomSanitizer { @@ -58,15 +59,22 @@ class FakeSanitazer extends DomSanitizer { } } -declare let jasmine: any; - describe('User info component', () => { - let userInfoComp: UserInfoComponent; + let component: UserInfoComponent; let fixture: ComponentFixture; let element: HTMLElement; - let stubAuthService: AuthenticationService; - let stubContent: ContentService; + let authService: AuthenticationService; + let contentService: ContentService; + let ecmUserService: EcmUserService; + let bpmUserService: BpmUserService; + + function openUserInfo() { + fixture.detectChanges(); + let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); + imageButton.click(); + fixture.detectChanges(); + } beforeEach(async(() => { TestBed.configureTestingModule({ @@ -78,18 +86,25 @@ describe('User info component', () => { ], providers: [ EcmUserService, - BpmUserService + BpmUserService, + ContentService ] }).compileComponents().then(() => { fixture = TestBed.createComponent(UserInfoComponent); - userInfoComp = fixture.componentInstance; + component = fixture.componentInstance; element = fixture.nativeElement; - stubAuthService = TestBed.get(AuthenticationService); - stubContent = TestBed.get(ContentService); + authService = TestBed.get(AuthenticationService); + ecmUserService = TestBed.get(EcmUserService); + bpmUserService = TestBed.get(BpmUserService); + contentService = TestBed.get(ContentService); }); })); + afterEach(() => { + fixture.destroy(); + }); + it('should not show any image if the user is not logged in', () => { expect(element.querySelector('#userinfo_container')).toBeDefined(); expect(element.querySelector('#logged-user-img')).toBeNull(); @@ -104,107 +119,77 @@ describe('User info component', () => { describe('when user is logged on ecm', () => { - beforeEach(() => { - spyOn(stubAuthService, 'isEcmLoggedIn').and.returnValue(true); - spyOn(stubAuthService, 'isLoggedIn').and.returnValue(true); - jasmine.Ajax.install(); + describe('ui ', () => { + + beforeEach(() => { + spyOn(authService, 'isEcmLoggedIn').and.returnValue(true); + spyOn(authService, 'isLoggedIn').and.returnValue(true); + spyOn(ecmUserService, 'getCurrentUserInfo').and.returnValue(Observable.of(fakeEcmEditedUser)); + }); + + it('should show ecm only last name when user first name is null ', async(() => { + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); + imageButton.click(); + fixture.detectChanges(); + expect(element.querySelector('#userinfo_container')).toBeDefined(); + let ecmUsername = fixture.debugElement.query(By.css('#ecm-username')); + expect(ecmUsername).toBeDefined(); + expect(ecmUsername).not.toBeNull(); + expect(ecmUsername.nativeElement.textContent).not.toContain('fake-ecm-first-name'); + expect(ecmUsername.nativeElement.textContent).not.toContain('null'); + }); + })); + + it('should show the username when showName attribute is true', async(() => { + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(component.showName).toBeTruthy(); + expect(element.querySelector('#adf-userinfo-ecm-name-display')).not.toBeNull(); + }); + })); + + it('should hide the username when showName attribute is false', async(() => { + component.showName = false; + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-userinfo-ecm-name-display')).toBeNull(); + }); + })); + + it('should have the defined class to show the name on the right side', async(() => { + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#userinfo_container').classList).toContain('adf-userinfo-name-right'); + }); + })); + + it('should not have the defined class to show the name on the left side', async(() => { + component.namePosition = 'left'; + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#userinfo_container').classList).not.toContain('adf-userinfo-name-right'); + }); + })); }); - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - - it('should show ecm only last name when user first name is null ', async(() => { - fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmEditedUser }) - }); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); - imageButton.click(); - fixture.detectChanges(); - expect(element.querySelector('#userinfo_container')).toBeDefined(); - let ecmUsername = fixture.debugElement.query(By.css('#ecm-username')); - expect(ecmUsername).toBeDefined(); - expect(ecmUsername).not.toBeNull(); - expect(ecmUsername.nativeElement.textContent).not.toContain('fake-ecm-first-name'); - expect(ecmUsername.nativeElement.textContent).not.toContain('null'); - }); - })); - - it('should show the username when showName attribute is true', async(() => { - fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmEditedUser }) - }); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(userInfoComp.showName).toBeTruthy(); - expect(element.querySelector('#adf-userinfo-ecm-name-display')).not.toBeNull(); - }); - })); - - it('should hide the username when showName attribute is false', async(() => { - userInfoComp.showName = false; - fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmEditedUser }) - }); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-userinfo-ecm-name-display')).toBeNull(); - }); - })); - - it('should have the defined class to show the name on the right side', async(() => { - fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmEditedUser }) - }); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(element.querySelector('#userinfo_container').classList).toContain('adf-userinfo-name-right'); - }); - })); - - it('should not have the defined class to show the name on the left side', async(() => { - userInfoComp.namePosition = 'left'; - fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmEditedUser }) - }); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(element.querySelector('#userinfo_container').classList).not.toContain('adf-userinfo-name-right'); - }); - })); - describe('and has image', () => { beforeEach(async(() => { - spyOn(stubContent, 'getContentUrl').and.returnValue('assets/images/ecmImg.gif'); + spyOn(authService, 'isEcmLoggedIn').and.returnValue(true); + spyOn(authService, 'isLoggedIn').and.returnValue(true); + spyOn(ecmUserService, 'getCurrentUserInfo').and.returnValue(Observable.of(fakeEcmUser)); + spyOn(contentService, 'getContentUrl').and.returnValue('assets/images/ecmImg.gif'); fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmUser }) - }); })); it('should get the ecm current user image from the service', async(() => { @@ -222,20 +207,22 @@ describe('User info component', () => { })); it('should display the current user image if user has avatarId', async(() => { + fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); imageButton.click(); fixture.detectChanges(); let loggedImage = fixture.debugElement.query(By.css('#logged-user-img')); - expect(userInfoComp.ecmUser.avatarId).toBe('fake-avatar-id'); + expect(component.ecmUser.avatarId).toBe('fake-avatar-id'); expect(element.querySelector('#userinfo_container')).not.toBeNull(); expect(loggedImage).not.toBeNull(); expect(loggedImage.properties.src).toContain('assets/images/ecmImg.gif'); }); })); - it('should get the ecm user informations from the service', () => { + it('should get the ecm user informations from the service', async(() => { + fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); @@ -252,18 +239,16 @@ describe('User info component', () => { expect(ecmFullName.nativeElement.textContent).toContain('fake-ecm-first-name fake-ecm-last-name'); expect(ecmJobTitle.nativeElement.textContent).toContain('USER_PROFILE.LABELS.ECM.JOB_TITLE'); }); - }); + })); }); describe('and has no image', () => { beforeEach(async(() => { + spyOn(authService, 'isEcmLoggedIn').and.returnValue(true); + spyOn(authService, 'isLoggedIn').and.returnValue(true); + spyOn(ecmUserService, 'getCurrentUserInfo').and.returnValue(Observable.of(fakeEcmUserNoImage)); fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmUserNoImage }) - }); fixture.whenStable().then(() => fixture.detectChanges()); })); @@ -290,7 +275,7 @@ describe('User info component', () => { fixture.whenStable().then(() => { fixture.detectChanges(); let pipe = new InitialUsernamePipe(new FakeSanitazer()); - expect(userInfoComp.ecmUser.avatarId).toBeNull(); + expect(component.ecmUser.avatarId).toBeNull(); expect(pipe.transform({ id: 13, firstName: 'Wilbur', @@ -305,24 +290,16 @@ describe('User info component', () => { describe('when user is logged on bpm', () => { + let getCurrentUserInfoStub; + beforeEach(async(() => { - spyOn(stubAuthService, 'isBpmLoggedIn').and.returnValue(true); - spyOn(stubAuthService, 'isLoggedIn').and.returnValue(true); - jasmine.Ajax.install(); + spyOn(authService, 'isBpmLoggedIn').and.returnValue(true); + spyOn(authService, 'isLoggedIn').and.returnValue(true); + getCurrentUserInfoStub = spyOn(bpmUserService, 'getCurrentUserInfo').and.returnValue(Observable.of(fakeBpmUser)); })); - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - - it('should show full name next the user image', () => { + it('should show full name next the user image', async(() => { fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify(fakeBpmUser) - }); - fixture.whenStable().then(() => { fixture.detectChanges(); let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); @@ -334,16 +311,10 @@ describe('User info component', () => { expect(bpmUserName).not.toBeNull(); expect(bpmUserName.nativeElement.innerHTML).toContain('fake-bpm-first-name fake-bpm-last-name'); }); - }); + })); - it('should get the bpm current user image from the service', () => { + it('should get the bpm current user image from the service', async(() => { fixture.detectChanges(); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify(fakeBpmUser) - }); - fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#userinfo_container')).not.toBeNull(); @@ -351,118 +322,93 @@ describe('User info component', () => { expect(element.querySelector('#logged-user-img').getAttribute('src')) .toContain('activiti-app/app/rest/admin/profile-picture'); }); - }); + })); - it('should show last name if first name is null', () => { - fixture.detectChanges(); + it('should show last name if first name is null', async(() => { let wrongBpmUser: BpmUserModel = new BpmUserModel({ firstName: null, lastName: 'fake-last-name' }); - userInfoComp.bpmUser = wrongBpmUser; + getCurrentUserInfoStub.and.returnValue(Observable.of(wrongBpmUser)); + fixture.detectChanges(); fixture.whenStable().then(() => { - fixture.detectChanges(); expect(element.querySelector('#userinfo_container')).toBeDefined(); - expect(element.querySelector('#bpm-username')).not.toBeNull(); - expect(element.querySelector('#bpm-username').textContent).toContain('fake-last-name'); - expect(element.querySelector('#bpm-username').textContent).not.toContain('fake-bpm-first-name'); + expect(element.querySelector('#adf-userinfo-bpm-name-display')).not.toBeNull(); + expect(element.querySelector('#adf-userinfo-bpm-name-display').textContent).toContain('fake-last-name'); + expect(element.querySelector('#adf-userinfo-bpm-name-display').textContent).not.toContain('fake-bpm-first-name'); }); - }); + })); - it('should not show first name if it is null string', () => { - fixture.detectChanges(); + it('should not show first name if it is null string', async(() => { let wrongFirstNameBpmUser: BpmUserModel = new BpmUserModel({ firstName: 'null', lastName: 'fake-last-name' }); - userInfoComp.bpmUser = wrongFirstNameBpmUser; + getCurrentUserInfoStub.and.returnValue(Observable.of(wrongFirstNameBpmUser)); + fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#userinfo_container')).toBeDefined(); - expect(element.querySelector('#bpm-full-name')).toBeDefined(); - expect(element.querySelector('#bpm-full-name').textContent).toContain('fake-last-name'); - expect(element.querySelector('#bpm-full-name').textContent).not.toContain('null'); + expect(element.querySelector('#adf-userinfo-bpm-name-display')).toBeDefined(); + expect(element.querySelector('#adf-userinfo-bpm-name-display').textContent).toContain('fake-last-name'); + expect(element.querySelector('#adf-userinfo-bpm-name-display').textContent).not.toContain('null'); }); - }); + })); - it('should not show last name if it is null string', () => { - fixture.detectChanges(); + it('should not show last name if it is null string', async(() => { let wrongLastNameBpmUser: BpmUserModel = new BpmUserModel({ firstName: 'fake-first-name', lastName: 'null' }); - userInfoComp.bpmUser = wrongLastNameBpmUser; + getCurrentUserInfoStub.and.returnValue(Observable.of(wrongLastNameBpmUser)); + fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#userinfo_container')).toBeDefined(); - expect(element.querySelector('#bpm-full-name')).toBeDefined(); - expect(element.querySelector('#bpm-full-name').textContent).toContain('fake-first-name'); - expect(element.querySelector('#bpm-full-name').textContent).not.toContain('null'); + expect(element.querySelector('#adf-userinfo-bpm-name-display')).toBeDefined(); + expect(element.querySelector('#adf-userinfo-bpm-name-display').textContent).toContain('fake-first-name'); + expect(element.querySelector('#adf-userinfo-bpm-name-display').textContent).not.toContain('null'); }); - }); + })); - it('should not show the tabs', () => { + it('should not show the tabs', async(() => { + fixture.detectChanges(); + let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); + imageButton.click(); fixture.detectChanges(); - fixture.whenStable().then(() => { fixture.detectChanges(); - expect(element.querySelector('#tab-bar-env').getAttribute('hidden')).not.toBeNull(); + expect(fixture.debugElement.query(By.css('#tab-group-env')).classes['adf-hide-tab']).toBeTruthy(); }); - }); + })); }); describe('when user is logged on bpm and ecm', () => { - beforeEach(async(() => { - - })); + let ecmUserInfoSpy; beforeEach(async(() => { - spyOn(stubAuthService, 'isEcmLoggedIn').and.returnValue(true); - spyOn(stubAuthService, 'isBpmLoggedIn').and.returnValue(true); - spyOn(stubAuthService, 'isLoggedIn').and.returnValue(true); - spyOn(stubContent, 'getContentUrl').and.returnValue('src/assets/images/ecmImg.gif'); - jasmine.Ajax.install(); + spyOn(authService, 'isEcmLoggedIn').and.returnValue(true); + spyOn(authService, 'isBpmLoggedIn').and.returnValue(true); + spyOn(authService, 'isLoggedIn').and.returnValue(true); + spyOn(contentService, 'getContentUrl').and.returnValue('src/assets/images/ecmImg.gif'); - fixture.detectChanges(); - - jasmine.Ajax.requests.first().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({ entry: fakeEcmUser }) - }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: fakeBpmUser - }); + ecmUserInfoSpy = spyOn(ecmUserService, 'getCurrentUserInfo').and.returnValue(Observable.of(fakeEcmUser)); + spyOn(bpmUserService, 'getCurrentUserInfo').and.returnValue(Observable.of(fakeBpmUser)); })); - beforeEach(() => { - fixture.detectChanges(); - - let imageButton: HTMLButtonElement = element.querySelector('#logged-user-img'); - imageButton.click(); - - fixture.detectChanges(); - }); - - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - - it('should get the bpm user informations from the service', () => { + it('should get the bpm user informations from the service', async(() => { + openUserInfo(); let bpmTab = fixture.debugElement.queryAll(By.css('#tab-group-env .mat-tab-labels .mat-tab-label'))[1]; bpmTab.triggerEventHandler('click', null); fixture.detectChanges(); - let bpmUsername = fixture.debugElement.query(By.css('#bpm-username')); - let bpmImage = fixture.debugElement.query(By.css('#bpm-user-detail-image')); - fixture.whenStable().then(() => { + let bpmUsername = fixture.debugElement.query(By.css('#bpm-username')); + let bpmImage = fixture.debugElement.query(By.css('#bpm-user-detail-image')); expect(element.querySelector('#userinfo_container')).not.toBeNull(); expect(bpmUsername).not.toBeNull(); expect(bpmImage).not.toBeNull(); @@ -470,12 +416,14 @@ describe('User info component', () => { expect(bpmUsername.nativeElement.textContent).toContain('fake-bpm-first-name fake-bpm-last-name'); expect(fixture.debugElement.query(By.css('#bpm-tenant')).nativeElement.textContent).toContain('fake-tenant-name'); }); - }); + })); - it('should get the ecm user informations from the service', () => { + it('should get the ecm user informations from the service', async(() => { + openUserInfo(); let ecmUsername = fixture.debugElement.query(By.css('#ecm-username')); let ecmImage = fixture.debugElement.query(By.css('#ecm-user-detail-image')); + fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('#userinfo_container')).toBeDefined(); expect(ecmUsername).not.toBeNull(); @@ -484,26 +432,29 @@ describe('User info component', () => { expect(fixture.debugElement.query(By.css('#ecm-full-name')).nativeElement.textContent).toContain('fake-ecm-first-name fake-ecm-last-name'); expect(fixture.debugElement.query(By.css('#ecm-job-title')).nativeElement.textContent).toContain('job-ecm-test'); }); - }); + })); - it('should show the ecm image if exists', () => { + it('should show the ecm image if exists', async(() => { + openUserInfo(); expect(element.querySelector('#userinfo_container')).toBeDefined(); expect(element.querySelector('#logged-user-img')).toBeDefined(); expect(element.querySelector('#logged-user-img').getAttribute('src')).toEqual('src/assets/images/ecmImg.gif'); - }); + })); - it('should show the bpm image if ecm does not have it', () => { - userInfoComp.ecmUserImage = null; + it('should show the ecm initials if the ecm user has no image', async(() => { + ecmUserInfoSpy.and.returnValue(Observable.of(fakeEcmUserNoImage)); fixture.detectChanges(); + fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#userinfo_container')).toBeDefined(); - expect(element.querySelector('#logged-user-img')).toBeDefined(); - expect(element.querySelector('#logged-user-img').getAttribute('src')).toContain('rest/admin/profile-picture'); + expect(element.querySelector('#logged-user-img')).toBeNull(); + expect(element.querySelector('#user-initials-image').textContent).toContain('ff'); }); - }); + })); it('should show the tabs for the env', () => { + openUserInfo(); let tabGroup = fixture.debugElement.query(By.css('#tab-group-env')); let tabs = fixture.debugElement.queryAll(By.css('#tab-group-env .mat-tab-labels .mat-tab-label')); @@ -513,6 +464,7 @@ describe('User info component', () => { }); it('should not close the menu when a tab is clicked', () => { + openUserInfo(); let tabGroup = fixture.debugElement.query(By.css('#tab-group-env')); let tabs = fixture.debugElement.queryAll(By.css('#tab-group-env .mat-tab-labels .mat-tab-label')); diff --git a/lib/core/userinfo/components/user-info.component.ts b/lib/core/userinfo/components/user-info.component.ts index fc5189c099..4b3803be0e 100644 --- a/lib/core/userinfo/components/user-info.component.ts +++ b/lib/core/userinfo/components/user-info.component.ts @@ -77,8 +77,7 @@ export class UserInfoComponent implements OnInit { .subscribe((res) => { this.ecmUser = new EcmUserModel(res); this.getEcmAvatar(); - } - ); + }); } else { this.ecmUser = null; this.ecmUserImage = null; diff --git a/lib/core/viewer/components/imgViewer.component.ts b/lib/core/viewer/components/imgViewer.component.ts index 129b53aaeb..9442fcd034 100644 --- a/lib/core/viewer/components/imgViewer.component.ts +++ b/lib/core/viewer/components/imgViewer.component.ts @@ -65,7 +65,7 @@ export class ImgViewerComponent implements OnInit, OnChanges, OnDestroy { } ngOnInit() { - this.element = ( this.el.nativeElement).querySelector('#viewer-image'); + this.element = this.el.nativeElement.querySelector('#viewer-image'); if (this.element) { this.element.addEventListener('mousedown', this.onMouseDown.bind(this)); diff --git a/lib/core/viewer/components/viewer.component.spec.ts b/lib/core/viewer/components/viewer.component.spec.ts index 6d6957fb91..4dfd5c5428 100644 --- a/lib/core/viewer/components/viewer.component.spec.ts +++ b/lib/core/viewer/components/viewer.component.spec.ts @@ -40,8 +40,6 @@ import { ViewerComponent } from './viewer.component'; import { FlexLayoutModule } from '@angular/flex-layout'; import 'rxjs/add/observable/throw'; -declare let jasmine: any; - @Component({ selector: 'adf-viewer-container-toolbar', template: ` @@ -112,6 +110,8 @@ class ViewerWithCustomOpenWithComponent {} }) class ViewerWithCustomMoreActionsComponent {} +declare var require: any; + describe('ViewerComponent', () => { let component: ViewerComponent; @@ -155,96 +155,621 @@ describe('ViewerComponent', () => { }).compileComponents(); })); - beforeEach(() => { - fixture = TestBed.createComponent(ViewerComponent); + describe('Viewer Example Component Rendering', () => { - element = fixture.nativeElement; - component = fixture.componentInstance; + it('should use custom toolbar', () => { + let customFixture = TestBed.createComponent(ViewerWithCustomToolbarComponent); + let customElement: HTMLElement = customFixture.nativeElement; - jasmine.Ajax.install(); + customFixture.detectChanges(); + expect(customElement.querySelector('.custom-toolbar-element')).toBeDefined(); + }); - alfrescoApiService = TestBed.get(AlfrescoApiService); + it('should use custom info drawer', () => { + let customFixture = TestBed.createComponent(ViewerWithCustomSidebarComponent); + let customElement: HTMLElement = customFixture.nativeElement; - component.showToolbar = true; - component.urlFile = 'base/src/assets/fake-test-file.pdf'; - component.mimeType = 'application/pdf'; - component.ngOnChanges(null); - fixture.detectChanges(); + customFixture.detectChanges(); + expect(customElement.querySelector('.custom-info-drawer-element')).toBeDefined(); + }); + + it('should use custom open with menu', () => { + let customFixture = TestBed.createComponent(ViewerWithCustomOpenWithComponent); + let customElement: HTMLElement = customFixture.nativeElement; + + customFixture.detectChanges(); + expect(customElement.querySelector('.adf-viewer-container-open-with')).toBeDefined(); + }); + + it('should use custom more actions menu', () => { + let customFixture = TestBed.createComponent(ViewerWithCustomMoreActionsComponent); + let customElement: HTMLElement = customFixture.nativeElement; + + customFixture.detectChanges(); + expect(customElement.querySelector('.adf-viewer-container-more-actions')).toBeDefined(); + }); }); - afterEach(() => { - jasmine.Ajax.uninstall(); + describe('Base component', () => { + + beforeEach(() => { + fixture = TestBed.createComponent(ViewerComponent); + element = fixture.nativeElement; + component = fixture.componentInstance; + component.showToolbar = true; + component.urlFile = 'base/src/assets/fake-test-file.pdf'; + component.mimeType = 'application/pdf'; + + alfrescoApiService = TestBed.get(AlfrescoApiService); + + fixture.detectChanges(); + }); + + afterEach(() => { + fixture.destroy(); + }); + + describe('SideBar Test', () => { + + it('should NOT display sidebar if is not allowed', () => { + component.showSidebar = true; + component.allowSidebar = false; + component.sidebarPosition = 'left'; + fixture.detectChanges(); + let sidebar = element.querySelector('.adf-viewer__sidebar'); + expect(sidebar).toBeNull(); + }); + + it('should display sidebar on the left side', () => { + component.showSidebar = true; + component.allowSidebar = true; + component.sidebarPosition = 'left'; + fixture.detectChanges(); + let sidebar = element.querySelector('.adf-viewer__sidebar'); + expect(getComputedStyle(sidebar).order).toEqual('1'); + }); + + it('should display sidebar on the right side', () => { + component.showSidebar = true; + component.allowSidebar = true; + component.sidebarPosition = 'right'; + fixture.detectChanges(); + let sidebar = element.querySelector('.adf-viewer__sidebar'); + expect(getComputedStyle(sidebar).order).toEqual('4'); + }); + + it('should display sidebar on the right side as fallback', () => { + component.showSidebar = true; + component.allowSidebar = true; + component.sidebarPosition = 'unknown-value'; + fixture.detectChanges(); + let sidebar = element.querySelector('.adf-viewer__sidebar'); + expect(getComputedStyle(sidebar).order).toEqual('4'); + }); + }); + + describe('Toolbar', () => { + + it('should render fullscreen button', () => { + expect(element.querySelector('[data-automation-id="toolbar-fullscreen"]')).toBeDefined(); + }); + + it('should not render fullscreen button', () => { + component.allowFullScreen = false; + fixture.detectChanges(); + + expect(element.querySelector('[data-automation-id="toolbar-fullscreen"]')).toBeNull(); + }); + + it('should render default download button', () => { + component.allowDownload = true; + + expect(element.querySelector('[data-automation-id="toolbar-download"]')).toBeDefined(); + }); + + it('should not render default download button', () => { + component.allowDownload = false; + fixture.detectChanges(); + + expect(element.querySelector('[data-automation-id="toolbar-download"]')).toBeNull(); + }); + + it('should invoke download action with the toolbar button', () => { + component.allowDownload = true; + spyOn(component, 'downloadContent').and.stub(); + fixture.detectChanges(); + + const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-download"]') as HTMLButtonElement; + button.click(); + + expect(component.downloadContent).toHaveBeenCalled(); + }); + + it('should raise download event with the toolbar button', async(() => { + component.allowDownload = true; + fixture.detectChanges(); + + component.download.subscribe(e => { + expect(e).not.toBeNull(); + }); + + const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-download"]') as HTMLButtonElement; + button.click(); + })); + + it('should render default print button', () => { + component.allowPrint = true; + fixture.detectChanges(); + + expect(element.querySelector('[data-automation-id="toolbar-print"]')).toBeDefined(); + }); + + it('should not render default print button', () => { + component.allowPrint = false; + fixture.detectChanges(); + + expect(element.querySelector('[data-automation-id="toolbar-print"]')).toBeNull(); + }); + + it('should invoke print action with the toolbar button', () => { + component.allowPrint = true; + fixture.detectChanges(); + + spyOn(component, 'printContent').and.stub(); + + const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-print"]') as HTMLButtonElement; + button.click(); + + expect(component.printContent).toHaveBeenCalled(); + }); + + it('should raise the print event with the toolbar button', async(() => { + component.allowPrint = true; + fixture.detectChanges(); + + component.print.subscribe(e => { + expect(e).not.toBeNull(); + }); + + const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-print"]') as HTMLButtonElement; + button.click(); + })); + + it('should render default share button', () => { + component.allowShare = true; + fixture.detectChanges(); + + expect(element.querySelector('[data-automation-id="toolbar-share"]')).toBeDefined(); + }); + + it('should not render default share button', () => { + component.allowShare = false; + fixture.detectChanges(); + + expect(element.querySelector('[data-automation-id="toolbar-share"]')).toBeNull(); + }); + + it('should invoke share action with the toolbar button', () => { + component.allowShare = true; + fixture.detectChanges(); + + spyOn(component, 'shareContent').and.stub(); + + const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-share"]') as HTMLButtonElement; + button.click(); + + expect(component.shareContent).toHaveBeenCalled(); + }); + + it('should raise share event with the toolbar button', async(() => { + component.allowShare = true; + fixture.detectChanges(); + + component.share.subscribe(e => { + expect(e).not.toBeNull(); + }); + + const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-share"]') as HTMLButtonElement; + button.click(); + })); + + }); + + describe('View', () => { + + describe('Overlay mode true', () => { + + beforeEach(() => { + component.overlayMode = true; + fixture.detectChanges(); + }); + + it('should header be present if is overlay mode', () => { + expect(element.querySelector('.adf-viewer-toolbar')).not.toBeNull(); + }); + + it('should Name File be present if is overlay mode ', async(() => { + component.ngOnChanges(null); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('fake-test-file.pdf'); + }); + })); + + it('should Close button be present if overlay mode', () => { + expect(element.querySelector('.adf-viewer-close-button')).not.toBeNull(); + }); + + it('should Click on close button hide the viewer', () => { + let closebutton: any = element.querySelector('.adf-viewer-close-button'); + closebutton.click(); + fixture.detectChanges(); + expect(element.querySelector('.adf-viewer-content')).toBeNull(); + }); + + it('should Esc button hide the viewer', () => { + EventMock.keyUp(27); + fixture.detectChanges(); + expect(element.querySelector('.adf-viewer-content')).toBeNull(); + }); + }); + + describe('Overlay mode false', () => { + + beforeEach(() => { + component.overlayMode = false; + fixture.detectChanges(); + }); + + it('should header be NOT be present if is not overlay mode', () => { + expect(element.querySelector('header')).toBeNull(); + }); + + it('should Esc button not hide the viewer if is not overlay mode', () => { + EventMock.keyDown(27); + fixture.detectChanges(); + expect(element.querySelector('.adf-viewer-content')).not.toBeNull(); + }); + }); + }); + + describe('Attribute', () => { + + it('should Url or fileNodeId be mandatory', () => { + component.showViewer = true; + component.fileNodeId = undefined; + component.urlFile = undefined; + + expect(() => { + component.ngOnChanges(null); + }).toThrow(); + }); + + it('should FileNodeId present not thrown any error ', () => { + component.showViewer = true; + component.fileNodeId = 'file-node-id'; + component.urlFile = undefined; + + expect(() => { + component.ngOnChanges(null); + }).not.toThrow(); + }); + + it('should urlFile present not thrown any error ', () => { + component.showViewer = true; + component.fileNodeId = undefined; + + expect(() => { + component.ngOnChanges(null); + }).not.toThrow(); + }); + + it('should showViewer default value be true', () => { + expect(component.showViewer).toBe(true); + }); + + it('should viewer be hide if showViewer value is false', () => { + component.showViewer = false; + + fixture.detectChanges(); + expect(element.querySelector('.adf-viewer-content')).toBeNull(); + }); + }); + + describe('Extension Type Test', () => { + + it('should extension file pdf be loaded', async(() => { + component.urlFile = 'base/src/assets/fake-test-file.pdf'; + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); + }); + })); + + it('should extension file png be loaded', async(() => { + component.urlFile = 'fake-url-file.png'; + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#viewer-image')).not.toBeNull(); + }); + })); + + it('should extension file mp4 be loaded', async(() => { + component.urlFile = 'fake-url-file.mp4'; + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-media-player')).not.toBeNull(); + }); + })); + + it('should extension file mp3 be loaded', async(() => { + component.urlFile = 'fake-url-file.mp3'; + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-media-player')).not.toBeNull(); + }); + })); + + it('should extension file wav be loaded', async(() => { + component.urlFile = 'fake-url-file.wav'; + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-media-player')).not.toBeNull(); + }); + })); + + it('should extension file txt be loaded', async(() => { + component.urlFile = require('../assets/fake-test-file.txt'); + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-txt-viewer')).not.toBeNull(); + }); + })); + + it('should display [unknown format] for unsupported extensions', async(() => { + component.urlFile = 'fake-url-file.unsupported'; + component.mimeType = ''; + component.ngOnChanges(null); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-viewer-unknown-format')).toBeDefined(); + }); + })); + }); + + describe('MimeType handling', () => { + + it('should display a PDF file identified by mimetype when the filename has no extension', async(() => { + component.urlFile = 'content'; + component.mimeType = 'application/pdf'; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); + }); + + })); + + it('should display a PDF file identified by mimetype when the file extension is wrong', async(() => { + component.urlFile = 'content.bin'; + component.mimeType = 'application/pdf'; + component.ngOnChanges(null); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); + }); + })); + + it('should display an image file identified by mimetype when the filename has no extension', async(() => { + component.urlFile = 'content'; + component.mimeType = 'image/png'; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#viewer-image')).not.toBeNull(); + }); + })); + + it('should display a image file identified by mimetype when the file extension is wrong', async(() => { + component.urlFile = 'content.bin'; + component.mimeType = 'image/png'; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#viewer-image')).not.toBeNull(); + }); + })); + + it('should display the media player if the file identified by mimetype is a media when the filename has wrong extension', async(() => { + component.urlFile = 'content.bin'; + component.mimeType = 'video/mp4'; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-media-player')).not.toBeNull(); + }); + })); + + it('should display the txt viewer if the file identified by mimetype is a txt when the filename has wrong extension', async(() => { + component.urlFile = 'content.bin'; + component.mimeType = 'text/txt'; + component.urlFile = require('../assets/fake-test-file.txt'); + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-txt-viewer')).not.toBeNull(); + }); + })); + + it('should display the media player if the file identified by mimetype is a media when the filename has no extension', async(() => { + component.urlFile = 'content'; + component.mimeType = 'video/mp4'; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('adf-media-player')).not.toBeNull(); + }); + })); + }); + + describe('Events', () => { + + it('should if the extension change extension Change event be fired ', async(() => { + + component.extensionChange.subscribe((fileExtension) => { + expect(fileExtension).toEqual('png'); + }); + + component.urlFile = 'fake-url-file.png'; + + component.ngOnChanges(null); + })); + }); + + describe('display name property override by urlFile', () => { + + it('should displayName override the default name if is present and urlFile is set' , async(() => { + component.urlFile = 'base/src/assets/fake-test-file.pdf'; + component.displayName = 'test name'; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('test name'); + }); + })); + + it('should use the urlFile name if displayName is NOT set and urlFile is set' , async(() => { + component.urlFile = 'base/src/assets/fake-test-file.pdf'; + component.displayName = null; + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('fake-test-file.pdf'); + }); + })); + }); + + describe('display name property override by blobFile', () => { + + it('should displayName override the name if is present and blobFile is set' , async(() => { + component.displayName = 'blob file display name'; + component.blobFile = new Blob(['This is my blob content'], {type : 'text/plain'}); + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('blob file display name'); + }); + })); + + it('should show uknownn name if displayName is NOT set and blobFile is set' , async(() => { + component.displayName = null; + component.blobFile = new Blob(['This is my blob content'], {type : 'text/plain'}); + fixture.detectChanges(); + component.ngOnChanges(null); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('Unknown'); + }); + })); + }); + + describe('display name property override by nodeId', () => { + + const displayName = 'the-name'; + const nodeDetails = { name: displayName, id: '12', content: { mimeType: 'txt' } }; + const contentUrl = '/content/url/path'; + const alfrescoApiInstanceMock = { + nodes: { getNodeInfo: () => Promise.resolve(nodeDetails) }, + content: { getContentUrl: () => contentUrl } + }; + + it('should use the displayName if displayName is set and fileNodeId is set', async(() => { + const userDefinedDisplayName = 'user defined display name'; + component.fileNodeId = '12'; + component.urlFile = null; + component.displayName = userDefinedDisplayName; + spyOn(alfrescoApiService, 'getInstance').and.returnValue(alfrescoApiInstanceMock); + + component.ngOnChanges(null); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual(userDefinedDisplayName); + }); + })); + + it('should use the node name if displayName is NOT set and fileNodeId is set', async(() => { + component.fileNodeId = '12'; + component.urlFile = null; + component.displayName = null; + spyOn(alfrescoApiService, 'getInstance').and.returnValue(alfrescoApiInstanceMock); + + component.ngOnChanges(null); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual(displayName); + }); + })); + }); + }); - it('should use custom toolbar', () => { - let customFixture = TestBed.createComponent(ViewerWithCustomToolbarComponent); - let customElement: HTMLElement = customFixture.nativeElement; + describe('Viewer component - Full Screen Mode - Mocking fixture element', () => { - customFixture.detectChanges(); - expect(customElement.querySelector('.custom-toolbar-element')).toBeDefined(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ViewerComponent); + element = fixture.nativeElement; + component = fixture.componentInstance; - it('should use custom info drawer', () => { - let customFixture = TestBed.createComponent(ViewerWithCustomSidebarComponent); - let customElement: HTMLElement = customFixture.nativeElement; + component.showToolbar = true; + component.urlFile = 'base/src/assets/fake-test-file.pdf'; + component.mimeType = 'application/pdf'; + fixture.detectChanges(); + }); - customFixture.detectChanges(); - expect(customElement.querySelector('.custom-info-drawer-element')).toBeDefined(); - }); - - it('should use custom open with menu', () => { - let customFixture = TestBed.createComponent(ViewerWithCustomOpenWithComponent); - let customElement: HTMLElement = customFixture.nativeElement; - - customFixture.detectChanges(); - expect(customElement.querySelector('.adf-viewer-container-open-with')).toBeDefined(); - }); - - it('should use custom more actions menu', () => { - let customFixture = TestBed.createComponent(ViewerWithCustomMoreActionsComponent); - let customElement: HTMLElement = customFixture.nativeElement; - - customFixture.detectChanges(); - expect(customElement.querySelector('.adf-viewer-container-more-actions')).toBeDefined(); - }); - - it('should NOT display sidebar if is not allowed', () => { - component.showSidebar = true; - component.allowSidebar = false; - component.sidebarPosition = 'left'; - fixture.detectChanges(); - let sidebar = element.querySelector('.adf-viewer__sidebar'); - expect(sidebar).toBeNull(); - }); - - it('should display sidebar on the left side', () => { - component.showSidebar = true; - component.allowSidebar = true; - component.sidebarPosition = 'left'; - fixture.detectChanges(); - let sidebar = element.querySelector('.adf-viewer__sidebar'); - expect(getComputedStyle(sidebar).order).toEqual('1'); - }); - - it('should display sidebar on the right side', () => { - component.showSidebar = true; - component.allowSidebar = true; - component.sidebarPosition = 'right'; - fixture.detectChanges(); - let sidebar = element.querySelector('.adf-viewer__sidebar'); - expect(getComputedStyle(sidebar).order).toEqual('4'); - }); - - it('should display sidebar on the right side as fallback', () => { - component.showSidebar = true; - component.allowSidebar = true; - component.sidebarPosition = 'unknown-value'; - fixture.detectChanges(); - let sidebar = element.querySelector('.adf-viewer__sidebar'); - expect(getComputedStyle(sidebar).order).toEqual('4'); - }); - - describe('Full Screen Mode', () => { + afterEach(() => { + fixture.destroy(); + }); it('should request only if enabled', () => { const domElement = jasmine.createSpyObj('el', ['requestFullscreen']); @@ -290,489 +815,4 @@ describe('ViewerComponent', () => { }); - describe('Toolbar', () => { - - it('should render fullscreen button', () => { - component.allowFullScreen = true; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-fullscreen"]')).toBeDefined(); - }); - - it('should not render fullscreen button', () => { - component.allowFullScreen = false; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-fullscreen"]')).toBeNull(); - }); - - it('should render default download button', () => { - component.allowDownload = true; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-download"]')).toBeDefined(); - }); - - it('should not render default download button', () => { - component.allowDownload = false; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-download"]')).toBeNull(); - }); - - it('should invoke download action with the toolbar button', () => { - component.allowDownload = true; - fixture.detectChanges(); - - spyOn(component, 'downloadContent').and.stub(); - - const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-download"]') as HTMLButtonElement; - button.click(); - - expect(component.downloadContent).toHaveBeenCalled(); - }); - - xit('should raise download event with the toolbar button', (done) => { - component.allowDownload = true; - fixture.detectChanges(); - - component.download.subscribe(e => { - e.preventDefault(); - done(); - }); - - const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-download"]') as HTMLButtonElement; - button.click(); - }); - - it('should render default print button', () => { - component.allowPrint = true; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-print"]')).toBeDefined(); - }); - - it('should not render default print button', () => { - component.allowPrint = false; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-print"]')).toBeNull(); - }); - - it('should invoke print action with the toolbar button', () => { - component.allowPrint = true; - fixture.detectChanges(); - - spyOn(component, 'printContent').and.stub(); - - const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-print"]') as HTMLButtonElement; - button.click(); - - expect(component.printContent).toHaveBeenCalled(); - }); - - xit('should raise the print event with the toolbar button', (done) => { - component.allowPrint = true; - fixture.detectChanges(); - - component.print.subscribe(e => { - e.preventDefault(); - done(); - }); - - const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-print"]') as HTMLButtonElement; - button.click(); - }); - - it('should render default share button', () => { - component.allowShare = true; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-share"]')).toBeDefined(); - }); - - it('should not render default share button', () => { - component.allowShare = false; - fixture.detectChanges(); - - expect(element.querySelector('[data-automation-id="toolbar-share"]')).toBeNull(); - }); - - it('should invoke share action with the toolbar button', () => { - component.allowShare = true; - fixture.detectChanges(); - - spyOn(component, 'shareContent').and.stub(); - - const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-share"]') as HTMLButtonElement; - button.click(); - - expect(component.shareContent).toHaveBeenCalled(); - }); - - xit('should raise share event with the toolbar button', (done) => { - component.allowShare = true; - fixture.detectChanges(); - - component.share.subscribe(e => { - e.preventDefault(); - done(); - }); - - const button: HTMLButtonElement = element.querySelector('[data-automation-id="toolbar-share"]') as HTMLButtonElement; - button.click(); - }); - - }); - - describe('View', () => { - - describe('Overlay mode true', () => { - - beforeEach(() => { - component.overlayMode = true; - fixture.detectChanges(); - }); - - it('should header be present if is overlay mode', () => { - expect(element.querySelector('.adf-viewer-toolbar')).not.toBeNull(); - }); - - it('should Name File be present if is overlay mode ', () => { - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('.adf-viewer-filename').innerHTML).toEqual('fake-test-file.pdf'); - }); - }); - - it('should Close button be present if overlay mode', () => { - expect(element.querySelector('.adf-viewer-close-button')).not.toBeNull(); - }); - - it('should Click on close button hide the viewer', () => { - let closebutton: any = element.querySelector('.adf-viewer-close-button'); - closebutton.click(); - fixture.detectChanges(); - expect(element.querySelector('.adf-viewer-content')).toBeNull(); - }); - - it('should Esc button hide the viewer', () => { - EventMock.keyUp(27); - fixture.detectChanges(); - expect(element.querySelector('.adf-viewer-content')).toBeNull(); - }); - }); - - describe('Overlay mode false', () => { - - beforeEach(() => { - component.overlayMode = false; - fixture.detectChanges(); - }); - - it('should header be NOT be present if is not overlay mode', () => { - expect(element.querySelector('header')).toBeNull(); - }); - - it('should Esc button not hide the viewer if is not overlay mode', () => { - EventMock.keyDown(27); - fixture.detectChanges(); - expect(element.querySelector('.adf-viewer-content')).not.toBeNull(); - }); - }); - }); - - describe('Attribute', () => { - it('should Url or fileNodeId be mandatory', () => { - component.showViewer = true; - component.fileNodeId = undefined; - component.urlFile = undefined; - - expect(() => { - component.ngOnChanges(null); - }).toThrow(); - }); - - it('should FileNodeId present not thrown any error ', () => { - component.showViewer = true; - component.fileNodeId = 'file-node-id'; - component.urlFile = undefined; - - expect(() => { - component.ngOnChanges(null); - }).not.toThrow(); - }); - - it('should urlFile present not thrown any error ', () => { - component.showViewer = true; - component.fileNodeId = undefined; - - expect(() => { - component.ngOnChanges(null); - }).not.toThrow(); - }); - - it('should showViewer default value be true', () => { - expect(component.showViewer).toBe(true); - }); - - it('should viewer be hide if showViewer value is false', () => { - component.showViewer = false; - - fixture.detectChanges(); - expect(element.querySelector('.adf-viewer-content')).toBeNull(); - }); - }); - - describe('Extension Type Test', () => { - it('should extension file pdf be loaded', (done) => { - component.urlFile = 'base/src/assets/fake-test-file.pdf'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); - done(); - }); - }); - - it('should extension file png be loaded', (done) => { - component.urlFile = 'fake-url-file.png'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#viewer-image')).not.toBeNull(); - done(); - }); - }); - - it('should extension file mp4 be loaded', (done) => { - component.urlFile = 'fake-url-file.mp4'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-media-player')).not.toBeNull(); - done(); - }); - }); - - it('should extension file mp3 be loaded', (done) => { - component.urlFile = 'fake-url-file.mp3'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-media-player')).not.toBeNull(); - done(); - }); - }); - - it('should extension file wav be loaded', (done) => { - component.urlFile = 'fake-url-file.wav'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-media-player')).not.toBeNull(); - done(); - }); - }); - - it('should extension file txt be loaded', (done) => { - component.urlFile = 'fake-url-file.txt'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-txt-viewer')).not.toBeNull(); - done(); - }); - }); - - it('should display [unknown format] for unsupported extensions', (done) => { - component.urlFile = 'fake-url-file.unsupported'; - component.mimeType = ''; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-viewer-unknown-format')).toBeDefined(); - done(); - }); - }); - }); - - describe('MimeType handling', () => { - it('should display a PDF file identified by mimetype when the filename has no extension', (done) => { - component.urlFile = 'content'; - component.mimeType = 'application/pdf'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); - done(); - }); - - }); - - it('should display a PDF file identified by mimetype when the file extension is wrong', (done) => { - component.urlFile = 'content.bin'; - component.mimeType = 'application/pdf'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); - done(); - }); - }); - - it('should display an image file identified by mimetype when the filename has no extension', (done) => { - component.urlFile = 'content'; - component.mimeType = 'image/png'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#viewer-image')).not.toBeNull(); - done(); - }); - }); - - it('should display a image file identified by mimetype when the file extension is wrong', (done) => { - component.urlFile = 'content.bin'; - component.mimeType = 'image/png'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#viewer-image')).not.toBeNull(); - done(); - }); - }); - - it('should display the media player if the file identified by mimetype is a media when the filename has wrong extension', (done) => { - component.urlFile = 'content.bin'; - component.mimeType = 'video/mp4'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-media-player')).not.toBeNull(); - done(); - }); - }); - - it('should display the txt viewer if the file identified by mimetype is a txt when the filename has wrong extension', (done) => { - component.urlFile = 'content.bin'; - component.mimeType = 'text/txt'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-txt-viewer')).not.toBeNull(); - done(); - }); - }); - - it('should display the media player if the file identified by mimetype is a media when the filename has no extension', (done) => { - component.urlFile = 'content'; - component.mimeType = 'video/mp4'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('adf-media-player')).not.toBeNull(); - done(); - }); - }); - }); - - describe('Events', () => { - it('should if the extension change extension Change event be fired ', (done) => { - - component.extensionChange.subscribe((fileExtension) => { - expect(fileExtension).toEqual('png'); - done(); - }); - - component.urlFile = 'fake-url-file.png'; - - component.ngOnChanges(null); - }); - }); - - describe('display name property override by urlFile', () => { - it('should displayName override the default name if is present and urlFile is set' , (done) => { - component.urlFile = 'base/src/assets/fake-test-file.pdf'; - component.displayName = 'test name'; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('test name'); - done(); - }); - }); - - it('should use the urlFile name if displayName is NOT set and urlFile is set' , (done) => { - component.urlFile = 'base/src/assets/fake-test-file.pdf'; - component.displayName = null; - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('fake-test-file.pdf'); - done(); - }); - }); - }); - - describe('display name property override by blobFile', () => { - it('should displayName override the name if is present and blobFile is set' , (done) => { - component.displayName = 'blob file display name'; - component.blobFile = new Blob(['This is my blob content'], {type : 'text/plain'}); - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('blob file display name'); - done(); - }); - }); - - it('should show uknownn name if displayName is NOT set and blobFile is set' , (done) => { - component.displayName = null; - component.blobFile = new Blob(['This is my blob content'], {type : 'text/plain'}); - - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('Unknown'); - done(); - }); - }); - }); - - describe('display name property override by nodeId', () => { - const displayName = 'the-name'; - const nodeDetails = { name: displayName, id: '12', content: { mimeType: 'txt' }}; - const contentUrl = '/content/url/path'; - const alfrescoApiInstanceMock = { - nodes: { getNodeInfo: () => Promise.resolve(nodeDetails) }, - content: { getContentUrl: () => contentUrl } - }; - - it('should use the displayName if displayName is set and fileNodeId is set' , (done) => { - const userDefinedDisplayName = 'user defined display name'; - component.fileNodeId = '12'; - component.urlFile = null; - component.displayName = userDefinedDisplayName; - - spyOn(alfrescoApiService, 'getInstance').and.returnValue(alfrescoApiInstanceMock); - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual(userDefinedDisplayName); - done(); - }); - }); - - it('should use the node name if displayName is NOT set and fileNodeId is set' , (done) => { - component.fileNodeId = '12'; - component.urlFile = null; - component.displayName = null; - - spyOn(alfrescoApiService, 'getInstance').and.returnValue(alfrescoApiInstanceMock); - component.ngOnChanges(null).then(() => { - fixture.detectChanges(); - expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual(displayName); - done(); - }); - }); - }); }); diff --git a/lib/core/viewer/components/viewer.component.ts b/lib/core/viewer/components/viewer.component.ts index 6cee07923d..db4ad2edb8 100644 --- a/lib/core/viewer/components/viewer.component.ts +++ b/lib/core/viewer/components/viewer.component.ts @@ -186,106 +186,113 @@ export class ViewerComponent implements OnChanges { if (!this.isSourceDefined()) { throw new Error('A content source attribute value is missing.'); } - - return new Promise((resolve, reject) => { - if (this.blobFile) { - this.displayName = this.getDisplayName('Unknown'); - this.isLoading = true; - this.mimeType = this.blobFile.type; - this.viewerType = this.getViewerTypeByMimeType(this.mimeType); - - this.allowDownload = false; - // TODO: wrap blob into the data url and allow downloading - - this.extensionChange.emit(this.mimeType); - this.isLoading = false; - this.scrollTop(); - resolve(); - } else if (this.urlFile) { - this.isLoading = true; - let filenameFromUrl = this.getFilenameFromUrl(this.urlFile); - this.displayName = this.getDisplayName(filenameFromUrl); - this.extension = this.getFileExtension(filenameFromUrl); - this.urlFileContent = this.urlFile; - - this.downloadUrl = this.urlFile; - this.fileName = this.displayName; - - this.viewerType = this.urlFileViewer || this.getViewerTypeByExtension(this.extension); - if (this.viewerType === 'unknown') { - this.viewerType = this.getViewerTypeByMimeType(this.mimeType); - } - - this.extensionChange.emit(this.extension); - this.isLoading = false; - this.scrollTop(); - resolve(); - } else if (this.fileNodeId) { - this.isLoading = true; - this.apiService.getInstance().nodes.getNodeInfo(this.fileNodeId).then( - (data: MinimalNodeEntryEntity) => { - this.mimeType = data.content.mimeType; - this.displayName = this.getDisplayName(data.name); - this.urlFileContent = this.apiService.getInstance().content.getContentUrl(data.id); - this.extension = this.getFileExtension(data.name); - - this.fileName = data.name; - this.downloadUrl = this.apiService.getInstance().content.getContentUrl(data.id, true); - - this.viewerType = this.getViewerTypeByExtension(this.extension); - if (this.viewerType === 'unknown') { - this.viewerType = this.getViewerTypeByMimeType(this.mimeType); - } - - if (this.viewerType === 'unknown') { - this.displayNodeRendition(data.id); - } else { - this.isLoading = false; - } - - this.extensionChange.emit(this.extension); - this.sidebarTemplateContext.node = data; - this.scrollTop(); - resolve(); - }, - (error) => { - this.isLoading = false; - reject(error); - this.logService.error('This node does not exist'); - } - ); - } else if (this.sharedLinkId) { - this.isLoading = true; - - this.apiService.sharedLinksApi.getSharedLink(this.sharedLinkId).then(details => { - this.mimeType = details.entry.content.mimeType; - this.displayName = this.getDisplayName(details.entry.name); - this.extension = this.getFileExtension(details.entry.name); - this.fileName = details.entry.name; - - this.urlFileContent = this.apiService.contentApi.getSharedLinkContentUrl(this.sharedLinkId, false); - this.downloadUrl = this.apiService.contentApi.getSharedLinkContentUrl(this.sharedLinkId, true); - - this.viewerType = this.getViewerTypeByMimeType(this.mimeType); - if (this.viewerType === 'unknown') { - this.viewerType = this.getViewerTypeByExtension(this.extension); - } - - if (this.viewerType === 'unknown') { - this.displaySharedLinkRendition(this.sharedLinkId); - } else { - this.isLoading = false; - } - - this.extensionChange.emit(this.extension); + if (this.blobFile) { + this.setUpBlobData(); + } else if (this.urlFile) { + this.setUpUrlFile(); + } else if (this.fileNodeId) { + this.isLoading = true; + this.apiService.getInstance().nodes.getNodeInfo(this.fileNodeId).then( + (data: MinimalNodeEntryEntity) => { + this.setUpNodeFile(data); + }, + (error) => { this.isLoading = false; - resolve(); - }); - } - }); + this.logService.error('This node does not exist'); + } + ); + } else if (this.sharedLinkId) { + this.isLoading = true; + + this.apiService.sharedLinksApi.getSharedLink(this.sharedLinkId).then(details => { + this.setUpSharedLinkFile(details); + }); + } } } + private setUpBlobData() { + this.displayName = this.getDisplayName('Unknown'); + this.isLoading = true; + this.mimeType = this.blobFile.type; + this.viewerType = this.getViewerTypeByMimeType(this.mimeType); + + this.allowDownload = false; + // TODO: wrap blob into the data url and allow downloading + + this.extensionChange.emit(this.mimeType); + this.isLoading = false; + this.scrollTop(); + } + + private setUpUrlFile() { + this.isLoading = true; + let filenameFromUrl = this.getFilenameFromUrl(this.urlFile); + this.displayName = this.getDisplayName(filenameFromUrl); + this.extension = this.getFileExtension(filenameFromUrl); + this.urlFileContent = this.urlFile; + + this.downloadUrl = this.urlFile; + this.fileName = this.displayName; + + this.viewerType = this.urlFileViewer || this.getViewerTypeByExtension(this.extension); + if (this.viewerType === 'unknown') { + this.viewerType = this.getViewerTypeByMimeType(this.mimeType); + } + + this.extensionChange.emit(this.extension); + this.isLoading = false; + this.scrollTop(); + } + + private setUpNodeFile(data: MinimalNodeEntryEntity) { + this.mimeType = data.content.mimeType; + this.displayName = this.getDisplayName(data.name); + this.urlFileContent = this.apiService.getInstance().content.getContentUrl(data.id); + this.extension = this.getFileExtension(data.name); + + this.fileName = data.name; + this.downloadUrl = this.apiService.getInstance().content.getContentUrl(data.id, true); + + this.viewerType = this.getViewerTypeByExtension(this.extension); + if (this.viewerType === 'unknown') { + this.viewerType = this.getViewerTypeByMimeType(this.mimeType); + } + + if (this.viewerType === 'unknown') { + this.displayNodeRendition(data.id); + } else { + this.isLoading = false; + } + + this.extensionChange.emit(this.extension); + this.sidebarTemplateContext.node = data; + this.scrollTop(); + } + + private setUpSharedLinkFile(details: any) { + this.mimeType = details.entry.content.mimeType; + this.displayName = this.getDisplayName(details.entry.name); + this.extension = this.getFileExtension(details.entry.name); + this.fileName = details.entry.name; + + this.urlFileContent = this.apiService.contentApi.getSharedLinkContentUrl(this.sharedLinkId, false); + this.downloadUrl = this.apiService.contentApi.getSharedLinkContentUrl(this.sharedLinkId, true); + + this.viewerType = this.getViewerTypeByMimeType(this.mimeType); + if (this.viewerType === 'unknown') { + this.viewerType = this.getViewerTypeByExtension(this.extension); + } + + if (this.viewerType === 'unknown') { + this.displaySharedLinkRendition(this.sharedLinkId); + } else { + this.isLoading = false; + } + this.extensionChange.emit(this.extension); + this.isLoading = false; + } + toggleSidebar() { this.showSidebar = !this.showSidebar; if (this.showSidebar && this.fileNodeId) { diff --git a/lib/insights/diagram/components/tooltip/diagram-tooltip.component.ts b/lib/insights/diagram/components/tooltip/diagram-tooltip.component.ts index a1721523d7..fba722878a 100644 --- a/lib/insights/diagram/components/tooltip/diagram-tooltip.component.ts +++ b/lib/insights/diagram/components/tooltip/diagram-tooltip.component.ts @@ -103,7 +103,7 @@ export class DiagramTooltipComponent implements AfterViewInit, OnDestroy { if (this.strategy === STRATEGY.ELEMENT ) { props = event.target.getBoundingClientRect(); - }else { + } else { props = {top: (event.pageY - 150), left: event.pageX , width: event.layerX, height: 50}; } diff --git a/lib/package.json b/lib/package.json index 21a9200cff..38277716c7 100644 --- a/lib/package.json +++ b/lib/package.json @@ -77,7 +77,7 @@ "moment-es6": "^1.0.0", "ng-packagr": "2.0.0-rc.4", "ng2-charts": "1.6.0", - "pdfjs-dist": "1.5.404", + "pdfjs-dist": "2.0.265", "raphael": "2.2.7", "reflect-metadata": "0.1.10", "rxjs": "5.5.2", @@ -85,7 +85,7 @@ "zone.js": "0.8.14" }, "devDependencies": { - "@angular/compiler-cli": "5.1.1", + "@angular/compiler-cli": "^5.2.0", "@types/hammerjs": "2.0.35", "@types/jasmine": "^2.5.35", "@types/node": "6.0.90", @@ -139,7 +139,7 @@ "traceur": "0.0.91", "ts-loader": "3.3.0", "ts-node": "2.0.0", - "tslint": "5.7.0", + "tslint": "5.9.1", "tslint-loader": "3.5.3", "typescript": "2.6.1", "uglifyjs-webpack-plugin": "1.1.6", diff --git a/lib/tslint.json b/lib/tslint.json index 597f0ceb03..4cb34547e3 100644 --- a/lib/tslint.json +++ b/lib/tslint.json @@ -21,6 +21,12 @@ "curly": true, "eofline": true, "forin": true, + "import-blacklist": [ + true, + "rxjs", + "rxjs/Rx" + ], + "import-spacing": true, "indent": [ true, "spaces" @@ -32,10 +38,17 @@ true, 180 ], + "member-access": false, "member-ordering": [ true, - "static-before-instance", - "variables-before-functions" + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } ], "no-any": false, "no-arg": true, @@ -54,6 +67,7 @@ "no-construct": true, "no-constructor-vars": false, "no-debugger": true, + "no-duplicate-super": true, "no-duplicate-variable": true, "no-empty": false, "no-eval": true, @@ -82,7 +96,10 @@ "avoid-escape" ], "radix": true, - "semicolon": true, + "semicolon": [ + true, + "always" + ], "switch-default": true, "trailing-comma": [ true, @@ -152,7 +169,6 @@ "use-pipe-transform-interface": true, "component-class-suffix": true, "directive-class-suffix": true, - "no-access-missing-member": false, "adf-file-name": true, "adf-class-name": true, "adf-prefix-name": true,