From 9db3c9147190028fc66d5bb4362209e9fd2dda40 Mon Sep 17 00:00:00 2001 From: Nikolaz Date: Fri, 25 Sep 2026 12:06:29 +0200 Subject: [PATCH] Corrige auth.guard.spec.ts : la garde valide desormais la session serveur Le test datait d'avant l'evolution d'authGuard en Observable (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). --- .../src/app/core/guards/auth.guard.spec.ts | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/core/guards/auth.guard.spec.ts b/frontend/src/app/core/guards/auth.guard.spec.ts index 4b30511..f8e029e 100644 --- a/frontend/src/app/core/guards/auth.guard.spec.ts +++ b/frontend/src/app/core/guards/auth.guard.spec.ts @@ -4,6 +4,8 @@ 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'; @@ -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). * La garde est exécutée via `TestBed.runInInjectionContext` pour disposer du * contexte d'injection (`inject(...)`). + * + * La garde retourne un `Observable` : 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; @@ -27,8 +34,10 @@ describe('authGuard', () => { beforeEach(() => { urlTreeFactice = {} as UrlTree; + validerSessionSpy = jasmine.createSpy('validerSession'); const authServiceMock: Partial = { - estAuthentifie: (() => estAuthentifieValeur) as AuthService['estAuthentifie'] + estAuthentifie: (() => estAuthentifieValeur) as AuthService['estAuthentifie'], + validerSession: validerSessionSpy as unknown as AuthService['validerSession'] }; createUrlTreeSpy = jasmine.createSpy('createUrlTree').and.returnValue(urlTreeFactice); @@ -44,20 +53,47 @@ describe('authGuard', () => { }); }); - it('retourne true lorsque l utilisateur est authentifié', () => { - estAuthentifieValeur = true; + /** Résout l'Observable (ou la valeur synchrone) retourné par la garde. */ + function resoudre(resultat: unknown): Promise { + return isObservable(resultat) + ? new Promise((resolve) => (resultat as Observable).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(validerSessionSpy).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; - 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(resultat).toBe(urlTreeFactice); });