149 lines
5.3 KiB
TypeScript
149 lines
5.3 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
|
|
import { configureCsrfTokenReader } from "@metis/core/client";
|
|
|
|
import { COMPANY_LOGO_LIMITS, COMPANY_LOGO_TYPES } from "../../common";
|
|
import { getAccess } from "../access/list/api";
|
|
import { saveAccess } from "../access/shared/api";
|
|
import { validateCompanyLogo } from "../companies/change-logo/helpers";
|
|
import { getCompany } from "../companies/detail/api";
|
|
import { listCompanies } from "../companies/list/api";
|
|
import { saveMailboxUse } from "../mailbox-uses/shared/api";
|
|
import { getMailboxes } from "../mailboxes/list/api";
|
|
import { buildPersonRequest } from "../people/shared/adapters";
|
|
import { buildProcessTemplateInput } from "../process-templates/shared/adapters";
|
|
import { buildSiteRequest } from "../sites/shared/adapters";
|
|
|
|
const COMPANY_ID = "e0420eb9-2aab-4368-96a0-2ce83dd23eb4";
|
|
|
|
test("las consultas de compañías conservan sus rutas y rechazan respuestas inválidas", async (context) => {
|
|
context.after(configureCsrfTokenReader(() => "a".repeat(64)));
|
|
context.mock.method(globalThis, "fetch", async (url: unknown, options: RequestInit) => {
|
|
assert.equal(options.method, "GET");
|
|
if (url === "/api/companies") {
|
|
return Response.json({ companies: [] });
|
|
}
|
|
assert.equal(url, `/api/companies/${COMPANY_ID}`);
|
|
|
|
return Response.json({ company: { id: COMPANY_ID } });
|
|
});
|
|
assert.deepEqual(await listCompanies(), { companies: [] });
|
|
await assert.rejects(getCompany(COMPANY_ID));
|
|
});
|
|
|
|
test("lectura y guardado de accesos están separados sin cambiar el contrato HTTP", async (context) => {
|
|
context.after(configureCsrfTokenReader(() => "a".repeat(64)));
|
|
const calls: { url: unknown; options: RequestInit }[] = [];
|
|
|
|
context.mock.method(globalThis, "fetch", async (url: unknown, options: RequestInit) => {
|
|
calls.push({ url, options });
|
|
|
|
return Response.json({ items: [], reviews: [], coverage: [] });
|
|
});
|
|
await getAccess("global");
|
|
const values = { kind: "system", name: "Directory", active: true } as const;
|
|
|
|
await saveAccess("global", values, COMPANY_ID);
|
|
assert.deepEqual(
|
|
calls.map((call) => call.url),
|
|
["/api/access/global", `/api/access/global/${COMPANY_ID}/update`]
|
|
);
|
|
assert.equal(calls[0]?.options.method, "GET");
|
|
const save = calls[1]?.options;
|
|
|
|
assert.ok(save);
|
|
assert.equal(save.method, "POST");
|
|
assert.equal(save.body, JSON.stringify({ values }));
|
|
assert.equal(new Headers(save.headers).get("x-csrf-token"), "a".repeat(64));
|
|
});
|
|
|
|
test("el guardado de usos de buzón mantiene su endpoint y no se confunde con la consulta", async (context) => {
|
|
context.after(configureCsrfTokenReader(() => "a".repeat(64)));
|
|
const calls: { url: unknown; options: RequestInit }[] = [];
|
|
|
|
context.mock.method(globalThis, "fetch", async (url: unknown, options: RequestInit) => {
|
|
calls.push({ url, options });
|
|
|
|
return Response.json({ mailboxes: [], uses: [] });
|
|
});
|
|
await getMailboxes(COMPANY_ID);
|
|
const values = {
|
|
mailboxId: COMPANY_ID,
|
|
personId: COMPANY_ID,
|
|
startDate: "2026-10-09",
|
|
endDate: null,
|
|
};
|
|
|
|
await saveMailboxUse(COMPANY_ID, values, COMPANY_ID);
|
|
assert.deepEqual(
|
|
calls.map((call) => call.url),
|
|
[`/api/mailboxes/${COMPANY_ID}`, `/api/mailboxes/${COMPANY_ID}/uses/${COMPANY_ID}/update`]
|
|
);
|
|
assert.equal(calls[0]?.options.method, "GET");
|
|
assert.equal(calls[1]?.options.method, "POST");
|
|
assert.equal(calls[1]?.options.body, JSON.stringify({ values }));
|
|
});
|
|
|
|
test("los adapters mantienen la ausencia semántica sin modificar los campos del formulario", () => {
|
|
const person = {
|
|
name: "Ana",
|
|
position: " ",
|
|
email: " ana@example.test ",
|
|
phone: "",
|
|
active: false,
|
|
isContact: true,
|
|
};
|
|
const request = buildPersonRequest(person);
|
|
|
|
assert.equal(request.position, null);
|
|
assert.equal(request.email, "ana@example.test");
|
|
assert.equal(request.phone, null);
|
|
assert.equal(request.active, false);
|
|
assert.equal(person.email, " ana@example.test ");
|
|
assert.deepEqual(
|
|
buildSiteRequest({ active: true, name: "Office", address: " ", phone: " " }),
|
|
{
|
|
active: true,
|
|
name: "Office",
|
|
address: null,
|
|
phone: null,
|
|
}
|
|
);
|
|
const site = buildSiteRequest({
|
|
active: true,
|
|
name: "Office",
|
|
address: " Street\n Floor ",
|
|
phone: " +34 900 123 456 ",
|
|
});
|
|
|
|
assert.equal(site.address, " Street\n Floor ");
|
|
assert.equal(site.phone, " +34 900 123 456 ");
|
|
});
|
|
|
|
test("las instrucciones de proceso conservan el orden y excluyen líneas vacías", () => {
|
|
const values = {
|
|
name: "Starter",
|
|
kind: "onboarding",
|
|
active: true,
|
|
notes: null,
|
|
lines: " First\n\n Second \r\n ",
|
|
} as const;
|
|
|
|
assert.deepEqual(buildProcessTemplateInput(values).instructions, ["First", "Second"]);
|
|
assert.equal(values.lines, " First\n\n Second \r\n ");
|
|
assert.deepEqual(buildProcessTemplateInput({ ...values, lines: "\n " }).instructions, []);
|
|
});
|
|
|
|
test("la validación de logos conserva tipos permitidos, vacío y límite exacto de tamaño", () => {
|
|
for (const type of COMPANY_LOGO_TYPES) {
|
|
assert.equal(validateCompanyLogo({ type, size: COMPANY_LOGO_LIMITS.inputBytes }), null);
|
|
assert.equal(validateCompanyLogo({ type, size: 0 }), "LOGO_TOO_LARGE");
|
|
assert.equal(
|
|
validateCompanyLogo({ type, size: COMPANY_LOGO_LIMITS.inputBytes + 1 }),
|
|
"LOGO_TOO_LARGE"
|
|
);
|
|
}
|
|
assert.equal(validateCompanyLogo({ type: "image/svg+xml", size: 1 }), "INVALID_LOGO");
|
|
});
|