Files
basic-erp/apps/web/src/app/features/admin/permissions.page.spec.ts
T

96 lines
4.3 KiB
TypeScript
Raw Normal View History

import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { type ComponentFixture, TestBed } from '@angular/core/testing';
import { beforeEach, describe, expect, it } from 'vitest';
import { SessionStore } from '../../core/auth/session.store';
import { PermissionsPage } from './permissions.page';
describe('PermissionsPage', () => {
let fixture: ComponentFixture<PermissionsPage>;
let ctrl: HttpTestingController;
const el = () => fixture.nativeElement as HTMLElement;
const tick = async () => {
fixture.detectChanges();
await new Promise((r) => setTimeout(r));
fixture.detectChanges();
};
const click = async (selector: string, index = 0) => {
(el().querySelectorAll(selector)[index] as HTMLElement).click();
await tick();
};
const byText = (selector: string, text: string) =>
[...el().querySelectorAll<HTMLElement>(selector)].find((e) => e.textContent?.trim().startsWith(text))!;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PermissionsPage],
providers: [provideHttpClient(), provideHttpClientTesting()],
}).compileComponents();
TestBed.inject(SessionStore); // sin sesión: solo necesitamos que exista
ctrl = TestBed.inject(HttpTestingController);
fixture = TestBed.createComponent(PermissionsPage);
await tick();
ctrl.expectOne('/api/permissions').flush([
{ webUser: 'ana', paths: ['/ventas/*', '/socios/clientes'] },
{ webUser: 'luis', paths: ['*'] },
]);
await tick();
});
it('lista los usuarios con permisos', () => {
expect([...el().querySelectorAll('.users li button')].map((b) => b.textContent?.trim())).toEqual(['ana', 'luis']);
});
it('al elegir un usuario marca sus pantallas (el módulo completo por /ventas/*)', async () => {
await click('.users li button', 0);
const checked = [...el().querySelectorAll<HTMLInputElement>('fieldset .items input')].filter((i) => i.checked);
expect(checked.length).toBe(8); // 7 de ventas + Clientes
expect(el().querySelector<HTMLButtonElement>('.actions .main')!.disabled).toBe(true); // sin cambios
});
it('el acceso total oculta las casillas y no ofrece Administración como casilla', async () => {
await click('.users li button', 1);
expect(el().querySelector('fieldset')).toBeNull();
await click('.users li button', 0);
expect(byText('legend label', 'Administración')).toBeUndefined();
});
it('guarda los patrones resultantes con PUT', async () => {
await click('.users li button', 0);
const inv = byText('legend label', 'Inventario').querySelector('input')!;
inv.click();
await tick();
expect(el().querySelector<HTMLButtonElement>('.actions .main')!.disabled).toBe(false);
await click('.actions .main');
const req = ctrl.expectOne((r) => r.method === 'PUT');
expect(req.request.url).toBe('/api/permissions/ana');
expect(req.request.body).toEqual({ paths: ['/ventas/*', '/inventario/*', '/socios/clientes'] });
req.flush({ webUser: 'ana', paths: [] });
await tick();
ctrl.expectOne('/api/permissions').flush([{ webUser: 'ana', paths: ['/ventas/*', '/inventario/*', '/socios/clientes'] }]);
await tick();
expect(el().querySelector('.msg')?.textContent).toContain('Permisos de ana guardados');
});
it('muestra el error del servidor, por ejemplo al quitar el último administrador', async () => {
await click('.users li button', 1);
await click('.actions .danger');
ctrl.expectOne((r) => r.method === 'DELETE' && r.url === '/api/permissions/luis').flush(
{ message: 'No se puede quitar al último administrador' },
{ status: 409, statusText: 'Conflict' },
);
await tick();
expect(el().querySelector('.msg.err')?.textContent).toContain('último administrador');
});
it('agregar un usuario lo selecciona sin guardar hasta pulsar Guardar', async () => {
const input = el().querySelector<HTMLInputElement>('.add input')!;
input.value = 'marta';
input.dispatchEvent(new Event('input'));
await tick();
await click('.add .btn');
expect([...el().querySelectorAll('.users li button')].map((b) => b.textContent?.trim())).toContain('marta');
expect(el().querySelector('.detail h2')?.textContent).toBe('marta');
ctrl.expectNone((r) => r.method === 'PUT');
});
});