ObjectCacheService docs & tests

This commit is contained in:
Art Lowel
2017-03-08 12:57:03 +01:00
parent f1bf3e4062
commit 0e516beabd
3 changed files with 194 additions and 6 deletions

View File

@@ -0,0 +1,112 @@
import { ObjectCacheState, CacheableObject } from "./object-cache.reducer";
import { Store } from "@ngrx/store";
import { ObjectCacheService } from "./object-cache.service";
import { AddToObjectCacheAction, RemoveFromObjectCacheAction } from "./object-cache.actions";
import { Observable } from "rxjs";
class TestClass implements CacheableObject {
constructor(
public uuid: string,
public foo: string
) {}
test(): string {
return this.foo + this.uuid;
}
}
describe("ObjectCacheService", () => {
let service: ObjectCacheService;
let store: Store<ObjectCacheState>;
const uuid = '1698f1d3-be98-4c51-9fd8-6bfedcbd59b7';
const timestamp = new Date().getTime();
const msToLive = 900000;
const objectToCache = {
uuid: uuid,
foo: 'bar'
};
const cacheEntry = {
data: objectToCache,
timeAdded: timestamp,
msToLive: msToLive
};
const invalidCacheEntry = Object.assign({}, cacheEntry, { msToLive: -1 });
beforeEach(() => {
store = new Store<ObjectCacheState>(undefined, undefined, undefined);
spyOn(store, 'dispatch');
service = new ObjectCacheService(store);
spyOn(window, 'Date').and.returnValue({ getTime: () => timestamp });
});
describe("add", () => {
it("should dispatch an ADD action with the object to add, the time to live, and the current timestamp", () => {
service.add(objectToCache, msToLive);
expect(store.dispatch).toHaveBeenCalledWith(new AddToObjectCacheAction(objectToCache, timestamp, msToLive));
});
});
describe("remove", () => {
it("should dispatch a REMOVE action with the UUID of the object to remove", () => {
service.remove(uuid);
expect(store.dispatch).toHaveBeenCalledWith(new RemoveFromObjectCacheAction(uuid));
});
});
describe("get", () => {
it("should return an observable of the cached object with the specified UUID and type", () => {
spyOn(store, 'select').and.returnValue(Observable.of(cacheEntry));
let testObj: any;
//due to the implementation of spyOn above, this subscribe will be synchronous
service.get(uuid, TestClass).take(1).subscribe(o => testObj = o);
expect(testObj.uuid).toBe(uuid);
expect(testObj.foo).toBe("bar");
// this only works if testObj is an instance of TestClass
expect(testObj.test()).toBe("bar" + uuid);
});
it("should not return a cached object that has exceeded its time to live", () => {
spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry));
let testObj: any;
service.get(uuid, TestClass).take(1).subscribe(o => testObj = o);
expect(testObj).toBeUndefined();
});
});
describe("getList", () => {
it("should return an observable of the array of cached objects with the specified UUID and type", () => {
spyOn(service, 'get').and.returnValue(Observable.of(new TestClass(uuid, "bar")));
let testObjs: Array<any>;
service.getList([uuid, uuid], TestClass).take(1).subscribe(arr => testObjs = arr);
expect(testObjs[0].uuid).toBe(uuid);
expect(testObjs[0].foo).toBe("bar");
expect(testObjs[0].test()).toBe("bar" + uuid);
expect(testObjs[1].uuid).toBe(uuid);
expect(testObjs[1].foo).toBe("bar");
expect(testObjs[1].test()).toBe("bar" + uuid);
});
});
describe("has", () => {
it("should return true if the object with the supplied UUID is cached and still valid", () => {
spyOn(store, 'select').and.returnValue(Observable.of(cacheEntry));
expect(service.has(uuid)).toBe(true);
});
it("should return false if the object with the supplied UUID isn't cached", () => {
spyOn(store, 'select').and.returnValue(Observable.of(undefined));
expect(service.has(uuid)).toBe(false);
});
it("should return false if the object with the supplied UUID is cached but has exceeded its time to live", () => {
spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry));
expect(service.has(uuid)).toBe(false);
});
});
});