From 28783322fdf4b4c857eb4273e01b6b0de65c7683 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Mon, 3 Oct 2016 12:51:51 +0100 Subject: [PATCH] Re-add search control tests working for final NG 2.0.0 Refs #737 --- ng2-components/ng2-alfresco-search/index.ts | 1 + ...esco-search-autocomplete.component.spec.ts | 180 ++++++++---------- .../alfresco-search-autocomplete.component.ts | 4 +- .../alfresco-search-control.component.spec.ts | 100 +++++----- .../alfresco-search-control.component.ts | 33 ++-- 5 files changed, 163 insertions(+), 155 deletions(-) diff --git a/ng2-components/ng2-alfresco-search/index.ts b/ng2-components/ng2-alfresco-search/index.ts index c3d7b740af..2953569171 100644 --- a/ng2-components/ng2-alfresco-search/index.ts +++ b/ng2-components/ng2-alfresco-search/index.ts @@ -29,6 +29,7 @@ export * from './src/services/alfresco-search.service'; export * from './src/services/alfresco-thumbnail.service'; export * from './src/components/alfresco-search.component'; export * from './src/components/alfresco-search-control.component'; +export * from './src/components/alfresco-search-autocomplete.component'; export const ALFRESCO_SEARCH_DIRECTIVES: [any] = [ AlfrescoSearchComponent, diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.spec.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.spec.ts index a2eee1014e..6b9340f131 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.spec.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.spec.ts @@ -15,10 +15,7 @@ * limitations under the License. */ -/* -import { it, describe, expect, inject, beforeEachProviders, beforeEach, afterEach } from '@angular/core/testing'; -import { PLATFORM_PIPES } from '@angular/core'; -import { TestComponentBuilder } from '@angular/compiler/testing'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { TranslationMock } from './../assets/translation.service.mock'; @@ -29,14 +26,13 @@ import { AlfrescoAuthenticationService, AlfrescoContentService, AlfrescoTranslationService, - AlfrescoPipeTranslate + CoreModule } from 'ng2-alfresco-core'; -declare let jasmine: any; - describe('AlfrescoSearchAutocompleteComponent', () => { - let alfrescoSearchComponentFixture, element, component; + let alfrescoSearchComponentFixture: ComponentFixture, element: HTMLElement; + let component: AlfrescoSearchAutocompleteComponent; let result = { list: { @@ -98,47 +94,41 @@ describe('AlfrescoSearchAutocompleteComponent', () => { } }; - beforeEachProviders(() => { - return [ - { provide: PLATFORM_PIPES, useValue: AlfrescoPipeTranslate, multi: true }, - {provide: AlfrescoTranslationService, useClass: TranslationMock}, - AlfrescoThumbnailService, - AlfrescoSettingsService, - AlfrescoApiService, - AlfrescoAuthenticationService, - AlfrescoContentService, - AlfrescoSearchService - ]; - }); - - beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchAutocompleteComponent) - .then(fixture => { - jasmine.Ajax.install(); - alfrescoSearchComponentFixture = fixture; - element = alfrescoSearchComponentFixture.nativeElement; - component = alfrescoSearchComponentFixture.componentInstance; - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + CoreModule + ], + declarations: [ AlfrescoSearchAutocompleteComponent ], // declare the test component + providers: [ + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + AlfrescoThumbnailService, + AlfrescoSettingsService, + AlfrescoApiService, + AlfrescoAuthenticationService, + AlfrescoContentService, + AlfrescoSearchService + ] + }).compileComponents().then(() => { + alfrescoSearchComponentFixture = TestBed.createComponent(AlfrescoSearchAutocompleteComponent); + component = alfrescoSearchComponentFixture.componentInstance; + element = alfrescoSearchComponentFixture.nativeElement; + }); })); - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - - it('should setup i18n folder', () => { - let translation = jasmine.createSpyObj('AlfrescoTranslationService', [ - 'addTranslationFolder' - ]); - let search = new AlfrescoSearchAutocompleteComponent(null, translation, null); - expect(search).toBeDefined(); - - }); + // it('should setup i18n folder', () => { + // let translation = jasmine.createSpyObj('AlfrescoTranslationService', [ + // 'addTranslationFolder' + // ]); + // let search = new AlfrescoSearchAutocompleteComponent(null, translation, null); + // expect(search).toBeDefined(); + // + // }); it('should display search results when a search term is provided', () => { let searchTerm = { currentValue: 'customSearchTerm', previousValue: ''}; spyOn(component, 'displaySearchResults').and.stub(); - component.searchTerm = searchTerm; + component.searchTerm = 'searchTerm'; component.ngOnChanges({ searchTerm: searchTerm }); @@ -147,6 +137,11 @@ describe('AlfrescoSearchAutocompleteComponent', () => { }); it('should display the returned search results', (done) => { + + let searchService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoSearchService); + spyOn(searchService, 'getSearchNodesPromise') + .and.returnValue(Promise.resolve(result)); + component.resultsEmitter.subscribe(x => { alfrescoSearchComponentFixture.detectChanges(); expect( element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); @@ -154,93 +149,84 @@ describe('AlfrescoSearchAutocompleteComponent', () => { done(); }); - component.searchTerm = { currentValue: 'searchTerm', previousValue: ''}; - component.ngOnChanges({searchTerm: component.searchTerm }); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: result - }); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''} }); }); it('should display the correct thumbnail for result items', (done) => { + let searchService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoSearchService); + spyOn(searchService, 'getSearchNodesPromise') + .and.returnValue(Promise.resolve(result)); + component.baseComponentPath = 'http://localhost'; - spyOn(component.alfrescoThumbnailService, 'getMimeTypeIcon').and.returnValue('fake-type-icon.svg'); - spyOn(component.alfrescoThumbnailService, 'getMimeTypeKey').and.returnValue('FAKE_TYPE'); + + let thumbnailService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoThumbnailService); + spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue('fake-type-icon.svg'); + spyOn(thumbnailService, 'getMimeTypeKey').and.returnValue('FAKE_TYPE'); component.resultsEmitter.subscribe(() => { alfrescoSearchComponentFixture.detectChanges(); - let imgEl = element.querySelector('#result_row_0 img'); + let imgEl = element.querySelector('#result_row_0 img'); expect(imgEl).not.toBeNull(); expect(imgEl.src).toBe('http://localhost/img/fake-type-icon.svg'); expect(imgEl.alt).toBe('SEARCH.ICONS.FAKE_TYPE'); done(); }); - component.searchTerm = { currentValue: 'searchTerm', previousValue: ''}; - component.ngOnChanges({searchTerm: component.searchTerm }); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: result - }); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''} }); }); it('should display no result if no result are returned', (done) => { + + let searchService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoSearchService); + spyOn(searchService, 'getSearchNodesPromise') + .and.returnValue(Promise.resolve(noResult)); + component.resultsEmitter.subscribe(x => { alfrescoSearchComponentFixture.detectChanges(); expect(element.querySelector('#search_no_result')).not.toBeNull(); done(); }); - component.searchTerm = { currentValue: 'searchTerm', previousValue: ''}; - component.ngOnChanges({searchTerm: component.searchTerm}); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: noResult - }); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}}); }); it('should display an error if an error is encountered running the search', (done) => { + + let searchService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoSearchService); + spyOn(searchService, 'getSearchNodesPromise') + .and.returnValue(Promise.reject(errorJson)); + component.errorEmitter.subscribe(() => { alfrescoSearchComponentFixture.detectChanges(); let resultsEl = element.querySelector('[data-automation-id="autocomplete_results"]'); - let errorEl = element.querySelector('[data-automation-id="autocomplete_error_message"]'); + let errorEl = element.querySelector('[data-automation-id="autocomplete_error_message"]'); expect(resultsEl).toBeNull(); expect(errorEl).not.toBeNull(); expect(errorEl.innerText).toBe('SEARCH.RESULTS.ERROR'); done(); }); - component.searchTerm = { currentValue: 'searchTerm', previousValue: ''}; - component.ngOnChanges({searchTerm: component.searchTerm}); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 500, - contentType: 'json', - responseText: errorJson - }); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}}); }); it('should emit preview when file item clicked', (done) => { + + let searchService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoSearchService); + spyOn(searchService, 'getSearchNodesPromise') + .and.returnValue(Promise.resolve(result)); + component.resultsEmitter.subscribe(x => { alfrescoSearchComponentFixture.detectChanges(); - element.querySelector('#result_row_0').click(); + ( element.querySelector('#result_row_0')).click(); }); - component.searchTerm = { currentValue: 'searchTerm', previousValue: ''}; - component.ngOnChanges({searchTerm: component.searchTerm}); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: result - }); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}}); component.preview.subscribe(e => { done(); @@ -248,23 +234,21 @@ describe('AlfrescoSearchAutocompleteComponent', () => { }); it('should not emit preview if a non-file item is clicked', (done) => { + + let searchService = alfrescoSearchComponentFixture.debugElement.injector.get(AlfrescoSearchService); + spyOn(searchService, 'getSearchNodesPromise') + .and.returnValue(Promise.resolve(folderResult)); + spyOn(component.preview, 'emit'); component.resultsEmitter.subscribe(x => { alfrescoSearchComponentFixture.detectChanges(); - element.querySelector('#result_row_0').click(); + ( element.querySelector('#result_row_0')).click(); expect(component.preview.emit).not.toHaveBeenCalled(); done(); }); - component.searchTerm = { currentValue: 'searchTerm', previousValue: ''}; - component.ngOnChanges({searchTerm: component.searchTerm}); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: folderResult - }); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}}); }); }); -*/ diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts index 6d43ed470f..f4e7f75274 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.ts @@ -73,8 +73,8 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges { public displaySearchResults(searchTerm) { if (searchTerm !== null && searchTerm !== '') { this.alfrescoSearchService - .getLiveSearchResults(searchTerm) - .subscribe( + .getSearchNodesPromise(searchTerm) + .then( results => { this.results = results.list.entries; this.errorMessage = null; diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.spec.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.spec.ts index 258e7e4202..c8c6bd9d1f 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.spec.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.spec.ts @@ -15,11 +15,10 @@ * limitations under the License. */ -/* -import { provide, PLATFORM_PIPES } from '@angular/core'; -import { it, describe, expect, inject, beforeEachProviders, beforeEach } from '@angular/core/testing'; -import { TestComponentBuilder } from '@angular/compiler/testing'; +import { SimpleChange } from '@angular/core'; +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 { @@ -28,53 +27,67 @@ import { AlfrescoAuthenticationService, AlfrescoContentService, AlfrescoTranslationService, - AlfrescoPipeTranslate + CoreModule } from 'ng2-alfresco-core'; import { AlfrescoSearchService } from '../services/alfresco-search.service'; describe('AlfrescoSearchControlComponent', () => { - let alfrescoSearchControlComponentFixture, element, component; + let alfrescoSearchControlComponentFixture: ComponentFixture; + let component: AlfrescoSearchControlComponent, element: HTMLElement; - beforeEachProviders(() => { - return [ - { provide: PLATFORM_PIPES, useValue: AlfrescoPipeTranslate, multi: true }, - AlfrescoSearchService, - provide(AlfrescoTranslationService, {useClass: TranslationMock}), - AlfrescoThumbnailService, - AlfrescoSettingsService, - AlfrescoApiService, - AlfrescoAuthenticationService, - AlfrescoContentService - ]; - }); - - beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchControlComponent) - .then(fixture => { - alfrescoSearchControlComponentFixture = fixture; - element = alfrescoSearchControlComponentFixture.nativeElement; - component = alfrescoSearchControlComponentFixture.componentInstance; - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + CoreModule + ], + declarations: [ + AlfrescoSearchControlComponent, + AlfrescoSearchAutocompleteComponent + ], + providers: [ + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + AlfrescoThumbnailService, + AlfrescoSettingsService, + AlfrescoApiService, + AlfrescoAuthenticationService, + AlfrescoContentService, + AlfrescoSearchService + ] + }).compileComponents().then(() => { + alfrescoSearchControlComponentFixture = TestBed.createComponent(AlfrescoSearchControlComponent); + component = alfrescoSearchControlComponentFixture.componentInstance; + element = alfrescoSearchControlComponentFixture.nativeElement; + }); })); it('should setup i18n folder', () => { - let translation = jasmine.createSpyObj('AlfrescoTranslationService', [ - 'addTranslationFolder' - ]); - - let alfrescoSearchControlComponent = new AlfrescoSearchControlComponent(translation); - expect(alfrescoSearchControlComponent).toBeDefined(); + let translationService = alfrescoSearchControlComponentFixture.debugElement.injector.get(AlfrescoTranslationService); + spyOn(translationService, 'addTranslationFolder'); + alfrescoSearchControlComponentFixture.detectChanges(); + expect(translationService.addTranslationFolder) + .toHaveBeenCalledWith('node_modules/ng2-alfresco-search/dist/src'); }); - it('should emit searchChange when search term changed', () => { - alfrescoSearchControlComponentFixture.componentInstance.searchTerm = 'customSearchTerm'; - alfrescoSearchControlComponentFixture.detectChanges(); + it('should emit searchChange when search term input changed', (done) => { alfrescoSearchControlComponentFixture.componentInstance.searchChange.subscribe(e => { expect(e.value).toBe('customSearchTerm'); + done(); }); + alfrescoSearchControlComponentFixture.detectChanges(); + alfrescoSearchControlComponentFixture.componentInstance.searchTerm = 'customSearchTerm'; + alfrescoSearchControlComponentFixture.componentInstance + .ngOnChanges({'searchTerm': new SimpleChange('', 'customSearchTerm')}); + }); + + it('should emit searchChange when search term changed by user', (done) => { + alfrescoSearchControlComponentFixture.componentInstance.searchChange.subscribe(e => { + expect(e.value).toBe('customSearchTerm211'); + done(); + }); + alfrescoSearchControlComponentFixture.detectChanges(); + component.searchControl.setValue('customSearchTerm211', true); }); describe('Component rendering', () => { @@ -124,9 +137,9 @@ describe('AlfrescoSearchControlComponent', () => { it('should fire a search when a term has been entered', () => { spyOn(component.searchSubmit, 'emit'); alfrescoSearchControlComponentFixture.detectChanges(); - let formEl = element.querySelector('form'); + let formEl: HTMLElement = element.querySelector('form'); component.searchTerm = 'searchTerm1'; - component.searchControl.updateValue('searchTerm1'); + component.searchControl.setValue('searchTerm1', true); alfrescoSearchControlComponentFixture.detectChanges(); formEl.dispatchEvent(new Event('submit')); @@ -140,8 +153,8 @@ describe('AlfrescoSearchControlComponent', () => { it('should not fire a search when no term has been entered', () => { spyOn(component.searchSubmit, 'emit'); alfrescoSearchControlComponentFixture.detectChanges(); - let inputEl = element.querySelector('input[type="text"]'); - let formEl = element.querySelector('form'); + let inputEl: HTMLInputElement = element.querySelector('input[type="text"]'); + let formEl: HTMLElement = element.querySelector('form'); inputEl.value = ''; formEl.dispatchEvent(new Event('submit')); @@ -156,7 +169,7 @@ describe('AlfrescoSearchControlComponent', () => { it('should fire an event when the search box receives focus', () => { spyOn(component.expand, 'emit'); - let inputEl = element.querySelector('input'); + let inputEl: HTMLElement = element.querySelector('input'); inputEl.dispatchEvent(new Event('focus')); expect(component.expand.emit).toHaveBeenCalledWith({ expanded: true @@ -165,7 +178,7 @@ describe('AlfrescoSearchControlComponent', () => { it('should fire an event when the search box loses focus', () => { spyOn(component.expand, 'emit'); - let inputEl = element.querySelector('input'); + let inputEl: HTMLElement = element.querySelector('input'); inputEl.dispatchEvent(new Event('blur')); expect(component.expand.emit).toHaveBeenCalledWith({ expanded: false @@ -176,7 +189,7 @@ describe('AlfrescoSearchControlComponent', () => { () => { spyOn(component.expand, 'emit'); component.expandable = false; - let inputEl = element.querySelector('input'); + let inputEl: HTMLElement = element.querySelector('input'); inputEl.dispatchEvent(new Event('focus')); inputEl.dispatchEvent(new Event('blur')); expect(component.expand.emit).not.toHaveBeenCalled(); @@ -199,4 +212,3 @@ describe('AlfrescoSearchControlComponent', () => { }); }); -*/ diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.ts index 1432361a88..2737c2162a 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-control.component.ts @@ -16,7 +16,7 @@ */ import { FormControl, Validators } from '@angular/forms'; -import { Component, Input, Output, ElementRef, EventEmitter, ViewChild } from '@angular/core'; +import { Component, Input, Output, OnInit, OnChanges, SimpleChanges, ElementRef, EventEmitter, ViewChild } from '@angular/core'; import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { SearchTermValidator } from './../forms/search-term-validator'; @@ -28,7 +28,7 @@ declare let __moduleName: string; templateUrl: './alfresco-search-control.component.html', styleUrls: ['./alfresco-search-control.component.css'] }) -export class AlfrescoSearchControlComponent { +export class AlfrescoSearchControlComponent implements OnInit, OnChanges { @Input() searchTerm = ''; @@ -71,20 +71,31 @@ export class AlfrescoSearchControlComponent { this.searchTerm, Validators.compose([Validators.required, SearchTermValidator.minAlphanumericChars(3)]) ); + } + ngOnInit(): void { this.searchControl.valueChanges.map(value => this.searchControl.valid ? value : '') - .debounceTime(400).distinctUntilChanged().subscribe( - (value: string) => { - this.autocompleteSearchTerm = value; - this.searchValid = this.searchControl.valid; - this.searchChange.emit({ - value: value, - valid: this.searchValid - }); + .debounceTime(400).distinctUntilChanged().subscribe((value: string) => { + this.onSearchTermChange(value); } ); - translate.addTranslationFolder('node_modules/ng2-alfresco-search/dist/src'); + this.translate.addTranslationFolder('node_modules/ng2-alfresco-search/dist/src'); + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.hasOwnProperty('searchTerm')) { + this.searchControl.setValue(changes['searchTerm'].currentValue, true); + } + } + + private onSearchTermChange(value: string): void { + this.autocompleteSearchTerm = value; + this.searchValid = this.searchControl.valid; + this.searchChange.emit({ + value: value, + valid: this.searchValid + }); } getTextFieldClassName(): string {