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

154 lines
6.2 KiB
TypeScript

import assert from "node:assert/strict";
import { randomUUID } from "node:crypto";
import type { TeleworkAuthorizationInput } from "@metis/companies/common";
import {
CompanyResponseSchema,
TeleworkAuthorizationResponseSchema,
TeleworkAuthorizationsResponseSchema,
} from "@metis/companies/common";
import type { Sequelize } from "sequelize";
import { z } from "zod/v4";
type Request = (path: string, body?: unknown, origin?: string, token?: string) => Promise<Response>;
export async function verifyTelework(
request: Request,
companyId: string,
otherId: string,
database: Sequelize
) {
const personValues = {
name: "Persona teletrabajo",
position: null,
email: null,
phone: null,
active: true,
isContact: false,
};
const createdPerson = await request(`/companies/${companyId}/people`, personValues);
assert.equal(createdPerson.status, 201);
const person = CompanyResponseSchema.parse(await createdPerson.json()).company.people.at(-1);
assert.ok(person);
const path = `/telework-authorizations/${companyId}`;
const input: TeleworkAuthorizationInput = {
personId: person.id,
active: true,
startsOn: null,
expiresOn: null,
notes: null,
};
const error = async (values: unknown, code: string, id?: string, status = 409) => {
const response = await request(path + (id ? `/${id}/update` : ""), { values });
assert.equal(response.status, status);
assert.equal(z.object({ code: z.string() }).parse(await response.json()).code, code);
};
const save = async (values: TeleworkAuthorizationInput, id: string) => {
const response = await request(`${path}/${id}/update`, { values });
assert.equal(response.status, 200);
return TeleworkAuthorizationResponseSchema.parse(await response.json()).authorization;
};
const list = async (scope = companyId) =>
TeleworkAuthorizationsResponseSchema.parse(
await (await request(`/telework-authorizations/${scope}`)).json()
).authorizations;
await error({ ...input, actorId: person.id }, "INVALID_REQUEST", undefined, 400);
await error(
{ ...input, startsOn: "2026-12-01", expiresOn: "2026-11-30" },
"INVALID_REQUEST",
undefined,
400
);
await error({ ...input, personId: randomUUID() }, "TELEWORK_PERSON_NOT_FOUND", undefined, 404);
assert.equal((await request(path, { values: input }, "https://other.example")).status, 403);
assert.equal((await request(path, { values: input }, undefined, "a".repeat(64))).status, 403);
const concurrent = await Promise.all([
request(path, { values: input }),
request(path, { values: input }),
]);
assert.deepEqual(concurrent.map((response) => response.status).sort(), [201, 409]);
const created = concurrent.find((response) => response.status === 201);
assert.ok(created);
const authorization = TeleworkAuthorizationResponseSchema.parse(
await created.json()
).authorization;
assert.equal(authorization.id[14], "7");
assert.equal(authorization.history[0]?.id[14], "7");
assert.equal(authorization.effective, true);
assert.equal(authorization.status, "authorized");
assert.equal(authorization.needsReview, false);
assert.deepEqual(await save(input, authorization.id), authorization);
await error({ ...input, personId: randomUUID() }, "TELEWORK_PERSON_IMMUTABLE", authorization.id);
const otherCreate = await request(`/telework-authorizations/${otherId}`, { values: input });
assert.equal(otherCreate.status, 404);
assert.equal((await list(otherId)).length, 0);
const foreignUpdate = await request(
`/telework-authorizations/${otherId}/${authorization.id}/update`,
{ values: input }
);
assert.equal(foreignUpdate.status, 404);
const today = new Date().toISOString().slice(0, 10);
const oneDay = await save({ ...input, startsOn: today, expiresOn: today }, authorization.id);
assert.equal(oneDay.status, "authorized");
assert.equal(oneDay.effective, true);
const scheduled = await save(
{ ...input, startsOn: "9999-12-31", expiresOn: "9999-12-31" },
authorization.id
);
assert.equal(scheduled.status, "scheduled");
assert.equal(scheduled.effective, false);
const expired = await save(
{ ...input, startsOn: "2000-01-01", expiresOn: "2000-01-01" },
authorization.id
);
assert.equal(expired.status, "expired");
assert.equal(expired.effective, false);
const renewed = await save(input, authorization.id);
assert.equal(renewed.status, "authorized");
assert.equal(
(
await request(`/companies/${companyId}/people/${person.id}/update`, {
...personValues,
active: false,
})
).status,
200
);
const reviewed = (await list()).find((item) => item.id === authorization.id);
assert.ok(reviewed);
assert.equal(reviewed.needsReview, true);
assert.equal(reviewed.effective, false);
await error({ ...input, notes: "Extender" }, "TELEWORK_PERSON_INACTIVE", authorization.id);
const revoked = await save({ ...input, active: false, notes: "Salida" }, authorization.id);
assert.equal(revoked.status, "revoked");
assert.equal(revoked.needsReview, false);
assert.equal(revoked.history.length, 6);
assert.equal(revoked.history[0]?.values.active, true);
await error(input, "TELEWORK_PERSON_INACTIVE", authorization.id);
assert.equal(
(await request(`/companies/${companyId}/people/${person.id}/update`, personValues)).status,
200
);
await error(input, "TELEWORK_ALREADY_EXISTS");
const reactivated = await save({ ...input, notes: "Regresa" }, authorization.id);
assert.equal(reactivated.effective, true);
assert.equal(reactivated.history.length, 7);
assert.ok(reactivated.history.every((revision) => revision.actorId !== person.id));
await database.query("UPDATE telework_authorizations SET `values`=:values WHERE id=:id", {
replacements: {
id: authorization.id,
values: JSON.stringify({ ...reactivated.values, personId: randomUUID() }),
},
});
try {
const corrupt = await request(path);
assert.equal(corrupt.status, 500);
const body = await corrupt.text();
assert.ok(!body.includes("SELECT"));
assert.ok(!body.includes("inconsistente"));
} finally {
await database.query("UPDATE telework_authorizations SET `values`=:values WHERE id=:id", {
replacements: { id: authorization.id, values: JSON.stringify(reactivated.values) },
});
}
}