metis-desk/apps/server/src/intervention-templates.integration.ts
2026-10-08 16:43:34 +02:00

124 lines
5.0 KiB
TypeScript

import assert from "node:assert/strict";
import { randomUUID } from "node:crypto";
import type { InterventionTemplateDTO } from "@metis/companies/common";
import {
InterventionTemplateResponseSchema,
InterventionTemplatesSchema,
} from "@metis/companies/common";
type Request = (path: string, body?: unknown, origin?: string, token?: string) => Promise<Response>;
export async function verifyInterventionTemplates(
request: Request,
companyId: string,
otherId: string,
migrate: () => Promise<void>
) {
const path = "/intervention-templates/global";
const list = InterventionTemplatesSchema.parse(await (await request(path)).json());
assert.equal(list.templates.length, 6);
assert.ok(list.templates.every((template) => template.companyId === null));
const values = {
name: "Procedimiento de prueba",
description: "Prueba",
active: true,
steps: [
{ id: randomUUID(), title: "Primer paso", instructions: "", required: false },
{ id: randomUUID(), title: "Segundo paso", instructions: "Verificar", required: true },
],
};
const body = { values, requestKey: randomUUID(), expectedRevisionId: null };
async function save(url: string, payload: unknown, status = 201) {
const response = await request(url, payload);
assert.equal(response.status, status, await response.clone().text());
return InterventionTemplateResponseSchema.parse(await response.json()).template;
}
const created = await save(path, body);
assert.equal(created.id[14], "7");
assert.equal(created.history.length, 1);
assert.equal((await save(path, body)).id, created.id);
assert.equal((await request(path, { ...body, values: { ...values, name: "Otro" } })).status, 409);
assert.equal((await request(path, { ...body, requestKey: randomUUID() })).status, 409);
assert.equal((await request(`/intervention-templates/${companyId}`, body)).status, 409);
const local = await save(`/intervention-templates/${companyId}`, {
...body,
requestKey: randomUUID(),
});
assert.equal(local.companyId, companyId);
const scoped = InterventionTemplatesSchema.parse(
await (await request(`/intervention-templates/${companyId}`)).json()
);
assert.ok(scoped.templates.some((item) => item.id === created.id));
assert.ok(scoped.templates.some((item) => item.id === local.id));
const other = InterventionTemplatesSchema.parse(
await (await request(`/intervention-templates/${otherId}`)).json()
);
assert.ok(other.templates.every((item) => item.companyId === null));
const updateBody = (template: InterventionTemplateDTO) => ({
values: { ...template.values, active: false, steps: [...template.values.steps].reverse() },
requestKey: randomUUID(),
expectedRevisionId: template.history.at(-1)?.id,
});
assert.equal(
(
await request(
`/intervention-templates/${companyId}/${created.id}/update`,
updateBody(created)
)
).status,
404
);
assert.equal(
(await request(`/intervention-templates/${otherId}/${local.id}/update`, updateBody(local)))
.status,
404
);
const updated = await save(`${path}/${created.id}/update`, updateBody(created), 200);
assert.equal(updated.history.length, 2);
assert.equal(updated.values.active, false);
assert.equal(updated.history[0]?.values.active, true);
assert.equal(updated.values.steps[0]?.id, values.steps[1]?.id);
const same = await save(
`${path}/${created.id}/update`,
{ ...body, values: updated.values, expectedRevisionId: updated.history.at(-1)?.id },
200
);
assert.equal(same.history.length, 2);
assert.equal((await request(`${path}/${created.id}/update`, updateBody(created))).status, 409);
const responses = await Promise.all(
["Una edición", "Otra edición"].map((description) =>
request(`${path}/${created.id}/update`, {
...updateBody(updated),
values: { ...updated.values, description },
})
)
);
assert.deepEqual(responses.map((response) => response.status).sort(), [200, 409]);
assert.equal(
(await request(path, { ...body, requestKey: randomUUID(), values: { ...values, steps: [] } }))
.status,
400
);
assert.equal((await request(path, { ...body, unknown: true })).status, 400);
assert.equal((await request(`${path}?unknown=1`)).status, 400);
assert.equal((await request(`/intervention-templates/${randomUUID()}`)).status, 404);
assert.equal((await request(path, body, "http://evil.example")).status, 403);
assert.equal((await request(path, body, undefined, "invalid")).status, 403);
const seed = list.templates[0];
assert.ok(seed);
const modifiedSeed = await save(
`${path}/${seed.id}/update`,
{
...updateBody(seed),
values: { ...seed.values, active: false, description: "Cambio conservado tras migración" },
},
200
);
await migrate();
await migrate();
const afterMigration = InterventionTemplatesSchema.parse(await (await request(path)).json());
const retained = afterMigration.templates.find((item) => item.id === seed.id);
assert.deepEqual(retained, modifiedSeed);
assert.equal(afterMigration.templates.length, 7);
}