diff --git a/src/app/core/cache/object-cache.effects.spec.ts b/src/app/core/cache/object-cache.effects.spec.ts new file mode 100644 index 0000000000..48241c2c4f --- /dev/null +++ b/src/app/core/cache/object-cache.effects.spec.ts @@ -0,0 +1,38 @@ +import { TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs/Observable'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { cold, hot } from 'jasmine-marbles'; +import { ObjectCacheEffects } from './object-cache.effects'; +import { ResetObjectCacheTimestampsAction } from './object-cache.actions'; +import { StoreActionTypes } from '../../store.actions'; + +describe('ObjectCacheEffects', () => { + let cacheEffects: ObjectCacheEffects; + let actions: Observable; + const timestamp = 10000; + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + ObjectCacheEffects, + provideMockActions(() => actions), + // other providers + ], + }); + + cacheEffects = TestBed.get(ObjectCacheEffects); + }); + + describe('fixTimestampsOnRehydrate$', () => { + + it('should return a RESET_TIMESTAMPS action in response to an REHYDRATE action to a new route', () => { + spyOn(Date.prototype, 'getTime').and.callFake(() => { + return timestamp; + }); + actions = hot('--a-', { a: { type: StoreActionTypes.REHYDRATE, payload: {} } }); + + const expected = cold('--b-', { b: new ResetObjectCacheTimestampsAction(new Date().getTime()) }); + + expect(cacheEffects.fixTimestampsOnRehydrate).toBeObservable(expected); + }); + }); +}); diff --git a/src/app/core/data/object-cache.effects.ts b/src/app/core/cache/object-cache.effects.ts similarity index 89% rename from src/app/core/data/object-cache.effects.ts rename to src/app/core/cache/object-cache.effects.ts index a0018d2b58..019c792973 100644 --- a/src/app/core/data/object-cache.effects.ts +++ b/src/app/core/cache/object-cache.effects.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { Actions, Effect } from '@ngrx/effects'; import { StoreActionTypes } from '../../store.actions'; -import { ResetObjectCacheTimestampsAction } from '../cache/object-cache.actions'; +import { ResetObjectCacheTimestampsAction } from './object-cache.actions'; @Injectable() export class ObjectCacheEffects { diff --git a/src/app/core/cache/response-cache.effects.spec.ts b/src/app/core/cache/response-cache.effects.spec.ts new file mode 100644 index 0000000000..422b8bf181 --- /dev/null +++ b/src/app/core/cache/response-cache.effects.spec.ts @@ -0,0 +1,38 @@ +import { TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs/Observable'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { cold, hot } from 'jasmine-marbles'; +import { StoreActionTypes } from '../../store.actions'; +import { ResponseCacheEffects } from './response-cache.effects'; +import { ResetResponseCacheTimestampsAction } from './response-cache.actions'; + +describe('ResponseCacheEffects', () => { + let cacheEffects: ResponseCacheEffects; + let actions: Observable; + const timestamp = 10000; + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + ResponseCacheEffects, + provideMockActions(() => actions), + // other providers + ], + }); + + cacheEffects = TestBed.get(ResponseCacheEffects); + }); + + describe('fixTimestampsOnRehydrate$', () => { + + it('should return a RESET_TIMESTAMPS action in response to an REHYDRATE action to a new route', () => { + spyOn(Date.prototype, 'getTime').and.callFake(() => { + return timestamp; + }); + actions = hot('--a-', { a: { type: StoreActionTypes.REHYDRATE, payload: {} } }); + + const expected = cold('--b-', { b: new ResetResponseCacheTimestampsAction(new Date().getTime()) }); + + expect(cacheEffects.fixTimestampsOnRehydrate).toBeObservable(expected); + }); + }); +}); diff --git a/src/app/core/data/request-cache.effects.ts b/src/app/core/cache/response-cache.effects.ts similarity index 85% rename from src/app/core/data/request-cache.effects.ts rename to src/app/core/cache/response-cache.effects.ts index a9c1c24957..d340750797 100644 --- a/src/app/core/data/request-cache.effects.ts +++ b/src/app/core/cache/response-cache.effects.ts @@ -1,11 +1,11 @@ import { Injectable } from '@angular/core'; import { Actions, Effect } from '@ngrx/effects'; -import { ResetResponseCacheTimestampsAction } from '../cache/response-cache.actions'; +import { ResetResponseCacheTimestampsAction } from './response-cache.actions'; import { StoreActionTypes } from '../../store.actions'; @Injectable() -export class RequestCacheEffects { +export class ResponseCacheEffects { /** * When the store is rehydrated in the browser, set all cache diff --git a/src/app/core/cache/response-cache.reducer.spec.ts b/src/app/core/cache/response-cache.reducer.spec.ts index 613b62f30f..9037b20030 100644 --- a/src/app/core/cache/response-cache.reducer.spec.ts +++ b/src/app/core/cache/response-cache.reducer.spec.ts @@ -4,8 +4,9 @@ import { responseCacheReducer, ResponseCacheState } from './response-cache.reduc import { ResponseCacheRemoveAction, - ResetResponseCacheTimestampsAction + ResetResponseCacheTimestampsAction, ResponseCacheAddAction } from './response-cache.actions'; +import { RestResponse } from './response-cache.models'; class NullAction extends ResponseCacheRemoveAction { type = null; @@ -16,212 +17,108 @@ class NullAction extends ResponseCacheRemoveAction { } } -// describe('responseCacheReducer', () => { -// const keys = ['125c17f89046283c5f0640722aac9feb', 'a06c3006a41caec5d635af099b0c780c']; -// const services = [new OpaqueToken('service1'), new OpaqueToken('service2')]; -// const msToLive = 900000; -// const uuids = [ -// '9e32a2e2-6b91-4236-a361-995ccdc14c60', -// '598ce822-c357-46f3-ab70-63724d02d6ad', -// 'be8325f7-243b-49f4-8a4b-df2b793ff3b5' -// ]; -// const resourceID = '9978'; -// const paginationOptions = { 'resultsPerPage': 10, 'currentPage': 1 }; -// const sortOptions = { 'field': 'id', 'direction': 0 }; -// const testState = { -// [keys[0]]: { -// 'key': keys[0], -// 'service': services[0], -// 'resourceUUIDs': [uuids[0], uuids[1]], -// 'isLoading': false, -// 'paginationOptions': paginationOptions, -// 'sortOptions': sortOptions, -// 'timeAdded': new Date().getTime(), -// 'msToLive': msToLive -// }, -// [keys[1]]: { -// 'key': keys[1], -// 'service': services[1], -// 'resourceID': resourceID, -// 'resourceUUIDs': [uuids[2]], -// 'isLoading': false, -// 'timeAdded': new Date().getTime(), -// 'msToLive': msToLive -// } -// }; -// deepFreeze(testState); -// const errorState: {} = { -// [keys[0]]: { -// errorMessage: 'error', -// resourceUUIDs: uuids -// } -// }; -// deepFreeze(errorState); -// -// -// it('should return the current state when no valid actions have been made', () => { -// const action = new NullAction(); -// const newState = responseCacheReducer(testState, action); -// -// expect(newState).toEqual(testState); -// }); -// -// it('should start with an empty cache', () => { -// const action = new NullAction(); -// const initialState = responseCacheReducer(undefined, action); -// -// expect(initialState).toEqual(Object.create(null)); -// }); -// -// describe('FIND_BY_ID', () => { -// const action = new ResponseCacheFindByIDAction(keys[0], services[0], resourceID); -// -// it('should perform the action without affecting the previous state', () => { -// //testState has already been frozen above -// responseCacheReducer(testState, action); -// }); -// -// it('should add the request to the cache', () => { -// const state = Object.create(null); -// const newState = responseCacheReducer(state, action); -// expect(newState[keys[0]].key).toBe(keys[0]); -// expect(newState[keys[0]].service).toEqual(services[0]); -// expect(newState[keys[0]].resourceID).toBe(resourceID); -// }); -// -// it('should set responsePending to true', () => { -// const state = Object.create(null); -// const newState = responseCacheReducer(state, action); -// expect(newState[keys[0]].responsePending).toBe(true); -// }); -// -// it('should remove any previous error message or resourceUUID for the request', () => { -// const newState = responseCacheReducer(errorState, action); -// expect(newState[keys[0]].resourceUUIDs.length).toBe(0); -// expect(newState[keys[0]].errorMessage).toBeUndefined(); -// }); -// }); -// -// describe('FIND_ALL', () => { -// const action = new ResponseCacheFindAllAction(keys[0], services[0], resourceID, paginationOptions, sortOptions); -// -// it('should perform the action without affecting the previous state', () => { -// //testState has already been frozen above -// responseCacheReducer(testState, action); -// }); -// -// it('should add the request to the cache', () => { -// const state = Object.create(null); -// const newState = responseCacheReducer(state, action); -// expect(newState[keys[0]].key).toBe(keys[0]); -// expect(newState[keys[0]].service).toEqual(services[0]); -// expect(newState[keys[0]].scopeID).toBe(resourceID); -// expect(newState[keys[0]].paginationOptions).toEqual(paginationOptions); -// expect(newState[keys[0]].sortOptions).toEqual(sortOptions); -// }); -// -// it('should set responsePending to true', () => { -// const state = Object.create(null); -// const newState = responseCacheReducer(state, action); -// expect(newState[keys[0]].responsePending).toBe(true); -// }); -// -// it('should remove any previous error message or resourceUUIDs for the request', () => { -// const newState = responseCacheReducer(errorState, action); -// expect(newState[keys[0]].resourceUUIDs.length).toBe(0); -// expect(newState[keys[0]].errorMessage).toBeUndefined(); -// }); -// }); -// -// describe('SUCCESS', () => { -// const successUUIDs = [uuids[0], uuids[2]]; -// const successTimeAdded = new Date().getTime(); -// const successMsToLive = 5; -// const action = new ResponseCacheSuccessAction(keys[0], successUUIDs, successTimeAdded, successMsToLive); -// -// it('should perform the action without affecting the previous state', () => { -// //testState has already been frozen above -// responseCacheReducer(testState, action); -// }); -// -// it('should add the response to the cached request', () => { -// const newState = responseCacheReducer(testState, action); -// expect(newState[keys[0]].resourceUUIDs).toBe(successUUIDs); -// expect(newState[keys[0]].timeAdded).toBe(successTimeAdded); -// expect(newState[keys[0]].msToLive).toBe(successMsToLive); -// }); -// -// it('should set responsePending to false', () => { -// const newState = responseCacheReducer(testState, action); -// expect(newState[keys[0]].responsePending).toBe(false); -// }); -// -// it('should remove any previous error message for the request', () => { -// const newState = responseCacheReducer(errorState, action); -// expect(newState[keys[0]].errorMessage).toBeUndefined(); -// }); -// }); -// -// describe('ERROR', () => { -// const errorMsg = 'errorMsg'; -// const action = new ResponseCacheErrorAction(keys[0], errorMsg); -// -// it('should perform the action without affecting the previous state', () => { -// //testState has already been frozen above -// responseCacheReducer(testState, action); -// }); -// -// it('should set an error message for the request', () => { -// const newState = responseCacheReducer(errorState, action); -// expect(newState[keys[0]].errorMessage).toBe(errorMsg); -// }); -// -// it('should set responsePending to false', () => { -// const newState = responseCacheReducer(testState, action); -// expect(newState[keys[0]].responsePending).toBe(false); -// }); -// }); -// -// describe('REMOVE', () => { -// it('should perform the action without affecting the previous state', () => { -// const action = new ResponseCacheRemoveAction(keys[0]); -// //testState has already been frozen above -// responseCacheReducer(testState, action); -// }); -// -// it('should remove the specified request from the cache', () => { -// const action = new ResponseCacheRemoveAction(keys[0]); -// const newState = responseCacheReducer(testState, action); -// expect(testState[keys[0]]).not.toBeUndefined(); -// expect(newState[keys[0]]).toBeUndefined(); -// }); -// -// it('shouldn't do anything when the specified key isn't cached', () => { -// const wrongKey = 'this isn't cached'; -// const action = new ResponseCacheRemoveAction(wrongKey); -// const newState = responseCacheReducer(testState, action); -// expect(testState[wrongKey]).toBeUndefined(); -// expect(newState).toEqual(testState); -// }); -// }); -// -// describe('RESET_TIMESTAMPS', () => { -// const newTimeStamp = new Date().getTime(); -// const action = new ResetResponseCacheTimestampsAction(newTimeStamp); -// -// it('should perform the action without affecting the previous state', () => { -// //testState has already been frozen above -// responseCacheReducer(testState, action); -// }); -// -// it('should set the timestamp of all requests in the cache', () => { -// const newState = responseCacheReducer(testState, action); -// Object.keys(newState).forEach((key) => { -// expect(newState[key].timeAdded).toEqual(newTimeStamp); -// }); -// }); -// -// }); -// -// -// }); +describe('responseCacheReducer', () => { + const keys = ['125c17f89046283c5f0640722aac9feb', 'a06c3006a41caec5d635af099b0c780c']; + const msToLive = 900000; + const uuids = [ + '9e32a2e2-6b91-4236-a361-995ccdc14c60', + '598ce822-c357-46f3-ab70-63724d02d6ad', + 'be8325f7-243b-49f4-8a4b-df2b793ff3b5' + ]; + const testState: ResponseCacheState = { + [keys[0]]: { + key: keys[0], + response: new RestResponse(true, '200'), + timeAdded: new Date().getTime(), + msToLive: msToLive + }, + [keys[1]]: { + key: keys[1], + response: new RestResponse(true, '200'), + timeAdded: new Date().getTime(), + msToLive: msToLive + } + }; + deepFreeze(testState); + const errorState: {} = { + [keys[0]]: { + errorMessage: 'error', + resourceUUIDs: uuids + } + }; + deepFreeze(errorState); + + it('should return the current state when no valid actions have been made', () => { + const action = new NullAction(); + const newState = responseCacheReducer(testState, action); + + expect(newState).toEqual(testState); + }); + + it('should start with an empty cache', () => { + const action = new NullAction(); + const initialState = responseCacheReducer(undefined, action); + + expect(initialState).toEqual(Object.create(null)); + }); + + describe('ADD', () => { + const addTimeAdded = new Date().getTime(); + const addMsToLive = 5; + const addResponse = new RestResponse(true, '200'); + const action = new ResponseCacheAddAction(keys[0], addResponse, addTimeAdded, addMsToLive); + + it('should perform the action without affecting the previous state', () => { + // testState has already been frozen above + responseCacheReducer(testState, action); + }); + + it('should add the response to the cached request', () => { + const newState = responseCacheReducer(testState, action); + expect(newState[keys[0]].timeAdded).toBe(addTimeAdded); + expect(newState[keys[0]].msToLive).toBe(addMsToLive); + expect(newState[keys[0]].response).toBe(addResponse); + }); + }); + + describe('REMOVE', () => { + it('should perform the action without affecting the previous state', () => { + const action = new ResponseCacheRemoveAction(keys[0]); + // testState has already been frozen above + responseCacheReducer(testState, action); + }); + + it('should remove the specified request from the cache', () => { + const action = new ResponseCacheRemoveAction(keys[0]); + const newState = responseCacheReducer(testState, action); + expect(testState[keys[0]]).not.toBeUndefined(); + expect(newState[keys[0]]).toBeUndefined(); + }); + + it('shouldn\'t do anything when the specified key isn\'t cached', () => { + const wrongKey = 'this isn\'t cached'; + const action = new ResponseCacheRemoveAction(wrongKey); + const newState = responseCacheReducer(testState, action); + expect(testState[wrongKey]).toBeUndefined(); + expect(newState).toEqual(testState); + }); + }); + + describe('RESET_TIMESTAMPS', () => { + const newTimeStamp = new Date().getTime(); + const action = new ResetResponseCacheTimestampsAction(newTimeStamp); + + it('should perform the action without affecting the previous state', () => { + // testState has already been frozen above + responseCacheReducer(testState, action); + }); + + it('should set the timestamp of all requests in the cache', () => { + const newState = responseCacheReducer(testState, action); + Object.keys(newState).forEach((key) => { + expect(newState[key].timeAdded).toEqual(newTimeStamp); + }); + }); + + }); +}); diff --git a/src/app/core/cache/response-cache.service.spec.ts b/src/app/core/cache/response-cache.service.spec.ts index 71b1da789c..1def7faa02 100644 --- a/src/app/core/cache/response-cache.service.spec.ts +++ b/src/app/core/cache/response-cache.service.spec.ts @@ -1,147 +1,83 @@ -import { OpaqueToken } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; import { Store } from '@ngrx/store'; import { ResponseCacheService } from './response-cache.service'; -import { ResponseCacheState, ResponseCacheEntry } from './response-cache.reducer'; +import { Observable } from 'rxjs/Observable'; +import { CoreState } from '../core.reducers'; +import { RestResponse } from './response-cache.models'; +import { ResponseCacheEntry } from './response-cache.reducer'; -// describe('ResponseCacheService', () => { -// let service: ResponseCacheService; -// let store: Store; -// -// const keys = ['125c17f89046283c5f0640722aac9feb', 'a06c3006a41caec5d635af099b0c780c']; -// const serviceTokens = [new OpaqueToken('service1'), new OpaqueToken('service2')]; -// const resourceID = '9978'; -// const paginationOptions = { 'resultsPerPage': 10, 'currentPage': 1 }; -// const sortOptions = { 'field': 'id', 'direction': 0 }; -// const timestamp = new Date().getTime(); -// const validCacheEntry = (key) => { -// return { -// key: key, -// timeAdded: timestamp, -// msToLive: 24 * 60 * 60 * 1000 // a day -// } -// }; -// const invalidCacheEntry = (key) => { -// return { -// key: key, -// timeAdded: 0, -// msToLive: 0 -// } -// }; -// -// beforeEach(() => { -// store = new Store(undefined, undefined, undefined); -// spyOn(store, 'dispatch'); -// service = new ResponseCacheService(store); -// spyOn(window, 'Date').and.returnValue({ getTime: () => timestamp }); -// }); -// -// describe('findAll', () => { -// beforeEach(() => { -// spyOn(service, 'get').and.callFake((key) => Observable.of({key: key})); -// }); -// describe('if the key isn't cached', () => { -// beforeEach(() => { -// spyOn(service, 'has').and.returnValue(false); -// }); -// it('should dispatch a FIND_ALL action with the key, service, scopeID, paginationOptions and sortOptions', () => { -// service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions); -// expect(store.dispatch).toHaveBeenCalledWith(new ResponseCacheFindAllAction(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions)) -// }); -// it('should return an observable of the newly cached request with the specified key', () => { -// let result: ResponseCacheEntry; -// service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions).take(1).subscribe(entry => result = entry); -// expect(result.key).toEqual(keys[0]); -// }); -// }); -// describe('if the key is already cached', () => { -// beforeEach(() => { -// spyOn(service, 'has').and.returnValue(true); -// }); -// it('shouldn't dispatch anything', () => { -// service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions); -// expect(store.dispatch).not.toHaveBeenCalled(); -// }); -// it('should return an observable of the existing cached request with the specified key', () => { -// let result: ResponseCacheEntry; -// service.findAll(keys[0], serviceTokens[0], resourceID, paginationOptions, sortOptions).take(1).subscribe(entry => result = entry); -// expect(result.key).toEqual(keys[0]); -// }); -// }); -// }); -// -// describe('findById', () => { -// beforeEach(() => { -// spyOn(service, 'get').and.callFake((key) => Observable.of({key: key})); -// }); -// describe('if the key isn't cached', () => { -// beforeEach(() => { -// spyOn(service, 'has').and.returnValue(false); -// }); -// it('should dispatch a FIND_BY_ID action with the key, service, and resourceID', () => { -// service.findById(keys[0], serviceTokens[0], resourceID); -// expect(store.dispatch).toHaveBeenCalledWith(new ResponseCacheFindByIDAction(keys[0], serviceTokens[0], resourceID)) -// }); -// it('should return an observable of the newly cached request with the specified key', () => { -// let result: ResponseCacheEntry; -// service.findById(keys[0], serviceTokens[0], resourceID).take(1).subscribe(entry => result = entry); -// expect(result.key).toEqual(keys[0]); -// }); -// }); -// describe('if the key is already cached', () => { -// beforeEach(() => { -// spyOn(service, 'has').and.returnValue(true); -// }); -// it('shouldn't dispatch anything', () => { -// service.findById(keys[0], serviceTokens[0], resourceID); -// expect(store.dispatch).not.toHaveBeenCalled(); -// }); -// it('should return an observable of the existing cached request with the specified key', () => { -// let result: ResponseCacheEntry; -// service.findById(keys[0], serviceTokens[0], resourceID).take(1).subscribe(entry => result = entry); -// expect(result.key).toEqual(keys[0]); -// }); -// }); -// }); -// -// describe('get', () => { -// it('should return an observable of the cached request with the specified key', () => { -// spyOn(store, 'select').and.callFake((...args:Array) => { -// return Observable.of(validCacheEntry(args[args.length - 1])); -// }); -// -// let testObj: ResponseCacheEntry; -// service.get(keys[1]).take(1).subscribe(entry => testObj = entry); -// expect(testObj.key).toEqual(keys[1]); -// }); -// -// it('should not return a cached request that has exceeded its time to live', () => { -// spyOn(store, 'select').and.callFake((...args:Array) => { -// return Observable.of(invalidCacheEntry(args[args.length - 1])); -// }); -// -// let getObsHasFired = false; -// const subscription = service.get(keys[1]).subscribe(entry => getObsHasFired = true); -// expect(getObsHasFired).toBe(false); -// subscription.unsubscribe(); -// }); -// }); -// -// describe('has', () => { -// it('should return true if the request with the supplied key is cached and still valid', () => { -// spyOn(store, 'select').and.returnValue(Observable.of(validCacheEntry(keys[1]))); -// expect(service.has(keys[1])).toBe(true); -// }); -// -// it('should return false if the request with the supplied key isn't cached', () => { -// spyOn(store, 'select').and.returnValue(Observable.of(undefined)); -// expect(service.has(keys[1])).toBe(false); -// }); -// -// it('should return false if the request with the supplied key is cached but has exceeded its time to live', () => { -// spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry(keys[1]))); -// expect(service.has(keys[1])).toBe(false); -// }); -// }); -// }); +describe('ResponseCacheService', () => { + let service: ResponseCacheService; + let store: Store; + + const keys = ['125c17f89046283c5f0640722aac9feb', 'a06c3006a41caec5d635af099b0c780c']; + const timestamp = new Date().getTime(); + const validCacheEntry = (key) => { + return { + key: key, + response: new RestResponse(true, '200'), + timeAdded: timestamp, + msToLive: 24 * 60 * 60 * 1000 // a day + } + }; + const invalidCacheEntry = (key) => { + return { + key: key, + response: new RestResponse(true, '200'), + timeAdded: 0, + msToLive: 0 + } + }; + + beforeEach(() => { + store = new Store(undefined, undefined, undefined); + spyOn(store, 'dispatch'); + service = new ResponseCacheService(store); + spyOn(Date.prototype, 'getTime').and.callFake(() => { + return timestamp; + }); + }); + + describe('get', () => { + it('should return an observable of the cached request with the specified key', () => { + spyOn(store, 'select').and.callFake((...args: any[]) => { + return Observable.of(validCacheEntry(keys[1])); + }); + + let testObj: ResponseCacheEntry; + service.get(keys[1]).first().subscribe((entry) => { + console.log(entry); + testObj = entry; + }); + expect(testObj.key).toEqual(keys[1]); + }); + + it('should not return a cached request that has exceeded its time to live', () => { + spyOn(store, 'select').and.callFake((...args: any[]) => { + return Observable.of(invalidCacheEntry(keys[1])); + }); + + let getObsHasFired = false; + const subscription = service.get(keys[1]).subscribe((entry) => getObsHasFired = true); + expect(getObsHasFired).toBe(false); + subscription.unsubscribe(); + }); + }); + + describe('has', () => { + it('should return true if the request with the supplied key is cached and still valid', () => { + spyOn(store, 'select').and.returnValue(Observable.of(validCacheEntry(keys[1]))); + expect(service.has(keys[1])).toBe(true); + }); + + it('should return false if the request with the supplied key isn\'t cached', () => { + spyOn(store, 'select').and.returnValue(Observable.of(undefined)); + expect(service.has(keys[1])).toBe(false); + }); + + it('should return false if the request with the supplied key is cached but has exceeded its time to live', () => { + spyOn(store, 'select').and.returnValue(Observable.of(invalidCacheEntry(keys[1]))); + expect(service.has(keys[1])).toBe(false); + }); + }); +}); diff --git a/src/app/core/cache/response-cache.service.ts b/src/app/core/cache/response-cache.service.ts index d734940496..65ce8b2bac 100644 --- a/src/app/core/cache/response-cache.service.ts +++ b/src/app/core/cache/response-cache.service.ts @@ -4,7 +4,7 @@ import { MemoizedSelector, Store } from '@ngrx/store'; import { Observable } from 'rxjs/Observable'; import { ResponseCacheEntry } from './response-cache.reducer'; -import { hasNoValue, hasValue } from '../../shared/empty.util'; +import { hasNoValue } from '../../shared/empty.util'; import { ResponseCacheRemoveAction, ResponseCacheAddAction } from './response-cache.actions'; import { RestResponse } from './response-cache.models'; import { CoreState } from '../core.reducers'; @@ -25,7 +25,6 @@ export class ResponseCacheService { add(key: string, response: RestResponse, msToLive: number): Observable { if (!this.has(key)) { - // this.store.dispatch(new ResponseCacheFindAllAction(key, service, scopeID, paginationOptions, sortOptions)); this.store.dispatch(new ResponseCacheAddAction(key, response, new Date().getTime(), msToLive)); } return this.get(key); diff --git a/src/app/core/core.effects.ts b/src/app/core/core.effects.ts index 593b17e0f5..f144f773a1 100644 --- a/src/app/core/core.effects.ts +++ b/src/app/core/core.effects.ts @@ -1,11 +1,11 @@ -import { ObjectCacheEffects } from './data/object-cache.effects'; -import { RequestCacheEffects } from './data/request-cache.effects'; +import { ObjectCacheEffects } from './cache/object-cache.effects'; +import { ResponseCacheEffects } from './cache/response-cache.effects'; import { UUIDIndexEffects } from './index/uuid-index.effects'; import { RequestEffects } from './data/request.effects'; export const coreEffects = [ - RequestCacheEffects, + ResponseCacheEffects, RequestEffects, ObjectCacheEffects, UUIDIndexEffects,