Files
scouthub/scouthub-eventi-fe/src/app/core/auth/require-branca-access.guard.spec.ts
T
2026-07-25 12:03:40 +02:00

123 lines
4.9 KiB
TypeScript

import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, provideRouter, Router } from '@angular/router';
import Keycloak from 'keycloak-js';
import { of, throwError } from 'rxjs';
import { EventiApiService, EventoDettaglioView } from '../eventi-api.service';
import { requireBrancaAccessEventoGuard, requireCreaEventoGuard } from './require-branca-access.guard';
const state = {} as RouterStateSnapshot;
const eventoLupetti: EventoDettaglioView = {
id: 'evento-1',
orgId: 'org-1',
brancaId: 'Lupetti',
parentId: null,
titolo: 'Campo estivo',
descrizione: null,
dataInizio: '2026-07-10T08:00:00.000Z',
dataFine: '2026-07-10T18:00:00.000Z',
tipo: 'campo',
location: null,
creatoDa: 'user-1',
creatoIl: '2026-06-01T00:00:00.000Z',
figli: [],
risorseCollegate: []
};
function setup(options: {
roles?: string[];
groups?: string[];
getEvento?: ReturnType<typeof vi.fn>;
}): void {
const keycloakMock = {
tokenParsed: {
realm_access: { roles: options.roles ?? [] },
groups: options.groups ?? []
}
};
TestBed.configureTestingModule({
providers: [
provideRouter([]),
{ provide: Keycloak, useValue: keycloakMock },
{ provide: EventiApiService, useValue: { getEvento: options.getEvento ?? vi.fn().mockReturnValue(of(eventoLupetti)) } }
]
});
}
describe('requireCreaEventoGuard', () => {
const route = {} as ActivatedRouteSnapshot;
it('lascia proseguire capo-gruppo', () => {
setup({ roles: ['capo-gruppo'] });
const result = TestBed.runInInjectionContext(() => requireCreaEventoGuard(route, state));
expect(result).toBe(true);
});
it('lascia proseguire capo-unita con almeno una branca', () => {
setup({ roles: ['capo-unita'], groups: ['/Lupetti'] });
const result = TestBed.runInInjectionContext(() => requireCreaEventoGuard(route, state));
expect(result).toBe(true);
});
it('reindirizza alla vista mensile per censito', () => {
setup({ roles: ['censito'], groups: ['/Lupetti'] });
const result = TestBed.runInInjectionContext(() => requireCreaEventoGuard(route, state));
const router = TestBed.inject(Router);
expect((result as UrlTree).toString()).toBe(router.parseUrl('/vista-mensile').toString());
});
it('reindirizza alla vista mensile per capo-unita senza nessuna branca', () => {
setup({ roles: ['capo-unita'], groups: [] });
const result = TestBed.runInInjectionContext(() => requireCreaEventoGuard(route, state));
const router = TestBed.inject(Router);
expect((result as UrlTree).toString()).toBe(router.parseUrl('/vista-mensile').toString());
});
it('lascia proseguire capo con almeno una branca (stessi permessi di capo-unita)', () => {
setup({ roles: ['capo'], groups: ['/Lupetti'] });
const result = TestBed.runInInjectionContext(() => requireCreaEventoGuard(route, state));
expect(result).toBe(true);
});
});
describe('requireBrancaAccessEventoGuard', () => {
function buildRoute(id: string | null): ActivatedRouteSnapshot {
return { paramMap: { get: () => id } } as unknown as ActivatedRouteSnapshot;
}
it('lascia proseguire capo-gruppo su qualunque branca', async () => {
setup({ roles: ['capo-gruppo'] });
const result = await TestBed.runInInjectionContext(() => requireBrancaAccessEventoGuard(buildRoute('evento-1'), state));
expect(result).toBe(true);
});
it('lascia proseguire capo-unita sulla branca dell\'evento', async () => {
setup({ roles: ['capo-unita'], groups: ['/Lupetti'] });
const result = await TestBed.runInInjectionContext(() => requireBrancaAccessEventoGuard(buildRoute('evento-1'), state));
expect(result).toBe(true);
});
it('reindirizza al dettaglio evento per capo-unita di un\'altra branca', async () => {
setup({ roles: ['capo-unita'], groups: ['/Esploratori'] });
const result = await TestBed.runInInjectionContext(() => requireBrancaAccessEventoGuard(buildRoute('evento-1'), state));
const router = TestBed.inject(Router);
expect((result as UrlTree).toString()).toBe(router.parseUrl('/vista-evento/evento-1').toString());
});
it('reindirizza alla vista mensile se il caricamento dell\'evento fallisce', async () => {
setup({ roles: ['capo-gruppo'], getEvento: vi.fn().mockReturnValue(throwError(() => new Error('404'))) });
const result = await TestBed.runInInjectionContext(() => requireBrancaAccessEventoGuard(buildRoute('evento-1'), state));
const router = TestBed.inject(Router);
expect((result as UrlTree).toString()).toBe(router.parseUrl('/vista-mensile').toString());
});
it('reindirizza alla vista mensile se manca il param id', async () => {
setup({ roles: ['capo-gruppo'] });
const result = await TestBed.runInInjectionContext(() => requireBrancaAccessEventoGuard(buildRoute(null), state));
const router = TestBed.inject(Router);
expect((result as UrlTree).toString()).toBe(router.parseUrl('/vista-mensile').toString());
});
});