metis-desk/apps/server/src/sites.integration.test.ts
2026-10-16 11:09:56 +02:00

122 lines
4.9 KiB
TypeScript

import assert from "node:assert/strict";
import { randomUUID } from "node:crypto";
import { test } from "node:test";
import { DataTypes, Op } from "sequelize";
import { CompanyUseCases } from "../../../modules/companies/src/api/application/company.use-cases";
import { CompanyInputMapper } from "../../../modules/companies/src/api/application/company-input.mapper";
import {
CompanyModel,
SiteModel,
initializeCompanyModels,
} from "../../../modules/companies/src/api/infrastructure/persistence/company.model";
import { CompanyPersistenceMapper } from "../../../modules/companies/src/api/infrastructure/persistence/company-persistence.mapper";
import { migrateCompanies } from "../../../modules/companies/src/api/infrastructure/persistence/migrate-companies";
import { migratePeople } from "../../../modules/companies/src/api/infrastructure/persistence/migrate-people";
import { initializePeopleModels } from "../../../modules/companies/src/api/infrastructure/persistence/people.model";
import { SequelizeCompanyRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-company.repository";
import { createDatabase, readDatabaseEnvironment } from "./config/database";
test("MariaDB: archivo reversible y borrado de sedes solo sin referencias", async () => {
const environment = readDatabaseEnvironment(process.env);
assert.equal(environment.NODE_ENV, "test");
assert.equal(environment.DB_NAME, "metis_desk_test");
const database = createDatabase(environment);
const companyIds: string[] = [];
const linksTable = `site_lifecycle_test_${randomUUID().replaceAll("-", "")}`;
let createdLinks = false;
try {
await migrateCompanies(database);
await migratePeople(database);
initializeCompanyModels(database);
initializePeopleModels(database);
const useCases = new CompanyUseCases(
new SequelizeCompanyRepository(database, new CompanyPersistenceMapper()),
new CompanyInputMapper()
);
const created = await useCases.create({ name: "Prueba de ciclo de sedes", active: true });
assert.ok(created.isSuccess);
const companyId = created.data.id.toPrimitive();
companyIds.push(companyId);
const other = await useCases.create({ name: "Otra compañía de prueba de sedes", active: true });
assert.ok(other.isSuccess);
companyIds.push(other.data.id.toPrimitive());
const added = await useCases.addSite(companyId, { name: "Sede", active: true });
assert.ok(added.isSuccess);
const site = added.data.sites[0];
assert.ok(site);
const siteId = site.id.toPrimitive();
const foreign = await useCases.removeSite(other.data.id.toPrimitive(), siteId);
assert.ok(!foreign.isSuccess);
assert.equal(foreign.error.code, "SITE_NOT_FOUND");
for (const active of [false, false, true]) {
const changed = await useCases.updateSite(companyId, siteId, { name: "Sede", active });
assert.ok(changed.isSuccess);
assert.equal(changed.data.sites[0]?.active, active);
const reloaded = await useCases.get(companyId);
assert.ok(reloaded.isSuccess);
assert.equal(reloaded.data.sites[0]?.active, active);
}
await database.getQueryInterface().createTable(linksTable, {
id: { type: DataTypes.UUID, primaryKey: true },
siteId: {
type: DataTypes.UUID,
allowNull: false,
references: { model: "company_sites", key: "id" },
onDelete: "RESTRICT",
},
});
createdLinks = true;
await database.getQueryInterface().bulkInsert(linksTable, [{ id: randomUUID(), siteId }]);
const blocked = await useCases.removeSite(companyId, siteId);
assert.ok(!blocked.isSuccess);
assert.equal(blocked.error.code, "SITE_IN_USE");
const archived = await useCases.updateSite(companyId, siteId, { name: "Sede", active: false });
assert.ok(archived.isSuccess);
await migrateCompanies(database);
const reloaded = await useCases.get(companyId);
assert.ok(reloaded.isSuccess);
assert.equal(reloaded.data.sites[0]?.active, false);
const stillBlocked = await useCases.removeSite(companyId, siteId);
assert.ok(!stillBlocked.isSuccess);
assert.equal(stillBlocked.error.code, "SITE_IN_USE");
await database.getQueryInterface().bulkDelete(linksTable, { siteId });
const removed = await useCases.removeSite(companyId, siteId);
assert.ok(removed.isSuccess);
assert.equal(removed.data.sites.length, 0);
const missing = await useCases.removeSite(companyId, siteId);
assert.ok(!missing.isSuccess);
assert.equal(missing.error.code, "SITE_NOT_FOUND");
} finally {
try {
if (createdLinks) {
await database.getQueryInterface().dropTable(linksTable);
}
if (companyIds.length) {
await SiteModel.destroy({ where: { companyId: { [Op.in]: companyIds } } });
await CompanyModel.destroy({ where: { id: { [Op.in]: companyIds } } });
}
} finally {
await database.close();
}
}
});