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