Files
plantillas-proyectos/frontend/src/lib/server/dashboard-shell-cache.test.ts
Kevin_Ramirez 695af2f0b1 perf(dashboard): cachear my-tenants/my-apps del Hub por sesión estable
my-tenants y my-apps no tienen caché propia en el Hub — se repetían en cada
+layout.server.ts load del dashboard, sin importar cuántas veces navegara el
usuario en la misma sesión.

- jwt.ts: getJwtSessionKey() extrae sid/sub del JWT — identificador estable que
  sobrevive al refresh del access token (rota cada ~60s).
- dashboard-shell-cache.ts: caché en memoria (Map + TTL de 30s) para el bundle
  de tenants/apps, keyed por session key — NUNCA por el access token, que
  rotando cada ~60s haría que cada set()/get() usaran llaves distintas y la
  caché nunca acertara.
- +layout.server.ts: usa el caché antes de golpear al Hub; lo llena tras el
  primer fetch exitoso de la sesión.
- dashboard-shell-cache.test.ts: cubre hit/miss, expiración por TTL, y que
  sobrevive a la rotación del access token (llave estable).

Verificado: 5/5 tests nuevos pasan; svelte-check da los mismos 38 errores/8
warnings preexistentes que main (0 nuevos); los 2 fallos de backend.test.ts son
preexistentes (ENOTFOUND backend fuera de Docker, igual en main).
2026-07-21 16:13:02 -05:00

50 lines
1.6 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import {
getDashboardShellCache,
setDashboardShellCache,
DASHBOARD_SHELL_CACHE_TTL_MS
} from './dashboard-shell-cache';
const SAMPLE_DATA = {
userTenants: [{ id: 1, name: 'Tenant A', slug: 'tenant-a' }],
myApps: { apps: [{ id: 'app-1' }], routing: 'default' }
};
describe('dashboard-shell-cache', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
it('devuelve null si no hay nada cacheado para esa llave', () => {
expect(getDashboardShellCache('sesion-inexistente')).toBeNull();
});
it('devuelve lo cacheado dentro del TTL', () => {
setDashboardShellCache('sesion-1', SAMPLE_DATA);
expect(getDashboardShellCache('sesion-1')).toEqual(SAMPLE_DATA);
});
it('sigue acertando aunque el "access token" hubiera rotado — la llave es el session key, no el token', () => {
// Simula dos navegaciones con tokens de acceso distintos (rotación cada ~60s)
// pero el mismo session key estable (sid/sub) — como haría getJwtSessionKey().
setDashboardShellCache('mismo-session-key', SAMPLE_DATA);
vi.advanceTimersByTime(5_000);
expect(getDashboardShellCache('mismo-session-key')).toEqual(SAMPLE_DATA);
});
it('expira después del TTL', () => {
setDashboardShellCache('sesion-2', SAMPLE_DATA);
vi.advanceTimersByTime(DASHBOARD_SHELL_CACHE_TTL_MS + 1);
expect(getDashboardShellCache('sesion-2')).toBeNull();
});
it('no acierta entre llaves distintas (sesiones distintas)', () => {
setDashboardShellCache('sesion-usuario-a', SAMPLE_DATA);
expect(getDashboardShellCache('sesion-usuario-b')).toBeNull();
});
});