test fixes

This commit is contained in:
Lotte Hofstede
2018-03-15 16:15:02 +01:00
parent e374f9ec1f
commit 6c2a249fdd
11 changed files with 164 additions and 100 deletions

View File

@@ -51,7 +51,7 @@ module.exports = function (config) {
*/ */
files: [{ files: [{
pattern: './spec-bundle.js', pattern: './spec-bundle.js',
watched: false watched: false,
}], }],
/* /*

View File

@@ -10,59 +10,111 @@ import { ViewMode } from '../../+search-page/search-options.model';
import { RouteService } from '../../shared/route.service'; import { RouteService } from '../../shared/route.service';
import { GLOBAL_CONFIG } from '../../../config'; import { GLOBAL_CONFIG } from '../../../config';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { RequestService } from '../../core/data/request.service'; import { RequestService } from '../../core/data/request.service';
import { ResponseCacheService } from '../../core/cache/response-cache.service'; import { ResponseCacheService } from '../../core/cache/response-cache.service';
import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; import { ActivatedRouteStub } from '../../shared/testing/active-router-stub';
import { RouterStub } from '../../shared/testing/router-stub';
@Component({ template: '' }) @Component({ template: '' })
class DummyComponent { } class DummyComponent {
}
describe('SearchService', () => { describe('SearchService', () => {
let searchService: SearchService; describe('By default', () => {
let searchService: SearchService;
beforeEach(() => { const router = new RouterStub();
TestBed.configureTestingModule({ const route = new ActivatedRouteStub();
imports: [ beforeEach(() => {
CommonModule, TestBed.configureTestingModule({
RouterTestingModule.withRoutes([ imports: [
{ path: 'search', component: DummyComponent, pathMatch: 'full' }, CommonModule,
]) RouterTestingModule.withRoutes([
], { path: 'search', component: DummyComponent, pathMatch: 'full' },
declarations: [ ])
DummyComponent ],
], declarations: [
providers: [ DummyComponent
{ provide: ItemDataService, useValue: {} }, ],
{ provide: RouteService, useValue: {} }, providers: [
{ provide: ResponseCacheService, useValue: {} }, { provide: ItemDataService, useValue: {} },
{ provide: RequestService, useValue: {} }, { provide: RouteService, useValue: {} },
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() }, { provide: ResponseCacheService, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} }, { provide: RequestService, useValue: {} },
{ provide: GLOBAL_CONFIG, useValue: {} }, { provide: ActivatedRoute, useValue: route },
SearchService { provide: RemoteDataBuildService, useValue: {} },
], { provide: GLOBAL_CONFIG, useValue: {} },
{ provide: Router, useValue: router },
SearchService
],
});
searchService = TestBed.get(SearchService);
}); });
searchService = TestBed.get(SearchService);
});
it('should return list view mode by default', () => { it('should return list view mode', () => {
searchService.getViewMode().subscribe((viewMode) => { searchService.getViewMode().subscribe((viewMode) => {
expect(viewMode).toBe(ViewMode.List); expect(viewMode).toBe(ViewMode.List);
});
}); });
}); });
describe('', () => {
let searchService: SearchService;
const router = new RouterStub();
const route = new ActivatedRouteStub();
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
CommonModule,
RouterTestingModule.withRoutes([
{ path: 'search', component: DummyComponent, pathMatch: 'full' },
])
],
declarations: [
DummyComponent
],
providers: [
{ provide: ItemDataService, useValue: {} },
{ provide: RouteService, useValue: {} },
{ provide: ResponseCacheService, useValue: {} },
{ provide: RequestService, useValue: {} },
{ provide: ActivatedRoute, useValue: route },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: GLOBAL_CONFIG, useValue: {} },
{ provide: Router, useValue: router },
SearchService
],
});
searchService = TestBed.get(SearchService);
});
it('should return the view mode set through setViewMode', fakeAsync(() => { it('should call the navigate method on the Router with view mode list parameter as a parameter when setViewMode is called', () => {
searchService.setViewMode(ViewMode.Grid) searchService.setViewMode(ViewMode.List);
tick(); expect(router.navigate).toHaveBeenCalledWith(['/search'], {
let viewMode = ViewMode.List; queryParams: { view: ViewMode.List },
searchService.getViewMode().subscribe((mode) => viewMode = mode); queryParamsHandling: 'merge'
expect(viewMode).toBe(ViewMode.Grid); });
});
searchService.setViewMode(ViewMode.List) it('should call the navigate method on the Router with view mode grid parameter as a parameter when setViewMode is called', () => {
tick(); searchService.setViewMode(ViewMode.Grid);
searchService.getViewMode().subscribe((mode) => viewMode = mode); expect(router.navigate).toHaveBeenCalledWith(['/search'], {
expect(viewMode).toBe(ViewMode.List); queryParams: { view: ViewMode.Grid },
})); queryParamsHandling: 'merge'
});
});
it('should return ViewMode.List when the viewMode is set to ViewMode.List in the ActivatedRoute', () => {
let viewMode = ViewMode.Grid;
route.testParams = { view: ViewMode.List };
searchService.getViewMode().subscribe((mode) => viewMode = mode);
expect(viewMode).toEqual(ViewMode.List);
});
it('should return ViewMode.Grid when the viewMode is set to ViewMode.Grid in the ActivatedRoute', () => {
let viewMode = ViewMode.List;
route.testParams = { view: ViewMode.Grid };
searchService.getViewMode().subscribe((mode) => viewMode = mode);
expect(viewMode).toEqual(ViewMode.Grid);
});
});
}); });

View File

@@ -88,13 +88,13 @@ export class SearchService extends HALEndpointService implements OnDestroy {
// searchOptions: BehaviorSubject<SearchOptions>; // searchOptions: BehaviorSubject<SearchOptions>;
searchOptions: SearchOptions; searchOptions: SearchOptions;
constructor(protected responseCache: ResponseCacheService, constructor(private router: Router,
private route: ActivatedRoute,
protected responseCache: ResponseCacheService,
protected requestService: RequestService, protected requestService: RequestService,
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig, @Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
private routeService: RouteService, private routeService: RouteService,
private route: ActivatedRoute, private rdb: RemoteDataBuildService,) {
private rdb: RemoteDataBuildService,
private router: Router) {
super(); super();
const pagination: PaginationComponentOptions = new PaginationComponentOptions(); const pagination: PaginationComponentOptions = new PaginationComponentOptions();
pagination.id = 'search-results-pagination'; pagination.id = 'search-results-pagination';
@@ -228,9 +228,10 @@ export class SearchService extends HALEndpointService implements OnDestroy {
const value = searchFilterConfigName + ' ' + (i + 1); const value = searchFilterConfigName + ' ' + (i + 1);
if (!selectedValues.includes(value)) { if (!selectedValues.includes(value)) {
payload.push({ payload.push({
value: value, value: value,
count: Math.floor(Math.random() * 20) + 20 * (totalFilters - i), // make sure first results have the highest (random) count count: Math.floor(Math.random() * 20) + 20 * (totalFilters - i), // make sure first results have the highest (random) count
search: (decodeURI(this.router.url) + (this.router.url.includes('?') ? '&' : '?') + filterConfig.paramName + '=' + value)} search: (decodeURI(this.router.url) + (this.router.url.includes('?') ? '&' : '?') + filterConfig.paramName + '=' + value)
}
); );
} }
} }
@@ -271,12 +272,12 @@ export class SearchService extends HALEndpointService implements OnDestroy {
getClearFiltersQueryParams(): any { getClearFiltersQueryParams(): any {
const params = {}; const params = {};
this.sub = this.route.queryParamMap this.sub = this.route.queryParamMap
.subscribe((map) => { .subscribe((pmap) => {
map.keys pmap.keys
.filter((key) => this.config .filter((key) => this.config
.findIndex((conf: SearchFilterConfig) => conf.paramName === key) < 0) .findIndex((conf: SearchFilterConfig) => conf.paramName === key) < 0)
.forEach((key) => { .forEach((key) => {
params[key] = map.get(key); params[key] = pmap.get(key);
}) })
}); });
return params; return params;

View File

@@ -154,13 +154,6 @@ export class EndpointMapRequest extends GetRequest {
} }
} }
export class RootEndpointRequest extends EndpointMapRequest {
constructor(uuid: string, EnvConfig: GlobalConfig) {
const href = new RESTURLCombiner(EnvConfig, '/').toString();
super(uuid, href);
}
}
export class BrowseEndpointRequest extends GetRequest { export class BrowseEndpointRequest extends GetRequest {
constructor(uuid: string, href: string) { constructor(uuid: string, href: string) {
super(uuid, href); super(uuid, href);

View File

@@ -2,9 +2,9 @@ import { cold, hot } from 'jasmine-marbles';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { getMockRequestService } from '../../shared/mocks/mock-request.service'; import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';
import { RootEndpointRequest } from '../data/request.models';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { HALEndpointService } from './hal-endpoint.service'; import { HALEndpointService } from './hal-endpoint.service';
import { EndpointMapRequest } from '../data/request.models';
describe('HALEndpointService', () => { describe('HALEndpointService', () => {
let service: HALEndpointService; let service: HALEndpointService;
@@ -32,7 +32,7 @@ describe('HALEndpointService', () => {
describe('getRootEndpointMap', () => { describe('getRootEndpointMap', () => {
beforeEach(() => { beforeEach(() => {
responseCache = jasmine.createSpyObj('responseCache', { responseCache = jasmine.createSpyObj('responseCache', {
get: hot('--a-', { get: hot('a-', {
a: { a: {
response: { endpointMap: endpointMap } response: { endpointMap: endpointMap }
} }
@@ -52,45 +52,51 @@ describe('HALEndpointService', () => {
); );
}); });
it('should configure a new RootEndpointRequest', () => { it('should configure a new EndpointMapRequest', () => {
(service as any).getRootEndpointMap(); (service as any).getRootEndpointMap();
const expected = new RootEndpointRequest(requestService.generateRequestId(), envConfig); const expected = new EndpointMapRequest(requestService.generateRequestId(), envConfig.rest.baseUrl);
expect(requestService.configure).toHaveBeenCalledWith(expected); expect(requestService.configure).toHaveBeenCalledWith(expected);
}); });
it('should return an Observable of the endpoint map', () => { it('should return an Observable of the endpoint map', () => {
const result = (service as any).getRootEndpointMap(); const result = (service as any).getRootEndpointMap();
const expected = cold('--b-', { b: endpointMap }); const expected = cold('b-', { b: endpointMap });
expect(result).toBeObservable(expected); expect(result).toBeObservable(expected);
}); });
}); });
describe('getEndpoint', () => { describe('getEndpoint', () => {
beforeEach(() => { beforeEach(() => {
envConfig = {
rest: { baseUrl: 'https://rest.api/' }
} as any;
service = new TestService( service = new TestService(
responseCache, responseCache,
requestService, requestService,
envConfig envConfig
); );
spyOn(service as any, 'getRootEndpointMap').and
.returnValue(hot('--a-', { a: endpointMap }));
}); });
it('should return the endpoint URL for the service\'s linkPath', () => { it('should return the endpoint URL for the service\'s linkPath', () => {
spyOn(service as any, 'getEndpointAt').and
.returnValue(hot('a-', { a: 'https://rest.api/test' }));
const result = service.getEndpoint(); const result = service.getEndpoint();
const expected = cold('--b-', { b: endpointMap.test });
const expected = cold('b-', { b: endpointMap.test });
expect(result).toBeObservable(expected); expect(result).toBeObservable(expected);
}); });
it('should return undefined for a linkPath that isn\'t in the endpoint map', () => { it('should return undefined for a linkPath that isn\'t in the endpoint map', () => {
(service as any).linkPath = 'unknown'; (service as any).linkPath = 'unknown';
spyOn(service as any, 'getEndpointAt').and
.returnValue(hot('a-', { a: undefined }));
const result = service.getEndpoint(); const result = service.getEndpoint();
const expected = cold('--b-', { b: undefined }); const expected = cold('b-', { b: undefined });
expect(result).toBeObservable(expected); expect(result).toBeObservable(expected);
}); });
}); });
describe('isEnabledOnRestApi', () => { describe('isEnabledOnRestApi', () => {
@@ -127,7 +133,7 @@ describe('HALEndpointService', () => {
(service as any).linkPath = 'unknown'; (service as any).linkPath = 'unknown';
const result = service.isEnabledOnRestApi(); const result = service.isEnabledOnRestApi();
const expected = cold('b-c-', { b: undefined, c: false }); const expected = cold('b-c-', { b: undefined, c: false });
expect(result).toBeObservable(expected); expect(result).toBeObservable(expected);
}); });

View File

@@ -4,7 +4,7 @@ import { RequestService } from '../data/request.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { EndpointMap, EndpointMapSuccessResponse } from '../cache/response-cache.models'; import { EndpointMap, EndpointMapSuccessResponse } from '../cache/response-cache.models';
import { EndpointMapRequest, RootEndpointRequest } from '../data/request.models'; import { EndpointMapRequest } from '../data/request.models';
import { ResponseCacheEntry } from '../cache/response-cache.reducer'; import { ResponseCacheEntry } from '../cache/response-cache.reducer';
import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner'; import { RESTURLCombiner } from '../url-combiner/rest-url-combiner';

View File

@@ -1,8 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { renderElementsFor} from '../../../object-collection/shared/dso-element-decorator'; import { renderElementsFor} from '../../../object-collection/shared/dso-element-decorator';
import { SearchResultGridElementComponent } from '../search-result-grid-element.component'; import { SearchResultGridElementComponent } from '../search-result-grid-element.component';
import { Collection } from '../../../../core/shared/collection.model'; import { Collection } from '../../../../core/shared/collection.model';
import { ViewMode } from '../../../../+search-page/search-options.model'; import { ViewMode } from '../../../../+search-page/search-options.model';

View File

@@ -1,6 +1,4 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Community } from '../../../../core/shared/community.model'; import { Community } from '../../../../core/shared/community.model';
import { renderElementsFor } from '../../../object-collection/shared/dso-element-decorator'; import { renderElementsFor } from '../../../object-collection/shared/dso-element-decorator';
import { SearchResultGridElementComponent } from '../search-result-grid-element.component'; import { SearchResultGridElementComponent } from '../search-result-grid-element.component';

View File

@@ -1,16 +1,16 @@
import { Params } from '@angular/router'; import { convertToParamMap, ParamMap, Params } from '@angular/router';
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class ActivatedRouteStub { export class ActivatedRouteStub {
private _testParams?: any; private _testParams?: any;
// ActivatedRoute.params is Observable // ActivatedRoute.params is Observable
private subject?: BehaviorSubject<any> = new BehaviorSubject(this.testParams); private subject?: BehaviorSubject<any> = new BehaviorSubject(this.testParams);
params = this.subject.asObservable(); params = this.subject.asObservable();
queryParams = this.subject.asObservable(); queryParams = this.subject.asObservable();
queryParamMap = this.subject.asObservable().map((params: Params) => convertToParamMap(params));
constructor(params?: Params) { constructor(params?: Params) {
if (params) { if (params) {

View File

@@ -0,0 +1,32 @@
import { Observable } from 'rxjs/Observable';
import { ViewMode } from '../../+search-page/search-options.model';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class SearchServiceStub {
private _viewMode: ViewMode;
private subject?: BehaviorSubject<any> = new BehaviorSubject(this.testViewMode);
viewMode = this.subject.asObservable();
constructor() {
this.setViewMode(ViewMode.List);
}
getViewMode(): Observable<ViewMode> {
return this.viewMode;
}
setViewMode(viewMode: ViewMode) {
this.testViewMode = viewMode;
}
get testViewMode(): ViewMode {
return this._viewMode;
}
set testViewMode(viewMode: ViewMode) {
this._viewMode = viewMode;
this.subject.next(viewMode);
}
}

View File

@@ -4,19 +4,12 @@ import { By } from '@angular/platform-browser';
import { MockTranslateLoader } from '../mocks/mock-translate-loader'; import { MockTranslateLoader } from '../mocks/mock-translate-loader';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { Component } from '@angular/core'; import { ChangeDetectionStrategy, Component } from '@angular/core';
import { SearchService } from '../../+search-page/search-service/search.service'; import { SearchService } from '../../+search-page/search-service/search.service';
import { ItemDataService } from './../../core/data/item-data.service';
import { ViewModeSwitchComponent } from './view-mode-switch.component'; import { ViewModeSwitchComponent } from './view-mode-switch.component';
import { ViewMode } from '../../+search-page/search-options.model'; import { ViewMode } from '../../+search-page/search-options.model';
import { RouteService } from '../route.service'; import { SearchServiceStub } from '../testing/search-service-stub';
import { ResponseCacheService } from '../../core/cache/response-cache.service';
import { RequestService } from '../../core/data/request.service';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { ActivatedRoute } from '@angular/router';
import { GLOBAL_CONFIG } from '../../../config';
import { ActivatedRouteStub } from '../testing/active-router-stub';
@Component({ template: '' }) @Component({ template: '' })
class DummyComponent { } class DummyComponent { }
@@ -24,10 +17,9 @@ class DummyComponent { }
describe('ViewModeSwitchComponent', () => { describe('ViewModeSwitchComponent', () => {
let comp: ViewModeSwitchComponent; let comp: ViewModeSwitchComponent;
let fixture: ComponentFixture<ViewModeSwitchComponent>; let fixture: ComponentFixture<ViewModeSwitchComponent>;
let searchService: SearchService; const searchService = new SearchServiceStub();
let listButton: HTMLElement; let listButton: HTMLElement;
let gridButton: HTMLElement; let gridButton: HTMLElement;
let route = new ActivatedRouteStub();
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
@@ -46,15 +38,10 @@ describe('ViewModeSwitchComponent', () => {
DummyComponent DummyComponent
], ],
providers: [ providers: [
{ provide: ItemDataService, useValue: {} }, { provide: SearchService, useValue: searchService },
{ provide: RouteService, useValue: {} },
{ provide: ResponseCacheService, useValue: {} },
{ provide: RequestService, useValue: {} },
{ provide: ActivatedRoute, useValue: route },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: GLOBAL_CONFIG, useValue: {} },
SearchService
], ],
}).overrideComponent(ViewModeSwitchComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents(); }).compileComponents();
})); }));
@@ -65,12 +52,10 @@ describe('ViewModeSwitchComponent', () => {
const debugElements = fixture.debugElement.queryAll(By.css('a')); const debugElements = fixture.debugElement.queryAll(By.css('a'));
listButton = debugElements[0].nativeElement; listButton = debugElements[0].nativeElement;
gridButton = debugElements[1].nativeElement; gridButton = debugElements[1].nativeElement;
searchService = fixture.debugElement.injector.get(SearchService);
}); });
it('should set list button as active when on list mode', fakeAsync(() => { it('should set list button as active when on list mode', fakeAsync(() => {
searchService.setViewMode(ViewMode.List); searchService.setViewMode(ViewMode.List);
route = new ActivatedRouteStub([{view: ViewMode.List}])
tick(); tick();
fixture.detectChanges(); fixture.detectChanges();
expect(comp.currentMode).toBe(ViewMode.List); expect(comp.currentMode).toBe(ViewMode.List);
@@ -80,7 +65,6 @@ describe('ViewModeSwitchComponent', () => {
it('should set grid button as active when on grid mode', fakeAsync(() => { it('should set grid button as active when on grid mode', fakeAsync(() => {
searchService.setViewMode(ViewMode.Grid); searchService.setViewMode(ViewMode.Grid);
route = new ActivatedRouteStub([{view: ViewMode.Grid}])
tick(); tick();
fixture.detectChanges(); fixture.detectChanges();
expect(comp.currentMode).toBe(ViewMode.Grid); expect(comp.currentMode).toBe(ViewMode.Grid);