/*! * @license * Copyright 2016 Alfresco Software, Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { AlfrescoSearchControlComponent } from './alfresco-search-control.component'; import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { TranslationMock } from './../assets/translation.service.mock'; import { result } from './../assets/alfresco-search.component.mock'; import { AlfrescoSettingsService, AlfrescoApiService, AlfrescoAuthenticationService, AlfrescoContentService, AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core'; import { AlfrescoSearchService } from '../services/alfresco-search.service'; describe('AlfrescoSearchControlComponent', () => { let fixture: ComponentFixture; let component: AlfrescoSearchControlComponent, element: HTMLElement; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ CoreModule ], declarations: [ AlfrescoSearchControlComponent, AlfrescoSearchAutocompleteComponent ], providers: [ {provide: AlfrescoTranslationService, useClass: TranslationMock}, AlfrescoThumbnailService, AlfrescoSettingsService, AlfrescoApiService, AlfrescoAuthenticationService, AlfrescoContentService, AlfrescoSearchService ] }).compileComponents().then(() => { fixture = TestBed.createComponent(AlfrescoSearchControlComponent); component = fixture.componentInstance; element = fixture.nativeElement; }); })); it('should setup i18n folder', () => { let translationService = fixture.debugElement.injector.get(AlfrescoTranslationService); spyOn(translationService, 'addTranslationFolder'); fixture.detectChanges(); expect(translationService.addTranslationFolder) .toHaveBeenCalledWith('node_modules/ng2-alfresco-search/dist/src'); }); it('should emit searchChange when search term input changed', (done) => { fixture.componentInstance.searchChange.subscribe(e => { expect(e.value).toBe('customSearchTerm'); done(); }); fixture.detectChanges(); fixture.componentInstance.searchTerm = 'customSearchTerm'; fixture.detectChanges(); }); it('should emit searchChange when search term changed by user', (done) => { fixture.detectChanges(); fixture.componentInstance.searchChange.subscribe(e => { expect(e.value).toBe('customSearchTerm211'); done(); }); component.searchControl.setValue('customSearchTerm211', true); fixture.detectChanges(); }); describe('Component rendering', () => { it('should display a text input field by default', () => { fixture.detectChanges(); expect(element.querySelectorAll('input[type="text"]').length).toBe(1); }); it('should display a search input field when specified', () => { fixture.componentInstance.inputType = 'search'; fixture.detectChanges(); expect(element.querySelectorAll('input[type="search"]').length).toBe(1); }); it('should set browser autocomplete to off by default', () => { fixture.detectChanges(); let attr = element.querySelectorAll('input[type="text"]')[0].getAttribute('autocomplete'); expect(attr).toBe('off'); }); it('should set browser autocomplete to on when configured', () => { fixture.componentInstance.autocomplete = true; fixture.detectChanges(); expect(element.querySelectorAll('input[type="text"]')[0].getAttribute('autocomplete')).toBe('on'); }); it('should show an expanding control by default', () => { fixture.detectChanges(); expect(element.querySelectorAll('div.mdl-textfield--expandable').length).toBe(1); expect(element.querySelectorAll('div.mdl-textfield__expandable-holder').length).toBe(1); expect(element.querySelectorAll('label.mdl-button--icon').length).toBe(1); }); it('should show a normal non-expanding control when configured', () => { fixture.detectChanges(); fixture.componentInstance.expandable = false; fixture.detectChanges(); expect(element.querySelectorAll('div.mdl-textfield--expandable').length).toBe(0); expect(element.querySelectorAll('div.mdl-textfield__expandable-holder').length).toBe(0); expect(element.querySelectorAll('label.mdl-button--icon').length).toBe(0); }); }); describe('Find as you type', () => { let inputEl: HTMLInputElement; beforeEach(() => { inputEl = element.querySelector('input'); }); it('should display a find-as-you-type control by default', () => { fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete).not.toBeNull(); }); it('should make find-as-you-type control hidden initially', () => { fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete.classList.contains('active')).toBe(false); }); it('should make find-as-you-type control visible when search box has focus', (done) => { fixture.detectChanges(); inputEl.dispatchEvent(new FocusEvent('focus')); window.setTimeout(() => { // wait for debounce() to complete fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete.classList.contains('active')).toBe(true); done(); }, 100); }); it('should hide find-as-you-type results when the search box loses focus', (done) => { fixture.detectChanges(); inputEl.dispatchEvent(new FocusEvent('focus')); inputEl.dispatchEvent(new FocusEvent('blur')); window.setTimeout(() => { fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete.classList.contains('active')).toBe(false); done(); }, 100); }); it('should keep find-as-you-type control visible when user tabs into results', (done) => { let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); spyOn(searchService, 'getSearchNodesPromise') .and.returnValue(Promise.resolve(result)); fixture.detectChanges(); inputEl.dispatchEvent(new FocusEvent('focus')); fixture.detectChanges(); inputEl.dispatchEvent(new FocusEvent('blur')); component.onAutoCompleteFocus(new FocusEvent('focus')); window.setTimeout(() => { // wait for debounce() to complete fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete.classList.contains('active')).toBe(true); done(); }, 100); }); it('should hide find-as-you-type results when escape key pressed', () => { fixture.detectChanges(); inputEl.dispatchEvent(new Event('focus')); inputEl.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' })); fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete.classList.contains('active')).toBe(false); }); it('should make find-as-you-type control visible again when down arrow is pressed', () => { fixture.detectChanges(); inputEl.dispatchEvent(new Event('focus')); inputEl.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' })); inputEl.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown' })); fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete.classList.contains('active')).toBe(true); }); it('should select the first result in find-as-you-type when down arrow is pressed and FAYT is visible', (done) => { fixture.detectChanges(); spyOn(component.autocompleteComponent, 'focusResult'); fixture.detectChanges(); inputEl.dispatchEvent(new Event('focus')); window.setTimeout(() => { // wait for debounce() to complete fixture.detectChanges(); inputEl.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown' })); fixture.detectChanges(); expect(component.autocompleteComponent.focusResult).toHaveBeenCalled(); done(); }, 100); }); it('should focus input element when find-as-you-type returns control', () => { fixture.detectChanges(); spyOn(inputEl, 'focus'); fixture.detectChanges(); component.onAutoCompleteReturn(new KeyboardEvent('keyup', { key: 'ArrowUp' })); expect(inputEl.focus).toHaveBeenCalled(); }); it('should focus input element when find-as-you-type is cancelled', () => { fixture.detectChanges(); spyOn(inputEl, 'focus'); fixture.detectChanges(); component.onAutoCompleteCancel(new KeyboardEvent('keyup', { key: 'ArrowUp' })); expect(inputEl.focus).toHaveBeenCalled(); }); it('should NOT display a find-as-you-type control when configured not to', () => { fixture.componentInstance.autocompleteEnabled = false; fixture.detectChanges(); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); expect(autocomplete).toBeNull(); }); }); describe('search submit', () => { it('should fire a search when a term has been entered', () => { spyOn(component.searchSubmit, 'emit'); fixture.detectChanges(); let formEl: HTMLElement = element.querySelector('form'); component.searchTerm = 'searchTerm1'; component.searchControl.setValue('searchTerm1', true); fixture.detectChanges(); formEl.dispatchEvent(new Event('submit')); fixture.detectChanges(); expect(component.searchSubmit.emit).toHaveBeenCalledWith({ 'value': 'searchTerm1' }); }); it('should not fire a search when no term has been entered', () => { spyOn(component.searchSubmit, 'emit'); fixture.detectChanges(); let inputEl: HTMLInputElement = element.querySelector('input[type="text"]'); let formEl: HTMLElement = element.querySelector('form'); inputEl.value = ''; formEl.dispatchEvent(new Event('submit')); fixture.detectChanges(); expect(component.searchSubmit.emit).not.toHaveBeenCalled(); }); }); describe('component focus', () => { it('should fire an event when the search box receives focus', (done) => { spyOn(component.expand, 'emit'); let inputEl: HTMLElement = element.querySelector('input'); inputEl.dispatchEvent(new FocusEvent('focus')); window.setTimeout(() => { expect(component.expand.emit).toHaveBeenCalledWith({ expanded: true }); done(); }, 100); }); it('should fire an event when the search box loses focus', (done) => { spyOn(component.expand, 'emit'); let inputEl: HTMLElement = element.querySelector('input'); inputEl.dispatchEvent(new FocusEvent('blur')); window.setTimeout(() => { expect(component.expand.emit).toHaveBeenCalledWith({ expanded: false }); done(); }, 100); }); it('should NOT fire an event when the search box receives/loses focus but the component is not expandable', (done) => { spyOn(component.expand, 'emit'); component.expandable = false; let inputEl: HTMLElement = element.querySelector('input'); inputEl.dispatchEvent(new FocusEvent('focus')); inputEl.dispatchEvent(new FocusEvent('blur')); window.setTimeout(() => { expect(component.expand.emit).not.toHaveBeenCalled(); done(); }, 100); }); }); describe('file preview', () => { it('should emit a preview event when onFileClicked is called', () => { spyOn(component.preview, 'emit'); component.onFileClicked({ value: 'node12345' }); expect(component.preview.emit).toHaveBeenCalledWith({ 'value': 'node12345' }); }); }); });