metis-desk/apps/server/src/network-share-folder-compatibility.fixture.ts

225 lines
8.6 KiB
TypeScript
Raw Normal View History

import assert from "node:assert/strict";
import type { Sequelize } from "sequelize";
import { AccessUseCases } from "../../../modules/companies/src/api/application/access.use-cases";
import { FolderMappingUseCases } from "../../../modules/companies/src/api/application/folder-mapping.use-cases";
import { buildFolderResponse } from "../../../modules/companies/src/api/application/folder-mapping-response.builder";
import { WorkProfileUseCases } from "../../../modules/companies/src/api/application/work-profile.use-cases";
import {
AccessPersistenceMapper,
SequelizeAccessRepository,
} from "../../../modules/companies/src/api/infrastructure/persistence/access-persistence";
import { CompanyPersistenceMapper } from "../../../modules/companies/src/api/infrastructure/persistence/company-persistence.mapper";
import { migrateFolderMappings } from "../../../modules/companies/src/api/infrastructure/persistence/folder-mapping-migration";
import { SequelizeCompanyRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-company.repository";
import { SequelizeFolderMappingRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-folder-mapping.repository";
import { SequelizeWorkProfileRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-work-profile.repository";
import { migrateWorkProfiles } from "../../../modules/companies/src/api/infrastructure/persistence/work-profile-migration";
import { UniqueID } from "../../../packages/rdx-ddd/src/index";
import type { prepareMembershipFixture } from "./asset-directory-memberships.fixture";
/** Comprueba un mapeo persistido real; todos los datos pertenecen a la compañía de fixture. */
export async function verifyFolderCompatibility(
database: Sequelize,
fixture: Awaited<ReturnType<typeof prepareMembershipFixture>>,
company: string,
actor: string
) {
await migrateWorkProfiles(database);
await migrateFolderMappings(database);
const personId = UniqueID.generateNewID().toPrimitive();
const asset = await fixture.asset(company, "desktop");
const inventory = { list: async () => [{ id: asset.id, notRetired: true, isProfileHost: true }] };
const access = new AccessUseCases(
new SequelizeAccessRepository(
database,
new SequelizeCompanyRepository(database, new CompanyPersistenceMapper()),
new AccessPersistenceMapper()
)
);
const profiles = new WorkProfileUseCases(new SequelizeWorkProfileRepository(database, inventory));
const folders = new FolderMappingUseCases(
new SequelizeFolderMappingRepository(database, inventory)
);
const loaded = await fixture.resourceUseCases.get(company);
assert.ok(loaded.isSuccess);
const resource = loaded.data.resources.find(
(item) => item.values.toPrimitive().integration?.kind === "access"
);
assert.ok(resource);
const values = resource.values.toPrimitive();
assert.ok(values.integration?.kind === "access");
const { referenceFieldId, resourceTypeId } = values.integration;
const originalPath = values.characteristics[referenceFieldId];
assert.equal(typeof originalPath, "string");
assert.ok(typeof originalPath === "string");
await database.query(
"INSERT INTO company_contacts (id,companyId,name,isContact,active) VALUES (:personId,:company,'SMB person fixture',0,1)",
{ replacements: { personId, company } }
);
try {
const permission = await access.save(
company,
undefined,
{
kind: "permission",
name: "SMB read fixture",
active: true,
description: null,
resourceTypeId,
},
actor
);
assert.ok(permission.isSuccess);
const permissionItem = permission.data.workspace.items.find(
(item) => item.values.data.kind === "permission"
);
assert.ok(permissionItem);
const need = await access.save(
company,
undefined,
{
kind: "need",
personId,
resourceId: resource.id.toPrimitive(),
permissionIds: [permissionItem.id.toPrimitive()],
startDate: "2020-01-01",
endDate: null,
notes: null,
},
actor
);
assert.ok(need.isSuccess);
const needItem = need.data.workspace.items.find((item) => item.values.data.kind === "need");
assert.ok(needItem);
const profile = await profiles.save(
company,
undefined,
{
name: "SMB profile fixture",
personId,
assetId: asset.id.toPrimitive(),
accountId: null,
active: true,
notes: null,
},
actor
);
assert.ok(profile.isSuccess);
const mapping = await folders.save(
company,
undefined,
{
profileId: profile.data.profile.id.toPrimitive(),
needId: needItem.id.toPrimitive(),
path: originalPath,
driveLetter: "F:",
state: "configured",
notes: null,
},
actor
);
assert.ok(mapping.isSuccess);
const before = buildFolderResponse(mapping.data.mapping, mapping.data.context);
assert.equal(before.needsReview, false);
assert.equal(before.permissionsCovered, false);
const changed = await fixture.resourceUseCases.save(
company,
resource.id.toPrimitive(),
{
...values,
characteristics: {
...values.characteristics,
[referenceFieldId]: String.raw`\\NAS\NuevaDireccion`,
},
},
actor
);
assert.ok(changed.isSuccess);
const after = await folders.get(company);
assert.ok(after.isSuccess);
const persisted = after.data.mappings.find((item) => item.id.equals(mapping.data.mapping.id));
assert.ok(persisted);
const response = buildFolderResponse(persisted, after.data);
assert.deepEqual(response.values, before.values);
assert.deepEqual(response.history, before.history);
assert.equal(response.values.driveLetter, "F");
assert.equal(response.needsReview, true);
assert.equal(response.permissionsCovered, false);
const blocked = await fixture.resourceUseCases.remove(company, resource.id.toPrimitive());
assert.ok(!blocked.isSuccess);
assert.equal(blocked.error.code, "RESOURCE_IN_USE");
} finally {
for (const [table, column, parent] of [
["folder_mapping_revisions", "mappingId", "folder_mappings"],
["work_profile_revisions", "profileId", "work_profiles"],
]) {
await database.query(
`DELETE FROM ${table} WHERE ${column} IN (SELECT id FROM ${parent} WHERE companyId=:company)`,
{ replacements: { company } }
);
}
for (const table of ["folder_mappings", "work_profiles"]) {
await database.query(`DELETE FROM ${table} WHERE companyId=:company`, {
replacements: { company },
});
}
for (const kind of ["need", "permission"]) {
if (kind === "need") {
await database.query(
"DELETE p FROM access_need_permissions p JOIN access_items i ON i.id=p.ownerId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company",
{ replacements: { company } }
);
await database.query(
"DELETE p FROM access_need_revision_permissions p JOIN access_revisions r ON r.id=p.ownerId JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company",
{ replacements: { company } }
);
}
await database.query(
`DELETE v FROM access_${kind}_values v JOIN access_items i ON i.id=v.ownerId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`,
{ replacements: { company } }
);
await database.query(
`DELETE v FROM access_${kind}_revision_values v JOIN access_revisions r ON r.id=v.ownerId JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`,
{ replacements: { company } }
);
}
await database.query("DELETE FROM access_person_references WHERE personId=:personId", {
replacements: { personId },
});
for (const table of ["access_references", "access_revisions"]) {
const column = "itemId";
await database.query(
`DELETE v FROM ${table} v JOIN access_items i ON i.id=v.${column} JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company AND i.kind IN ('need','permission')`,
{ replacements: { company } }
);
}
await database.query(
"DELETE i FROM access_items i JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company AND i.kind IN ('need','permission')",
{ replacements: { company } }
);
await database.query("DELETE FROM company_contacts WHERE id=:personId AND companyId=:company", {
replacements: { personId, company },
});
}
}