- 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.
175 lines
5.6 KiB
TypeScript
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);
|
|
});
|