oggui/ogWebconsole/src/app/layout/sidebar/sidebar.component.spec.ts

186 lines
8.5 KiB
TypeScript

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { MatDialogModule } from '@angular/material/dialog';
import { TranslateModule } from '@ngx-translate/core';
import { SidebarComponent } from './sidebar.component';
import { AuthService, UserCategory } from '@services/auth.service';
// ─────────────────────────────────────────────────────────────────────────────
// Rutas con condiciones de visibilidad (según sidebar.component.html)
// ─────────────────────────────────────────────────────────────────────────────
/** Siempre visibles para todos los roles autenticados */
const ALWAYS_VISIBLE = ['/groups'];
/** Solo visibles para super-admin y ou-admin (ocultos para operator y minimal) */
const ADMIN_ONLY_ROUTES = [
'/dhcp-servers',
'/boot-servers',
'/calendars',
'/repositories',
'/menus',
];
// ─────────────────────────────────────────────────────────────────────────────
// Helper: cuenta mat-list-item visibles en el DOM
// ─────────────────────────────────────────────────────────────────────────────
function countVisibleListItems(fixture: ComponentFixture<SidebarComponent>): number {
return fixture.debugElement.queryAll(By.css('mat-list-item')).length;
}
/** Devuelve true si existe algún mat-list-item con [routerLink] apuntando a la ruta dada */
function hasRouteLink(fixture: ComponentFixture<SidebarComponent>, route: string): boolean {
const items = fixture.debugElement.queryAll(By.css(`[routerLink="${route}"]`));
return items.length > 0;
}
// ─────────────────────────────────────────────────────────────────────────────
// Mock de AuthService
// ─────────────────────────────────────────────────────────────────────────────
function mockAuthService(category: UserCategory) {
return {
userCategory: category,
username: 'test-user',
isSuperAdmin: category === 'super-admin',
isOUAdmin: category === 'ou-admin',
isOUOperator: category === 'ou-operator',
isOUMinimal: category === 'ou-minimal',
getCurrentRole: () => category,
};
}
// ─────────────────────────────────────────────────────────────────────────────
// Suite principal
// ─────────────────────────────────────────────────────────────────────────────
describe('SidebarComponent — visibilidad de elementos por rol', () => {
let fixture: ComponentFixture<SidebarComponent>;
let component: SidebarComponent;
async function createComponent(category: UserCategory) {
await TestBed.configureTestingModule({
declarations: [SidebarComponent],
imports: [
RouterTestingModule,
MatDialogModule,
TranslateModule.forRoot(),
],
providers: [
{ provide: AuthService, useValue: mockAuthService(category) },
],
schemas: [CUSTOM_ELEMENTS_SCHEMA], // ignora mat-* desconocidos
}).compileComponents();
fixture = TestBed.createComponent(SidebarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}
// ── Grupos — siempre visible ───────────────────────────────────────────────
describe('/groups — siempre visible para cualquier rol', () => {
(['super-admin', 'ou-admin', 'ou-operator', 'ou-minimal'] as UserCategory[]).forEach(role => {
it(`${role} ve el enlace a /groups`, async () => {
await createComponent(role);
expect(hasRouteLink(fixture, '/groups')).toBeTrue();
});
});
});
// ── Super-admin ve todo ────────────────────────────────────────────────────
describe('super-admin — ve todos los elementos del sidebar', () => {
beforeEach(async () => createComponent('super-admin'));
ADMIN_ONLY_ROUTES.forEach(route => {
it(`ve el enlace a ${route}`, () => {
expect(hasRouteLink(fixture, route)).toBeTrue();
});
});
it('ve el menú de acciones (commands)', () => {
// El parent de commands es un mat-list-item sin routerLink pero con el ngIf
const items = fixture.debugElement.queryAll(By.css('mat-list-item'));
expect(items.length).toBeGreaterThan(1);
});
});
// ── Ou-admin ve todo ───────────────────────────────────────────────────────
describe('ou-admin — ve todos los elementos del sidebar', () => {
beforeEach(async () => createComponent('ou-admin'));
ADMIN_ONLY_ROUTES.forEach(route => {
it(`ve el enlace a ${route}`, () => {
expect(hasRouteLink(fixture, route)).toBeTrue();
});
});
});
// ── Ou-operator: /groups y las trazas de sus acciones ──────────────────────
describe('ou-operator — ve /groups y /commands-logs', () => {
beforeEach(async () => createComponent('ou-operator'));
it('ve /groups', () => {
expect(hasRouteLink(fixture, '/groups')).toBeTrue();
});
ADMIN_ONLY_ROUTES.forEach(route => {
it(`NO ve el enlace a ${route}`, () => {
expect(hasRouteLink(fixture, route)).toBeFalse();
});
});
it('ve el menú de acciones (commands) para acceder a las trazas', () => {
// /groups + el desplegable de acciones
expect(countVisibleListItems(fixture)).toBe(2);
});
it('ve el enlace a /commands-logs al desplegar el menú de acciones', () => {
component.toggleCommandSub();
fixture.detectChanges();
expect(hasRouteLink(fixture, '/commands-logs')).toBeTrue();
});
it('NO ve los enlaces de gestión de comandos ni tareas', () => {
component.toggleCommandSub();
fixture.detectChanges();
expect(hasRouteLink(fixture, '/commands')).toBeFalse();
expect(hasRouteLink(fixture, '/commands-task')).toBeFalse();
});
});
// ── Ou-minimal: solo /groups ───────────────────────────────────────────────
describe('ou-minimal — solo ve /groups', () => {
beforeEach(async () => createComponent('ou-minimal'));
it('ve /groups', () => {
expect(hasRouteLink(fixture, '/groups')).toBeTrue();
});
ADMIN_ONLY_ROUTES.forEach(route => {
it(`NO ve el enlace a ${route}`, () => {
expect(hasRouteLink(fixture, route)).toBeFalse();
});
});
it('NO ve el menú de acciones (commands)', () => {
expect(countVisibleListItems(fixture)).toBe(1);
});
});
// ── Comparativa admin vs operator ─────────────────────────────────────────
describe('comparativa: ou-admin ve más items que ou-operator', () => {
it('ou-admin tiene más mat-list-items visibles que ou-operator', async () => {
await createComponent('ou-admin');
const adminCount = countVisibleListItems(fixture);
TestBed.resetTestingModule();
await createComponent('ou-operator');
const operatorCount = countVisibleListItems(fixture);
expect(adminCount).toBeGreaterThan(operatorCount);
});
});
});