272 lines
9.4 KiB
TypeScript
272 lines
9.4 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 { renderToStaticMarkup } from "react-dom/server";
|
|
import { I18nextProvider } from "react-i18next";
|
|
|
|
import type { AccessResponseDTO } from "../../common";
|
|
|
|
import { accessKeys } from "./access-api";
|
|
import { accessFields } from "./access-fields";
|
|
import { AccessForm } from "./access-form";
|
|
import { AccessWorkspacePage } from "./access-workspace";
|
|
import { accessEnglish, accessSpanish } from "./i18n";
|
|
import { quickCreatePlan } from "./quick-create-plan";
|
|
|
|
test("los catálogos presentan alta mediante acción y no un formulario junto al listado", async () => {
|
|
for (const [language, label] of [
|
|
["es", "Nuevo sistema"],
|
|
["en", "New system"],
|
|
] as const) {
|
|
const i18n = createInstance();
|
|
await i18n.init({
|
|
lng: language,
|
|
resources: { es: { access: accessSpanish }, en: { access: accessEnglish } },
|
|
});
|
|
const client = new QueryClient();
|
|
client.setQueryData(accessKeys.scope("global"), { items: [], reviews: [], coverage: [] });
|
|
const markup = renderToStaticMarkup(
|
|
<I18nextProvider i18n={i18n}>
|
|
<QueryClientProvider client={client}>
|
|
<AccessWorkspacePage csrfToken="test" scope="global" />
|
|
</QueryClientProvider>
|
|
</I18nextProvider>
|
|
);
|
|
assert.ok(markup.includes(label));
|
|
assert.equal(markup.includes("<form"), false);
|
|
client.clear();
|
|
}
|
|
});
|
|
test("cuentas ofrecen caducidad opcional y campos sin contraseña", async () => {
|
|
const i18n = createInstance();
|
|
await i18n.init({ lng: "es", resources: { es: { access: accessSpanish } } });
|
|
const client = new QueryClient();
|
|
const markup = renderToStaticMarkup(
|
|
<I18nextProvider i18n={i18n}>
|
|
<QueryClientProvider client={client}>
|
|
<AccessForm
|
|
csrfToken="test"
|
|
data={{ items: [], reviews: [], coverage: [] }}
|
|
kind="account"
|
|
onSaved={() => undefined}
|
|
people={[]}
|
|
scope="e0420eb9-2aab-4368-96a0-2ce83dd23eb4"
|
|
/>
|
|
</QueryClientProvider>
|
|
</I18nextProvider>
|
|
);
|
|
assert.ok(markup.includes("Fecha de caducidad"));
|
|
assert.ok(markup.includes('aria-label="Añadir sistema"'));
|
|
assert.equal(markup.includes('aria-label="Añadir entorno"'), false);
|
|
assert.ok(markup.includes("Sistema, entorno y uso quedan fijos"));
|
|
assert.equal(markup.includes('type="password"'), false);
|
|
const field = markup.match(/<input[^>]*name="expiresOn"[^>]*>/)?.[0];
|
|
assert.ok(field);
|
|
assert.equal(field.includes("required"), false);
|
|
client.clear();
|
|
});
|
|
|
|
test("la ayuda explica todos los elementos en ambos idiomas y distingue el ámbito", async () => {
|
|
const { EntityHelp } = await import("./entity-help");
|
|
const { accessSpanish: helpSpanish, accessEnglish: helpEnglish } = await import("./i18n");
|
|
for (const [language, content] of [
|
|
["es", helpSpanish],
|
|
["en", helpEnglish],
|
|
] as const) {
|
|
const i18n = createInstance();
|
|
await i18n.init({ lng: language, resources: { [language]: { access: content } } });
|
|
for (const kind of [
|
|
"system",
|
|
"resource_type",
|
|
"permission",
|
|
"template",
|
|
"environment",
|
|
"account",
|
|
"account_person",
|
|
"group",
|
|
"membership",
|
|
"resource",
|
|
"grant",
|
|
"need",
|
|
"coverage",
|
|
"company",
|
|
"person",
|
|
"department",
|
|
"site",
|
|
"assignment",
|
|
] as const) {
|
|
const markup = renderToStaticMarkup(
|
|
<I18nextProvider i18n={i18n}>
|
|
<EntityHelp kind={kind} scope="global" />
|
|
</I18nextProvider>
|
|
);
|
|
assert.ok(markup.includes("<details"));
|
|
assert.ok(
|
|
markup.includes(
|
|
content.helpContent[kind].examples.replaceAll("&", "&").replaceAll("'", "'")
|
|
)
|
|
);
|
|
assert.equal(markup.includes("helpContent."), false);
|
|
}
|
|
const renderScope = (scope: string) =>
|
|
renderToStaticMarkup(
|
|
<I18nextProvider i18n={i18n}>
|
|
<EntityHelp kind="system" scope={scope} />
|
|
</I18nextProvider>
|
|
);
|
|
assert.ok(renderScope("global").includes(content.helpGlobalScope));
|
|
assert.ok(renderScope("company").includes(content.helpCompanyScope));
|
|
assert.equal(renderScope("company").includes(content.helpGlobalScope), false);
|
|
}
|
|
});
|
|
test("los ejemplos del sistema orientan sin rellenar datos del alta", async () => {
|
|
const i18n = createInstance();
|
|
await i18n.init({ lng: "es", resources: { es: { access: accessSpanish } } });
|
|
const client = new QueryClient();
|
|
const markup = renderToStaticMarkup(
|
|
<I18nextProvider i18n={i18n}>
|
|
<QueryClientProvider client={client}>
|
|
<AccessForm
|
|
csrfToken="test"
|
|
data={{ items: [], reviews: [], coverage: [] }}
|
|
kind="system"
|
|
onSaved={() => undefined}
|
|
people={[]}
|
|
scope="global"
|
|
/>
|
|
</QueryClientProvider>
|
|
</I18nextProvider>
|
|
);
|
|
assert.ok(markup.includes("Microsoft 365"));
|
|
assert.ok(markup.includes("Ámbito global"));
|
|
assert.ok(markup.indexOf('name="name"') < markup.indexOf("<aside"));
|
|
assert.ok(markup.indexOf("<aside") < markup.indexOf('type="submit"'));
|
|
const name = markup.match(/<input[^>]*name="name"[^>]*>/)?.[0];
|
|
assert.ok(name);
|
|
assert.equal(/value="[^"]+"/.test(name), false);
|
|
assert.equal(markup.includes('value="Microsoft 365"'), false);
|
|
client.clear();
|
|
});
|
|
|
|
test("las altas rápidas respetan el contexto, ámbito y relaciones históricas", () => {
|
|
const data: AccessResponseDTO = {
|
|
items: [
|
|
{
|
|
id: "system",
|
|
companyId: null,
|
|
history: [],
|
|
values: { kind: "system", name: "Directorio", active: true },
|
|
},
|
|
{
|
|
id: "type",
|
|
companyId: null,
|
|
history: [],
|
|
values: { kind: "resource_type", name: "Carpeta", active: true },
|
|
},
|
|
{
|
|
id: "resource",
|
|
companyId: "company",
|
|
history: [],
|
|
values: {
|
|
kind: "resource",
|
|
name: "Documentos",
|
|
resourceTypeId: "type",
|
|
active: true,
|
|
systemId: null,
|
|
environmentId: null,
|
|
reference: null,
|
|
notes: null,
|
|
},
|
|
},
|
|
{
|
|
id: "account",
|
|
companyId: "company",
|
|
history: [],
|
|
values: {
|
|
kind: "account",
|
|
systemId: "system",
|
|
environmentId: "env",
|
|
login: "ana",
|
|
expiresOn: null,
|
|
notes: null,
|
|
usage: "personal",
|
|
active: true,
|
|
},
|
|
},
|
|
],
|
|
reviews: [],
|
|
coverage: [],
|
|
};
|
|
const field = (kind: keyof typeof accessFields, key: string) => {
|
|
const result = accessFields[kind].find((candidate) => candidate.key === key);
|
|
assert.ok(result);
|
|
return result;
|
|
};
|
|
const plan = (kind: keyof typeof accessFields, key: string, values = {}, scope = "company") =>
|
|
quickCreatePlan(field(kind, key), scope, kind, data, values);
|
|
assert.equal(plan("account", "usage"), undefined);
|
|
assert.equal(plan("account", "environmentId"), undefined);
|
|
assert.deepEqual(plan("account", "environmentId", { systemId: "system" }), {
|
|
type: "simple",
|
|
target: { kind: "environment", systemId: "system", systemName: "Directorio" },
|
|
});
|
|
assert.equal(plan("grant", "permissionId"), undefined);
|
|
assert.deepEqual(plan("grant", "permissionId", { resourceId: "resource" }), {
|
|
type: "access",
|
|
kind: "permission",
|
|
scope: "company",
|
|
defaults: { active: true, resourceTypeId: "type" },
|
|
locked: ["active", "resourceTypeId"],
|
|
});
|
|
assert.equal(plan("membership", "groupId"), undefined);
|
|
assert.deepEqual(plan("membership", "groupId", { accountId: "account" }), {
|
|
type: "access",
|
|
kind: "group",
|
|
scope: "company",
|
|
defaults: { active: true, systemId: "system", environmentId: "env" },
|
|
locked: ["active", "systemId", "environmentId"],
|
|
});
|
|
assert.deepEqual(plan("account_person", "personId"), { type: "person" });
|
|
assert.equal(plan("account_person", "personId", {}, "global"), undefined);
|
|
assert.deepEqual(plan("group", "templateId"), {
|
|
type: "access",
|
|
kind: "template",
|
|
scope: "global",
|
|
defaults: { active: true },
|
|
locked: ["active"],
|
|
});
|
|
for (const entry of accessFields.coverage) {
|
|
assert.equal(quickCreatePlan(entry, "company", "coverage", data, {}), undefined);
|
|
}
|
|
});
|
|
|
|
test("los formularios ofrecen altas relacionadas y el segundo modal evita altas anidadas", async () => {
|
|
const i18n = createInstance();
|
|
await i18n.init({ lng: "es", resources: { es: { access: accessSpanish } } });
|
|
const client = new QueryClient();
|
|
const render = (kind: keyof typeof accessFields, allowQuickCreate = true) =>
|
|
renderToStaticMarkup(
|
|
<I18nextProvider i18n={i18n}>
|
|
<QueryClientProvider client={client}>
|
|
<AccessForm
|
|
allowQuickCreate={allowQuickCreate}
|
|
csrfToken="test"
|
|
data={{ items: [], reviews: [], coverage: [] }}
|
|
kind={kind}
|
|
onSaved={() => undefined}
|
|
people={[]}
|
|
scope="company"
|
|
/>
|
|
</QueryClientProvider>
|
|
</I18nextProvider>
|
|
);
|
|
for (const kind of ["permission", "account_person", "grant", "need", "group"] as const) {
|
|
assert.ok(render(kind).includes('data-slot="button-group"'), kind);
|
|
assert.equal(render(kind, false).includes('data-slot="button-group"'), false, kind);
|
|
}
|
|
assert.equal(render("coverage").includes('data-slot="button-group"'), false);
|
|
client.clear();
|
|
});
|