Skip to content
Snippets Groups Projects
Commit d3b2e16b authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-3696 OZG-4180 Add handling for HTTP error 403' (#273)...

Merge pull request 'OZG-3696 OZG-4180 Add handling for HTTP error 403' (#273) from OZG-3969-Umleiten-Wiedervorlage into master

Reviewed-on: https://git.ozg-sh.de/mgm/goofy/pulls/273


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents c32299df 7f4fa638
No related branches found
No related tags found
No related merge requests found
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen * Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen. * unter der Lizenz sind dem Lizenztext zu entnehmen.
*/ */
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot, UrlSegment } from '@angular/router'; import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot, UrlSegment } from '@angular/router';
import faker from '@faker-js/faker'; import faker from '@faker-js/faker';
...@@ -28,7 +29,7 @@ import { encodeUrlForEmbedding } from '@goofy-client/tech-shared'; ...@@ -28,7 +29,7 @@ import { encodeUrlForEmbedding } from '@goofy-client/tech-shared';
import { mock } from '@goofy-client/test-utils'; import { mock } from '@goofy-client/test-utils';
import { SnackBarService } from '@goofy-client/ui'; import { SnackBarService } from '@goofy-client/ui';
import { WiedervorlageService } from '@goofy-client/wiedervorlage-shared'; import { WiedervorlageService } from '@goofy-client/wiedervorlage-shared';
import { Observable, of } from 'rxjs'; import { EMPTY, Observable, of } from 'rxjs';
import * as RouterHelper from '@angular/router'; import * as RouterHelper from '@angular/router';
import * as Guard from './wiedervorlage.guard'; import * as Guard from './wiedervorlage.guard';
...@@ -39,6 +40,7 @@ const state: RouterStateSnapshot = { root: { url: [<UrlSegment>{}] } } as unknow ...@@ -39,6 +40,7 @@ const state: RouterStateSnapshot = { root: { url: [<UrlSegment>{}] } } as unknow
describe('wiedervorlageGuard', () => { describe('wiedervorlageGuard', () => {
const wiedervorlageService = mock(WiedervorlageService); const wiedervorlageService = mock(WiedervorlageService);
const snackbarService = mock(SnackBarService); const snackbarService = mock(SnackBarService);
const createUrlTreeForVorgang = jest.spyOn(Guard, 'createUrlTreeForVorgang').mockReturnValue(<RouterHelper.UrlTree>{});
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
...@@ -54,7 +56,7 @@ describe('wiedervorlageGuard', () => { ...@@ -54,7 +56,7 @@ describe('wiedervorlageGuard', () => {
] ]
}); });
jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(false)); jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(EMPTY);
}); });
...@@ -65,6 +67,7 @@ describe('wiedervorlageGuard', () => { ...@@ -65,6 +67,7 @@ describe('wiedervorlageGuard', () => {
}); });
describe('wiedervorlageGuard', () => { describe('wiedervorlageGuard', () => {
it('should call wiedervorlageService.hasEditLink', () => { it('should call wiedervorlageService.hasEditLink', () => {
const spy = jest.spyOn(wiedervorlageService, 'hasEditLink'); const spy = jest.spyOn(wiedervorlageService, 'hasEditLink');
next.params['wiedervorlageUrl'] = encodeUrlForEmbedding(faker.internet.url()); next.params['wiedervorlageUrl'] = encodeUrlForEmbedding(faker.internet.url());
...@@ -74,37 +77,40 @@ describe('wiedervorlageGuard', () => { ...@@ -74,37 +77,40 @@ describe('wiedervorlageGuard', () => {
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}) })
it('should call createUrlTreeFromSnapshot', () => { it('should return UrlTree object', (done) => {
const createUrlTreeFromSnapshot = jest.spyOn(RouterHelper, 'createUrlTreeFromSnapshot');
jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(false)); jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(false));
TestBed.runInInjectionContext(() => ( TestBed.runInInjectionContext(() => (
Guard.wiedervorlageGuard(next, state) as Observable<RouterHelper.UrlTree>).subscribe() Guard.wiedervorlageGuard(next, state) as Observable<RouterHelper.UrlTree>).subscribe(
result => {
expect(result).toBeInstanceOf(Object);
done();
}
)
) as unknown as CanActivateFn; ) as unknown as CanActivateFn;
expect(createUrlTreeFromSnapshot).toHaveBeenCalled();
}) })
it.skip('should return UrlTree', (done) => { it('should return true', (done) => {
jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(false)); jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(true));
TestBed.runInInjectionContext(() => ( TestBed.runInInjectionContext(() => (
Guard.wiedervorlageGuard(next, state) as Observable<RouterHelper.UrlTree>).subscribe( Guard.wiedervorlageGuard(next, state) as Observable<RouterHelper.UrlTree>).subscribe(
result => { result => {
expect(result).toBeInstanceOf(RouterHelper.UrlTree); expect(result).toBeTruthy();
done(); done();
} }
) )
) as unknown as CanActivateFn; ) as unknown as CanActivateFn;
}) })
it('should return true', (done) => { it.skip('should call handleError if error occurs', (done) => {
jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(true)); jest.spyOn(wiedervorlageService, 'hasEditLink').mockReturnValue(of(new Error()));
const spy = jest.spyOn(Guard, 'handleError');
TestBed.runInInjectionContext(() => ( TestBed.runInInjectionContext(() => (
Guard.wiedervorlageGuard(next, state) as Observable<RouterHelper.UrlTree>).subscribe( Guard.wiedervorlageGuard(next, state) as Observable<RouterHelper.UrlTree>).subscribe(
result => { () => {
expect(result).toBeTruthy(); expect(spy).toHaveBeenCalled();
done(); done();
} }
) )
...@@ -121,7 +127,7 @@ describe('wiedervorlageGuard', () => { ...@@ -121,7 +127,7 @@ describe('wiedervorlageGuard', () => {
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}) })
it.skip('should call showSnackbar if hasLink is false', () => { it('should call showSnackbar if hasLink is false', () => {
const hasLink = false; const hasLink = false;
const spy = jest.spyOn(Guard, 'showSnackbar'); const spy = jest.spyOn(Guard, 'showSnackbar');
...@@ -130,14 +136,13 @@ describe('wiedervorlageGuard', () => { ...@@ -130,14 +136,13 @@ describe('wiedervorlageGuard', () => {
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}) })
it.skip('should return URLTree object if hasLink is false', () => { it('should call createUrlTreeForVorgang if hasLink is false', () => {
const spy = jest.spyOn(RouterHelper, 'createUrlTreeFromSnapshot');
const hasLink = false; const hasLink = false;
jest.spyOn(Guard, 'showSnackbar'); jest.spyOn(Guard, 'showSnackbar');
Guard.handleLinkCheck(hasLink, next, snackbarService as unknown as SnackBarService); Guard.handleLinkCheck(hasLink, next, snackbarService as unknown as SnackBarService);
expect(spy).toHaveBeenCalled(); expect(createUrlTreeForVorgang).toHaveBeenCalled();
}) })
}) })
...@@ -151,4 +156,28 @@ describe('wiedervorlageGuard', () => { ...@@ -151,4 +156,28 @@ describe('wiedervorlageGuard', () => {
}) })
}) })
describe('handleError', () => {
it('should return Observable<UrlTree> if HTTP Status 403', () => {
const error = createHttpError(HttpStatusCode.Forbidden);
const res: RouterHelper.UrlTree = Guard.handleError(error, next);
expect(res).toBeInstanceOf(Object);
})
it('should return nothing if HTTP Status is not 403', () => {
const error = createHttpError(HttpStatusCode.Unauthorized);
function monitorErrorThrowing() {
Guard.handleError(error, next);
}
expect(monitorErrorThrowing).toThrow();
})
})
function createHttpError(status: HttpStatusCode): any {
return { error: new HttpErrorResponse({ status }) };
}
}); });
...@@ -23,11 +23,14 @@ ...@@ -23,11 +23,14 @@
*/ */
import { inject } from '@angular/core'; import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot, UrlTree, createUrlTreeFromSnapshot } from '@angular/router'; import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot, UrlTree, createUrlTreeFromSnapshot } from '@angular/router';
import { isForbidden } from '@goofy-client/tech-shared';
import { SnackBarService } from '@goofy-client/ui'; import { SnackBarService } from '@goofy-client/ui';
import { WiedervorlageService } from '@goofy-client/wiedervorlage-shared'; import { WiedervorlageService } from '@goofy-client/wiedervorlage-shared';
import { map } from 'rxjs'; import { Observable, catchError, map, of } from 'rxjs';
export const wiedervorlageGuard: CanActivateFn = (next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { import * as Guard from './wiedervorlage.guard';
export const wiedervorlageGuard: CanActivateFn = (next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean | UrlTree> | UrlTree => {
const wiedervorlageService = inject(WiedervorlageService) const wiedervorlageService = inject(WiedervorlageService)
const snackbarService = inject(SnackBarService); const snackbarService = inject(SnackBarService);
...@@ -37,7 +40,8 @@ export const wiedervorlageGuard: CanActivateFn = (next: ActivatedRouteSnapshot, ...@@ -37,7 +40,8 @@ export const wiedervorlageGuard: CanActivateFn = (next: ActivatedRouteSnapshot,
} }
return wiedervorlageService.hasEditLink(wiedervorlageUrl).pipe( return wiedervorlageService.hasEditLink(wiedervorlageUrl).pipe(
map(hasLink => handleLinkCheck(hasLink, next, snackbarService)) map(hasLink => Guard.handleLinkCheck(hasLink, next, snackbarService)),
catchError((err) => of(Guard.handleError(err, next)))
); );
}; };
...@@ -46,11 +50,23 @@ export function handleLinkCheck(hasLink: boolean, next: ActivatedRouteSnapshot, ...@@ -46,11 +50,23 @@ export function handleLinkCheck(hasLink: boolean, next: ActivatedRouteSnapshot,
return true; return true;
} }
showSnackbar(snackbarService); Guard.showSnackbar(snackbarService);
return createUrlTreeFromSnapshot(next, ['/vorgang', next.params['vorgangWithEingangUrl']]); return Guard.createUrlTreeForVorgang(next);
} }
export function showSnackbar(snackbarService: SnackBarService): void { export function showSnackbar(snackbarService: SnackBarService): void {
snackbarService.showError('Im Status "Zu löschen" ist die Bearbeitung von Wiedervorlagen nicht möglich.'); snackbarService.showError('Im Status "Zu löschen" ist die Bearbeitung von Wiedervorlagen nicht möglich.');
} }
export function handleError(err: any, next: ActivatedRouteSnapshot): UrlTree {
if (isForbidden(err.error.status)) {
return Guard.createUrlTreeForVorgang(next);
}
throw err;
}
export function createUrlTreeForVorgang(next: ActivatedRouteSnapshot): UrlTree {
return createUrlTreeFromSnapshot(next, ['/vorgang', next.params['vorgangWithEingangUrl']]);
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment