metis-desk/modules/companies/src/web/components/companies-page.test.tsx
David 5adbe81364 feat: enhance access management with quick create functionality and improved forms
- Added QuickCreateDialog for creating systems and environments quickly.
- Implemented quickCreatePlan to handle creation logic based on context.
- Updated AccessForm to support quick creation and related modals.
- Enhanced i18n support for new quick add features in both English and Spanish.
- Refactored AssignmentForm to allow department creation directly from the form.
- Introduced SelectWithAction component for better user interaction with selections.
- Added tests for new components and functionalities to ensure reliability.
2026-10-04 15:46:39 +02:00

175 lines
5.6 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "node:test";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { createInstance } from "i18next";
import type { ReactNode } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { I18nextProvider } from "react-i18next";
import { companyKeys } from "../api/company-api";
import { companiesEnglish, companiesSpanish } from "../i18n";
import { AssignmentForm } from "./assignment-form";
import { CompaniesPage } from "./companies-page";
import { CompanyDetail } from "./company-detail";
import { PersonForm } from "./person-form";
import { SiteForm } from "./site-form";
const companyId = "e0420eb9-2aab-4368-96a0-2ce83dd23eb4";
async function renderPage(
language: string,
children: ReactNode,
seed: (client: QueryClient) => void
) {
const i18n = createInstance();
await i18n.init({
lng: language,
fallbackLng: "es",
resources: { es: { companies: companiesSpanish }, en: { companies: companiesEnglish } },
interpolation: { escapeValue: false },
});
const client = new QueryClient({
defaultOptions: { queries: { retry: false, staleTime: Number.POSITIVE_INFINITY } },
});
seed(client);
try {
return renderToStaticMarkup(
<I18nextProvider i18n={i18n}>
<QueryClientProvider client={client}>{children}</QueryClientProvider>
</I18nextProvider>
);
} finally {
client.clear();
}
}
test("el listado presenta estado vacío y acceso al alta sin formularios visibles", async () => {
for (const [language, title, empty] of [
["es", "Compañías", "Todavía no hay compañías"],
["en", "Companies", "No companies yet"],
] as const) {
const markup = await renderPage(language, <CompaniesPage csrfToken="test" />, (client) =>
client.setQueryData(companyKeys.list, { companies: [] })
);
assert.ok(markup.includes(title));
assert.ok(markup.includes(empty));
assert.ok(markup.includes(language === "es" ? "Nueva compañía" : "New company"));
assert.equal(markup.includes("<form"), false);
assert.equal(markup.includes('name="name"'), false);
}
});
test("la ficha presenta datos de la compañía, contactos y acceso a sedes", async () => {
const markup = await renderPage(
"es",
<CompanyDetail csrfToken="test" id={companyId} onBack={() => undefined} />,
(client) =>
client.setQueryData(companyKeys.detail(companyId), {
company: {
id: companyId,
name: "Empresa test",
active: true,
departments: [],
assignments: [],
people: [
{
id: companyId,
companyId,
name: "Ana",
position: "Responsable IT",
email: "ana@example.test",
phone: "900123456",
active: false,
isContact: true,
},
],
contacts: [],
sites: [],
},
})
);
assert.ok(markup.includes("Empresa test"));
assert.ok(markup.includes("Responsable IT"));
assert.ok(markup.includes("Personas (1)"));
assert.ok(markup.includes("Sedes (0)"));
assert.ok(markup.includes("Nueva persona"));
assert.ok(markup.includes("Editar compañía"));
assert.equal(markup.includes("<form"), false);
});
test("el formulario de sede ofrece dirección multilínea optativa", async () => {
const markup = await renderPage(
"es",
<SiteForm companyId={companyId} csrfToken="test" />,
() => undefined
);
assert.ok(markup.includes("Dirección (opcional)"));
assert.match(markup, /<textarea[^>]*rows="6"/);
assert.match(markup, /<textarea[^>]*name="address"/);
const textarea = markup.match(/<textarea[^>]*>/)?.[0];
assert.ok(textarea);
assert.equal(textarea.includes("required"), false);
});
test("el formulario de persona distingue contactos de cuentas de acceso y permite datos opcionales", async () => {
const markup = await renderPage(
"es",
<PersonForm companyId={companyId} csrfToken="test" onSaved={() => undefined} />,
() => undefined
);
assert.ok(markup.includes("Esta persona no tiene acceso a Metis Desk"));
assert.ok(markup.includes("Contacto de la compañía"));
for (const name of ["position", "email", "phone"]) {
const field = markup.match(new RegExp(`<input[^>]*name="${name}"[^>]*>`))?.[0];
assert.ok(field);
assert.equal(field.includes("required"), false);
}
assert.equal(markup.includes('name="password"'), false);
});
test("asignar un departamento permite añadir el primero y conserva el selector en edición", async () => {
const company = {
id: companyId,
name: "Empresa",
active: true,
departments: [],
assignments: [],
people: [],
contacts: [],
sites: [],
};
const markup = await renderPage(
"es",
<AssignmentForm
company={company}
csrfToken="test"
onSaved={() => undefined}
personId={companyId}
/>,
() => undefined
);
assert.ok(markup.includes('aria-label="Nuevo departamento"'));
assert.ok(markup.includes('role="combobox"'));
assert.equal(markup.includes("<select"), false);
const edited = await renderPage(
"es",
<AssignmentForm
assignment={{
id: companyId,
personId: companyId,
departmentId: companyId,
companyId,
history: [],
position: null,
startDate: "2026-01-01",
endDate: null,
isPrimary: false,
}}
company={company}
csrfToken="test"
onSaved={() => undefined}
personId={companyId}
/>,
() => undefined
);
assert.equal(edited.includes('aria-label="Nuevo departamento"'), false);
});