Cierra autenticación en /api/deployer, POST /api/modules, /api/stats y /verify (assertIT + validación de slugs/nombres). GET /api/modules público sanitizado (solo visibles, sin repoUrl ni logs). Corrige estado unhealthy, XSS en plantillas, open redirect en login. Sesión HMAC en tiempo constante, secret obligatorio, 503 si el backend cae, cookie secure solo en prod. Migra middleware a proxy, rate-limit en login, vitest + typecheck, Tailwind/CDN fuera, Boxicons local, polling pausado y código muerto eliminado. Estandariza pnpm (lock, Dockerfile, packageManager).
86 lines
2.4 KiB
TypeScript
86 lines
2.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
envOf,
|
|
getStatusInfo,
|
|
sectionOf,
|
|
visibleModules,
|
|
type ModuleState,
|
|
} from "./sam";
|
|
|
|
function mod(over: Partial<ModuleState> = {}): ModuleState {
|
|
return {
|
|
name: "test",
|
|
repoUrl: "",
|
|
branch: "main",
|
|
subdomain: "test",
|
|
port: 3000,
|
|
active: true,
|
|
...over,
|
|
};
|
|
}
|
|
|
|
describe("getStatusInfo", () => {
|
|
it("detecta (unhealthy) como no saludable aunque contenga 'healthy'", () => {
|
|
const s = getStatusInfo(mod({ container: "Up 2 hours (unhealthy)" }));
|
|
expect(s.label).toBe("No saludable");
|
|
expect(s.cls).toBe("status-unhealthy");
|
|
});
|
|
|
|
it("detecta (healthy) como activo", () => {
|
|
const s = getStatusInfo(mod({ container: "Up 2 hours (healthy)" }));
|
|
expect(s.label).toBe("Activo");
|
|
expect(s.cls).toBe("status-healthy");
|
|
});
|
|
|
|
it("detecta starting como iniciando", () => {
|
|
const s = getStatusInfo(mod({ container: "Up 5 seconds (health: starting)" }));
|
|
expect(s.label).toBe("Iniciando");
|
|
expect(s.cls).toBe("status-starting");
|
|
});
|
|
|
|
it("contenedor Up sin health-check cuenta como activo", () => {
|
|
const s = getStatusInfo(mod({ container: "Up 10 minutes" }));
|
|
expect(s.cls).toBe("status-healthy");
|
|
});
|
|
|
|
it("sin contenedor es detenido", () => {
|
|
expect(getStatusInfo(mod({ container: null })).cls).toBe("status-unhealthy");
|
|
expect(getStatusInfo(mod({ container: "" })).label).toBe("Detenido");
|
|
});
|
|
|
|
it("contenedor Exited es detenido", () => {
|
|
expect(getStatusInfo(mod({ container: "Exited (1) 2 hours ago" })).cls).toBe(
|
|
"status-unhealthy"
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("visibleModules", () => {
|
|
it("filtra visible:false y conserva el resto", () => {
|
|
const list = [
|
|
mod({ name: "a" }),
|
|
mod({ name: "b", visible: false }),
|
|
mod({ name: "c", visible: true }),
|
|
];
|
|
expect(visibleModules(list).map((m) => m.name)).toEqual(["a", "c"]);
|
|
});
|
|
});
|
|
|
|
describe("sectionOf", () => {
|
|
it("usa la categoría cuando es una sección válida", () => {
|
|
expect(sectionOf("sam")).toBe("sam");
|
|
});
|
|
it("cae en otras-apps con categoría desconocida o vacía", () => {
|
|
expect(sectionOf("inventada")).toBe("otras-apps");
|
|
expect(sectionOf()).toBe("otras-apps");
|
|
});
|
|
});
|
|
|
|
describe("envOf", () => {
|
|
it("main/master/prod son Prod, resto Dev", () => {
|
|
expect(envOf("main").label).toBe("Prod");
|
|
expect(envOf("master").label).toBe("Prod");
|
|
expect(envOf("develop").label).toBe("Dev");
|
|
});
|
|
});
|