metis-desk/modules/companies/src/api/domain/telework-authorization.test.ts
David 2382e0ea20 feat: add telework authorization management functionality
- Implemented RESTful API routes for telework authorizations, including GET and POST methods for retrieving and saving authorizations.
- Created Sequelize repository for managing telework authorization data with methods for loading and saving authorizations.
- Developed migration scripts to set up necessary database tables for telework authorizations and revisions.
- Added persistence mapping for telework authorization entities to facilitate data transformation between domain and database layers.
- Introduced common schemas for validating telework authorization requests and responses using Zod.
- Built frontend components for managing telework authorizations, including forms for creating and editing authorizations, and summaries for displaying authorization details.
- Integrated internationalization support for English and Spanish languages in the telework module.
- Added unit tests to ensure functionality and correctness of telework authorization components and API interactions.
2026-10-06 18:10:35 +02:00

184 lines
7.0 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "node:test";
import { UniqueID } from "@repo/rdx-ddd";
import type { TeleworkAuthorizationContext } from "../application/telework-authorization.repository";
import { mapTeleworkAuthorizationInput } from "../application/telework-authorization-input.mapper";
import { teleworkAuthorizationState } from "../application/telework-authorization-policy";
import { TeleworkAuthorizationPersistenceMapper } from "../infrastructure/persistence/telework-authorization-persistence.mapper";
import { TeleworkAuthorization } from "./telework-authorization.aggregate";
import {
type TeleworkAuthorizationInput,
TeleworkAuthorizationInputSchema,
} from "./telework-authorization-values";
import { TeleworkAuthorizationValues } from "./value-objects/telework-authorization-values";
const company = UniqueID.generateNewID();
const person = UniqueID.generateNewID();
const actor = UniqueID.generateNewID();
const input: TeleworkAuthorizationInput = {
personId: person.toPrimitive(),
active: true,
startsOn: null,
expiresOn: null,
notes: null,
};
const now = "2026-10-06T09:00:00.000Z";
const context: TeleworkAuthorizationContext = {
authorizations: [],
people: [{ id: person, active: true }],
actors: new Map([[actor.toPrimitive(), "Técnico"]]),
today: "2026-10-06",
};
function values(value: TeleworkAuthorizationInput) {
const result = TeleworkAuthorizationValues.create(value);
assert.ok(result.isSuccess);
return result.data;
}
function create(value: TeleworkAuthorizationInput = input) {
const result = TeleworkAuthorization.create(company, values(value), actor, now);
assert.ok(result.isSuccess);
return result.data;
}
test("teletrabajo: ausencia, límites, fechas reales y contrato estricto", () => {
assert.ok(TeleworkAuthorizationInputSchema.safeParse(input).success);
assert.ok(
!TeleworkAuthorizationInputSchema.safeParse({ ...input, startsOn: "2026-02-30" }).success
);
assert.ok(
!TeleworkAuthorizationInputSchema.safeParse({
...input,
startsOn: "2026-10-07",
expiresOn: "2026-10-06",
}).success
);
assert.ok(
!TeleworkAuthorizationInputSchema.safeParse({ ...input, notes: "a".repeat(4001) }).success
);
assert.ok(!TeleworkAuthorizationInputSchema.safeParse({ ...input, password: "secret" }).success);
assert.equal(values({ ...input, notes: " " }).toPrimitive().notes, null);
assert.equal(values({ ...input, notes: " Condiciones " }).toPrimitive().notes, "Condiciones");
});
test("teletrabajo: UUID, renovación y revocación auditadas, igualdad y destino fijo", () => {
const item = create();
assert.equal(item.id.toPrimitive()[14], "7");
assert.equal(item.history[0]?.id.toPrimitive()[14], "7");
const repeated = item.update(values(input), actor, "invalid");
assert.ok(repeated.isSuccess);
assert.equal(repeated.data, item);
const revoked = item.update(
values({ ...input, active: false, notes: "Salida" }),
actor,
"2026-10-07T09:00:00.000Z"
);
assert.ok(revoked.isSuccess);
assert.ok(revoked.data.id.equals(item.id));
assert.equal(revoked.data.history.length, 2);
assert.notEqual(
revoked.data.history[0]?.id.toPrimitive(),
revoked.data.history[1]?.id.toPrimitive()
);
assert.equal(item.values.active, true);
const renewed = revoked.data.update(
values({ ...input, expiresOn: "2026-12-31" }),
actor,
"2026-10-08T09:00:00.000Z"
);
assert.ok(renewed.isSuccess);
assert.equal(renewed.data.history.length, 3);
const foreign = item.update(
values({ ...input, personId: UniqueID.generateNewID().toPrimitive() }),
actor,
now
);
assert.ok(!foreign.isSuccess);
assert.equal(foreign.error.code, "TELEWORK_PERSON_IMMUTABLE");
assert.ok(
!item.update(values({ ...input, active: false }), actor, "2026-10-05T09:00:00.000Z").isSuccess
);
assert.ok(!TeleworkAuthorization.create(company, values(input), actor, "invalid").isSuccess);
});
test("teletrabajo: vigencia inclusiva, programación, caducidad y persona inactiva", () => {
const day = { ...input, startsOn: "2026-10-06", expiresOn: "2026-10-06" };
assert.deepEqual(teleworkAuthorizationState(create(day), context), {
status: "authorized",
effective: true,
needsReview: false,
});
assert.equal(
teleworkAuthorizationState(create(day), { ...context, today: "2026-10-05" }).status,
"scheduled"
);
assert.equal(
teleworkAuthorizationState(create(day), { ...context, today: "2026-10-07" }).status,
"expired"
);
assert.equal(
teleworkAuthorizationState(create({ ...day, active: false }), context).status,
"revoked"
);
assert.deepEqual(
teleworkAuthorizationState(create(), { ...context, people: [{ id: person, active: false }] }),
{ status: "authorized", effective: false, needsReview: true }
);
});
test("teletrabajo: ámbito, unicidad incluso revocada, disponibilidad y retirada", () => {
const missing = mapTeleworkAuthorizationInput(input, { ...context, people: [] });
assert.ok(!missing.isSuccess);
assert.equal(missing.error.code, "TELEWORK_PERSON_NOT_FOUND");
const inactive = { ...context, people: [{ id: person, active: false }] };
const rejected = mapTeleworkAuthorizationInput(input, inactive);
assert.ok(!rejected.isSuccess);
assert.equal(rejected.error.code, "TELEWORK_PERSON_INACTIVE");
const item = create();
assert.ok(mapTeleworkAuthorizationInput({ ...input, active: false }, inactive, item).isSuccess);
assert.ok(mapTeleworkAuthorizationInput(input, inactive, item).isSuccess);
const duplicate = mapTeleworkAuthorizationInput(input, {
...context,
authorizations: [create({ ...input, active: false })],
});
assert.ok(!duplicate.isSuccess);
assert.equal(duplicate.error.code, "TELEWORK_ALREADY_EXISTS");
const foreign = mapTeleworkAuthorizationInput(
{ ...input, personId: UniqueID.generateNewID().toPrimitive() },
context,
item
);
assert.ok(!foreign.isSuccess);
assert.equal(foreign.error.code, "TELEWORK_PERSON_IMMUTABLE");
});
test("teletrabajo: rehidratación preserva identidad y detecta corrupción de raíz e historial", () => {
const mapper = new TeleworkAuthorizationPersistenceMapper();
const item = create();
const record = mapper.toPersistence(item);
const restored = mapper.toDomain(record.root, record.revisions);
assert.ok(restored.id.equals(item.id));
assert.ok(restored.values.equals(item.values));
assert.ok(item.history[0]);
assert.ok(restored.history[0]?.id.equals(item.history[0].id));
assert.throws(() => mapper.toDomain(record.root, []));
assert.throws(() =>
mapper.toDomain({ ...record.root, personId: actor.toPrimitive() }, record.revisions)
);
assert.throws(() =>
mapper.toDomain(
record.root,
record.revisions.map((r) => ({ ...r, authorizationId: actor.toPrimitive() }))
)
);
assert.throws(() =>
mapper.toDomain(
record.root,
record.revisions.map((r) => ({ ...r, position: 1 }))
)
);
assert.throws(() =>
mapper.toDomain(
record.root,
record.revisions.map((r) => ({ ...r, recordedAt: "invalid" }))
)
);
});