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).
This commit is contained in:
2026-09-25 12:06:29 +02:00
parent 7e80427e09
commit 9db3c91471
@@ -4,6 +4,8 @@ import {
ActivatedRouteSnapshot, ActivatedRouteSnapshot,
RouterStateSnapshot RouterStateSnapshot
} from '@angular/router'; } from '@angular/router';
import { Observable, of, throwError } from 'rxjs';
import { isObservable } from 'rxjs';
import { authGuard } from './auth.guard'; import { authGuard } from './auth.guard';
import { AuthService } from '../services/auth.service'; import { AuthService } from '../services/auth.service';
@@ -14,11 +16,16 @@ import { AuthService } from '../services/auth.service';
* Tâche 10.4 — Exigences 4.6 (routes protégées), 9.3 (redirection onboarding/login). * 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 * La garde est exécutée via `TestBed.runInInjectionContext` pour disposer du
* contexte d'injection (`inject(...)`). * 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', () => { describe('authGuard', () => {
let estAuthentifieValeur: boolean; let estAuthentifieValeur: boolean;
let urlTreeFactice: UrlTree; let urlTreeFactice: UrlTree;
let createUrlTreeSpy: jasmine.Spy; let createUrlTreeSpy: jasmine.Spy;
let validerSessionSpy: jasmine.Spy;
// Paramètres de la CanActivateFn (non utilisés par la garde, mais requis). // Paramètres de la CanActivateFn (non utilisés par la garde, mais requis).
const route = {} as ActivatedRouteSnapshot; const route = {} as ActivatedRouteSnapshot;
@@ -27,8 +34,10 @@ describe('authGuard', () => {
beforeEach(() => { beforeEach(() => {
urlTreeFactice = {} as UrlTree; urlTreeFactice = {} as UrlTree;
validerSessionSpy = jasmine.createSpy('validerSession');
const authServiceMock: Partial<AuthService> = { const authServiceMock: Partial<AuthService> = {
estAuthentifie: (() => estAuthentifieValeur) as AuthService['estAuthentifie'] estAuthentifie: (() => estAuthentifieValeur) as AuthService['estAuthentifie'],
validerSession: validerSessionSpy as unknown as AuthService['validerSession']
}; };
createUrlTreeSpy = jasmine.createSpy('createUrlTree').and.returnValue(urlTreeFactice); createUrlTreeSpy = jasmine.createSpy('createUrlTree').and.returnValue(urlTreeFactice);
@@ -44,20 +53,47 @@ describe('authGuard', () => {
}); });
}); });
it('retourne true lorsque l utilisateur est authentifié', () => { /** Résout l'Observable (ou la valeur synchrone) retourné par la garde. */
estAuthentifieValeur = true; function resoudre(resultat: unknown): Promise<unknown> {
return isObservable(resultat)
? new Promise((resolve) => (resultat as Observable<unknown>).subscribe((v) => resolve(v)))
: Promise.resolve(resultat);
}
const resultat = TestBed.runInInjectionContext(() => authGuard(route, state)); 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(resultat).toBeTrue();
expect(validerSessionSpy).toHaveBeenCalled();
expect(createUrlTreeSpy).not.toHaveBeenCalled(); expect(createUrlTreeSpy).not.toHaveBeenCalled();
}); });
it('retourne un UrlTree vers /login lorsque l utilisateur n est pas authentifié', () => { it('retourne un UrlTree vers /login lorsque aucun jeton local n est présent', async () => {
estAuthentifieValeur = false; estAuthentifieValeur = false;
const resultat = TestBed.runInInjectionContext(() => authGuard(route, state)); 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(createUrlTreeSpy).toHaveBeenCalledWith(['/login']);
expect(resultat).toBe(urlTreeFactice); expect(resultat).toBe(urlTreeFactice);
}); });