diff --git a/demo-shell-ng2/app/components/search/search-bar.component.ts b/demo-shell-ng2/app/components/search/search-bar.component.ts index cb83bf6ce6..318bfb7877 100644 --- a/demo-shell-ng2/app/components/search/search-bar.component.ts +++ b/demo-shell-ng2/app/components/search/search-bar.component.ts @@ -32,6 +32,7 @@ export class SearchBarComponent { fileNodeId: string; fileShowed: boolean = false; + searchTerm: string = ''; @Output() expand = new EventEmitter(); @@ -50,6 +51,11 @@ export class SearchBarComponent { } } + searchTermChange(event) { + console.log('Search term changed', event); + this.searchTerm = event.value; + } + onExpandToggle(event) { this.expand.emit(event); } diff --git a/ng2-components/ng2-alfresco-search/README.md b/ng2-components/ng2-alfresco-search/README.md index 76bc2575c2..e1e6479985 100644 --- a/ng2-components/ng2-alfresco-search/README.md +++ b/ng2-components/ng2-alfresco-search/README.md @@ -220,7 +220,7 @@ Also make sure you include these dependencies in your .html page: ``` Example of an component that displays search results, using the Angular2 router to supply a 'q' parameter containing the -search term. If no ruter is present pon the page of if the router does not provide such a parameter then an empty +search term. If no router is present pon the page of if the router does not provide such a parameter then an empty results page will be shown. ```ts diff --git a/ng2-components/ng2-alfresco-search/src/assets/alfresco-search.service.mock.ts b/ng2-components/ng2-alfresco-search/src/assets/alfresco-search.service.mock.ts deleted file mode 100644 index 822ceae126..0000000000 --- a/ng2-components/ng2-alfresco-search/src/assets/alfresco-search.service.mock.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*! - * @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 { AlfrescoSearchService } from '../services/alfresco-search.service'; -import { Observable } from 'rxjs/Rx'; - -export class SearchServiceMock extends AlfrescoSearchService { - - getLiveSearchResults(term: string): Observable { - if (term.length > 3) { - return Observable.of({ - list: { - entries: [ - { - entry: { - id: '123', - name: 'MyDoc', - content: { - mimetype: 'text/plain' - }, - createdByUser: { - displayName: 'John Doe' - }, - modifiedByUser: { - displayName: 'John Doe' - } - } - } - ] - } - }); - } else { - return Observable.throw('Fake server error'); - } - } -} diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.html b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.html index a8ee356b98..c6d3011623 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.html +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search-autocomplete.component.html @@ -1,10 +1,25 @@ - +
- - - + + +
{{getMimeTypeKey(result)|translate}}
{{result.entry.name}}
{{result.entry.createdByUser.displayName}}
{{getMimeTypeKey(result)|translate}} +
{{result.entry.name}}
+
{{result.entry.createdByUser.displayName}}
+
-

{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}

+ + + + + + +
+
{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}
+
+

{{ 'SEARCH.RESULTS.ERROR' | + translate:{errorMessage: errorMessage} }}

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 f8da51679f..dd1474c155 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,34 +15,81 @@ * limitations under the License. */ -import { provide } from '@angular/core'; -import { it, describe, expect, inject, beforeEachProviders } from '@angular/core/testing'; +import { it, describe, expect, inject, beforeEachProviders, beforeEach, afterEach } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component'; -import { SearchServiceMock } from './../assets/alfresco-search.service.mock'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; +import { TranslationMock } from './../assets/translation.service.mock'; import { AlfrescoSearchService } from '../services/alfresco-search.service'; import { AlfrescoSettingsService, AlfrescoAuthenticationService, AlfrescoContentService, - AlfrescoTranslationService } from 'ng2-alfresco-core'; + AlfrescoTranslationService +} from 'ng2-alfresco-core'; + +declare let jasmine: any; describe('AlfrescoSearchAutocompleteComponent', () => { + let alfrescoSearchComponentFixture, element, component; + + let result = { + list: { + entries: [ + { + entry: { + id: '123', + name: 'MyDoc', + isFile : true, + content: { + mimetype: 'text/plain' + }, + createdByUser: { + displayName: 'John Doe' + }, + modifiedByUser: { + displayName: 'John Doe' + } + } + } + ] + } + }; + + let noResult = { + list: { + entries: [] + } + }; + beforeEachProviders(() => { return [ - provide(AlfrescoSearchService, {useClass: SearchServiceMock}), - provide(AlfrescoThumbnailService, {}), - provide(AlfrescoTranslationService, {}), - provide(AlfrescoSettingsService, {}), - provide(AlfrescoAuthenticationService, {}), - provide(AlfrescoContentService, {}) + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + AlfrescoThumbnailService, + AlfrescoSettingsService, + AlfrescoAuthenticationService, + AlfrescoContentService, + AlfrescoSearchService ]; }); - it('should setup i18n folder', () => { + beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + return tcb + .createAsync(AlfrescoSearchAutocompleteComponent) + .then(fixture => { + jasmine.Ajax.install(); + alfrescoSearchComponentFixture = fixture; + element = alfrescoSearchComponentFixture.nativeElement; + component = alfrescoSearchComponentFixture.componentInstance; + }); + })); + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('should setup i18n folder', () => { let translation = jasmine.createSpyObj('AlfrescoTranslationService', [ 'addTranslationFolder' ]); @@ -51,99 +98,87 @@ describe('AlfrescoSearchAutocompleteComponent', () => { }); - it('should display search results when a search term is provided', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchAutocompleteComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance, - searchTerm = 'customSearchTerm'; - spyOn(componentInstance, 'displaySearchResults').and.stub(); - componentInstance.searchTerm = searchTerm; - componentInstance.ngOnChanges({ - searchTerm: searchTerm - }); - fixture.detectChanges(); - expect(componentInstance.displaySearchResults).toHaveBeenCalledWith(searchTerm); + it('should display search results when a search term is provided', () => { + let searchTerm = 'customSearchTerm'; + spyOn(component, 'displaySearchResults').and.stub(); + component.searchTerm = searchTerm; + component.ngOnChanges({ + searchTerm: searchTerm + }); + alfrescoSearchComponentFixture.detectChanges(); + expect(component.displaySearchResults).toHaveBeenCalledWith(searchTerm); + }); - }); - })); + it('should display the returned search results', (done) => { + component.resultsEmitter.subscribe(x => { + alfrescoSearchComponentFixture.detectChanges(); + expect( element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); + expect( element.querySelector('#result_name_0').innerHTML).toBe('MyDoc'); + done(); + }); - it('should display the returned search results', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchAutocompleteComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance; - componentInstance.results = [{ - entry: { - id: '123', - name: 'MyDoc', - content: { - mimetype: 'text/plain' - }, - createdByUser: { - displayName: 'John Doe' - } - } - }]; - componentInstance.searchTerm = ''; - fixture.detectChanges(); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: component.searchTerm}); - let element = fixture.nativeElement; - expect(element.querySelectorAll('table tr').length).toBe(1); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: result + }); + }); - }); - })); + it('should display no result if no result are returned', (done) => { + component.resultsEmitter.subscribe(x => { + alfrescoSearchComponentFixture.detectChanges(); + expect( element.querySelector('#search_no_result')).not.toBe(null); + done(); + }); - it('should emit preview when file item clicked', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchAutocompleteComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance; - componentInstance.results = [{ - entry: { - id: '123', - name: 'MyDoc', - content: { - mimetype: 'text/plain' - }, - isFile: true - } - }]; - fixture.detectChanges(componentInstance.results[0]); - componentInstance.preview.subscribe(e => { - expect(e.value).toBe(componentInstance.results[0]); - }); - componentInstance.onItemClick(); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: component.searchTerm}); - }); - })); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: noResult + }); + }); - it('should not emit preview when non-file item clicked', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchAutocompleteComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance; - componentInstance.results = [{ - entry: { - id: '123', - name: 'MyDoc', - content: { - mimetype: 'text/plain' - }, - isFile: true - } - }]; - fixture.detectChanges(componentInstance.results[0]); - componentInstance.preview.subscribe(e => { - expect(e.value).toBe(componentInstance.results[0]); - }); - componentInstance.onItemClick(); + it('should emit preview when file item clicked', (done) => { + component.resultsEmitter.subscribe(x => { + alfrescoSearchComponentFixture.detectChanges(); + element.querySelector('#result_row_0').click(); + }); - }); - })); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: component.searchTerm}); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: result + }); + + component.preview.subscribe(e => { + done(); + }); + }); + + it('should not emit preview when non-file item is clicked', () => { + spyOn(component, 'onItemClick').and.stub(); + + component.ngOnChanges({searchTerm: 'searchTerm'}); + + component.preview.subscribe(e => { + expect(e.value).toBe(component.results[0]); + }); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: result + }); + + expect(component.onItemClick).not.toHaveBeenCalled(); + }); }); 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 cd6b6cca04..fbaa6cb23a 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 @@ -15,13 +15,7 @@ * limitations under the License. */ -import { - Component, - EventEmitter, - Input, - OnChanges, - Output -} from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; import { AlfrescoSearchService } from './../services/alfresco-search.service'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { AlfrescoPipeTranslate, AlfrescoTranslationService } from 'ng2-alfresco-core'; @@ -53,6 +47,9 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges { @Output() preview: EventEmitter = new EventEmitter(); + @Output() + resultsEmitter = new EventEmitter(); + constructor(private alfrescoSearchService: AlfrescoSearchService, private translate: AlfrescoTranslationService, private alfrescoThumbnailService: AlfrescoThumbnailService) { @@ -62,9 +59,9 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges { this.results = null; } - ngOnChanges(changes): void { + ngOnChanges(changes) { if (changes.searchTerm) { - this.displaySearchResults(this.searchTerm); + this.displaySearchResults(changes.searchTerm); } } @@ -80,6 +77,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges { results => { this.results = results.list.entries; this.errorMessage = null; + this.resultsEmitter.emit(this.results); }, error => { this.results = 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 050ebfb72c..daaa56deee 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 @@ -16,133 +16,97 @@ */ import { provide } from '@angular/core'; -import { it, describe, expect, inject, beforeEachProviders } from '@angular/core/testing'; +import { it, describe, expect, inject, beforeEachProviders, beforeEach } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; import { AlfrescoSearchControlComponent } from './alfresco-search-control.component'; -import { SearchServiceMock } from './../assets/alfresco-search.service.mock'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { TranslationMock } from './../assets/translation.service.mock'; -import { - AlfrescoSettingsService, - AlfrescoAuthenticationService, - AlfrescoContentService, - AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { AlfrescoSettingsService, AlfrescoAuthenticationService, AlfrescoContentService, AlfrescoTranslationService +} from 'ng2-alfresco-core'; import { AlfrescoSearchService } from '../services/alfresco-search.service'; describe('AlfrescoSearchControlComponent', () => { + let alfrescoSearchControlComponentFixture, element, component; + beforeEachProviders(() => { return [ - provide(AlfrescoSearchService, {useClass: SearchServiceMock}), - provide(AlfrescoThumbnailService, {}), + AlfrescoSearchService, provide(AlfrescoTranslationService, {useClass: TranslationMock}), - provide(AlfrescoSettingsService, {}), - provide(AlfrescoAuthenticationService, {}), - provide(AlfrescoContentService, {}) + AlfrescoThumbnailService, + AlfrescoSettingsService, + AlfrescoAuthenticationService, + AlfrescoContentService ]; }); - it('should setup i18n folder', () => { + beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + return tcb + .createAsync(AlfrescoSearchControlComponent) + .then(fixture => { + alfrescoSearchControlComponentFixture = fixture; + element = alfrescoSearchControlComponentFixture.nativeElement; + component = alfrescoSearchControlComponentFixture.componentInstance; + }); + })); + it('should setup i18n folder', () => { let translation = jasmine.createSpyObj('AlfrescoTranslationService', [ 'addTranslationFolder' ]); let alfrescoSearchControlComponent = new AlfrescoSearchControlComponent(translation); expect(alfrescoSearchControlComponent).toBeDefined(); - }); - it('should emit searchChange when search term changed', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchControlComponent) - .then((componentFixture) => { - componentFixture.componentInstance.searchTerm = 'customSearchTerm'; - componentFixture.detectChanges(); - componentFixture.componentInstance.searchChange.subscribe(e => { - expect(e.value).toBe('customSearchTerm'); - }); - }); - })); + it('should emit searchChange when search term changed', () => { + alfrescoSearchControlComponentFixture.componentInstance.searchTerm = 'customSearchTerm'; + alfrescoSearchControlComponentFixture.detectChanges(); + alfrescoSearchControlComponentFixture.componentInstance.searchChange.subscribe(e => { + expect(e.value).toBe('customSearchTerm'); + }); + }); describe('Component rendering', () => { - it('should display a text input field by default', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchControlComponent) - .then((componentFixture) => { - const element = componentFixture.nativeElement; - componentFixture.detectChanges(); - expect(element.querySelectorAll('input[type="text"]').length).toBe(1); - }); - }) - ); + it('should display a text input field by default', () => { + alfrescoSearchControlComponentFixture.detectChanges(); + expect(element.querySelectorAll('input[type="text"]').length).toBe(1); + }); - it('should display a search input field when specified', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(AlfrescoSearchControlComponent).then((componentFixture) => { - const element = componentFixture.nativeElement; - componentFixture.componentInstance.inputType = 'search'; - componentFixture.detectChanges(); - expect(element.querySelectorAll('input[type="search"]').length).toBe(1); - }); - })); + it('should display a search input field when specified', () => { + alfrescoSearchControlComponentFixture.componentInstance.inputType = 'search'; + alfrescoSearchControlComponentFixture.detectChanges(); + expect(element.querySelectorAll('input[type="search"]').length).toBe(1); + }); - it('should set browser autocomplete to off by default', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchControlComponent) - .then((componentFixture) => { - const element = componentFixture.nativeElement; - componentFixture.detectChanges(); - let attr = element.querySelectorAll('input[type="text"]')[0].getAttribute('autocomplete'); - expect(attr).toBe('off'); - }); - }) - ); + it('should set browser autocomplete to off by default', () => { + alfrescoSearchControlComponentFixture.detectChanges(); + let attr = element.querySelectorAll('input[type="text"]')[0].getAttribute('autocomplete'); + expect(attr).toBe('off'); + }); - it('should set browser autocomplete to on when configured', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(AlfrescoSearchControlComponent).then((componentFixture) => { - const element = componentFixture.nativeElement; - componentFixture.componentInstance.autocomplete = true; - componentFixture.detectChanges(); - expect(element.querySelectorAll('input[type="text"]')[0].getAttribute('autocomplete')) - .toBe('on'); - }); - })); + it('should set browser autocomplete to on when configured', () => { + alfrescoSearchControlComponentFixture.componentInstance.autocomplete = true; + alfrescoSearchControlComponentFixture.detectChanges(); + expect(element.querySelectorAll('input[type="text"]')[0].getAttribute('autocomplete')).toBe('on'); + }); - it('should show an expanding control by default', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchControlComponent) - .then((componentFixture) => { - const element = componentFixture.nativeElement; - componentFixture.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 an expanding control by default', () => { + alfrescoSearchControlComponentFixture.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', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchControlComponent) - .then((componentFixture) => { - const element = componentFixture.nativeElement; - componentFixture.detectChanges(); - componentFixture.componentInstance.expandable = false; - componentFixture.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); - }); - }) - ); + it('should show a normal non-expanding control when configured', () => { + alfrescoSearchControlComponentFixture.detectChanges(); + alfrescoSearchControlComponentFixture.componentInstance.expandable = false; + alfrescoSearchControlComponentFixture.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); + }); }); }); diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css new file mode 100644 index 0000000000..eb625a5c99 --- /dev/null +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.css @@ -0,0 +1,16 @@ +:host .mdl-data-table caption { + margin: 0 0 16px 0; + text-align: left; +} +:host .mdl-data-table td { + max-width: 0; + white-space: nowrap; +} +:host .mdl-data-table td.col-mimetype-icon { + width: 24px; +} +:host .col-display-name { + min-width: 250px; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html index ccbb929d3c..2c9fcc4a50 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.html @@ -1,4 +1,3 @@ -

{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}

@@ -17,16 +16,25 @@ - + - - +
{{ 'SEARCH.RESULTS.SUMMARY' | translate:{numResults: results.length, searchTerm: searchTerm} }}
{{getMimeTypeKey(result)|translate}}{{result.entry.name}} - {{result.entry.modifiedByUser.displayName}}{{result.entry.modifiedByUser.displayName}} {{result.entry.modifiedAt | date}}
+ + + + + + +
+
{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}
+

{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}

diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts index 1ec34f048e..d1ac7b7fa7 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.spec.ts @@ -15,11 +15,10 @@ * limitations under the License. */ -import { it, describe, expect, inject, beforeEachProviders } from '@angular/core/testing'; +import { it, describe, expect, inject, beforeEachProviders, beforeEach } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; import { RouteParams } from '@angular/router-deprecated'; import { AlfrescoSearchComponent } from './alfresco-search.component'; -import { SearchServiceMock } from './../assets/alfresco-search.service.mock'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { TranslationMock } from './../assets/translation.service.mock'; import { AlfrescoSearchService } from '../services/alfresco-search.service'; @@ -27,22 +26,70 @@ import { AlfrescoSettingsService, AlfrescoAuthenticationService, AlfrescoContentService, - AlfrescoTranslationService } from 'ng2-alfresco-core'; + AlfrescoTranslationService +} from 'ng2-alfresco-core'; + +declare let jasmine: any; describe('AlfrescoSearchComponent', () => { - beforeEachProviders(() => { + let alfrescoSearchComponentFixture, element, component; + let result = { + list: { + entries: [ + { + entry: { + id: '123', + name: 'MyDoc', + isFile : true, + content: { + mimetype: 'text/plain' + }, + createdByUser: { + displayName: 'John Doe' + }, + modifiedByUser: { + displayName: 'John Doe' + } + } + } + ] + } + }; + + let noResult = { + list: { + entries: [] + } + }; + + beforeEachProviders(() => { return [ - { provide: AlfrescoSearchService, useClass: SearchServiceMock }, - { provide: AlfrescoThumbnailService }, - { provide: AlfrescoTranslationService, useClass: TranslationMock }, - { provide: AlfrescoSettingsService }, - { provide: AlfrescoAuthenticationService }, - { provide: AlfrescoContentService } + AlfrescoSearchService, + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + AlfrescoThumbnailService, + AlfrescoSettingsService, + AlfrescoAuthenticationService, + AlfrescoContentService ]; }); + beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { + return tcb + .createAsync(AlfrescoSearchComponent) + .then(fixture => { + jasmine.Ajax.install(); + alfrescoSearchComponentFixture = fixture; + element = alfrescoSearchComponentFixture.nativeElement; + component = alfrescoSearchComponentFixture.componentInstance; + }); + })); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + it('should not have a search term by default', () => { let search = new AlfrescoSearchComponent(null, null, null, null); expect(search).toBeDefined(); @@ -50,7 +97,7 @@ describe('AlfrescoSearchComponent', () => { }); it('should take the provided search term from query param provided via RouteParams', () => { - let search = new AlfrescoSearchComponent(null, null, null, new RouteParams({ q: 'exampleTerm692' })); + let search = new AlfrescoSearchComponent(null, null, null, new RouteParams({q: 'exampleTerm692'})); expect(search.searchTerm).toBe('exampleTerm692'); }); @@ -72,72 +119,69 @@ describe('AlfrescoSearchComponent', () => { describe('Rendering search results', () => { - it('should display search results when a search term is provided', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .createAsync(AlfrescoSearchComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance, - searchTerm = 'customSearchTerm'; - spyOn(componentInstance, 'displaySearchResults').and.stub(); - componentInstance.searchTerm = searchTerm; - componentInstance.ngOnChanges(); - fixture.detectChanges(); - expect(componentInstance.displaySearchResults).toHaveBeenCalledWith(searchTerm); + it('should display search results when a search term is provided', (done) => { - }); - })); + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: component.searchTerm}); - it('should display the returned search results', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .overrideProviders(AlfrescoSearchComponent, [ - { provide: AlfrescoSearchService, useClass: SearchServiceMock } - ]) - .createAsync(AlfrescoSearchComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance; - componentInstance.searchTerm = ''; - componentInstance.ngOnChanges(); - fixture.detectChanges(); + component.resultsEmitter.subscribe(x => { + alfrescoSearchComponentFixture.detectChanges(); + expect( element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); + expect( element.querySelector('#result_name_0').innerHTML).toBe('MyDoc'); + done(); + }); - let element = fixture.nativeElement; - expect(element.querySelectorAll('table tbody tr').length).toBe(1); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: result + }); + }); - }); - })); + it('should display no result if no result are returned', (done) => { + component.resultsEmitter.subscribe(x => { + alfrescoSearchComponentFixture.detectChanges(); + expect( element.querySelector('#search_no_result')).not.toBe(null); + done(); + }); + + component.searchTerm = 'searchTerm'; + component.ngOnChanges({searchTerm: component.searchTerm}); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: noResult + }); + }); }); describe('search result actions', () => { - it('should emit preview when file item clicked', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .overrideProviders(AlfrescoSearchComponent, [ - { provide: AlfrescoSearchService, useClass: SearchServiceMock } - ]) - .createAsync(AlfrescoSearchComponent) - .then((fixture) => { - let componentInstance = fixture.componentInstance; - componentInstance.results = [{ - entry: { - id: '123', - name: 'MyDoc', - content: { - mimetype: 'text/plain' - }, - isFile: true - } - }]; - fixture.detectChanges(componentInstance.results[0]); - componentInstance.preview.subscribe(e => { - expect(e.value).toBe(componentInstance.results[0]); - }); - componentInstance.onItemClick(); + it('should emit preview when file item clicked', () => { + component.results = [{ + entry: { + id: '123', + name: 'MyDoc', + content: { + mimetype: 'text/plain' + }, + isFile: true + } + }]; - }); - })); + alfrescoSearchComponentFixture.detectChanges(component.results[0]); + component.preview.subscribe(e => { + expect(e.value).toBe(component.results[0]); + }); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'text/plain', + responseText: '
' + }); + }); }); }); diff --git a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts index 3fc41ab0b7..2a4884a315 100644 --- a/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts +++ b/ng2-components/ng2-alfresco-search/src/components/alfresco-search.component.ts @@ -26,24 +26,7 @@ declare let __moduleName: string; @Component({ moduleId: __moduleName, selector: 'alfresco-search', - styles: [` - :host .mdl-data-table caption { - margin: 0 0 16px 0; - text-align: left; - } - :host .mdl-data-table td { - max-width: 0; - white-space: nowrap; - } - :host .mdl-data-table td.col-mimetype-icon { - width: 24px; - } - :host .col-display-name { - min-width: 250px; - overflow: hidden; - text-overflow: ellipsis; - } - `], + styleUrls: ['./alfresco-search.component.css'], templateUrl: './alfresco-search.component.html', providers: [AlfrescoSearchService], pipes: [AlfrescoPipeTranslate] @@ -58,6 +41,9 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { @Output() preview: EventEmitter = new EventEmitter(); + @Output() + resultsEmitter = new EventEmitter(); + results: any; errorMessage; @@ -84,7 +70,9 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { } ngOnChanges(changes): void { - this.displaySearchResults(this.searchTerm); + if (changes.searchTerm) { + this.displaySearchResults(changes.searchTerm); + } } /** @@ -123,6 +111,7 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit { .subscribe( results => { this.results = results.list.entries; + this.resultsEmitter.emit(this.results); this.errorMessage = null; }, error => {