74053: redirectOn404Or401

This commit is contained in:
Kristof De Langhe
2020-10-27 11:25:12 +01:00
parent d4bd128b67
commit 736704aae8
8 changed files with 36 additions and 24 deletions

View File

@@ -17,7 +17,7 @@ import { DSpaceObjectType } from '../core/shared/dspace-object-type.model';
import { Item } from '../core/shared/item.model'; import { Item } from '../core/shared/item.model';
import { import {
getSucceededRemoteData, getSucceededRemoteData,
redirectToPageNotFoundOn404, redirectOn404Or401,
toDSpaceObjectListRD toDSpaceObjectListRD
} from '../core/shared/operators'; } from '../core/shared/operators';
@@ -63,7 +63,7 @@ export class CollectionPageComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.collectionRD$ = this.route.data.pipe( this.collectionRD$ = this.route.data.pipe(
map((data) => data.dso as RemoteData<Collection>), map((data) => data.dso as RemoteData<Collection>),
redirectToPageNotFoundOn404(this.router), redirectOn404Or401(this.router),
take(1) take(1)
); );
this.logoRD$ = this.collectionRD$.pipe( this.logoRD$ = this.collectionRD$.pipe(

View File

@@ -13,7 +13,7 @@ import { MetadataService } from '../core/metadata/metadata.service';
import { fadeInOut } from '../shared/animations/fade'; import { fadeInOut } from '../shared/animations/fade';
import { hasValue } from '../shared/empty.util'; import { hasValue } from '../shared/empty.util';
import { redirectToPageNotFoundOn404 } from '../core/shared/operators'; import { redirectOn404Or401 } from '../core/shared/operators';
@Component({ @Component({
selector: 'ds-community-page', selector: 'ds-community-page',
@@ -47,7 +47,7 @@ export class CommunityPageComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.communityRD$ = this.route.data.pipe( this.communityRD$ = this.route.data.pipe(
map((data) => data.dso as RemoteData<Community>), map((data) => data.dso as RemoteData<Community>),
redirectToPageNotFoundOn404(this.router) redirectOn404Or401(this.router)
); );
this.logoRD$ = this.communityRD$.pipe( this.logoRD$ = this.communityRD$.pipe(
map((rd: RemoteData<Community>) => rd.payload), map((rd: RemoteData<Community>) => rd.payload),

View File

@@ -11,7 +11,7 @@ import { Item } from '../../core/shared/item.model';
import { MetadataService } from '../../core/metadata/metadata.service'; import { MetadataService } from '../../core/metadata/metadata.service';
import { fadeInOut } from '../../shared/animations/fade'; import { fadeInOut } from '../../shared/animations/fade';
import { redirectToPageNotFoundOn404 } from '../../core/shared/operators'; import { redirectOn404Or401 } from '../../core/shared/operators';
import { ViewMode } from '../../core/shared/view-mode.model'; import { ViewMode } from '../../core/shared/view-mode.model';
/** /**
@@ -56,7 +56,7 @@ export class ItemPageComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.itemRD$ = this.route.data.pipe( this.itemRD$ = this.route.data.pipe(
map((data) => data.item as RemoteData<Item>), map((data) => data.item as RemoteData<Item>),
redirectToPageNotFoundOn404(this.router) redirectOn404Or401(this.router)
); );
this.metadataService.processRemoteData(this.itemRD$); this.metadataService.processRemoteData(this.itemRD$);
} }

View File

@@ -55,7 +55,7 @@ export function getDSORoute(dso: DSpaceObject): string {
} }
} }
export const UNAUTHORIZED_PATH = 'unauthorized'; export const UNAUTHORIZED_PATH = '401';
export function getUnauthorizedRoute() { export function getUnauthorizedRoute() {
return `/${UNAUTHORIZED_PATH}`; return `/${UNAUTHORIZED_PATH}`;

View File

@@ -13,7 +13,8 @@ import {
getRequestFromRequestUUID, getRequestFromRequestUUID,
getResourceLinksFromResponse, getResourceLinksFromResponse,
getResponseFromEntry, getResponseFromEntry,
getSucceededRemoteData, redirectToPageNotFoundOn404 getSucceededRemoteData,
redirectOn404Or401
} from './operators'; } from './operators';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { RemoteDataError } from '../data/remote-data-error'; import { RemoteDataError } from '../data/remote-data-error';
@@ -23,7 +24,7 @@ import {
createSuccessfulRemoteDataObject createSuccessfulRemoteDataObject
} from '../../shared/remote-data.utils'; } from '../../shared/remote-data.utils';
describe('Core Module - RxJS Operators', () => { fdescribe('Core Module - RxJS Operators', () => {
let scheduler: TestScheduler; let scheduler: TestScheduler;
let requestService: RequestService; let requestService: RequestService;
const testRequestHref = 'https://rest.api/'; const testRequestHref = 'https://rest.api/';
@@ -199,7 +200,7 @@ describe('Core Module - RxJS Operators', () => {
}); });
}); });
describe('redirectToPageNotFoundOn404', () => { describe('redirectOn404Or401', () => {
let router; let router;
beforeEach(() => { beforeEach(() => {
router = jasmine.createSpyObj('router', ['navigateByUrl']); router = jasmine.createSpyObj('router', ['navigateByUrl']);
@@ -208,21 +209,28 @@ describe('Core Module - RxJS Operators', () => {
it('should call navigateByUrl to a 404 page, when the remote data contains a 404 error', () => { it('should call navigateByUrl to a 404 page, when the remote data contains a 404 error', () => {
const testRD = createFailedRemoteDataObject(undefined, new RemoteDataError(404, 'Not Found', 'Object was not found')); const testRD = createFailedRemoteDataObject(undefined, new RemoteDataError(404, 'Not Found', 'Object was not found'));
observableOf(testRD).pipe(redirectToPageNotFoundOn404(router)).subscribe(); observableOf(testRD).pipe(redirectOn404Or401(router)).subscribe();
expect(router.navigateByUrl).toHaveBeenCalledWith('/404', { skipLocationChange: true }); expect(router.navigateByUrl).toHaveBeenCalledWith('/404', { skipLocationChange: true });
}); });
it('should not call navigateByUrl to a 404 page, when the remote data contains another error than a 404', () => { it('should call navigateByUrl to a 401 page, when the remote data contains a 401 error', () => {
const testRD = createFailedRemoteDataObject(undefined, new RemoteDataError(401, 'Unauthorized', 'The current user is unauthorized'));
observableOf(testRD).pipe(redirectOn404Or401(router)).subscribe();
expect(router.navigateByUrl).toHaveBeenCalledWith('/401', { skipLocationChange: true });
});
it('should not call navigateByUrl to a 404 or 401 page, when the remote data contains another error than a 404 or 401', () => {
const testRD = createFailedRemoteDataObject(undefined, new RemoteDataError(500, 'Server Error', 'Something went wrong')); const testRD = createFailedRemoteDataObject(undefined, new RemoteDataError(500, 'Server Error', 'Something went wrong'));
observableOf(testRD).pipe(redirectToPageNotFoundOn404(router)).subscribe(); observableOf(testRD).pipe(redirectOn404Or401(router)).subscribe();
expect(router.navigateByUrl).not.toHaveBeenCalled(); expect(router.navigateByUrl).not.toHaveBeenCalled();
}); });
it('should not call navigateByUrl to a 404 page, when the remote data contains no error', () => { it('should not call navigateByUrl to a 404 or 401 page, when the remote data contains no error', () => {
const testRD = createSuccessfulRemoteDataObject(undefined); const testRD = createSuccessfulRemoteDataObject(undefined);
observableOf(testRD).pipe(redirectToPageNotFoundOn404(router)).subscribe(); observableOf(testRD).pipe(redirectOn404Or401(router)).subscribe();
expect(router.navigateByUrl).not.toHaveBeenCalled(); expect(router.navigateByUrl).not.toHaveBeenCalled();
}); });
}); });

View File

@@ -171,16 +171,20 @@ export const getAllSucceededRemoteListPayload = () =>
); );
/** /**
* Operator that checks if a remote data object contains a page not found error * Operator that checks if a remote data object returned a 401 or 404 error
* When it does contain such an error, it will redirect the user to a page not found, without altering the current URL * When it does contain such an error, it will redirect the user to the related error page, without altering the current URL
* @param router The router used to navigate to a new page * @param router The router used to navigate to a new page
*/ */
export const redirectToPageNotFoundOn404 = (router: Router) => export const redirectOn404Or401 = (router: Router) =>
<T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> => <T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
source.pipe( source.pipe(
tap((rd: RemoteData<T>) => { tap((rd: RemoteData<T>) => {
if (rd.hasFailed && rd.error.statusCode === 404) { if (rd.hasFailed) {
router.navigateByUrl('/404', { skipLocationChange: true }); if (rd.error.statusCode === 404) {
router.navigateByUrl('/404', {skipLocationChange: true});
} else if (rd.error.statusCode === 401) {
router.navigateByUrl('/401', {skipLocationChange: true});
}
} }
})); }));

View File

@@ -4,7 +4,7 @@ import { Observable } from 'rxjs/internal/Observable';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Process } from '../processes/process.model'; import { Process } from '../processes/process.model';
import { map, switchMap } from 'rxjs/operators'; import { map, switchMap } from 'rxjs/operators';
import { getFirstSucceededRemoteDataPayload, redirectToPageNotFoundOn404 } from '../../core/shared/operators'; import { getFirstSucceededRemoteDataPayload, redirectOn404Or401 } from '../../core/shared/operators';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/aletr-type';
import { ProcessDataService } from '../../core/data/processes/process-data.service'; import { ProcessDataService } from '../../core/data/processes/process-data.service';
import { PaginatedList } from '../../core/data/paginated-list'; import { PaginatedList } from '../../core/data/paginated-list';
@@ -49,7 +49,7 @@ export class ProcessDetailComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.processRD$ = this.route.data.pipe( this.processRD$ = this.route.data.pipe(
map((data) => data.process as RemoteData<Process>), map((data) => data.process as RemoteData<Process>),
redirectToPageNotFoundOn404(this.router) redirectOn404Or401(this.router)
); );
this.filesRD$ = this.processRD$.pipe( this.filesRD$ = this.processRD$.pipe(

View File

@@ -4,7 +4,7 @@ import { UsageReportService } from '../../core/statistics/usage-report-data.serv
import { map, switchMap } from 'rxjs/operators'; import { map, switchMap } from 'rxjs/operators';
import { UsageReport } from '../../core/statistics/models/usage-report.model'; import { UsageReport } from '../../core/statistics/models/usage-report.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { getRemoteDataPayload, getSucceededRemoteData, redirectToPageNotFoundOn404 } from '../../core/shared/operators'; import { getRemoteDataPayload, getSucceededRemoteData, redirectOn404Or401 } from '../../core/shared/operators';
import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
@@ -55,7 +55,7 @@ export abstract class StatisticsPageComponent<T extends DSpaceObject> implements
protected getScope$(): Observable<DSpaceObject> { protected getScope$(): Observable<DSpaceObject> {
return this.route.data.pipe( return this.route.data.pipe(
map((data) => data.scope as RemoteData<T>), map((data) => data.scope as RemoteData<T>),
redirectToPageNotFoundOn404(this.router), redirectOn404Or401(this.router),
getSucceededRemoteData(), getSucceededRemoteData(),
getRemoteDataPayload(), getRemoteDataPayload(),
); );