metis-desk/modules/resources/src/web/resources/shared/resources.test.tsx

166 lines
5.6 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "node:test";
import { UniqueID } from "@repo/rdx-ddd";
import { Maybe } from "@repo/rdx-utils";
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 { buildCatalogResponse } from "../../../api/application/resource-catalog-response.builder";
import { ResourceCatalog } from "../../../api/domain/resource-catalog.aggregate";
import { seedResourceCatalog } from "../../../api/domain/resource-catalog-seed";
import { catalogKeys } from "../../catalog/shared/api";
import { resourcesEnglish, resourcesSpanish } from "../../shared";
import { ResourcesPage } from "../list";
import { inventoryKeys } from "./api";
import { ResourceForm } from "./ui";
const companyId = UniqueID.generateNewID().toPrimitive();
async function render(language: string, children: ReactNode) {
const i18n = createInstance();
await i18n.init({
lng: language,
resources: { es: { resources: resourcesSpanish }, en: { resources: resourcesEnglish } },
});
const client = new QueryClient();
client.setQueryData(
catalogKeys.scope(companyId),
buildCatalogResponse(seedResourceCatalog(ResourceCatalog.create()), Maybe.none())
);
client.setQueryData(inventoryKeys.company(companyId), { resources: [] });
try {
return renderToStaticMarkup(
<I18nextProvider i18n={i18n}>
<QueryClientProvider client={client}>{children}</QueryClientProvider>
</I18nextProvider>
);
} finally {
client.clear();
}
}
test("recursos: listado con alta modal y sin formulario visible, en español e inglés", async () => {
for (const [language, label] of [
["es", "Nuevo recurso"],
["en", "New resource"],
]) {
assert.ok(language && label);
const html = await render(language, <ResourcesPage companyId={companyId} />);
assert.ok(html.includes(label));
assert.equal(html.includes("<form"), false);
}
});
test("recurso: ayuda inferior, plantilla con alta rápida y sin asignaciones de recursos", async () => {
const html = await render(
"es",
<ResourceForm companyId={companyId} items={[]} onSaved={() => undefined} />
);
assert.ok(html.includes('aria-label="Nueva plantilla"'));
assert.ok(html.indexOf('name="notes"') < html.indexOf("<aside"));
assert.ok(html.indexOf("<aside") < html.indexOf('type="submit"'));
assert.equal(html.includes('name="personId"'), false);
assert.equal(html.includes('name="siteId"'), false);
const child = await render(
"es",
<ResourceForm
allowQuickCreate={false}
companyId={companyId}
items={[]}
onSaved={() => undefined}
/>
);
assert.equal(child.includes('aria-label="Nueva plantilla"'), false);
});
test("licencia: formulario reutilizable con campos opcionales y ayuda antes de guardar", async () => {
const catalog = buildCatalogResponse(seedResourceCatalog(ResourceCatalog.create()), Maybe.none());
const template = catalog.items.find((item) => item.builtinKey === "template:software_license");
assert.ok(template && template.values.kind === "template");
const fields = template.values.fields.map((binding) => {
const field = catalog.items.find((item) => item.id === binding.fieldId);
assert.ok(field && field.values.kind === "field");
return {
fieldId: field.id,
name: field.values.name,
type: field.values.type,
unit: field.values.unit,
choices: field.values.choices,
required: binding.required,
};
});
const resource = {
id: UniqueID.generateNewID().toPrimitive(),
companyId,
specification: { templateId: template.id, templateName: template.values.name, fields },
values: {
name: "Microsoft 365",
templateId: template.id,
active: true,
notes: "",
characteristics: {},
},
history: [],
};
for (const [language, help] of [
["es", "Registra una licencia o suscripción"],
["en", "Register a software license or subscription"],
]) {
assert.ok(language && help);
const html = await render(
language,
<ResourceForm
companyId={companyId}
items={catalog.items}
onSaved={() => undefined}
resource={resource}
/>
);
assert.ok(html.includes("Cantidad contratada"));
assert.ok(html.includes("Fecha de renovación"));
assert.ok(html.includes("Renovación automática"));
assert.ok(html.includes(help));
assert.ok(html.indexOf(help) < html.indexOf('type="submit"'));
assert.equal(html.includes("Cantidad contratada *"), false);
assert.equal(html.includes("licenseDescription"), false);
}
});
test("asistencia: alta de recurso con plantilla específica y características opcionales", async () => {
const catalog = buildCatalogResponse(seedResourceCatalog(ResourceCatalog.create()), Maybe.none());
const template = catalog.items.find((item) => item.builtinKey === "template:support");
assert.ok(template && template.values.kind === "template");
assert.equal(template.values.usage, "support");
assert.ok(template.values.fields.every((field) => !field.required));
const html = await render(
"es",
<ResourceForm
allowQuickCreate={false}
companyId={companyId}
initialKind="support"
items={catalog.items}
onSaved={() => undefined}
/>
);
assert.ok(html.includes("Herramienta de asistencia remota"));
assert.ok(html.includes("Proveedor"));
assert.ok(html.includes("URL"));
assert.equal(html.includes('aria-label="Nueva plantilla"'), false);
});