mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
fix no result and refactoring tests
This commit is contained in:
parent
ef37150902
commit
0c253ffdf0
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<any> {
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,25 @@
|
||||
<table data-automation-id="autocomplete_results" *ngIf="results && results.length && searchTerm" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||
<table data-automation-id="autocomplete_results" *ngIf="results && results.length && searchTerm"
|
||||
class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||
<tbody>
|
||||
<tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)"
|
||||
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}" >
|
||||
<td class="img-td"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}" /></td>
|
||||
<td><div class="truncate" ><b>{{result.entry.name}}</b></div><div class="truncate">{{result.entry.createdByUser.displayName}}</div></td>
|
||||
<tr id="result_row_{{idx}}" *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)"
|
||||
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}">
|
||||
<td class="img-td"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}"/></td>
|
||||
<td>
|
||||
<div id="result_name_{{idx}}" class="truncate"><b>{{result.entry.name}}</b></div>
|
||||
<div id="result_user_{{idx}}" class="truncate">{{result.entry.createdByUser.displayName}}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p data-automation-id="autocomplete_error_message" *ngIf="errorMessage">{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}</p>
|
||||
<table id="search_no_result" data-automation-id="search_no_result_found" *ngIf="results && results.length === 0"
|
||||
class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="truncate"><b> {{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</b></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p data-automation-id="autocomplete_error_message" *ngIf="errorMessage">{{ 'SEARCH.RESULTS.ERROR' |
|
||||
translate:{errorMessage: errorMessage} }}</p>
|
||||
|
@ -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({
|
||||
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
|
||||
});
|
||||
fixture.detectChanges();
|
||||
expect(componentInstance.displaySearchResults).toHaveBeenCalledWith(searchTerm);
|
||||
|
||||
alfrescoSearchComponentFixture.detectChanges();
|
||||
expect(component.displaySearchResults).toHaveBeenCalledWith(searchTerm);
|
||||
});
|
||||
}));
|
||||
|
||||
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 = '<term>';
|
||||
fixture.detectChanges();
|
||||
|
||||
let element = fixture.nativeElement;
|
||||
expect(element.querySelectorAll('table tr').length).toBe(1);
|
||||
|
||||
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('<b _ngcontent-a-1="">MyDoc</b>');
|
||||
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]);
|
||||
component.searchTerm = 'searchTerm';
|
||||
component.ngOnChanges({searchTerm: component.searchTerm});
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
contentType: 'json',
|
||||
responseText: result
|
||||
});
|
||||
componentInstance.onItemClick();
|
||||
|
||||
});
|
||||
}));
|
||||
|
||||
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]);
|
||||
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();
|
||||
});
|
||||
componentInstance.onItemClick();
|
||||
|
||||
component.searchTerm = 'searchTerm';
|
||||
component.ngOnChanges({searchTerm: component.searchTerm});
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
contentType: 'json',
|
||||
responseText: noResult
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
@ -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<any> = 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;
|
||||
|
@ -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 => {
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
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);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
<p data-automation-id="search_no_result_found" *ngIf="results&& results.length == 0">{{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</p>
|
||||
<table data-automation-id="search_result_table" *ngIf="results && results.length && searchTerm" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||
<caption data-automation-id="search_result_found">{{ 'SEARCH.RESULTS.SUMMARY' | translate:{numResults: results.length, searchTerm: searchTerm} }}</caption>
|
||||
<thead>
|
||||
@ -17,16 +16,25 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)">
|
||||
<tr id="result_row_{{idx}}" *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)">
|
||||
<td class="col-mimetype-icon"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}" /></td>
|
||||
<td class="mdl-data-table__cell--non-numeric col-display-name"
|
||||
<td id="result_name_{{idx}}" class="mdl-data-table__cell--non-numeric col-display-name"
|
||||
attr.data-automation-id=file_{{result.entry.name}} >{{result.entry.name}}</td>
|
||||
<td class="mdl-data-table__cell--non-numeric col-modified-by"
|
||||
attr.data-automation-id=file_{{result.entry.name}}_{{result.entry.modifiedByUser.displayName}}>
|
||||
{{result.entry.modifiedByUser.displayName}}</td>
|
||||
<td id="result_user_{{idx}}" class="mdl-data-table__cell--non-numeric col-modified-by"
|
||||
attr.data-automation-id=file_{{result.entry.name}}_{{result.entry.modifiedByUser.displayName}}>{{result.entry.modifiedByUser.displayName}}</td>
|
||||
<td class="col-modified-at">{{result.entry.modifiedAt | date}}</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<table id="search_no_result" data-automation-id="search_no_result_found" *ngIf="results && results.length === 0"
|
||||
class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="truncate"><b> {{ 'SEARCH.RESULTS.NONE' | translate:{searchTerm: searchTerm} }}</b></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p data-automation-id="search_error_message" *ngIf="errorMessage">{{ 'SEARCH.RESULTS.ERROR' | translate:{errorMessage: errorMessage} }}</p>
|
||||
|
@ -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,55 +119,48 @@ 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});
|
||||
|
||||
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
|
||||
.overrideProviders(AlfrescoSearchComponent, [
|
||||
{ provide: AlfrescoSearchService, useClass: SearchServiceMock }
|
||||
])
|
||||
.createAsync(AlfrescoSearchComponent)
|
||||
.then((fixture) => {
|
||||
let componentInstance = fixture.componentInstance;
|
||||
componentInstance.searchTerm = '<term>';
|
||||
componentInstance.ngOnChanges();
|
||||
fixture.detectChanges();
|
||||
|
||||
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 = [{
|
||||
it('should emit preview when file item clicked', () => {
|
||||
component.results = [{
|
||||
entry: {
|
||||
id: '123',
|
||||
name: 'MyDoc',
|
||||
@ -130,14 +170,18 @@ describe('AlfrescoSearchComponent', () => {
|
||||
isFile: true
|
||||
}
|
||||
}];
|
||||
fixture.detectChanges(componentInstance.results[0]);
|
||||
componentInstance.preview.subscribe(e => {
|
||||
expect(e.value).toBe(componentInstance.results[0]);
|
||||
});
|
||||
componentInstance.onItemClick();
|
||||
|
||||
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: '<div></div>'
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -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<any> = 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 => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user