Skip to content

Commit

Permalink
Improve token validation logic and fix test coverage (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssylver93 authored Dec 9, 2024
1 parent ca16ca7 commit caf7c69
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { TestBed } from '@angular/core/testing';
import { PrevAuthGuard } from './prev-auth-guard';
import { TokenService } from 'src/app/services/token.service';
import { AppConfigService } from 'src/app/services/app-config.service';
import { Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';
import { of, Subject, BehaviorSubject } from 'rxjs';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { ResourcesRoutes } from 'src/app/utils';
import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import { BehaviorSubject, of, Subject } from 'rxjs';
import { AppConfigService } from 'src/app/services/app-config.service';
import { TokenService } from 'src/app/services/token.service';
import { PrevAuthGuard } from './prev-auth-guard';

class MockActivatedRouteSnapshot extends ActivatedRouteSnapshot {
constructor(public routeConfigOverride?: any) {
Expand Down Expand Up @@ -188,25 +187,71 @@ describe('PrevAuthGuard', () => {
});
});

it('should handle route with scopes when token validation fails', (done) => {
// Setup route with scopes
it('should redirect user to error page when token validation fails', fakeAsync(() => {
const route = new ActivatedRouteSnapshot();
route.data = { scopes: [['test-scope']] };


const state = jasmine.createSpyObj<RouterStateSnapshot>('RouterStateSnapshot', [], { url: '/test' });

// Mock token exists
tokenService.getOauthToken.and.returnValue('test-token');

// Mock token validation fails
tokenService.validateToken.and.returnValue(of(false));

// Spy on redirectToErrorPage
spyOn(guard, 'redirectToErrorPage');

guard.canActivate(route, state).subscribe(result => {
expect(guard.redirectToErrorPage).toHaveBeenCalled();
done();
});

guard.canActivate(route, state);

tick();
flush(); // Flush any remaining async operations

expect(guard.redirectToErrorPage).toHaveBeenCalled();
}));
})

it('should redirect to error page when getTokenInfo returns false', fakeAsync(() => {
const route = new MockActivatedRouteSnapshot();
route.data = { scopes: [['test-scope']] };
const state = jasmine.createSpyObj<RouterStateSnapshot>('RouterStateSnapshot', [], {
url: '/test'
});
});

// Spy on getTokenInfo to return false
spyOn(guard, 'getTokenInfo' as any).and.returnValue(Promise.resolve(false));

// Spy on redirectToErrorPage
spyOn(guard, 'redirectToErrorPage');

guard.canActivate(route, state).subscribe();

tick();
flush(); // Flush any remaining async operations

expect(guard.redirectToErrorPage).toHaveBeenCalled();
}));

it('should redirect to error page when getTokenInfo returns undefined', fakeAsync(() => {
const route = new MockActivatedRouteSnapshot();
route.data = { scopes: [['test-scope']] };
const state = jasmine.createSpyObj<RouterStateSnapshot>('RouterStateSnapshot', [], {
url: '/test'
});

// Spy on getTokenInfo to return undefined
spyOn(guard, 'getTokenInfo' as any).and.returnValue(Promise.resolve(undefined));

// Spy on redirectToErrorPage
spyOn(guard, 'redirectToErrorPage');

guard.canActivate(route, state).subscribe();

tick();
flush(); // Flush any remaining async operations

expect(guard.redirectToErrorPage).toHaveBeenCalled();
}));

describe('getTokenInfo', () => {
let mockRoute: any;
Expand Down Expand Up @@ -284,31 +329,31 @@ describe('PrevAuthGuard', () => {
tokenService.getOauthToken.and.returnValue(null);

const result = await guard.canAccessRoute([['test-scope']], tokenService);

expect(result).toBeFalse();
});

it('should return true when token is validated successfully', async () => {
// Mock token exists
tokenService.getOauthToken.and.returnValue('test-token');

// Mock token validation
tokenService.validateToken.and.returnValue(of(true));

const result = await guard.canAccessRoute([['test-scope']], tokenService);

expect(result).toBeTrue();
});

it('should return false when token validation fails', async () => {
// Mock token exists
tokenService.getOauthToken.and.returnValue('test-token');

// Mock token validation fails
tokenService.validateToken.and.returnValue(of(false));

const result = await guard.canAccessRoute([['test-scope']], tokenService);

expect(result).toBeFalse();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,26 @@ export class PrevAuthGuard extends AuthGuard {
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> {

if (!window.navigator.onLine) {
return of(false);
}

if (route?.data?.['scopes']?.length > 0) {
// Wrap the Promise returned by getTokenInfo with from()
return from(this.getTokenInfo(route)).pipe(
map(result => result),
catchError(() => of(false))
map(result => {
if (result === false || result === undefined) {
this.redirectToErrorPage();
return of(false);
}
return result;
}),
catchError(() => {
this.redirectToErrorPage();
return of(false);
})
);
} else {
console.log('returning true');
return of(true);
}
}
Expand Down

0 comments on commit caf7c69

Please sign in to comment.