154 lines
6.2 KiB
TypeScript
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) },
|
|
});
|
|
}
|
|
}
|