mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
87968: Manual fixes after NgRx migration
Selector typing Restored pre-13 behaviour where mock stores were reset after every test. The upgrade caused multiple tests to start failing; we could solve this by adjusting all of these one by one but that would take some time. (see https://ngrx.io/guide/migration/v13#testing-reset-mock-store)
This commit is contained in:
@@ -67,7 +67,6 @@ export class AuthEffects {
|
|||||||
* Authenticate user.
|
* Authenticate user.
|
||||||
* @method authenticate
|
* @method authenticate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public authenticate$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public authenticate$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.AUTHENTICATE),
|
ofType(AuthActionTypes.AUTHENTICATE),
|
||||||
switchMap((action: AuthenticateAction) => {
|
switchMap((action: AuthenticateAction) => {
|
||||||
@@ -79,13 +78,11 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public authenticateSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public authenticateSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.AUTHENTICATE_SUCCESS),
|
ofType(AuthActionTypes.AUTHENTICATE_SUCCESS),
|
||||||
map((action: AuthenticationSuccessAction) => new AuthenticatedAction(action.payload))
|
map((action: AuthenticationSuccessAction) => new AuthenticatedAction(action.payload))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public authenticated$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public authenticated$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.AUTHENTICATED),
|
ofType(AuthActionTypes.AUTHENTICATED),
|
||||||
switchMap((action: AuthenticatedAction) => {
|
switchMap((action: AuthenticatedAction) => {
|
||||||
@@ -95,7 +92,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public authenticatedSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public authenticatedSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.AUTHENTICATED_SUCCESS),
|
ofType(AuthActionTypes.AUTHENTICATED_SUCCESS),
|
||||||
tap((action: AuthenticatedSuccessAction) => this.authService.storeToken(action.payload.authToken)),
|
tap((action: AuthenticatedSuccessAction) => this.authService.storeToken(action.payload.authToken)),
|
||||||
@@ -112,7 +108,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public redirectAfterLoginSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public redirectAfterLoginSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS),
|
ofType(AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS),
|
||||||
tap((action: RedirectAfterLoginSuccessAction) => {
|
tap((action: RedirectAfterLoginSuccessAction) => {
|
||||||
@@ -122,13 +117,11 @@ export class AuthEffects {
|
|||||||
), { dispatch: false });
|
), { dispatch: false });
|
||||||
|
|
||||||
// It means "reacts to this action but don't send another"
|
// It means "reacts to this action but don't send another"
|
||||||
|
|
||||||
public authenticatedError$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public authenticatedError$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.AUTHENTICATED_ERROR),
|
ofType(AuthActionTypes.AUTHENTICATED_ERROR),
|
||||||
tap((action: LogOutSuccessAction) => this.authService.removeToken())
|
tap((action: LogOutSuccessAction) => this.authService.removeToken())
|
||||||
), { dispatch: false });
|
), { dispatch: false });
|
||||||
|
|
||||||
|
|
||||||
public retrieveAuthenticatedEperson$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public retrieveAuthenticatedEperson$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.RETRIEVE_AUTHENTICATED_EPERSON),
|
ofType(AuthActionTypes.RETRIEVE_AUTHENTICATED_EPERSON),
|
||||||
switchMap((action: RetrieveAuthenticatedEpersonAction) => {
|
switchMap((action: RetrieveAuthenticatedEpersonAction) => {
|
||||||
@@ -145,7 +138,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public checkToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN),
|
public checkToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN),
|
||||||
switchMap(() => {
|
switchMap(() => {
|
||||||
return this.authService.hasValidAuthenticationToken().pipe(
|
return this.authService.hasValidAuthenticationToken().pipe(
|
||||||
@@ -155,7 +147,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public checkTokenCookie$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public checkTokenCookie$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE),
|
ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE),
|
||||||
switchMap(() => {
|
switchMap(() => {
|
||||||
@@ -173,7 +164,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public retrieveToken$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public retrieveToken$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.RETRIEVE_TOKEN),
|
ofType(AuthActionTypes.RETRIEVE_TOKEN),
|
||||||
switchMap((action: AuthenticateAction) => {
|
switchMap((action: AuthenticateAction) => {
|
||||||
@@ -185,7 +175,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public refreshToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN),
|
public refreshToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN),
|
||||||
switchMap((action: RefreshTokenAction) => {
|
switchMap((action: RefreshTokenAction) => {
|
||||||
return this.authService.refreshAuthenticationToken(action.payload).pipe(
|
return this.authService.refreshAuthenticationToken(action.payload).pipe(
|
||||||
@@ -196,7 +185,6 @@ export class AuthEffects {
|
|||||||
));
|
));
|
||||||
|
|
||||||
// It means "reacts to this action but don't send another"
|
// It means "reacts to this action but don't send another"
|
||||||
|
|
||||||
public refreshTokenSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public refreshTokenSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.REFRESH_TOKEN_SUCCESS),
|
ofType(AuthActionTypes.REFRESH_TOKEN_SUCCESS),
|
||||||
tap((action: RefreshTokenSuccessAction) => this.authService.replaceToken(action.payload))
|
tap((action: RefreshTokenSuccessAction) => this.authService.replaceToken(action.payload))
|
||||||
@@ -206,13 +194,12 @@ export class AuthEffects {
|
|||||||
* When the store is rehydrated in the browser,
|
* When the store is rehydrated in the browser,
|
||||||
* clear a possible invalid token or authentication errors
|
* clear a possible invalid token or authentication errors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public clearInvalidTokenOnRehydrate$: Observable<any> = createEffect(() => this.actions$.pipe(
|
public clearInvalidTokenOnRehydrate$: Observable<any> = createEffect(() => this.actions$.pipe(
|
||||||
ofType(StoreActionTypes.REHYDRATE),
|
ofType(StoreActionTypes.REHYDRATE),
|
||||||
switchMap(() => {
|
switchMap(() => {
|
||||||
const isLoaded$ = this.store.pipe(select(isAuthenticatedLoaded));
|
const isLoaded$ = this.store.pipe(select(isAuthenticatedLoaded));
|
||||||
const authenticated$ = this.store.pipe(select(isAuthenticated));
|
const authenticated$ = this.store.pipe(select(isAuthenticated));
|
||||||
return observableCombineLatest(isLoaded$, authenticated$).pipe(
|
return observableCombineLatest([isLoaded$, authenticated$]).pipe(
|
||||||
take(1),
|
take(1),
|
||||||
filter(([loaded, authenticated]) => loaded && !authenticated),
|
filter(([loaded, authenticated]) => loaded && !authenticated),
|
||||||
tap(() => this.authService.removeToken()),
|
tap(() => this.authService.removeToken()),
|
||||||
@@ -230,7 +217,6 @@ export class AuthEffects {
|
|||||||
tap(() => this.authorizationsService.invalidateAuthorizationsRequestCache())
|
tap(() => this.authorizationsService.invalidateAuthorizationsRequestCache())
|
||||||
), { dispatch: false });
|
), { dispatch: false });
|
||||||
|
|
||||||
|
|
||||||
public logOut$: Observable<Action> = createEffect(() => this.actions$
|
public logOut$: Observable<Action> = createEffect(() => this.actions$
|
||||||
.pipe(
|
.pipe(
|
||||||
ofType(AuthActionTypes.LOG_OUT),
|
ofType(AuthActionTypes.LOG_OUT),
|
||||||
@@ -243,7 +229,6 @@ export class AuthEffects {
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public logOutSuccess$: Observable<Action> = createEffect(() => this.actions$
|
public logOutSuccess$: Observable<Action> = createEffect(() => this.actions$
|
||||||
.pipe(ofType(AuthActionTypes.LOG_OUT_SUCCESS),
|
.pipe(ofType(AuthActionTypes.LOG_OUT_SUCCESS),
|
||||||
tap(() => this.authService.removeToken()),
|
tap(() => this.authService.removeToken()),
|
||||||
@@ -251,7 +236,6 @@ export class AuthEffects {
|
|||||||
tap(() => this.authService.refreshAfterLogout())
|
tap(() => this.authService.refreshAfterLogout())
|
||||||
), { dispatch: false });
|
), { dispatch: false });
|
||||||
|
|
||||||
|
|
||||||
public redirectToLoginTokenExpired$: Observable<Action> = createEffect(() => this.actions$
|
public redirectToLoginTokenExpired$: Observable<Action> = createEffect(() => this.actions$
|
||||||
.pipe(
|
.pipe(
|
||||||
ofType(AuthActionTypes.REDIRECT_TOKEN_EXPIRED),
|
ofType(AuthActionTypes.REDIRECT_TOKEN_EXPIRED),
|
||||||
@@ -259,7 +243,6 @@ export class AuthEffects {
|
|||||||
tap(() => this.authService.redirectToLoginWhenTokenExpired())
|
tap(() => this.authService.redirectToLoginWhenTokenExpired())
|
||||||
), { dispatch: false });
|
), { dispatch: false });
|
||||||
|
|
||||||
|
|
||||||
public retrieveMethods$: Observable<Action> = createEffect(() => this.actions$
|
public retrieveMethods$: Observable<Action> = createEffect(() => this.actions$
|
||||||
.pipe(
|
.pipe(
|
||||||
ofType(AuthActionTypes.RETRIEVE_AUTH_METHODS),
|
ofType(AuthActionTypes.RETRIEVE_AUTH_METHODS),
|
||||||
@@ -278,7 +261,6 @@ export class AuthEffects {
|
|||||||
* => Return the action to set the user as idle ({@link SetUserAsIdleAction})
|
* => Return the action to set the user as idle ({@link SetUserAsIdleAction})
|
||||||
* @method trackIdleness
|
* @method trackIdleness
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public trackIdleness$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
public trackIdleness$: Observable<Action> = createEffect(() => this.actions$.pipe(
|
||||||
filter((action: Action) => !IDLE_TIMER_IGNORE_TYPES.includes(action.type)),
|
filter((action: Action) => !IDLE_TIMER_IGNORE_TYPES.includes(action.type)),
|
||||||
// Using switchMap the effect will stop subscribing to the previous timer if a new action comes
|
// Using switchMap the effect will stop subscribing to the previous timer if a new action comes
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { createSelector } from '@ngrx/store';
|
import { createFeatureSelector, createSelector } from '@ngrx/store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every reducer module's default export is the reducer function itself. In
|
* Every reducer module's default export is the reducer function itself. In
|
||||||
@@ -8,6 +8,8 @@ import { createSelector } from '@ngrx/store';
|
|||||||
*/
|
*/
|
||||||
import { AuthState } from './auth.reducer';
|
import { AuthState } from './auth.reducer';
|
||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
|
import { CoreState } from '../core.reducers';
|
||||||
|
import { coreSelector } from '../core.selectors';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the user state.
|
* Returns the user state.
|
||||||
@@ -15,7 +17,7 @@ import { AppState } from '../../app.reducer';
|
|||||||
* @param {AppState} state Top level state.
|
* @param {AppState} state Top level state.
|
||||||
* @return {AuthState}
|
* @return {AuthState}
|
||||||
*/
|
*/
|
||||||
export const getAuthState = (state: any) => state.core.auth;
|
export const getAuthState = createSelector(coreSelector, (state: CoreState) => state.auth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the user is authenticated.
|
* Returns true if the user is authenticated.
|
||||||
|
@@ -8,7 +8,7 @@ import { SubmissionObjectEntry, SubmissionSectionObject } from './objects/submis
|
|||||||
* Export a function to return a subset of the state by key
|
* Export a function to return a subset of the state by key
|
||||||
*/
|
*/
|
||||||
export function keySelector<T, V>(parentSelector: Selector<any, any>, subState: string, key: string): MemoizedSelector<T, V> {
|
export function keySelector<T, V>(parentSelector: Selector<any, any>, subState: string, key: string): MemoizedSelector<T, V> {
|
||||||
return createSelector(parentSelector, (state: T) => {
|
return createSelector<T,unknown[],V>(parentSelector, (state: T) => {
|
||||||
if (hasValue(state) && hasValue(state[subState])) {
|
if (hasValue(state) && hasValue(state[subState])) {
|
||||||
return state[subState][key];
|
return state[subState][key];
|
||||||
} else {
|
} else {
|
||||||
@@ -21,7 +21,7 @@ export function keySelector<T, V>(parentSelector: Selector<any, any>, subState:
|
|||||||
* Export a function to return a subset of the state
|
* Export a function to return a subset of the state
|
||||||
*/
|
*/
|
||||||
export function subStateSelector<T, V>(parentSelector: Selector<any, any>, subState: string): MemoizedSelector<T, V> {
|
export function subStateSelector<T, V>(parentSelector: Selector<any, any>, subState: string): MemoizedSelector<T, V> {
|
||||||
return createSelector(parentSelector, (state: T) => {
|
return createSelector<T,unknown[],V>(parentSelector, (state: T) => {
|
||||||
if (hasValue(state) && hasValue(state[subState])) {
|
if (hasValue(state) && hasValue(state[subState])) {
|
||||||
return state[subState];
|
return state[subState];
|
||||||
} else {
|
} else {
|
||||||
|
12
src/test.ts
12
src/test.ts
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import 'zone.js/testing';
|
import 'zone.js/testing';
|
||||||
import { getTestBed } from '@angular/core/testing';
|
import { getTestBed } from '@angular/core/testing';
|
||||||
|
import { MockStore } from '@ngrx/store/testing';
|
||||||
import {
|
import {
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting
|
platformBrowserDynamicTesting
|
||||||
@@ -12,10 +13,15 @@ declare const require: any;
|
|||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
getTestBed().initTestEnvironment(
|
getTestBed().initTestEnvironment(
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting(), {
|
platformBrowserDynamicTesting(),
|
||||||
teardown: { destroyAfterEach: false }
|
{ teardown: { destroyAfterEach: false } }
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If store is mocked, reset state after each test (see https://ngrx.io/guide/migration/v13)
|
||||||
|
jasmine.getEnv().afterEach(() => {
|
||||||
|
getTestBed().inject(MockStore, null)?.resetSelectors();
|
||||||
|
});
|
||||||
|
|
||||||
// Then we find all the tests.
|
// Then we find all the tests.
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
// And load the modules.
|
// And load the modules.
|
||||||
|
Reference in New Issue
Block a user