AAE-25392 Convert route guards to functional - part two (#10116)

This commit is contained in:
Ehsan Rezaei 2024-08-29 17:25:19 +02:00 committed by GitHub
parent 7910cd96c4
commit 0433ada548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 73 deletions

View File

@ -16,16 +16,13 @@
*/
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { provideRouter, Routes } from '@angular/router';
import { AuthenticationConfirmationComponent } from './view/authentication-confirmation/authentication-confirmation.component';
import { OidcAuthGuard } from './oidc-auth.guard';
const routes: Routes = [
{ path: 'view/authentication-confirmation', component: AuthenticationConfirmationComponent, canActivate: [OidcAuthGuard]}
];
const routes: Routes = [{ path: 'view/authentication-confirmation', component: AuthenticationConfirmationComponent, canActivate: [OidcAuthGuard] }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
providers: [provideRouter(routes)]
})
export class AuthRoutingModule {}

View File

@ -17,77 +17,45 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import { OidcAuthGuard } from './oidc-auth.guard';
import { AuthService } from './auth.service';
describe('OidcAuthGuard', () => {
let oidcAuthGuard: OidcAuthGuard;
let authServiceSpy: jasmine.SpyObj<AuthService>;
let routerSpy: jasmine.SpyObj<Router>;
const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
const state: RouterStateSnapshot = {} as RouterStateSnapshot;
beforeEach(() => {
const routerSpyObj = jasmine.createSpyObj('Router', ['navigateByUrl']);
const authSpy = jasmine.createSpyObj('AuthService', ['loginCallback']);
TestBed.configureTestingModule({
providers: [
OidcAuthGuard,
{ provide: AuthService, useValue: authSpy },
{ provide: Router, useValue: routerSpyObj }
],
providers: [OidcAuthGuard, { provide: AuthService, useValue: authSpy }, { provide: Router, useValue: routerSpyObj }],
imports: [RouterTestingModule]
});
routerSpy = TestBed.inject(Router) as jasmine.SpyObj<Router>;
oidcAuthGuard = TestBed.inject(OidcAuthGuard);
authServiceSpy = TestBed.inject(AuthService) as jasmine.SpyObj<AuthService>;
});
describe('canActivate', () => {
it('should return true if is authenticated', () => {
it('should return true if is authenticated', async () => {
authServiceSpy.authenticated = true;
const result = oidcAuthGuard.canActivate();
const oidcAuthGuard = await TestBed.runInInjectionContext(() => OidcAuthGuard(route, state));
expect(result).toBe(true);
});
it('should call isAuthenticated and return the result', () => {
const isAuthenticatedSpy = spyOn<any>(oidcAuthGuard, '_isAuthenticated').and.returnValue(true);
const result = oidcAuthGuard.canActivate();
expect(isAuthenticatedSpy).toHaveBeenCalled();
expect(result).toBe(true);
});
});
describe('canActivateChild', () => {
it('should call isAuthenticated and return its result', () => {
const isAuthenticatedSpy = spyOn<any>(oidcAuthGuard, '_isAuthenticated').and.returnValue(true);
const result = oidcAuthGuard.canActivateChild();
expect(isAuthenticatedSpy).toHaveBeenCalled();
expect(result).toBe(true);
expect(oidcAuthGuard).toBe(true);
});
});
describe('isAuthenticated', () => {
it('should return true if is authenticated', () => {
authServiceSpy.authenticated = true;
const result = oidcAuthGuard['_isAuthenticated']();
expect(result).toBe(true);
});
it('should call loginCallback and navigateByUrl if not authenticated', async () => {
authServiceSpy.authenticated = false;
authServiceSpy.loginCallback.and.returnValue(Promise.resolve('/fake-route'));
await oidcAuthGuard.canActivate();
await TestBed.runInInjectionContext(() => OidcAuthGuard(route, state));
expect(authServiceSpy.loginCallback).toHaveBeenCalled();
expect(routerSpy.navigateByUrl).toHaveBeenCalledWith('/fake-route', { replaceUrl: true });
@ -97,7 +65,7 @@ describe('OidcAuthGuard', () => {
authServiceSpy.authenticated = false;
authServiceSpy.loginCallback.and.returnValue(Promise.reject(new Error()));
await oidcAuthGuard.canActivate();
await TestBed.runInInjectionContext(() => OidcAuthGuard(route, state));
expect(routerSpy.navigateByUrl).toHaveBeenCalledWith('/', { replaceUrl: true });
});

View File

@ -15,37 +15,24 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { CanActivate, Router, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';
const ROUTE_DEFAULT = '/';
@Injectable({
providedIn: 'root'
})
export class OidcAuthGuard implements CanActivate {
constructor(private auth: AuthService, private _router: Router) { }
export const OidcAuthGuard: CanActivateFn = async (): Promise<boolean> => {
const authService = inject(AuthService);
const router = inject(Router);
canActivate(
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this._isAuthenticated();
if (authService.authenticated) {
return Promise.resolve(true);
}
canActivateChild() {
return this._isAuthenticated();
try {
const route = await authService.loginCallback({ customHashFragment: window.location.search });
return router.navigateByUrl(route, { replaceUrl: true });
} catch (error) {
return router.navigateByUrl(ROUTE_DEFAULT, { replaceUrl: true });
}
private _isAuthenticated() {
if (this.auth.authenticated) {
return true;
}
return this.auth.loginCallback({ customHashFragment: window.location.search })
.then(route => this._router.navigateByUrl(route, { replaceUrl: true }))
.catch(() => this._router.navigateByUrl(ROUTE_DEFAULT, { replaceUrl: true }));
}
}
};