mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
Merge pull request #276 from Alfresco/dev-wabson-190
Add meaningful tests for search component
This commit is contained in:
commit
68f67bef19
@ -54,6 +54,21 @@ System.config(config);
|
|||||||
|
|
||||||
System.import('@angular/platform-browser/src/browser/browser_adapter')
|
System.import('@angular/platform-browser/src/browser/browser_adapter')
|
||||||
.then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
|
.then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
|
||||||
|
.then(function () {
|
||||||
|
return Promise.all([
|
||||||
|
System.import('@angular/core/testing'),
|
||||||
|
System.import('@angular/platform-browser-dynamic/testing')
|
||||||
|
])
|
||||||
|
})
|
||||||
|
.then(function (providers) {
|
||||||
|
var testing = providers[0];
|
||||||
|
var testingBrowser = providers[1];
|
||||||
|
|
||||||
|
testing.setBaseTestProviders(
|
||||||
|
testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
|
||||||
|
testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
|
||||||
|
|
||||||
|
})
|
||||||
.then(function() { return Promise.all(resolveTestFiles()); })
|
.then(function() { return Promise.all(resolveTestFiles()); })
|
||||||
.then(
|
.then(
|
||||||
function() {
|
function() {
|
||||||
|
@ -15,6 +15,9 @@ module.exports = function (config) {
|
|||||||
{pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
|
{pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
|
||||||
{pattern: 'node_modules/@angular/**/*.map', included: false, watched: false},
|
{pattern: 'node_modules/@angular/**/*.map', included: false, watched: false},
|
||||||
|
|
||||||
|
{pattern: 'node_modules/material-design-lite/material.min.js', included: true, watched: false},
|
||||||
|
{pattern: 'node_modules/alfresco-js-api/bundle.js', included: true, watched: false},
|
||||||
|
|
||||||
{pattern: 'node_modules/ng2-alfresco-core/dist/**/*.js', included: false, served: true, watched: false},
|
{pattern: 'node_modules/ng2-alfresco-core/dist/**/*.js', included: false, served: true, watched: false},
|
||||||
{pattern: 'node_modules/ng2-translate/**/*.js', included: false, served: true, watched: false},
|
{pattern: 'node_modules/ng2-translate/**/*.js', included: false, served: true, watched: false},
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@
|
|||||||
"alfresco-js-api": "^0.1.0",
|
"alfresco-js-api": "^0.1.0",
|
||||||
"ng2-alfresco-core": "^0.1.25",
|
"ng2-alfresco-core": "^0.1.25",
|
||||||
"ng2-translate": "2.2.0",
|
"ng2-translate": "2.2.0",
|
||||||
"rimraf": "^2.5.2"
|
"rimraf": "^2.5.2",
|
||||||
|
"material-design-lite": "^1.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^2.1.0",
|
"concurrently": "^2.1.0",
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
/*!
|
||||||
|
* @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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,8 +19,7 @@ import {Observable} from 'rxjs/Rx';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AlfrescoSettingsService,
|
AlfrescoSettingsService,
|
||||||
AlfrescoAuthenticationService,
|
AlfrescoAuthenticationService
|
||||||
AlfrescoContentService
|
|
||||||
} from 'ng2-alfresco-core';
|
} from 'ng2-alfresco-core';
|
||||||
import {AlfrescoSearchService} from './../../src/services/alfresco-search.service';
|
import {AlfrescoSearchService} from './../../src/services/alfresco-search.service';
|
||||||
|
|
||||||
@ -30,10 +29,9 @@ export class AlfrescoServiceMock extends AlfrescoSearchService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
settings: AlfrescoSettingsService = null,
|
settings: AlfrescoSettingsService = null,
|
||||||
authService: AlfrescoAuthenticationService = null,
|
authService: AlfrescoAuthenticationService = null
|
||||||
contentService: AlfrescoContentService = null
|
|
||||||
) {
|
) {
|
||||||
super(settings, authService, contentService);
|
super(settings, authService);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFolder(folder: string) {
|
getFolder(folder: string) {
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*!
|
||||||
|
* @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 { Observable } from 'rxjs/Rx';
|
||||||
|
import { EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
|
export interface LangChangeEvent {
|
||||||
|
lang: string;
|
||||||
|
translations: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TranslationMock {
|
||||||
|
|
||||||
|
public onLangChange: EventEmitter<LangChangeEvent> = new EventEmitter<LangChangeEvent>();
|
||||||
|
|
||||||
|
public get(key: string|Array<string>, interpolateParams?: Object): Observable<string|any> {
|
||||||
|
return Observable.of(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
addTranslationFolder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<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>
|
<tbody>
|
||||||
<tr *ngFor="let result of results; let idx = index" (click)="_onItemClick(result, $event)"
|
<tr *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)"
|
||||||
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}" >
|
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}" >
|
||||||
<td class="img-td"><img src="{{_getMimeTypeIcon(result)}}" /></td>
|
<td class="img-td"><img src="{{_getMimeTypeIcon(result)}}" /></td>
|
||||||
<td><div class="truncate" ><b>{{result.entry.name}}</b></div><div class="truncate">{{result.entry.createdByUser.displayName}}</div></td>
|
<td><div class="truncate" ><b>{{result.entry.name}}</b></div><div class="truncate">{{result.entry.createdByUser.displayName}}</div></td>
|
||||||
|
@ -15,11 +15,32 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { it, describe } from '@angular/core/testing';
|
import { provide } from '@angular/core';
|
||||||
|
import { it, describe, expect, inject, beforeEachProviders } from '@angular/core/testing';
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component';
|
import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component';
|
||||||
|
import { SearchServiceMock } from './../assets/alfresco-search.service.mock';
|
||||||
|
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
||||||
|
import { AlfrescoSearchService } from '../services/alfresco-search.service';
|
||||||
|
import {
|
||||||
|
AlfrescoSettingsService,
|
||||||
|
AlfrescoAuthenticationService,
|
||||||
|
AlfrescoContentService,
|
||||||
|
AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
describe('AlfrescoSearchAutocompleteComponent', () => {
|
describe('AlfrescoSearchAutocompleteComponent', () => {
|
||||||
|
|
||||||
|
beforeEachProviders(() => {
|
||||||
|
return [
|
||||||
|
provide(AlfrescoSearchService, {useClass: SearchServiceMock}),
|
||||||
|
provide(AlfrescoThumbnailService, {}),
|
||||||
|
provide(AlfrescoTranslationService, {}),
|
||||||
|
provide(AlfrescoSettingsService, {}),
|
||||||
|
provide(AlfrescoAuthenticationService, {}),
|
||||||
|
provide(AlfrescoContentService, {})
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
it('should setup i18n folder', () => {
|
it('should setup i18n folder', () => {
|
||||||
|
|
||||||
let translation = jasmine.createSpyObj('AlfrescoTranslationService', [
|
let translation = jasmine.createSpyObj('AlfrescoTranslationService', [
|
||||||
@ -30,4 +51,99 @@ 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 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 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();
|
||||||
|
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -56,13 +56,15 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges {
|
|||||||
constructor(private _alfrescoSearchService: AlfrescoSearchService,
|
constructor(private _alfrescoSearchService: AlfrescoSearchService,
|
||||||
private translate: AlfrescoTranslationService,
|
private translate: AlfrescoTranslationService,
|
||||||
private _alfrescoThumbnailService: AlfrescoThumbnailService) {
|
private _alfrescoThumbnailService: AlfrescoThumbnailService) {
|
||||||
|
if (translate) {
|
||||||
translate.addTranslationFolder('node_modules/ng2-alfresco-search');
|
translate.addTranslationFolder('node_modules/ng2-alfresco-search');
|
||||||
|
}
|
||||||
this.results = null;
|
this.results = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes): void {
|
ngOnChanges(changes): void {
|
||||||
if (changes.searchTerm) {
|
if (changes.searchTerm) {
|
||||||
this._displaySearchResults(this.searchTerm);
|
this.displaySearchResults(this.searchTerm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +72,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges {
|
|||||||
* Loads and displays search results
|
* Loads and displays search results
|
||||||
* @param searchTerm Search query entered by user
|
* @param searchTerm Search query entered by user
|
||||||
*/
|
*/
|
||||||
private _displaySearchResults(searchTerm) {
|
public displaySearchResults(searchTerm) {
|
||||||
if (searchTerm !== null && searchTerm !== '') {
|
if (searchTerm !== null && searchTerm !== '') {
|
||||||
this._alfrescoSearchService
|
this._alfrescoSearchService
|
||||||
.getLiveSearchResults(searchTerm)
|
.getLiveSearchResults(searchTerm)
|
||||||
@ -99,7 +101,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onItemClick(node, event?: Event): void {
|
onItemClick(node, event?: Event): void {
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
<form (submit)="_onSearch($event)">
|
<form (submit)="onSearch($event)">
|
||||||
<div [class]="_getTextFieldClassName()">
|
<div [class]="getTextFieldClassName()">
|
||||||
<label *ngIf="expandable" class="mdl-button mdl-js-button mdl-button--icon" for="searchControl">
|
<label *ngIf="expandable" class="mdl-button mdl-js-button mdl-button--icon" for="searchControl">
|
||||||
<i class="material-icons">search</i>
|
<i class="material-icons">search</i>
|
||||||
</label>
|
</label>
|
||||||
<div [class]="_getTextFieldHolderClassName()">
|
<div [class]="getTextFieldHolderClassName()">
|
||||||
<input class="mdl-textfield__input" [type]="inputType" [autocomplete]="_getAutoComplete()" data-automation-id="search_input"
|
<input class="mdl-textfield__input" [type]="inputType" [autocomplete]="getAutoComplete()" data-automation-id="search_input"
|
||||||
id="searchControl" [ngFormControl]="searchControl" [(ngModel)]="searchTerm" (focus)="_onFocus($event)"
|
id="searchControl" [ngFormControl]="searchControl" [(ngModel)]="searchTerm" (focus)="onFocus($event)"
|
||||||
(blur)="_onBlur($event)">
|
(blur)="onBlur($event)">
|
||||||
<label class="mdl-textfield__label" for="searchControl">{{'SEARCH.CONTROL.LABEL' | translate}}</label>
|
<label class="mdl-textfield__label" for="searchControl">{{'SEARCH.CONTROL.LABEL' | translate}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<alfresco-search-autocomplete [searchTerm]="autocompleteSearchTerm" [ngClass]="{active: searchActive, valid: searchValid}"
|
<alfresco-search-autocomplete [searchTerm]="autocompleteSearchTerm" [ngClass]="{active: searchActive, valid: searchValid}"
|
||||||
(preview)="_onFileClicked($event)"></alfresco-search-autocomplete>
|
(preview)="onFileClicked($event)"></alfresco-search-autocomplete>
|
||||||
|
@ -15,11 +15,34 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { it, describe } from '@angular/core/testing';
|
import { provide } from '@angular/core';
|
||||||
|
import { it, describe, expect, inject, beforeEachProviders } from '@angular/core/testing';
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
import { AlfrescoSearchControlComponent } from './alfresco-search-control.component';
|
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 { AlfrescoSearchService } from '../services/alfresco-search.service';
|
||||||
|
|
||||||
|
|
||||||
describe('AlfrescoSearchControlComponent', () => {
|
describe('AlfrescoSearchControlComponent', () => {
|
||||||
|
|
||||||
|
beforeEachProviders(() => {
|
||||||
|
return [
|
||||||
|
provide(AlfrescoSearchService, {useClass: SearchServiceMock}),
|
||||||
|
provide(AlfrescoThumbnailService, {}),
|
||||||
|
provide(AlfrescoTranslationService, {useClass: TranslationMock}),
|
||||||
|
provide(AlfrescoSettingsService, {}),
|
||||||
|
provide(AlfrescoAuthenticationService, {}),
|
||||||
|
provide(AlfrescoContentService, {})
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
it('should setup i18n folder', () => {
|
it('should setup i18n folder', () => {
|
||||||
|
|
||||||
let translation = jasmine.createSpyObj('AlfrescoTranslationService', [
|
let translation = jasmine.createSpyObj('AlfrescoTranslationService', [
|
||||||
@ -30,4 +53,96 @@ describe('AlfrescoSearchControlComponent', () => {
|
|||||||
expect(alfrescoSearchControlComponent).toBeDefined();
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
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 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 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 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 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 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);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -86,15 +86,15 @@ export class AlfrescoSearchControlComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTextFieldClassName(): string {
|
getTextFieldClassName(): string {
|
||||||
return 'mdl-textfield mdl-js-textfield' + (this.expandable ? ' mdl-textfield--expandable' : '');
|
return 'mdl-textfield mdl-js-textfield' + (this.expandable ? ' mdl-textfield--expandable' : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTextFieldHolderClassName(): string {
|
getTextFieldHolderClassName(): string {
|
||||||
return this.expandable ? 'search-field mdl-textfield__expandable-holder' : 'search-field';
|
return this.expandable ? 'search-field mdl-textfield__expandable-holder' : 'search-field';
|
||||||
}
|
}
|
||||||
|
|
||||||
_getAutoComplete(): string {
|
getAutoComplete(): string {
|
||||||
return this.autocomplete ? 'on' : 'off';
|
return this.autocomplete ? 'on' : 'off';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ export class AlfrescoSearchControlComponent implements AfterViewInit {
|
|||||||
*
|
*
|
||||||
* @param event Submit event that was fired
|
* @param event Submit event that was fired
|
||||||
*/
|
*/
|
||||||
_onSearch(event): void {
|
onSearch(event): void {
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
@ -115,17 +115,17 @@ export class AlfrescoSearchControlComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onFileClicked(event): void {
|
onFileClicked(event): void {
|
||||||
this.preview.emit({
|
this.preview.emit({
|
||||||
value: event.value
|
value: event.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_onFocus(): void {
|
onFocus(): void {
|
||||||
this.searchActive = true;
|
this.searchActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onBlur(): void {
|
onBlur(): void {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
this.searchActive = false;
|
this.searchActive = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<tr *ngFor="let result of results; let idx = index">
|
<tr *ngFor="let result of results; let idx = index">
|
||||||
<td><img src="{{_getMimeTypeIcon(result)}}" /></td>
|
<td><img src="{{getMimeTypeIcon(result)}}" /></td>
|
||||||
<td attr.data-automation-id=file_{{result.entry.name}} >{{result.entry.name}}</td>
|
<td attr.data-automation-id=file_{{result.entry.name}} >{{result.entry.name}}</td>
|
||||||
<td attr.data-automation-id=file_{{result.entry.name}}_{{result.entry.modifiedByUser.displayName}} >{{result.entry.modifiedByUser
|
<td attr.data-automation-id=file_{{result.entry.name}}_{{result.entry.modifiedByUser.displayName}}>
|
||||||
.displayName}}</td>
|
{{result.entry.modifiedByUser.displayName}}</td>
|
||||||
<td>{{result.entry.modifiedAt | date}}</td>
|
<td>{{result.entry.modifiedAt | date}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -15,11 +15,50 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { it, describe } from '@angular/core/testing';
|
import { it, describe, expect, inject, beforeEachProviders } from '@angular/core/testing';
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
import { RouteParams } from '@angular/router-deprecated';
|
||||||
import { AlfrescoSearchComponent } from './alfresco-search.component';
|
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';
|
||||||
|
import {
|
||||||
|
AlfrescoSettingsService,
|
||||||
|
AlfrescoAuthenticationService,
|
||||||
|
AlfrescoContentService,
|
||||||
|
AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
describe('AlfrescoSearchComponent', () => {
|
describe('AlfrescoSearchComponent', () => {
|
||||||
|
|
||||||
|
beforeEachProviders(() => {
|
||||||
|
|
||||||
|
return [
|
||||||
|
{ provide: AlfrescoSearchService, useClass: SearchServiceMock },
|
||||||
|
{ provide: AlfrescoThumbnailService },
|
||||||
|
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||||
|
{ provide: AlfrescoSettingsService },
|
||||||
|
{ provide: AlfrescoAuthenticationService },
|
||||||
|
{ provide: AlfrescoContentService }
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not have a search term by default', () => {
|
||||||
|
let search = new AlfrescoSearchComponent(null, null, null, null);
|
||||||
|
expect(search).toBeDefined();
|
||||||
|
expect(search.searchTerm).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should take the provided search term from query param provided via RouteParams', () => {
|
||||||
|
let search = new AlfrescoSearchComponent(null, null, null, new RouteParams({ q: 'exampleTerm692' }));
|
||||||
|
expect(search.searchTerm).toBe('exampleTerm692');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a null search term if no query param provided via RouteParams', () => {
|
||||||
|
let search = new AlfrescoSearchComponent(null, null, null, new RouteParams({}));
|
||||||
|
expect(search.searchTerm).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
it('should setup i18n folder', () => {
|
it('should setup i18n folder', () => {
|
||||||
|
|
||||||
let translation = jasmine.createSpyObj('AlfrescoTranslationService', [
|
let translation = jasmine.createSpyObj('AlfrescoTranslationService', [
|
||||||
@ -31,4 +70,43 @@ describe('AlfrescoSearchComponent', () => {
|
|||||||
expect(translation.addTranslationFolder).toHaveBeenCalledWith('node_modules/ng2-alfresco-search');
|
expect(translation.addTranslationFolder).toHaveBeenCalledWith('node_modules/ng2-alfresco-search');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 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);
|
||||||
|
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -48,7 +48,10 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
|||||||
private translate: AlfrescoTranslationService,
|
private translate: AlfrescoTranslationService,
|
||||||
private _alfrescoThumbnailService: AlfrescoThumbnailService,
|
private _alfrescoThumbnailService: AlfrescoThumbnailService,
|
||||||
@Optional() params: RouteParams) {
|
@Optional() params: RouteParams) {
|
||||||
|
|
||||||
|
if (translate !== null) {
|
||||||
translate.addTranslationFolder('node_modules/ng2-alfresco-search');
|
translate.addTranslationFolder('node_modules/ng2-alfresco-search');
|
||||||
|
}
|
||||||
|
|
||||||
this.results = null;
|
this.results = null;
|
||||||
if (params) {
|
if (params) {
|
||||||
@ -57,11 +60,11 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this._displaySearchResults(this.searchTerm);
|
this.displaySearchResults(this.searchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes): void {
|
ngOnChanges(changes): void {
|
||||||
this._displaySearchResults(this.searchTerm);
|
this.displaySearchResults(this.searchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +72,7 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
|||||||
* @param node Node to get URL for.
|
* @param node Node to get URL for.
|
||||||
* @returns {string} URL address.
|
* @returns {string} URL address.
|
||||||
*/
|
*/
|
||||||
_getMimeTypeIcon(node: any): string {
|
getMimeTypeIcon(node: any): string {
|
||||||
if (node.entry.content && node.entry.content.mimeType) {
|
if (node.entry.content && node.entry.content.mimeType) {
|
||||||
let icon = this._alfrescoThumbnailService.getMimeTypeIcon(node.entry.content.mimeType);
|
let icon = this._alfrescoThumbnailService.getMimeTypeIcon(node.entry.content.mimeType);
|
||||||
return `${this.baseComponentPath}/img/${icon}`;
|
return `${this.baseComponentPath}/img/${icon}`;
|
||||||
@ -80,7 +83,7 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
|||||||
* Loads and displays search results
|
* Loads and displays search results
|
||||||
* @param searchTerm Search query entered by user
|
* @param searchTerm Search query entered by user
|
||||||
*/
|
*/
|
||||||
private _displaySearchResults(searchTerm): void {
|
public displaySearchResults(searchTerm): void {
|
||||||
if (searchTerm !== null) {
|
if (searchTerm !== null) {
|
||||||
this._alfrescoSearchService
|
this._alfrescoSearchService
|
||||||
.getLiveSearchResults(searchTerm)
|
.getLiveSearchResults(searchTerm)
|
||||||
|
@ -26,6 +26,6 @@ describe('AlfrescoSearchService', () => {
|
|||||||
let service: AlfrescoSearchService;
|
let service: AlfrescoSearchService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = new AlfrescoSearchService(null, null, null);
|
service = new AlfrescoSearchService(null, null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -20,8 +20,7 @@ import { Observable } from 'rxjs/Rx';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AlfrescoSettingsService,
|
AlfrescoSettingsService,
|
||||||
AlfrescoAuthenticationService,
|
AlfrescoAuthenticationService
|
||||||
AlfrescoContentService
|
|
||||||
} from 'ng2-alfresco-core';
|
} from 'ng2-alfresco-core';
|
||||||
|
|
||||||
declare let AlfrescoApi: any;
|
declare let AlfrescoApi: any;
|
||||||
@ -33,8 +32,7 @@ declare let AlfrescoApi: any;
|
|||||||
export class AlfrescoSearchService {
|
export class AlfrescoSearchService {
|
||||||
|
|
||||||
constructor(private settings: AlfrescoSettingsService,
|
constructor(private settings: AlfrescoSettingsService,
|
||||||
private authService: AlfrescoAuthenticationService,
|
private authService: AlfrescoAuthenticationService) {
|
||||||
private contentService: AlfrescoContentService) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getAlfrescoClient() {
|
private getAlfrescoClient() {
|
||||||
|
@ -28,4 +28,21 @@ describe('AlfrescoThumbnailService', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = new AlfrescoThumbnailService(null);
|
service = new AlfrescoThumbnailService(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return the correct icon for a plain text file', () => {
|
||||||
|
expect(service.getMimeTypeIcon('text/plain')).toBe('ft_ic_document.svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the correct icon for a PNG file', () => {
|
||||||
|
expect(service.getMimeTypeIcon('image/png')).toBe('ft_ic_raster_image.svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the correct icon for a MP4 video file', () => {
|
||||||
|
expect(service.getMimeTypeIcon('video/mp4')).toBe('ft_ic_video.svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a generic icon for an unknown file', () => {
|
||||||
|
expect(service.getMimeTypeIcon('x-unknown/yyy')).toBe('ft_ic_miscellaneous.svg');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user