/*! * @license * Copyright 2019 Alfresco Software, Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Location } from '@angular/common'; import { SpyLocation } from '@angular/common/testing'; import { Component } from '@angular/core'; import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; import { AlfrescoApiService, RenditionsService } from '../../services'; import { throwError } from 'rxjs'; import { EventMock } from '../../mock/event.mock'; import { RenderingQueueServices } from '../services/rendering-queue.services'; import { ViewerComponent } from './viewer.component'; import { setupTestBed } from '../../testing/setup-test-bed'; import { NodeEntry, VersionEntry } from '@alfresco/js-api'; import { CoreTestingModule } from '../../testing/core.testing.module'; import { TranslateModule } from '@ngx-translate/core'; import { MatDialog } from '@angular/material/dialog'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { UploadService } from '../../services/upload.service'; import { FileModel } from '../../models'; import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions'; @Component({ selector: 'adf-viewer-container-toolbar', template: `
` }) class ViewerWithCustomToolbarComponent { } @Component({ selector: 'adf-viewer-container-toolbar-actions', template: ` ` }) class ViewerWithCustomToolbarActionsComponent { } @Component({ selector: 'adf-viewer-container-sidebar', template: `
` }) class ViewerWithCustomSidebarComponent { } @Component({ selector: 'adf-dialog-dummy', template: `` }) class DummyDialogComponent { } @Component({ selector: 'adf-viewer-container-open-with', template: ` ` }) class ViewerWithCustomOpenWithComponent { } @Component({ selector: 'adf-viewer-container-more-actions', template: ` ` }) class ViewerWithCustomMoreActionsComponent { } describe('ViewerComponent', () => { let component: ViewerComponent; let fixture: ComponentFixture; let alfrescoApiService: AlfrescoApiService; let element: HTMLElement; let dialog: MatDialog; let uploadService: UploadService; let extensionService: AppExtensionService; setupTestBed({ imports: [ NoopAnimationsModule, TranslateModule.forRoot(), CoreTestingModule ], declarations: [ ViewerWithCustomToolbarComponent, ViewerWithCustomSidebarComponent, ViewerWithCustomOpenWithComponent, ViewerWithCustomMoreActionsComponent, ViewerWithCustomToolbarActionsComponent ], providers: [ { provide: RenditionsService, useValue: { getRendition: () => { return throwError('thrown'); } } }, RenderingQueueServices, { provide: Location, useClass: SpyLocation }, MatDialog ] }); beforeEach(() => { fixture = TestBed.createComponent(ViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; uploadService = TestBed.inject(UploadService); alfrescoApiService = TestBed.inject(AlfrescoApiService); dialog = TestBed.inject(MatDialog); extensionService = TestBed.inject(AppExtensionService); }); afterEach(() => { fixture.destroy(); }); describe('Extension Type Test', () => { it('should display pdf external viewer via wildcard notation', async () => { const extension: ViewerExtensionRef = { component: 'custom.component', id: 'custom.component.id', fileExtension: '*' }; spyOn(extensionService, 'getViewerExtensions').and.returnValue([extension]); fixture = TestBed.createComponent(ViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; component.urlFile = 'fake-test-file.pdf'; component.ngOnChanges(); fixture.detectChanges(); await fixture.whenStable(); expect(component.externalExtensions.includes('*')).toBe(true); expect(component.externalViewer).toBe(extension); expect(component.viewerType).toBe('external'); expect(element.querySelector('[data-automation-id="custom.component"]')).not.toBeNull(); }); it('should display pdf with the first external viewer provided', async () => { const extensions: ViewerExtensionRef[] = [ { component: 'custom.component.1', id: 'custom.component.id', fileExtension: '*' }, { component: 'custom.component.2', id: 'custom.component.id', fileExtension: '*' } ]; spyOn(extensionService, 'getViewerExtensions').and.returnValue(extensions); fixture = TestBed.createComponent(ViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; component.urlFile = 'fake-test-file.pdf'; component.ngOnChanges(); fixture.detectChanges(); await fixture.whenStable(); expect(element.querySelector('[data-automation-id="custom.component.1"]')).not.toBeNull(); expect(element.querySelector('[data-automation-id="custom.component.2"]')).toBeNull(); }); it('should display url with the external viewer provided', async () => { const extension: ViewerExtensionRef = { component: 'custom.component', id: 'custom.component.id', fileExtension: '*' }; spyOn(extensionService, 'getViewerExtensions').and.returnValue([extension]); fixture = TestBed.createComponent(ViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; component.urlFile = 'http://localhost:4200/alfresco'; component.ngOnChanges(); fixture.detectChanges(); await fixture.whenStable(); expect(component.externalExtensions.includes('*')).toBe(true); expect(component.externalViewer).toBe(extension); expect(component.viewerType).toBe('external'); expect(element.querySelector('[data-automation-id="custom.component"]')).not.toBeNull(); }); it('should use external viewer to display node by id', fakeAsync(() => { const extension: ViewerExtensionRef = { component: 'custom.component', id: 'custom.component.id', fileExtension: '*' }; spyOn(extensionService, 'getViewerExtensions').and.returnValue([extension]); fixture = TestBed.createComponent(ViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; spyOn(component.nodesApi, 'getNode').and.callFake(() => Promise.resolve({ entry: {} })); component.nodeId = '37f7f34d-4e64-4db6-bb3f-5c89f7844251'; component.ngOnChanges(); fixture.detectChanges(); tick(100); expect(component.nodesApi.getNode).toHaveBeenCalled(); expect(component.viewerType).toBe('external'); expect(component.isLoading).toBeFalsy(); expect(element.querySelector('[data-automation-id="custom.component"]')).not.toBeNull(); })); it('should extension file pdf be loaded', (done) => { component.urlFile = 'fake-test-file.pdf'; component.ngOnChanges(); fixture.detectChanges(); fixture.whenStable().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(); fixture.detectChanges(); fixture.whenStable().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(); fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-media-player')).not.toBeNull(); done(); }); }); it('should extension file txt be loaded', (done) => { component.urlFile = 'fake-test-file.txt'; component.ngOnChanges(); fixture.detectChanges(); fixture.whenStable().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(); fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-viewer-unknown-format')).toBeDefined(); done(); }); }); }); describe('MimeType handling', () => { it('should display an image file identified by mimetype when the filename has no extension', (done) => { component.urlFile = 'fake-content-img'; component.mimeType = 'image/png'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().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 = 'fake-content-img.bin'; component.mimeType = 'image/png'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#viewer-image')).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 = 'fake-content-txt.bin'; component.mimeType = 'text/plain'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-txt-viewer')).not.toBeNull(); done(); }); }); it('should node without content show unkonwn', (done) => { const displayName = 'the-name'; const contentUrl = '/content/url/path'; component.nodeId = '12'; component.urlFile = null; component.displayName = null; spyOn(component['nodesApi'], 'getNode').and.returnValue(Promise.resolve({ id: 'fake-node', entry: { content: { name: displayName, id: '12' } } })); spyOn(component['contentApi'], 'getContentUrl').and.returnValue(contentUrl); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-viewer-unknown-format')).toBeDefined(); 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 = 'fake-content-video.bin'; component.mimeType = 'video/mp4'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-media-player')).not.toBeNull(); done(); }); }, 25000); it('should display the media player if the file identified by mimetype is a media when the filename has no extension', (done) => { component.urlFile = 'fake-content-video'; component.mimeType = 'video/mp4'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-media-player')).not.toBeNull(); done(); }); }, 25000); it('should display a PDF file identified by mimetype when the filename has no extension', (done) => { component.urlFile = 'fake-content-pdf'; component.mimeType = 'application/pdf'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); done(); }); }, 25000); it('should display a PDF file identified by mimetype when the file extension is wrong', (done) => { component.urlFile = 'fake-content-pdf.bin'; component.mimeType = 'application/pdf'; component.ngOnChanges(); fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-pdf-viewer')).not.toBeNull(); done(); }); }, 25000); }); it('should change display name every time node changes', fakeAsync(() => { spyOn(component['nodesApi'], 'getNode').and.returnValues( Promise.resolve(new NodeEntry({ entry: { name: 'file1', content: {} } })), Promise.resolve(new NodeEntry({ entry: { name: 'file2', content: {} } })) ); component.urlFile = null; component.displayName = null; component.blobFile = null; component.showViewer = true; component.nodeId = 'id1'; component.ngOnChanges(); tick(); expect(component.fileTitle).toBe('file1'); component.nodeId = 'id2'; component.ngOnChanges(); tick(); expect(component.fileTitle).toBe('file2'); })); it('should append version of the file to the file content URL', fakeAsync(() => { spyOn(component['nodesApi'], 'getNode').and.returnValue( Promise.resolve(new NodeEntry({ entry: { name: 'file1', content: {}, properties: { 'cm:versionLabel': '10' } } })) ); spyOn(component['versionsApi'], 'getVersion').and.returnValue(Promise.resolve(undefined)); component.nodeId = 'id1'; component.urlFile = null; component.displayName = null; component.blobFile = null; component.showViewer = true; component.versionId = null; component.ngOnChanges(); tick(); expect(component.fileTitle).toBe('file1'); expect(component.urlFileContent).toContain('/public/alfresco/versions/1/nodes/id1/content?attachment=false&10'); })); it('should change display name every time node\`s version changes', fakeAsync(() => { spyOn(component['nodesApi'], 'getNode').and.returnValue( Promise.resolve(new NodeEntry({ entry: { name: 'node1', content: {} } })) ); spyOn(component['versionsApi'], 'getVersion').and.returnValues( Promise.resolve(new VersionEntry({ entry: { name: 'file1', content: {} } })), Promise.resolve(new VersionEntry({ entry: { name: 'file2', content: {} } })) ); component.nodeId = 'id1'; component.urlFile = null; component.displayName = null; component.blobFile = null; component.showViewer = true; component.versionId = '1.0'; component.ngOnChanges(); tick(); expect(component.fileTitle).toBe('file1'); component.versionId = '1.1'; component.ngOnChanges(); tick(); expect(component.fileTitle).toBe('file2'); })); it('should update node only if node name changed', fakeAsync(() => { spyOn(component['nodesApi'], 'getNode').and.returnValues( Promise.resolve(new NodeEntry({ entry: { name: 'file1', content: {} } })) ); spyOn(component, 'getViewerTypeByExtension').and.returnValue('jpg'); component.urlFile = null; component.displayName = null; component.blobFile = null; component.showViewer = true; component.nodeId = 'id1'; fixture.detectChanges(); component.ngOnChanges(); tick(); expect(component.fileTitle).toBe('file1'); alfrescoApiService.nodeUpdated.next( { id: 'id1', name: 'file2' }); fixture.detectChanges(); expect(component.fileTitle).toBe('file2'); alfrescoApiService.nodeUpdated.next( { id: 'id1', name: 'file3' }); fixture.detectChanges(); expect(component.fileTitle).toBe('file3'); alfrescoApiService.nodeUpdated.next( { id: 'id2', name: 'file4' }); fixture.detectChanges(); expect(component.fileTitle).toBe('file3'); expect(component.nodeId).toBe('id1'); })); describe('Viewer Example Component Rendering', () => { it('should use custom toolbar', (done) => { const customFixture = TestBed.createComponent(ViewerWithCustomToolbarComponent); const customElement: HTMLElement = customFixture.nativeElement; customFixture.detectChanges(); fixture.whenStable().then(() => { expect(customElement.querySelector('.custom-toolbar-element')).toBeDefined(); done(); }); }); it('should use custom toolbar actions', (done) => { const customFixture = TestBed.createComponent(ViewerWithCustomToolbarActionsComponent); const customElement: HTMLElement = customFixture.nativeElement; customFixture.detectChanges(); fixture.whenStable().then(() => { expect(customElement.querySelector('#custom-button')).toBeDefined(); done(); }); }); it('should use custom info drawer', (done) => { const customFixture = TestBed.createComponent(ViewerWithCustomSidebarComponent); const customElement: HTMLElement = customFixture.nativeElement; customFixture.detectChanges(); fixture.whenStable().then(() => { expect(customElement.querySelector('.custom-info-drawer-element')).toBeDefined(); done(); }); }); it('should use custom open with menu', (done) => { const customFixture = TestBed.createComponent(ViewerWithCustomOpenWithComponent); const customElement: HTMLElement = customFixture.nativeElement; customFixture.detectChanges(); fixture.whenStable().then(() => { expect(customElement.querySelector('.adf-viewer-container-open-with')).toBeDefined(); done(); }); }); it('should use custom more actions menu', (done) => { const customFixture = TestBed.createComponent(ViewerWithCustomMoreActionsComponent); const customElement: HTMLElement = customFixture.nativeElement; customFixture.detectChanges(); fixture.whenStable().then(() => { expect(customElement.querySelector('.adf-viewer-container-more-actions')).toBeDefined(); done(); }); }); }); describe('Base component', () => { beforeEach(() => { component.showToolbar = true; component.urlFile = 'fake-test-file.pdf'; component.mimeType = 'application/pdf'; fixture.detectChanges(); }); describe('SideBar Test', () => { it('should NOT display sidebar if is not allowed', (done) => { component.showRightSidebar = true; component.allowRightSidebar = false; fixture.detectChanges(); fixture.whenStable().then(() => { const sidebar = element.querySelector('#adf-right-sidebar'); expect(sidebar).toBeNull(); done(); }); }); it('should display sidebar on the right side', (done) => { component.allowRightSidebar = true; component.showRightSidebar = true; fixture.detectChanges(); fixture.whenStable().then(() => { const sidebar = element.querySelector('#adf-right-sidebar'); expect(getComputedStyle(sidebar).order).toEqual('4'); done(); }); }); it('should NOT display left sidebar if is not allowed', (done) => { component.showLeftSidebar = true; component.allowLeftSidebar = false; fixture.detectChanges(); fixture.whenStable().then(() => { const sidebar = element.querySelector('#adf-left-sidebar'); expect(sidebar).toBeNull(); done(); }); }); it('should display sidebar on the left side', (done) => { component.allowLeftSidebar = true; component.showLeftSidebar = true; fixture.detectChanges(); fixture.whenStable().then(() => { const sidebar = element.querySelector('#adf-left-sidebar'); expect(getComputedStyle(sidebar).order).toEqual('1'); done(); }); }); }); describe('Toolbar', () => { it('should render fullscreen button', () => { expect(element.querySelector('[data-automation-id="adf-toolbar-fullscreen"]')).toBeDefined(); }); it('should not render fullscreen button', (done) => { component.allowFullScreen = false; fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('[data-automation-id="adf-toolbar-fullscreen"]')).toBeNull(); done(); }); }); it('should render default download button', (done) => { component.allowDownload = true; fixture.whenStable().then(() => { expect(element.querySelector('[data-automation-id="adf-toolbar-download"]')).toBeDefined(); done(); }); }); it('should not render default download button', (done) => { component.allowDownload = false; fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('[data-automation-id="adf-toolbar-download"]')).toBeNull(); done(); }); }); it('should render default print button', (done) => { component.allowPrint = true; fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('[data-automation-id="adf-toolbar-print"]')).toBeDefined(); done(); }); }); it('should not render default print button', (done) => { component.allowPrint = false; fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('[data-automation-id="adf-toolbar-print"]')).toBeNull(); done(); }); }); it('should invoke print action with the toolbar button', (done) => { component.allowPrint = true; fixture.detectChanges(); spyOn(component, 'printContent').and.stub(); const button: HTMLButtonElement = element.querySelector('[data-automation-id="adf-toolbar-print"]') as HTMLButtonElement; button.click(); fixture.whenStable().then(() => { expect(component.printContent).toHaveBeenCalled(); done(); }); }); it('should raise the print event with the toolbar button', (done) => { component.allowPrint = true; fixture.detectChanges(); component.print.subscribe((e) => { expect(e).not.toBeNull(); done(); }); const button: HTMLButtonElement = element.querySelector('[data-automation-id="adf-toolbar-print"]') as HTMLButtonElement; button.click(); }); it('should get and assign node for download', (done) => { component.nodeId = '12'; component.urlFile = ''; const displayName = 'the-name'; const nodeDetails = { id: 'fake-node', entry: { name: displayName, id: '12', content: { mimeType: 'txt' } } }; const contentUrl = '/content/url/path'; spyOn(component['nodesApi'], 'getNode').and.returnValue(Promise.resolve(nodeDetails)); spyOn(component['contentApi'], 'getContentUrl').and.returnValue(contentUrl); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(component.nodeEntry).toBe(nodeDetails); done(); }); }); it('should render close viewer button if it is not a shared link', (done) => { fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('[data-automation-id="adf-toolbar-back"]')).toBeDefined(); expect(element.querySelector('[data-automation-id="adf-toolbar-back"]')).not.toBeNull(); done(); }); }); it('should emit `showViewerChange` event on close', async () => { spyOn(component.showViewerChange, 'emit'); const button: HTMLButtonElement = element.querySelector('[data-automation-id="adf-toolbar-back"]') as HTMLButtonElement; button.click(); fixture.detectChanges(); await fixture.whenStable(); expect(component.showViewerChange.emit).toHaveBeenCalled(); }); it('should not render close viewer button if it is a shared link', (done) => { spyOn(component['sharedLinksApi'], 'getSharedLink') .and.returnValue(Promise.reject({})); component.sharedLinkId = 'the-Shared-Link-id'; component.urlFile = null; component.mimeType = null; component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('[data-automation-id="adf-toolbar-back"]')).toBeNull(); done(); }); }); }); 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 ', (done) => { component.ngOnChanges(); fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('fake-test-file.pdf'); done(); }); }); it('should Close button be present if overlay mode', (done) => { fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('.adf-viewer-close-button')).not.toBeNull(); done(); }); }); it('should Click on close button hide the viewer', (done) => { const closebutton: any = element.querySelector('.adf-viewer-close-button'); closebutton.click(); fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('.adf-viewer-content')).toBeNull(); done(); }); }); it('should Esc button hide the viewer', (done) => { EventMock.keyDown(27); fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('.adf-viewer-content')).toBeNull(); done(); }); }); it('should not close the viewer on Escape event if dialog was opened', (done) => { const event = new KeyboardEvent('keydown', { bubbles: true, keyCode: 27 } as KeyboardEventInit); const dialogRef = dialog.open(DummyDialogComponent); dialogRef.afterClosed().subscribe(() => { document.body.dispatchEvent(event); fixture.detectChanges(); expect(element.querySelector('.adf-viewer-content')).toBeNull(); done(); }); fixture.detectChanges(); document.body.dispatchEvent(event); fixture.detectChanges(); expect(element.querySelector('.adf-viewer-content')).not.toBeNull(); }); }); describe('Overlay mode false', () => { beforeEach(() => { component.overlayMode = false; fixture.detectChanges(); }); it('should Esc button not hide the viewer if is not overlay mode', (done) => { EventMock.keyDown(27); fixture.detectChanges(); fixture.whenStable().then(() => { expect(element.querySelector('.adf-viewer-content')).not.toBeNull(); done(); }); }); }); }); describe('Attribute', () => { it('should Url or nodeId be mandatory', () => { component.showViewer = true; component.nodeId = undefined; component.urlFile = undefined; expect(() => { component.ngOnChanges(); }).toThrow(); }); it('should FileNodeId present not thrown any error ', () => { component.showViewer = true; component.nodeId = 'file-node-id'; component.urlFile = undefined; expect(() => { component.ngOnChanges(); }).not.toThrow(); }); it('should urlFile present not thrown any error ', () => { component.showViewer = true; component.nodeId = undefined; expect(() => { component.ngOnChanges(); }).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('error handling', () => { it('should show unknown view when node file not found', (done) => { spyOn(component['nodesApi'], 'getNode') .and.returnValue(Promise.reject({})); component.nodeId = 'the-node-id-of-the-file-to-preview'; component.urlFile = null; component.mimeType = null; component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-viewer-unknown-format')).not.toBeNull(); done(); }); }); it('should show unknown view when sharedLink file not found', (done) => { spyOn(component['sharedLinksApi'], 'getSharedLink') .and.returnValue(Promise.reject({})); component.sharedLinkId = 'the-Shared-Link-id'; component.urlFile = null; component.mimeType = null; component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-viewer-unknown-format')).not.toBeNull(); done(); }); }); it('should raise an event when the shared link is invalid', (done) => { spyOn(component['sharedLinksApi'], 'getSharedLink') .and.returnValue(Promise.reject({})); component.invalidSharedLink.subscribe(() => { done(); }); component.sharedLinkId = 'the-Shared-Link-id'; component.urlFile = null; component.mimeType = null; component.ngOnChanges(); }); it('should swicth to the unkwown template if the type specific viewers throw an error', (done) => { component.urlFile = 'fake-url-file.icns'; component.mimeType = 'image/png'; component.ngOnChanges(); fixture.detectChanges(); component.onUnsupportedFile(); fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('adf-viewer-unknown-format')).toBeDefined(); 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(); }); it('should update version when emitted by image-viewer and user has update permissions', () => { spyOn(uploadService, 'uploadFilesInTheQueue').and.callFake(() => { }); spyOn(uploadService, 'addToQueue'); component.readOnly = false; component.nodeEntry = new NodeEntry({ entry: { name: 'fakeImage.png', id: '12', content: { mimeType: 'img/png' } } }); const data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='); const fakeBlob = new Blob([data], { type: 'image/png' }); const newImageFile: File = new File([fakeBlob], component?.nodeEntry?.entry?.name, { type: component?.nodeEntry?.entry?.content?.mimeType }); const newFile = new FileModel( newImageFile, { majorVersion: false, newVersion: true, parentId: component?.nodeEntry?.entry?.parentId, nodeType: component?.nodeEntry?.entry?.content?.mimeType }, component.nodeEntry.entry?.id ); component.onSubmitFile(fakeBlob); fixture.detectChanges(); expect(uploadService.addToQueue).toHaveBeenCalledWith(...[newFile]); expect(uploadService.uploadFilesInTheQueue).toHaveBeenCalled(); }); it('should not update version when emitted by image-viewer and user doesn`t have update permissions', () => { spyOn(uploadService, 'uploadFilesInTheQueue').and.callFake(() => { }); component.readOnly = true; component.nodeEntry = new NodeEntry({ entry: { name: 'fakeImage.png', id: '12', content: { mimeType: 'img/png' } } }); const data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='); const fakeBlob = new Blob([data], { type: 'image/png' }); component.onSubmitFile(fakeBlob); fixture.detectChanges(); expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled(); }); }); describe('display name property override by urlFile', () => { it('should displayName override the default name if is present and urlFile is set', (done) => { component.urlFile = 'fake-test-file.pdf'; component.displayName = 'test name'; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().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 = 'fake-test-file.pdf'; component.displayName = null; fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().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' }); fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().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' }); fixture.detectChanges(); component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('Unknown'); done(); }); }); }); describe('display name property override by nodeId', () => { const contentUrl = '/content/url/path'; const nodeDetails = new NodeEntry({ entry: { name: 'node-id-name', id: '12', content: { mimeType: 'txt' } } }); it('should use the node name if displayName is NOT set and nodeId is set', (done) => { spyOn(component['nodesApi'], 'getNode').and.returnValue(Promise.resolve(nodeDetails)); spyOn(component['contentApi'], 'getContentUrl').and.returnValue(contentUrl); component.nodeId = '12'; component.urlFile = null; component.displayName = 'the-name'; component.ngOnChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(element.querySelector('#adf-viewer-display-name').textContent).toEqual('the-name'); done(); }); }); }); }); describe('Viewer component - Full Screen Mode - Mocking fixture element', () => { beforeEach(() => { fixture = TestBed.createComponent(ViewerComponent); element = fixture.nativeElement; component = fixture.componentInstance; component.showToolbar = true; component.urlFile = 'fake-test-file.pdf'; component.mimeType = 'application/pdf'; fixture.detectChanges(); }); it('should request only if enabled', () => { const domElement = jasmine.createSpyObj('el', ['requestFullscreen']); spyOn(fixture.nativeElement, 'querySelector').and.returnValue(domElement); component.allowFullScreen = false; component.enterFullScreen(); expect(domElement.requestFullscreen).not.toHaveBeenCalled(); }); it('should use standard mode', () => { const domElement = jasmine.createSpyObj('el', ['requestFullscreen']); spyOn(fixture.nativeElement, 'querySelector').and.returnValue(domElement); component.enterFullScreen(); expect(domElement.requestFullscreen).toHaveBeenCalled(); }); it('should use webkit prefix', () => { const domElement = jasmine.createSpyObj('el', ['webkitRequestFullscreen']); spyOn(fixture.nativeElement, 'querySelector').and.returnValue(domElement); component.enterFullScreen(); expect(domElement.webkitRequestFullscreen).toHaveBeenCalled(); }); it('should use moz prefix', () => { const domElement = jasmine.createSpyObj('el', ['mozRequestFullScreen']); spyOn(fixture.nativeElement, 'querySelector').and.returnValue(domElement); component.enterFullScreen(); expect(domElement.mozRequestFullScreen).toHaveBeenCalled(); }); it('should use ms prefix', () => { const domElement = jasmine.createSpyObj('el', ['msRequestFullscreen']); spyOn(fixture.nativeElement, 'querySelector').and.returnValue(domElement); component.enterFullScreen(); expect(domElement.msRequestFullscreen).toHaveBeenCalled(); }); }); });