added missing tests and docs

This commit is contained in:
lotte
2019-03-14 11:14:59 +01:00
parent 4c150988e2
commit 917c00f8fb
4 changed files with 83 additions and 19 deletions

View File

@@ -65,18 +65,10 @@ export class ObjectCacheService {
/** /**
* Get an observable of the object with the specified UUID * Get an observable of the object with the specified UUID
* *
* The type needs to be specified as well, in order to turn
* the cached plain javascript object in to an instance of
* a class.
*
* e.g. getByUUID('c96588c6-72d3-425d-9d47-fa896255a695', Item)
*
* @param uuid * @param uuid
* The UUID of the object to get * The UUID of the object to get
* @param type * @return Observable<NormalizedObject<T>>
* The type of the object to get * An observable of the requested object in normalized form
* @return Observable<T>
* An observable of the requested object
*/ */
getObjectByUUID<T extends CacheableObject>(uuid: string): Observable<NormalizedObject<T>> { getObjectByUUID<T extends CacheableObject>(uuid: string): Observable<NormalizedObject<T>> {
return this.store.pipe( return this.store.pipe(
@@ -86,6 +78,14 @@ export class ObjectCacheService {
) )
} }
/**
* Get an observable of the object with the specified selfLink
*
* @param selfLink
* The selfLink of the object to get
* @return Observable<NormalizedObject<T>>
* An observable of the requested object in normalized form
*/
getObjectBySelfLink<T extends CacheableObject>(selfLink: string): Observable<NormalizedObject<T>> { getObjectBySelfLink<T extends CacheableObject>(selfLink: string): Observable<NormalizedObject<T>> {
return this.getBySelfLink(selfLink).pipe( return this.getBySelfLink(selfLink).pipe(
map((entry: ObjectCacheEntry) => { map((entry: ObjectCacheEntry) => {
@@ -105,6 +105,14 @@ export class ObjectCacheService {
); );
} }
/**
* Get an observable of the object cache entry with the specified selfLink
*
* @param selfLink
* The selfLink of the object to get
* @return Observable<ObjectCacheEntry>
* An observable of the requested object cache entry
*/
getBySelfLink(selfLink: string): Observable<ObjectCacheEntry> { getBySelfLink(selfLink: string): Observable<ObjectCacheEntry> {
return this.store.pipe( return this.store.pipe(
select(entryFromSelfLinkSelector(selfLink)), select(entryFromSelfLinkSelector(selfLink)),
@@ -113,12 +121,28 @@ export class ObjectCacheService {
); );
} }
/**
* Get an observable of the request's uuid with the specified selfLink
*
* @param selfLink
* The selfLink of the object to get
* @return Observable<string>
* An observable of the request's uuid
*/
getRequestUUIDBySelfLink(selfLink: string): Observable<string> { getRequestUUIDBySelfLink(selfLink: string): Observable<string> {
return this.getBySelfLink(selfLink).pipe( return this.getBySelfLink(selfLink).pipe(
map((entry: ObjectCacheEntry) => entry.requestUUID), map((entry: ObjectCacheEntry) => entry.requestUUID),
distinctUntilChanged()); distinctUntilChanged());
} }
/**
* Get an observable of the request's uuid with the specified uuid
*
* @param uuid
* The uuid of the object to get
* @return Observable<string>
* An observable of the request's uuid
*/
getRequestUUIDByObjectUUID(uuid: string): Observable<string> { getRequestUUIDByObjectUUID(uuid: string): Observable<string> {
return this.store.pipe( return this.store.pipe(
select(selfLinkFromUuidSelector(uuid)), select(selfLinkFromUuidSelector(uuid)),

View File

@@ -39,7 +39,7 @@ export abstract class RestRequest {
} }
export class GetRequest extends RestRequest { export class GetRequest extends RestRequest {
public responseMsToLive = 60 * 15 * 1000; public responseMsToLive = 10000;
constructor( constructor(
public uuid: string, public uuid: string,

View File

@@ -1,5 +1,5 @@
import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { cold, getTestScheduler, hot } from 'jasmine-marbles';
import { of as observableOf } from 'rxjs'; import { of as observableOf, EMPTY } from 'rxjs';
import { getMockObjectCacheService } from '../../shared/mocks/mock-object-cache.service'; import { getMockObjectCacheService } from '../../shared/mocks/mock-object-cache.service';
import { defaultUUID, getMockUUIDService } from '../../shared/mocks/mock-uuid.service'; import { defaultUUID, getMockUUIDService } from '../../shared/mocks/mock-uuid.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
@@ -7,6 +7,7 @@ import { CoreState } from '../core.reducers';
import { UUIDService } from '../shared/uuid.service'; import { UUIDService } from '../shared/uuid.service';
import { RequestConfigureAction, RequestExecuteAction } from './request.actions'; import { RequestConfigureAction, RequestExecuteAction } from './request.actions';
import * as ngrx from '@ngrx/store'; import * as ngrx from '@ngrx/store';
import { ActionsSubject, Store } from '@ngrx/store';
import { import {
DeleteRequest, DeleteRequest,
GetRequest, GetRequest,
@@ -18,11 +19,8 @@ import {
RestRequest RestRequest
} from './request.models'; } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { ActionsSubject, Store } from '@ngrx/store';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { MockStore } from '../../shared/testing/mock-store';
import { IndexState } from '../index/index.reducer';
describe('RequestService', () => { describe('RequestService', () => {
let scheduler: TestScheduler; let scheduler: TestScheduler;
@@ -431,7 +429,7 @@ describe('RequestService', () => {
describe('when the given entry has a value, but the request is not completed', () => { describe('when the given entry has a value, but the request is not completed', () => {
let valid; let valid;
const requestEntry = { completed: false } ; const requestEntry = { completed: false };
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getByUUID').and.returnValue(observableOf(requestEntry)); spyOn(service, 'getByUUID').and.returnValue(observableOf(requestEntry));
valid = serviceAsAny.isValid(requestEntry); valid = serviceAsAny.isValid(requestEntry);
@@ -506,5 +504,39 @@ describe('RequestService', () => {
expect(valid).toBe(true); expect(valid).toBe(true);
}) })
}) })
}) });
describe('hasByHref', () => {
describe('when nothing is returned by getByHref', () => {
beforeEach(() => {
spyOn(service, 'getByHref').and.returnValue(EMPTY);
});
it('hasByHref should return false', () => {
const result = service.hasByHref('');
expect(result).toBe(false);
});
});
describe('when isValid returns false', () => {
beforeEach(() => {
spyOn(service, 'getByHref').and.returnValue(observableOf(undefined));
spyOn(service as any, 'isValid').and.returnValue(false);
});
it('hasByHref should return false', () => {
const result = service.hasByHref('');
expect(result).toBe(false);
});
});
describe('when isValid returns true', () => {
beforeEach(() => {
spyOn(service, 'getByHref').and.returnValue(observableOf(undefined));
spyOn(service as any, 'isValid').and.returnValue(true);
});
it('hasByHref should return true', () => {
const result = service.hasByHref('');
expect(result).toBe(true);
});
});
});
}); });

View File

@@ -80,6 +80,9 @@ export class RequestService {
return `client/${this.uuidService.generate()}`; return `client/${this.uuidService.generate()}`;
} }
/**
* Check if a request is currently pending
*/
isPending(request: GetRequest): boolean { isPending(request: GetRequest): boolean {
// first check requests that haven't made it to the store yet // first check requests that haven't made it to the store yet
if (this.requestsOnTheirWayToTheStore.includes(request.href)) { if (this.requestsOnTheirWayToTheStore.includes(request.href)) {
@@ -96,6 +99,9 @@ export class RequestService {
return isPending; return isPending;
} }
/**
* Retrieve a RequestEntry based on their uuid
*/
getByUUID(uuid: string): Observable<RequestEntry> { getByUUID(uuid: string): Observable<RequestEntry> {
return observableRace( return observableRace(
this.store.pipe(select(this.entryFromUUIDSelector(uuid))), this.store.pipe(select(this.entryFromUUIDSelector(uuid))),
@@ -108,6 +114,9 @@ export class RequestService {
); );
} }
/**
* Retrieve a RequestEntry based on their href
*/
getByHref(href: string): Observable<RequestEntry> { getByHref(href: string): Observable<RequestEntry> {
return this.store.pipe( return this.store.pipe(
select(this.uuidFromHrefSelector(href)), select(this.uuidFromHrefSelector(href)),
@@ -247,7 +256,6 @@ export class RequestService {
this.getByHref(href).pipe( this.getByHref(href).pipe(
take(1) take(1)
).subscribe((requestEntry: RequestEntry) => result = this.isValid(requestEntry)); ).subscribe((requestEntry: RequestEntry) => result = this.isValid(requestEntry));
return result; return result;
} }