- 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.
184 lines
7.0 KiB
TypeScript
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" }))
|
|
)
|
|
);
|
|
});
|