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; 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) }, }); } }