From c9e7cdcf9a20399a549242f18584a6ce0ae2db0e Mon Sep 17 00:00:00 2001 From: Lotte Hofstede Date: Mon, 9 Apr 2018 16:29:12 +0200 Subject: [PATCH] added search service test --- .../search-service/search.service.spec.ts | 138 +++++++++++++++++- .../search-service/search.service.ts | 2 +- src/app/shared/mocks/mock-request.service.ts | 4 +- .../mocks/mock-response-cache.service.ts | 12 +- 4 files changed, 143 insertions(+), 13 deletions(-) diff --git a/src/app/+search-page/search-service/search.service.spec.ts b/src/app/+search-page/search-service/search.service.spec.ts index 5f9f67390b..ef6efe3deb 100644 --- a/src/app/+search-page/search-service/search.service.spec.ts +++ b/src/app/+search-page/search-service/search.service.spec.ts @@ -16,6 +16,22 @@ import { ResponseCacheService } from '../../core/cache/response-cache.service'; import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; import { RouterStub } from '../../shared/testing/router-stub'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; +import { Observable } from 'rxjs/Observable'; +import { PaginatedSearchOptions } from '../paginated-search-options.model'; +import { RemoteData } from '../../core/data/remote-data'; +import { PaginatedList } from '../../core/data/paginated-list'; +import { SearchResult } from '../search-result.model'; +import { DSpaceObject } from '../../core/shared/dspace-object.model'; +import { ResponseCacheEntry } from '../../core/cache/response-cache.reducer'; +import { RequestEntry } from '../../core/data/request.reducer'; +import { getMockRequestService } from '../../shared/mocks/mock-request.service'; +import { getMockResponseCacheService } from '../../shared/mocks/mock-response-cache.service'; +import { + FacetConfigSuccessResponse, RestResponse, + SearchSuccessResponse +} from '../../core/cache/response-cache.models'; +import { SearchQueryResponse } from './search-query-response.model'; +import { SearchFilterConfig } from './search-filter-config.model'; @Component({ template: '' }) class DummyComponent { @@ -40,8 +56,8 @@ describe('SearchService', () => { providers: [ { provide: Router, useValue: router }, { provide: ActivatedRoute, useValue: route }, - { provide: ResponseCacheService, useValue: {} }, - { provide: RequestService, useValue: {} }, + { provide: ResponseCacheService, useValue: getMockResponseCacheService() }, + { provide: RequestService, useValue: getMockRequestService() }, { provide: RemoteDataBuildService, useValue: {} }, { provide: HALEndpointService, useValue: {} }, SearchService @@ -60,6 +76,26 @@ describe('SearchService', () => { let searchService: SearchService; const router = new RouterStub(); const route = new ActivatedRouteStub(); + + const halService = { + /* tslint:disable:no-empty */ + getEndpoint: () => {} + /* tslint:enable:no-empty */ + + }; + + const remoteDataBuildService = { + toRemoteDataObservable: (requestEntryObs: Observable, responseCacheObs: Observable, payloadObs: Observable) => { + return Observable.combineLatest(requestEntryObs, + responseCacheObs, payloadObs, (req, res, pay) => { + return { req, res, pay }; + }); + }, + aggregate: (input: Array>>): Observable> => { + return Observable.of(new RemoteData(false, false, true, null, [])); + } + }; + beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -74,10 +110,10 @@ describe('SearchService', () => { providers: [ { provide: Router, useValue: router }, { provide: ActivatedRoute, useValue: route }, - { provide: ResponseCacheService, useValue: {} }, - { provide: RequestService, useValue: {} }, - { provide: RemoteDataBuildService, useValue: {} }, - { provide: HALEndpointService, useValue: {} }, + { provide: ResponseCacheService, useValue: getMockResponseCacheService() }, + { provide: RequestService, useValue: getMockRequestService() }, + { provide: RemoteDataBuildService, useValue: remoteDataBuildService }, + { provide: HALEndpointService, useValue: halService }, SearchService ], }); @@ -113,5 +149,95 @@ describe('SearchService', () => { searchService.getViewMode().subscribe((mode) => viewMode = mode); expect(viewMode).toEqual(ViewMode.Grid); }); + + describe('when search is called', () => { + const endPoint = 'http://endpoint.com/test/test'; + const searchOptions = new PaginatedSearchOptions(); + const queryResponse = Object.assign(new SearchQueryResponse(), { objects: [] }); + const response = new SearchSuccessResponse(queryResponse, '200'); + const responseEntry = Object.assign(new ResponseCacheEntry(), { response: response }); + beforeEach(() => { + spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint)); + (searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry)); + /* tslint:disable:no-empty */ + searchService.search(searchOptions).subscribe((t) => {}); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((searchService as any).requestService.configure).toHaveBeenCalled(); + }); + + it('should call getByHref on the request service with the correct request url', () => { + expect((searchService as any).requestService.getByHref).toHaveBeenCalledWith(endPoint); + }); + it('should call get on the request service with the correct request url', () => { + expect((searchService as any).responseCache.get).toHaveBeenCalledWith(endPoint); + }); + }); + + describe('when getConfig is called without a scope', () => { + const endPoint = 'http://endpoint.com/test/config'; + const filterConfig = [new SearchFilterConfig()]; + const response = new FacetConfigSuccessResponse(filterConfig, '200'); + const responseEntry = Object.assign(new ResponseCacheEntry(), { response: response }); + beforeEach(() => { + spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint)); + (searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry)); + /* tslint:disable:no-empty */ + searchService.getConfig(null).subscribe((t) => {}); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((searchService as any).requestService.configure).toHaveBeenCalled(); + }); + + it('should call getByHref on the request service with the correct request url', () => { + expect((searchService as any).requestService.getByHref).toHaveBeenCalledWith(endPoint); + }); + it('should call get on the request service with the correct request url', () => { + expect((searchService as any).responseCache.get).toHaveBeenCalledWith(endPoint); + }); + }); + + describe('when getConfig is called with a scope', () => { + const endPoint = 'http://endpoint.com/test/config'; + const scope = 'test'; + const requestUrl = endPoint + '?scope=' + scope; + const filterConfig = [new SearchFilterConfig()]; + const response = new FacetConfigSuccessResponse(filterConfig, '200'); + const responseEntry = Object.assign(new ResponseCacheEntry(), { response: response }); + beforeEach(() => { + spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint)); + (searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry)); + /* tslint:disable:no-empty */ + searchService.getConfig(scope).subscribe((t) => {}); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((searchService as any).requestService.configure).toHaveBeenCalled(); + }); + + it('should call getByHref on the request service with the correct request url', () => { + expect((searchService as any).requestService.getByHref).toHaveBeenCalledWith(requestUrl); + }); + it('should call get on the request service with the correct request url', () => { + expect((searchService as any).responseCache.get).toHaveBeenCalledWith(requestUrl); + }); + }); }); }); diff --git a/src/app/+search-page/search-service/search.service.ts b/src/app/+search-page/search-service/search.service.ts index 42f527a411..6b1034fa33 100644 --- a/src/app/+search-page/search-service/search.service.ts +++ b/src/app/+search-page/search-service/search.service.ts @@ -96,6 +96,7 @@ export class SearchService implements OnDestroy { } search(searchOptions?: PaginatedSearchOptions): Observable>>> { + // this.halService.getEndpoint(this.searchLinkPath).subscribe((t) => console.log(t)); const requestObs = this.halService.getEndpoint(this.searchLinkPath).pipe( map((url: string) => { if (hasValue(searchOptions)) { @@ -110,7 +111,6 @@ export class SearchService implements OnDestroy { }), tap((request: RestRequest) => this.requestService.configure(request)), ); - const requestEntryObs = requestObs.pipe( flatMap((request: RestRequest) => this.requestService.getByHref(request.href)) ); diff --git a/src/app/shared/mocks/mock-request.service.ts b/src/app/shared/mocks/mock-request.service.ts index ed8ffa028d..02d3e54282 100644 --- a/src/app/shared/mocks/mock-request.service.ts +++ b/src/app/shared/mocks/mock-request.service.ts @@ -1,8 +1,10 @@ import { RequestService } from '../../core/data/request.service'; +import { RequestEntry } from '../../core/data/request.reducer'; export function getMockRequestService(): RequestService { return jasmine.createSpyObj('requestService', { configure: () => false, - generateRequestId: () => 'clients/b186e8ce-e99c-4183-bc9a-42b4821bdb78' + generateRequestId: () => 'clients/b186e8ce-e99c-4183-bc9a-42b4821bdb78', + getByHref: (uuid: string) => new RequestEntry() }); } diff --git a/src/app/shared/mocks/mock-response-cache.service.ts b/src/app/shared/mocks/mock-response-cache.service.ts index 95b4e7aca0..ad1457c3eb 100644 --- a/src/app/shared/mocks/mock-response-cache.service.ts +++ b/src/app/shared/mocks/mock-response-cache.service.ts @@ -1,10 +1,12 @@ import { ResponseCacheService } from '../../core/cache/response-cache.service'; +import { ResponseCacheEntry } from '../../core/cache/response-cache.reducer'; +import { RestResponse } from '../../core/cache/response-cache.models'; export function getMockResponseCacheService(): ResponseCacheService { - return jasmine.createSpyObj('ResponseCacheService', [ - 'add', - 'get', - 'has', - ]); + return jasmine.createSpyObj('ResponseCacheService', { + add: (key: string, response: RestResponse, msToLive: number) => new ResponseCacheEntry(), + get: (key: string) => new ResponseCacheEntry(), + has: (key: string) => false, + }); }