move effect for cleaning cache to auth.effects

This commit is contained in:
Giuseppe Digilio
2021-07-21 09:46:15 +02:00
parent b04c33a5fb
commit 85fa1c5a9c
4 changed files with 32 additions and 10 deletions

View File

@@ -35,6 +35,7 @@ import { EPersonMock } from '../../shared/testing/eperson.mock';
import { AppState, storeModuleConfig } from '../../app.reducer'; import { AppState, storeModuleConfig } from '../../app.reducer';
import { StoreActionTypes } from '../../store.actions'; import { StoreActionTypes } from '../../store.actions';
import { isAuthenticated, isAuthenticatedLoaded } from './selectors'; import { isAuthenticated, isAuthenticatedLoaded } from './selectors';
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
describe('AuthEffects', () => { describe('AuthEffects', () => {
let authEffects: AuthEffects; let authEffects: AuthEffects;
@@ -44,6 +45,8 @@ describe('AuthEffects', () => {
let token; let token;
let store: MockStore<AppState>; let store: MockStore<AppState>;
const authorizationService = jasmine.createSpyObj(['invalidateAuthorizationsRequestCache']);
function init() { function init() {
authServiceStub = new AuthServiceStub(); authServiceStub = new AuthServiceStub();
token = authServiceStub.getToken(); token = authServiceStub.getToken();
@@ -68,6 +71,7 @@ describe('AuthEffects', () => {
providers: [ providers: [
AuthEffects, AuthEffects,
provideMockStore({ initialState }), provideMockStore({ initialState }),
{ provide: AuthorizationDataService, useValue: authorizationService },
{ provide: AuthService, useValue: authServiceStub }, { provide: AuthService, useValue: authServiceStub },
provideMockActions(() => actions), provideMockActions(() => actions),
// other providers // other providers
@@ -417,4 +421,16 @@ describe('AuthEffects', () => {
})); }));
}); });
}); });
describe('invalidateAuthorizationsRequestCache$', () => {
it('should call invalidateAuthorizationsRequestCache method in response to a REHYDRATE action', (done) => {
actions = hot('--a-|', { a: { type: StoreActionTypes.REHYDRATE } });
authEffects.invalidateAuthorizationsRequestCache$.subscribe(() => {
expect((authEffects as any).authorizationsService.invalidateAuthorizationsRequestCache).toHaveBeenCalled();
});
done();
});
});
}); });

View File

@@ -53,6 +53,7 @@ import { RequestActionTypes } from '../data/request.actions';
import { NotificationsActionTypes } from '../../shared/notifications/notifications.actions'; import { NotificationsActionTypes } from '../../shared/notifications/notifications.actions';
import { LeaveZoneScheduler } from '../utilities/leave-zone.scheduler'; import { LeaveZoneScheduler } from '../utilities/leave-zone.scheduler';
import { EnterZoneScheduler } from '../utilities/enter-zone.scheduler'; import { EnterZoneScheduler } from '../utilities/enter-zone.scheduler';
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
// Action Types that do not break/prevent the user from an idle state // Action Types that do not break/prevent the user from an idle state
const IDLE_TIMER_IGNORE_TYPES: string[] const IDLE_TIMER_IGNORE_TYPES: string[]
@@ -218,6 +219,16 @@ export class AuthEffects {
); );
})); }));
/**
* When the store is rehydrated in the browser, invalidate all cache hits regarding the
* authorizations endpoint, to be sure to have consistent responses after a login with external idp
*
*/
@Effect({ dispatch: false }) invalidateAuthorizationsRequestCache$ = this.actions$
.pipe(ofType(StoreActionTypes.REHYDRATE),
tap(() => this.authorizationsService.invalidateAuthorizationsRequestCache())
);
@Effect() @Effect()
public logOut$: Observable<Action> = this.actions$ public logOut$: Observable<Action> = this.actions$
.pipe( .pipe(
@@ -284,11 +295,13 @@ export class AuthEffects {
* @constructor * @constructor
* @param {Actions} actions$ * @param {Actions} actions$
* @param {NgZone} zone * @param {NgZone} zone
* @param {AuthorizationDataService} authorizationsService
* @param {AuthService} authService * @param {AuthService} authService
* @param {Store} store * @param {Store} store
*/ */
constructor(private actions$: Actions, constructor(private actions$: Actions,
private zone: NgZone, private zone: NgZone,
private authorizationsService: AuthorizationDataService,
private authService: AuthService, private authService: AuthService,
private store: Store<AppState>) { private store: Store<AppState>) {
} }

View File

@@ -5,20 +5,16 @@ import { cold, hot } from 'jasmine-marbles';
import { ObjectCacheEffects } from './object-cache.effects'; import { ObjectCacheEffects } from './object-cache.effects';
import { ResetObjectCacheTimestampsAction } from './object-cache.actions'; import { ResetObjectCacheTimestampsAction } from './object-cache.actions';
import { StoreActionTypes } from '../../store.actions'; import { StoreActionTypes } from '../../store.actions';
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
describe('ObjectCacheEffects', () => { describe('ObjectCacheEffects', () => {
let cacheEffects: ObjectCacheEffects; let cacheEffects: ObjectCacheEffects;
let actions: Observable<any>; let actions: Observable<any>;
const timestamp = 10000; const timestamp = 10000;
const authorizationService = jasmine.createSpyObj(['invalidateAuthorizationsRequestCache']);
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
providers: [ providers: [
ObjectCacheEffects, ObjectCacheEffects,
provideMockActions(() => actions), provideMockActions(() => actions),
{ provide: AuthorizationDataService, useValue: authorizationService },
// other providers // other providers
], ],
}); });
@@ -37,7 +33,6 @@ describe('ObjectCacheEffects', () => {
const expected = cold('--b-', { b: new ResetObjectCacheTimestampsAction(new Date().getTime()) }); const expected = cold('--b-', { b: new ResetObjectCacheTimestampsAction(new Date().getTime()) });
expect(cacheEffects.fixTimestampsOnRehydrate).toBeObservable(expected); expect(cacheEffects.fixTimestampsOnRehydrate).toBeObservable(expected);
expect((cacheEffects as any).authorizationsService.invalidateAuthorizationsRequestCache).toHaveBeenCalled();
}); });
}); });
}); });

View File

@@ -1,10 +1,9 @@
import { map, tap } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects'; import { Actions, Effect, ofType } from '@ngrx/effects';
import { StoreActionTypes } from '../../store.actions'; import { StoreActionTypes } from '../../store.actions';
import { ResetObjectCacheTimestampsAction } from './object-cache.actions'; import { ResetObjectCacheTimestampsAction } from './object-cache.actions';
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
@Injectable() @Injectable()
export class ObjectCacheEffects { export class ObjectCacheEffects {
@@ -19,11 +18,10 @@ export class ObjectCacheEffects {
*/ */
@Effect() fixTimestampsOnRehydrate = this.actions$ @Effect() fixTimestampsOnRehydrate = this.actions$
.pipe(ofType(StoreActionTypes.REHYDRATE), .pipe(ofType(StoreActionTypes.REHYDRATE),
map(() => new ResetObjectCacheTimestampsAction(new Date().getTime())), map(() => new ResetObjectCacheTimestampsAction(new Date().getTime()))
tap(() => this.authorizationsService.invalidateAuthorizationsRequestCache())
); );
constructor(private actions$: Actions, private authorizationsService: AuthorizationDataService) { constructor(private actions$: Actions) {
} }
} }