import { describe, it, expect } from 'vitest' import { MODULOS, esModuloVisible, type Modulo } from './modulos' const porId = (id: string): Modulo => { const modulo = MODULOS.find((m) => m.id === id) if (!modulo) throw new Error(`Módulo ${id} no existe`) return modulo } describe('MODULOS', () => { it('expone los 7 módulos del ecosistema', () => { expect(MODULOS).toHaveLength(7) expect(MODULOS.map((m) => m.id)).toEqual([ 'cotizador', 'alta-clientes', 'clientes', 'chat-hermes', 'tableros', 'mi-dia', 'contactos', ]) }) it('cada módulo tiene nombre, descripción y claves ligadas a la matriz de roles', () => { for (const modulo of MODULOS) { expect(modulo.nombre.length).toBeGreaterThan(0) expect(modulo.descripcion.length).toBeGreaterThan(0) expect(modulo.claves.length).toBeGreaterThan(0) if (modulo.url !== undefined) expect(modulo.url).toMatch(/^\/[a-z]+\/$/) } }) it('apunta a los prefijos correctos (same-origin detrás de NGINX)', () => { expect(porId('cotizador').url).toBe('/quote/') expect(porId('alta-clientes').url).toBe('/client/') expect(porId('clientes').url).toBe('/pay/') expect(porId('chat-hermes').url).toBe('/ai/') expect(porId('tableros').url).toBe('/dash/') expect(porId('mi-dia').url).toBe('/hoy/') }) it('Contactos es vista interna (sin url externa)', () => { expect(porId('contactos').url).toBeUndefined() }) it('liga cada módulo a la matriz de roles del API', () => { expect(porId('cotizador').claves).toEqual(['cotizador']) expect(porId('alta-clientes').claves).toEqual(['alta-cliente', 'alta-afluencia']) expect(porId('clientes').claves).toEqual(['cobranza']) expect(porId('chat-hermes').claves).toEqual(['chat']) expect(porId('tableros').claves).toEqual(['mi-tablero', 'tablero-comercial']) expect(porId('mi-dia').claves).toEqual(['mi-dia']) expect(porId('contactos').claves).toEqual(['contactos']) }) it('no hay ids ni URLs duplicadas', () => { const ids = MODULOS.map((m) => m.id) const urls = MODULOS.map((m) => m.url).filter((u) => u !== undefined) expect(new Set(ids).size).toBe(MODULOS.length) expect(new Set(urls).size).toBe(urls.length) }) }) describe('esModuloVisible', () => { it('sin sesión (null) muestra todos los módulos', () => { for (const modulo of MODULOS) expect(esModuloVisible(modulo, null)).toBe(true) }) it('con sesión, un módulo es visible si ALGUNA de sus claves está permitida', () => { const vendedor = ['mi-dia', 'alta-cliente', 'alta-afluencia', 'cotizador', 'mi-tablero', 'contactos', 'chat'] expect(MODULOS.filter((m) => esModuloVisible(m, vendedor)).map((m) => m.id)).toEqual([ 'cotizador', 'alta-clientes', 'chat-hermes', 'tableros', // visible por 'mi-tablero' 'mi-dia', 'contactos', ]) // 'cobranza' no está permitida → Clientes no se muestra expect(esModuloVisible(porId('clientes'), vendedor)).toBe(false) }) })