зеркало из https://github.com/microsoft/paris.git
adding Paris.clearApiCallCache method to enable users to clear the apiCalls cache
* adding clearApiCallCache method to enable users to force clearing the apiCalls cache * upgraded to jest 24 + added caching mechanism tests * version bump
This commit is contained in:
Родитель
8e9213b8fd
Коммит
9635d65738
|
@ -1,5 +1,6 @@
|
|||
import {ApiCallBackendConfigInterface} from "../../config/api-call-backend-config.interface";
|
||||
import {HttpOptions, RequestMethod} from "../../data_access/http.service";
|
||||
import { ParisConfig } from "../../config/paris-config";
|
||||
|
||||
export class ApiCallModel<TResult = any, TInput = any>{
|
||||
config:ApiCallConfig<TResult, TInput>
|
||||
|
@ -12,7 +13,7 @@ export interface ApiCallType<TResult = any, TInput = any>{
|
|||
|
||||
export interface ApiCallConfig<TResult = any, TInput = any> extends ApiCallBackendConfigInterface<TResult> {
|
||||
name:string,
|
||||
parseQuery?:(input:TInput) => HttpOptions,
|
||||
parseQuery?:(input:TInput, config?: ParisConfig) => HttpOptions,
|
||||
parse?:(data?:any, input?:TInput) => TResult,
|
||||
method?:RequestMethod,
|
||||
responseType?: 'json' | 'blob' | 'text',
|
||||
|
|
|
@ -101,7 +101,7 @@ export interface EntityBackendConfig<TEntity extends ModelBase, TRawData = any,
|
|||
* `parseDataQuery` receives that DataQuery object and allows to modify it, so Paris can send to the API what it expects.
|
||||
* @param {DataQuery} dataQuery
|
||||
*/
|
||||
parseDataQuery?:(dataQuery:DataQuery) => { [index:string]:any },
|
||||
parseDataQuery?:(dataQuery:DataQuery, config?: ParisConfig) => { [index:string]:any },
|
||||
|
||||
/**
|
||||
* For query results, Paris accepts either an array of items or an object. That object may contain properties such as 'count', 'next' and 'previous'.
|
||||
|
|
23
lib/paris.ts
23
lib/paris.ts
|
@ -164,7 +164,7 @@ export class Paris<TConfigData = any> {
|
|||
|
||||
let httpOptions: HttpOptions = ((input !== undefined) && (input !== null))
|
||||
? apiCallType.config.parseQuery
|
||||
? apiCallType.config.parseQuery(input)
|
||||
? apiCallType.config.parseQuery(input, this.config)
|
||||
: apiCallType.config.method !== "GET" ? {data: input} : {params: input}
|
||||
: null;
|
||||
if (!httpOptions){
|
||||
|
@ -260,6 +260,25 @@ export class Paris<TConfigData = any> {
|
|||
return apiCall$;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all or specific ApiCallType caches
|
||||
* @param {ApiCallType<TResult, TInput>} apiCallType Optional ApiCallType class or array of classes. if omitted, all ApiCallType caches will be cleared. otherwise, only the caches of the specified ApiCallType(s) will be cleared.
|
||||
* @returns {void}
|
||||
*/
|
||||
clearApiCallCache(apiCallType?:ApiCallType | Array<ApiCallType>): void {
|
||||
if (!apiCallType) {
|
||||
this.apiCallsCache.clear();
|
||||
return;
|
||||
}
|
||||
const apiCallTypes = apiCallType instanceof Array ? apiCallType : [apiCallType];
|
||||
apiCallTypes.forEach(apiCallType => {
|
||||
const apiCallTypeCache = this.getApiCallCache(apiCallType);
|
||||
if (apiCallTypeCache) {
|
||||
apiCallTypeCache.clear();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private getApiCallCache<TResult, TInput>(apiCallType:ApiCallType<TResult, TInput>, addIfNotExists:boolean = false):DataCache<TResult>{
|
||||
let apiCallCache:DataCache<TResult> = this.apiCallsCache.get(apiCallType);
|
||||
if (!apiCallCache && addIfNotExists){
|
||||
|
@ -334,7 +353,7 @@ export class Paris<TConfigData = any> {
|
|||
* @returns {Observable<DataSet<TEntity extends ModelBase>>}
|
||||
*/
|
||||
callQuery<TEntity extends ModelBase>(entityConstructor:DataEntityType<TEntity>, backendConfig:EntityBackendConfig<TEntity>, query?: DataQuery, dataOptions: DataOptions = defaultDataOptions):Observable<DataSet<TEntity>>{
|
||||
let httpOptions:HttpOptions = backendConfig.parseDataQuery ? { params: backendConfig.parseDataQuery(query) } : queryToHttpOptions(query);
|
||||
let httpOptions:HttpOptions = backendConfig.parseDataQuery ? { params: backendConfig.parseDataQuery(query, this.config) } : queryToHttpOptions(query);
|
||||
if (!httpOptions){
|
||||
httpOptions = {};
|
||||
}
|
||||
|
|
14
package.json
14
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@microsoft/paris",
|
||||
"version": "1.5.1",
|
||||
"version": "1.6.0",
|
||||
"description": "Library for the implementation of Domain Driven Design with TypeScript + RxJS",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -48,7 +48,7 @@
|
|||
"@types/gulp-protractor": "^1.0.30",
|
||||
"@types/gulp-sass": "^0.0.30",
|
||||
"@types/gulp-util": "^3.0.29",
|
||||
"@types/jest": "^23.3.1",
|
||||
"@types/jest": "^24.0.0",
|
||||
"@types/json-stringify-safe": "^5.0.0",
|
||||
"@types/lodash-es": "4.17.1",
|
||||
"@types/node": "^8.0.25",
|
||||
|
@ -63,7 +63,7 @@
|
|||
"gulp-typescript": "^3.1.3",
|
||||
"husky": "^1.0.0-rc.13",
|
||||
"intl": "^1.2.5",
|
||||
"jest": "^23.6.0",
|
||||
"jest": "^24.7.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"lodash-es": "4.17.10",
|
||||
"merge2": "^1.0.2",
|
||||
|
@ -77,7 +77,7 @@
|
|||
"rxjs": "^6.0.0",
|
||||
"standard-version": "^3.0.0",
|
||||
"systemjs": ">=0.20.12",
|
||||
"ts-jest": "^23.1.3",
|
||||
"ts-jest": "^24.0.0",
|
||||
"ts-node": "^7.0.0",
|
||||
"typedoc": "^0.11.1",
|
||||
"typescript": "^2.7.2",
|
||||
|
@ -98,8 +98,10 @@
|
|||
"/node_modules/",
|
||||
"/dist/"
|
||||
],
|
||||
"setupTestFrameworkScriptFile": "<rootDir>/jest-setup.ts",
|
||||
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|js)$",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/jest-setup.ts"
|
||||
],
|
||||
"testRegex": "\\.(test|spec)\\.(ts|js)$",
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"js",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Observable, of } from 'rxjs';
|
||||
import { Observable, of, forkJoin } from 'rxjs';
|
||||
import { DataEntityType } from '../lib/api/entity/data-entity.base';
|
||||
import { RelationshipRepository } from '../lib/api/repository/relationship-repository';
|
||||
import { Repository } from '../lib/api/repository/repository';
|
||||
|
@ -218,7 +218,7 @@ describe('Paris main', () => {
|
|||
|
||||
describe('apiCall', () => {
|
||||
let jestGetApiCallCacheSpy: jest.SpyInstance<Observable<Paris>>;
|
||||
let jestMakeApiCallSpy: jest.SpyInstance<Observable<Paris>>;
|
||||
let jestMakeApiCallSpy: jest.SpyInstance<Observable<any>>;
|
||||
|
||||
beforeEach(() => {
|
||||
paris = new Paris();
|
||||
|
@ -228,8 +228,42 @@ describe('Paris main', () => {
|
|||
jestMakeApiCallSpy = jest.spyOn(paris, 'makeApiCall' as any);
|
||||
});
|
||||
|
||||
it.skip('should add data to cache if configured to', () => {
|
||||
// TODO: we need to subscribe in order for this to work
|
||||
describe('cache behaviour', () => {
|
||||
|
||||
function callTwoDifferentApiCalls() {
|
||||
return forkJoin(paris.apiCall(CreateTodoListApiCall), paris.apiCall(UpdateTodoApiCall));
|
||||
}
|
||||
|
||||
const testObj = {};
|
||||
|
||||
beforeEach(done => {
|
||||
jestMakeApiCallSpy.mockReturnValue(of(testObj));
|
||||
callTwoDifferentApiCalls().subscribe(_ => done());
|
||||
});
|
||||
|
||||
it('should retreive data from cache', done => {
|
||||
callTwoDifferentApiCalls().subscribe(val => {
|
||||
expect(val[0]).toBe(testObj);
|
||||
expect(jestMakeApiCallSpy).toHaveBeenCalledTimes(2);//expecting no additional calls to 'makeApiCall'
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should clear a specific ApiCall cache', done => {
|
||||
paris.clearApiCallCache(CreateTodoListApiCall);
|
||||
callTwoDifferentApiCalls().subscribe(_ => {
|
||||
expect(jestMakeApiCallSpy).toHaveBeenCalledTimes(3);//expecting exactly one additional call to 'makeApiCall'
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should clear all ApiCalls cache', done => {
|
||||
paris.clearApiCallCache();
|
||||
callTwoDifferentApiCalls().subscribe(_ => {
|
||||
expect(jestMakeApiCallSpy).toHaveBeenCalledTimes(4);//expecting exactly two additional calls to 'makeApiCall'
|
||||
done();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('should get data from cache if available and configured to', () => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче