AAE-39851 BffAuthErrorInterceptor: use DI for BFF redirect and update tests

This commit is contained in:
alep85
2025-12-05 17:09:05 +01:00
parent bf7abe5444
commit 1078741150
2 changed files with 44 additions and 5 deletions
@@ -19,9 +19,32 @@ import { HttpErrorResponse, HttpRequest } from '@angular/common/http';
import { TestBed } from '@angular/core/testing';
import { EMPTY, throwError, firstValueFrom } from 'rxjs';
import { bffAuthErrorInterceptor } from './bff-auth-error.interceptor';
import { BffUrlBuilder } from './bff-url-builder.service';
import { DOCUMENT } from '@angular/common';
describe('bffAuthErrorInterceptor', () => {
it('should return EMPTY when 401 error occurs on /bff/ URL', async () => {
let mockDocument: any;
let mockBffUrlBuilder: jasmine.SpyObj<BffUrlBuilder>;
beforeEach(() => {
mockDocument = {
location: {
href: ''
}
};
mockBffUrlBuilder = jasmine.createSpyObj('BffUrlBuilder', ['getLoginUrl']);
mockBffUrlBuilder.getLoginUrl.and.returnValue('http://localhost/bff/login');
TestBed.configureTestingModule({
providers: [
{ provide: DOCUMENT, useValue: mockDocument },
{ provide: BffUrlBuilder, useValue: mockBffUrlBuilder }
]
});
});
it('should redirect to login URL when 401 error occurs on /bff/ URL', async () => {
const req = new HttpRequest('GET', '/bff/resource');
const httpError = new HttpErrorResponse({ status: 401, url: '/bff/resource' });
const next = () => throwError(() => httpError);
@@ -30,6 +53,8 @@ describe('bffAuthErrorInterceptor', () => {
const result = await firstValueFrom(result$, { defaultValue: null });
expect(result).toBeNull();
expect(mockBffUrlBuilder.getLoginUrl).toHaveBeenCalled();
expect(mockDocument.location.href).toBe('http://localhost/bff/login');
});
it('should rethrow error when 401 on non-/bff/ URL', async () => {
@@ -40,6 +65,8 @@ describe('bffAuthErrorInterceptor', () => {
const result$ = TestBed.runInInjectionContext(() => bffAuthErrorInterceptor(req, next));
await expectAsync(firstValueFrom(result$)).toBeRejectedWith(httpError);
expect(mockBffUrlBuilder.getLoginUrl).not.toHaveBeenCalled();
expect(mockDocument.location.href).toBe('');
});
it('should rethrow error when status is not 401 even on /bff/ URL', async () => {
@@ -50,6 +77,8 @@ describe('bffAuthErrorInterceptor', () => {
const result$ = TestBed.runInInjectionContext(() => bffAuthErrorInterceptor(req, next));
await expectAsync(firstValueFrom(result$)).toBeRejectedWith(httpError);
expect(mockBffUrlBuilder.getLoginUrl).not.toHaveBeenCalled();
expect(mockDocument.location.href).toBe('');
});
it('should pass through successful response without intercepting', async () => {
@@ -60,5 +89,7 @@ describe('bffAuthErrorInterceptor', () => {
const result = await firstValueFrom(result$, { defaultValue: null });
expect(result).toBeNull();
expect(mockBffUrlBuilder.getLoginUrl).not.toHaveBeenCalled();
expect(mockDocument.location.href).toBe('');
});
});
@@ -18,18 +18,26 @@
import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { EMPTY, throwError } from 'rxjs';
import { BffUrlBuilder } from './bff-url-builder.service';
import { inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
/* eslint-disable no-console */
export const bffAuthErrorInterceptor: HttpInterceptorFn = (req, next) =>
next(req).pipe(
export const bffAuthErrorInterceptor: HttpInterceptorFn = (req, next) => {
const bffUrlBuilder = inject(BffUrlBuilder);
const document = inject(DOCUMENT);
return next(req).pipe(
catchError((err: HttpErrorResponse) => {
console.log('%c[bffAuthErrorInterceptor] err: ', 'color: red;', err);
if (err.status === 401 && req.url.includes('/bff/')) {
const returnUrl = window.location.pathname + window.location.search;
window.location.href = `/bff/login?returnUrl=${encodeURIComponent(returnUrl)}`;
const url = bffUrlBuilder.getLoginUrl();
console.log('%c[bffAuthErrorInterceptor] redirecting to login URL: ', 'color: yellow;', url);
document.location.href = url;
return EMPTY;
}
return throwError(() => err);
})
);
};