Files
SchotzIAD/frontend/src/app/core/guards/auth.guard.spec.ts
T
MadJax 9db3c91471 Corrige auth.guard.spec.ts : la garde valide desormais la session serveur
Le test datait d'avant l'evolution d'authGuard en Observable<boolean|UrlTree>
(validation de la session via GET /api/auth/moi, pour rejeter un jeton
residuel dont le compte n'existe plus). Mock de AuthService.validerSession
et resolution async du resultat de la garde. Ajout d'un 3e cas : session
invalide (401) -> redirection /login. 19/19 tests frontend verts (Karma
via Brave, CHROME_BIN=/usr/bin/brave-browser).
2026-09-25 12:06:29 +02:00

101 lines
3.6 KiB
TypeScript

import { TestBed } from '@angular/core/testing';
import { Router, UrlTree } from '@angular/router';
import {
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { Observable, of, throwError } from 'rxjs';
import { isObservable } from 'rxjs';
import { authGuard } from './auth.guard';
import { AuthService } from '../services/auth.service';
/**
* Tests unitaires de la garde `authGuard` (CanActivateFn).
*
* Tâche 10.4 — Exigences 4.6 (routes protégées), 9.3 (redirection onboarding/login).
* La garde est exécutée via `TestBed.runInInjectionContext` pour disposer du
* contexte d'injection (`inject(...)`).
*
* La garde retourne un `Observable<boolean | UrlTree>` : en présence d'un jeton local,
* elle valide la session côté serveur via `AuthService.validerSession()` avant de
* conclure (Exigence 9 : rejet d'un jeton résiduel dont le compte n'existe plus).
*/
describe('authGuard', () => {
let estAuthentifieValeur: boolean;
let urlTreeFactice: UrlTree;
let createUrlTreeSpy: jasmine.Spy;
let validerSessionSpy: jasmine.Spy;
// Paramètres de la CanActivateFn (non utilisés par la garde, mais requis).
const route = {} as ActivatedRouteSnapshot;
const state = { url: '/consultation' } as RouterStateSnapshot;
beforeEach(() => {
urlTreeFactice = {} as UrlTree;
validerSessionSpy = jasmine.createSpy('validerSession');
const authServiceMock: Partial<AuthService> = {
estAuthentifie: (() => estAuthentifieValeur) as AuthService['estAuthentifie'],
validerSession: validerSessionSpy as unknown as AuthService['validerSession']
};
createUrlTreeSpy = jasmine.createSpy('createUrlTree').and.returnValue(urlTreeFactice);
const routerMock: Partial<Router> = {
createUrlTree: createUrlTreeSpy as unknown as Router['createUrlTree']
};
TestBed.configureTestingModule({
providers: [
{ provide: AuthService, useValue: authServiceMock },
{ provide: Router, useValue: routerMock }
]
});
});
/** Résout l'Observable (ou la valeur synchrone) retourné par la garde. */
function resoudre(resultat: unknown): Promise<unknown> {
return isObservable(resultat)
? new Promise((resolve) => (resultat as Observable<unknown>).subscribe((v) => resolve(v)))
: Promise.resolve(resultat);
}
it('retourne true lorsque l utilisateur est authentifié et que la session est valide côté serveur', async () => {
estAuthentifieValeur = true;
validerSessionSpy.and.returnValue(of({ authentifie: true }));
const resultat = await resoudre(
TestBed.runInInjectionContext(() => authGuard(route, state))
);
expect(resultat).toBeTrue();
expect(validerSessionSpy).toHaveBeenCalled();
expect(createUrlTreeSpy).not.toHaveBeenCalled();
});
it('retourne un UrlTree vers /login lorsque aucun jeton local n est présent', async () => {
estAuthentifieValeur = false;
const resultat = await resoudre(
TestBed.runInInjectionContext(() => authGuard(route, state))
);
expect(validerSessionSpy).not.toHaveBeenCalled();
expect(createUrlTreeSpy).toHaveBeenCalledWith(['/login']);
expect(resultat).toBe(urlTreeFactice);
});
it('retourne un UrlTree vers /login lorsque la validation de session échoue (jeton résiduel invalide)', async () => {
estAuthentifieValeur = true;
validerSessionSpy.and.returnValue(throwError(() => new Error('401')));
const resultat = await resoudre(
TestBed.runInInjectionContext(() => authGuard(route, state))
);
expect(validerSessionSpy).toHaveBeenCalled();
expect(createUrlTreeSpy).toHaveBeenCalledWith(['/login']);
expect(resultat).toBe(urlTreeFactice);
});
});