2026-10-21 09:25:23 +00:00
import assert from "node:assert/strict" ;
import { once } from "node:events" ;
import { test } from "node:test" ;
import type { AccessFieldsDTO } from "@metis/companies/common" ;
import type { Sequelize } from "sequelize" ;
import { QueryTypes } from "sequelize" ;
import { WorkstationUseCases } from "../../../modules/assets/src/api/application/workstation.use-cases" ;
import { SequelizeAssetRepository } from "../../../modules/assets/src/api/infrastructure/persistence/sequelize-asset.repository" ;
import { AccessUseCases } from "../../../modules/companies/src/api/application/access.use-cases" ;
2026-10-21 10:37:59 +00:00
import { buildAccessResponse } from "../../../modules/companies/src/api/application/access-response.builder" ;
2026-10-21 09:25:23 +00:00
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 { AccessKindSchema } from "../../../modules/companies/src/api/domain/access/access-definition" ;
import { registerFolderMappingRoutes } from "../../../modules/companies/src/api/infrastructure/http/folder-mapping.routes" ;
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 {
completeLocalIdentityAssetConstraint ,
migrateLocalIdentityEnvironments ,
} from "../../../modules/companies/src/api/infrastructure/persistence/local-identity-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 { FolderMappingResponseSchema } from "../../../modules/companies/src/common/folder-mappings" ;
import { LocalIdentityPageSchema } from "../../../modules/companies/src/common/local-identity-environments" ;
import { UniqueID } from "../../../packages/rdx-ddd/src/index" ;
import {
cleanupMembershipFixture ,
prepareMembershipFixture ,
} from "./asset-directory-memberships.fixture" ;
import { createDatabase , readDatabaseEnvironment } from "./config/database" ;
test ( "MariaDB: identidades locales y cuenta documental de FolderMapping" , async ( t ) = > {
const env = readDatabaseEnvironment ( process . env ) ;
assert . equal ( env . NODE_ENV , "test" ) ;
assert . equal ( env . DB_NAME , "metis_desk_test" ) ;
const db = createDatabase ( env ) ;
const company = UniqueID . generateNewID ( ) . toPrimitive ( ) ;
const otherCompany = UniqueID . generateNewID ( ) . toPrimitive ( ) ;
const actor = UniqueID . generateNewID ( ) . toPrimitive ( ) ;
const person = UniqueID . generateNewID ( ) . toPrimitive ( ) ;
const otherPerson = UniqueID . generateNewID ( ) . toPrimitive ( ) ;
const workstations = new WorkstationUseCases ( new SequelizeAssetRepository ( db ) ) ;
let workstationId : string | undefined ;
let ready = false ;
try {
const f = await prepareMembershipFixture ( db , "http://localhost:5173" , actor , [
company ,
otherCompany ,
] ) ;
ready = true ;
await migrateWorkProfiles ( db ) ;
await migrateFolderMappings ( db ) ;
await migrateFolderMappings ( db ) ;
await migrateLocalIdentityEnvironments ( db ) ;
await completeLocalIdentityAssetConstraint ( db ) ;
const access = new AccessUseCases (
new SequelizeAccessRepository (
db ,
new SequelizeCompanyRepository ( db , new CompanyPersistenceMapper ( ) ) ,
new AccessPersistenceMapper ( )
)
) ;
const folders = new FolderMappingUseCases (
new SequelizeFolderMappingRepository ( db , f . inventory )
) ;
const profiles = new WorkProfileUseCases ( new SequelizeWorkProfileRepository ( db , f . inventory ) ) ;
registerFolderMappingRoutes ( f . app , folders , f . authenticate ) ;
for ( const id of [ person , otherPerson ] ) {
await db . query (
"INSERT INTO company_contacts (id,companyId,name,isContact,active) VALUES (:id,:company,'Local identity fixture',0,1)" ,
{ replacements : { id , company } }
) ;
}
const add = async ( values : AccessFieldsDTO , scope = company ) = > {
const before = await access . get ( scope ) ;
assert . ok ( before . isSuccess ) ;
const ids = new Set ( before . data . workspace . items . map ( ( item ) = > item . id . toPrimitive ( ) ) ) ;
const saved = await access . save ( scope , undefined , values , actor ) ;
assert . ok ( saved . isSuccess , saved . isSuccess ? "" : saved . error . code ) ;
const item = saved . data . workspace . items . find ( ( item ) = > ! ids . has ( item . id . toPrimitive ( ) ) ) ;
assert . ok ( item ) ;
return item ;
} ;
const nas = await f . asset ( company , "nas" ) ;
const nas2 = await f . asset ( company , "nas" ) ;
const desktop = await f . asset ( company , "desktop" ) ;
const laptop = await f . asset ( company , "laptop" ) ;
const foreign = await f . asset ( otherCompany , "nas" ) ;
const system = await add ( { kind : "system" , name : "Identidades explícitas" , active : true } ) ;
const local = ( input : unknown ) = > f . localIdentities . execute ( company , actor , input ) ;
const created = await local ( {
action : "create" ,
assetId : nas.id.toPrimitive ( ) ,
systemId : system.id.toPrimitive ( ) ,
name : "NAS identidades" ,
} ) ;
assert . ok ( created . isSuccess ) ;
const environmentId = created . data . toPrimitive ( ) . environmentId ;
await t . test (
"vínculos NAS, PC y portátil, sin dominio y con dominio; cuentas homónimas diferenciadas" ,
async ( ) = > {
for ( const [ asset , name ] of [
[ nas2 , "NAS segundo" ] ,
[ desktop , "PC" ] ,
[ laptop , "Portátil" ] ,
] as const ) {
assert . ok (
(
await local ( {
action : "create" ,
assetId : asset.id.toPrimitive ( ) ,
systemId : system.id.toPrimitive ( ) ,
name ,
} )
) . isSuccess
) ;
}
const domain = await f . domain ( company , ` local- ${ company . slice ( 0 , 8 ) } .local ` ) ;
assert . ok (
(
await f . membershipUseCases . execute (
company ,
desktop . id . toPrimitive ( ) ,
{ action : "join" , domainResourceId : domain.id.toPrimitive ( ) , role : "member" } ,
actor
)
) . isSuccess
) ;
const desktopLinks = await f . localIdentities . list ( company , {
assetId : desktop.id.toPrimitive ( ) ,
} ) ;
assert . ok ( desktopLinks . isSuccess ) ;
assert . equal ( desktopLinks . data . environments . length , 1 ) ;
const second = await f . localIdentities . list ( company , { assetId : nas2.id.toPrimitive ( ) } ) ;
assert . ok ( second . isSuccess && second . data . environments [ 0 ] ) ;
for ( const environment of [ environmentId , second . data . environments [ 0 ] . environmentId ] ) {
await add ( {
kind : "account" ,
login : "juan" ,
systemId : system.id.toPrimitive ( ) ,
environmentId : environment ,
usage : "shared" ,
active : true ,
expiresOn : null ,
notes : null ,
} ) ;
}
const snapshot = await access . get ( company ) ;
assert . ok ( snapshot . isSuccess ) ;
assert . equal (
snapshot . data . workspace . items . filter (
( item ) = > item . values . data . kind === "account" && item . values . data . login === "juan"
) . length ,
2
) ;
}
) ;
await t . test (
"asociación idempotente, propietario inmutable, ámbitos y rechazo AD" ,
async ( ) = > {
const repeat = await local ( {
action : "associate" ,
environmentId ,
assetId : nas.id.toPrimitive ( ) ,
} ) ;
assert . ok ( repeat . isSuccess ) ;
assert . equal ( repeat . data . id . toPrimitive ( ) , created . data . id . toPrimitive ( ) ) ;
assert . equal (
( await local ( { action : "associate" , environmentId , assetId : nas2.id.toPrimitive ( ) } ) )
. isSuccess ,
false
) ;
assert . equal (
( await local ( { action : "associate" , environmentId , assetId : foreign.id.toPrimitive ( ) } ) )
. isSuccess ,
false
) ;
const domainRows = await db . query < { environmentId : string ; systemId : string } > (
"SELECT environmentId,systemId FROM access_directory_environments WHERE companyId=:company" ,
{ replacements : { company } , type : QueryTypes . SELECT }
) ;
assert . ok ( domainRows [ 0 ] ) ;
assert . equal (
(
await local ( {
action : "associate" ,
environmentId : domainRows [ 0 ] . environmentId ,
assetId : nas.id.toPrimitive ( ) ,
} )
) . isSuccess ,
false
) ;
assert . equal (
(
await local ( {
action : "create" ,
systemId : domainRows [ 0 ] . systemId ,
assetId : nas.id.toPrimitive ( ) ,
name : "No clasificar AD como local" ,
} )
) . isSuccess ,
false
) ;
assert . equal (
(
await local ( {
action : "associate" ,
environmentId : system.id.toPrimitive ( ) ,
assetId : nas.id.toPrimitive ( ) ,
} )
) . isSuccess ,
false
) ;
const otherEnvironment = await add (
{
kind : "environment" ,
name : "Otra compañía" ,
systemId : (
await add ( { kind : "system" , name : "Otro" , active : true } , otherCompany )
) . id . toPrimitive ( ) ,
active : true ,
} ,
otherCompany
) ;
assert . equal (
(
await local ( {
action : "associate" ,
environmentId : otherEnvironment.id.toPrimitive ( ) ,
assetId : nas.id.toPrimitive ( ) ,
} )
) . isSuccess ,
false
) ;
}
) ;
await t . test (
"asocia un entorno existente sin reescribirlo y serializa altas duplicadas" ,
async ( ) = > {
const environment = await add ( {
kind : "environment" ,
name : "Entorno previamente creado" ,
systemId : system.id.toPrimitive ( ) ,
active : true ,
} ) ;
const command = {
action : "associate" ,
environmentId : environment.id.toPrimitive ( ) ,
assetId : laptop.id.toPrimitive ( ) ,
} ;
const results = await Promise . all ( [ local ( command ) , local ( command ) ] ) ;
assert . ok ( results [ 0 ] ? . isSuccess && results [ 1 ] ? . isSuccess ) ;
assert . equal ( results [ 0 ] . data . id . toPrimitive ( ) , results [ 1 ] . data . id . toPrimitive ( ) ) ;
const loaded = await access . get ( company ) ;
assert . ok ( loaded . isSuccess ) ;
const unchanged = loaded . data . workspace . items . find ( ( item ) = >
item . id . equals ( environment . id )
) ;
assert . deepEqual (
unchanged ? . history . map ( ( item ) = > item . id . toPrimitive ( ) ) ,
environment . history . map ( ( item ) = > item . id . toPrimitive ( ) )
) ;
}
) ;
await t . test (
"renombrado y desactivación conservan entorno, cuentas e historial; FK protege compañía y subtipo" ,
async ( ) = > {
assert . ok (
(
await f . assetUseCases . save (
company ,
nas . id . toPrimitive ( ) ,
{ . . . nas . values . toPrimitive ( ) , name : "NAS renombrado" , status : "retired" } ,
actor
)
) . isSuccess
) ;
assert . equal (
(
await local ( {
action : "create" ,
assetId : nas.id.toPrimitive ( ) ,
systemId : system.id.toPrimitive ( ) ,
name : "Activo retirado" ,
} )
) . isSuccess ,
false
) ;
const links = await f . localIdentities . list ( company , { assetId : nas.id.toPrimitive ( ) } ) ;
assert . ok ( links . isSuccess ) ;
assert . equal ( links . data . environments [ 0 ] ? . environmentId , environmentId ) ;
const snapshot = await access . get ( company ) ;
assert . ok ( snapshot . isSuccess ) ;
assert . equal (
snapshot . data . workspace . items . find ( ( item ) = > item . id . toPrimitive ( ) === environmentId )
? . values . data . kind ,
"environment"
) ;
const rows = await db . query < { name : string ; active : number } > (
"SELECT name,active FROM access_environment_values WHERE ownerId=:environmentId" ,
{ replacements : { environmentId } , type : QueryTypes . SELECT }
) ;
assert . equal ( rows [ 0 ] ? . name , "NAS identidades" ) ;
assert . equal ( rows [ 0 ] ? . active , 1 ) ;
assert . equal (
( await f . assetUseCases . remove ( company , nas . id . toPrimitive ( ) ) ) . isSuccess ,
false
) ;
await assert . rejects (
db . query (
"UPDATE access_local_identity_environments SET assetId=:foreign WHERE environmentId=:environmentId" ,
{ replacements : { foreign : foreign.id.toPrimitive ( ) , environmentId } }
)
) ;
await assert . rejects (
db . query ( "UPDATE access_items SET kind='group' WHERE id=:environmentId" , {
replacements : { environmentId } ,
} )
) ;
const retired = await local ( { action : "retire" , environmentId } ) ;
assert . ok ( retired . isSuccess ) ;
const repeat = await local ( { action : "retire" , environmentId } ) ;
assert . ok ( repeat . isSuccess ) ;
assert . deepEqual ( repeat . data . toPrimitive ( ) , retired . data . toPrimitive ( ) ) ;
assert . equal (
( await f . assetUseCases . remove ( company , nas . id . toPrimitive ( ) ) ) . isSuccess ,
false
) ;
assert . equal (
( await local ( { action : "associate" , environmentId , assetId : nas2.id.toPrimitive ( ) } ) )
. isSuccess ,
false
) ;
}
) ;
await t . test (
"rollback al crear vínculo revierte también el entorno y su revisión" ,
async ( ) = > {
const before = await access . get ( company ) ;
assert . ok ( before . isSuccess ) ;
const trigger = ` local_fixture_ ${ company . replaceAll ( "-" , "" ) } ` ;
await db . query (
` CREATE TRIGGER ${ trigger } BEFORE INSERT ON access_local_identity_environments FOR EACH ROW BEGIN IF NEW.companyId=' ${ company } ' THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='local fixture rollback'; END IF; END `
) ;
try {
await assert . rejects (
local ( {
action : "create" ,
assetId : desktop.id.toPrimitive ( ) ,
systemId : system.id.toPrimitive ( ) ,
name : "Rollback" ,
} )
) ;
} finally {
await db . query ( ` DROP TRIGGER ${ trigger } ` ) ;
}
const after = await access . get ( company ) ;
assert . ok ( after . isSuccess ) ;
assert . deepEqual (
after . data . workspace . items . map ( ( item ) = > [
item . id . toPrimitive ( ) ,
item . history . map ( ( revision ) = > revision . id . toPrimitive ( ) ) ,
] ) ,
before . data . workspace . items . map ( ( item ) = > [
item . id . toPrimitive ( ) ,
item . history . map ( ( revision ) = > revision . id . toPrimitive ( ) ) ,
] )
) ;
}
) ;
const resourceCatalog = await f . resourceUseCases . get ( company ) ;
assert . ok ( resourceCatalog . isSuccess ) ;
const template = resourceCatalog . data . catalog . definitions . find (
( item ) = > item . stockKey . getOrUndefined ( ) === "template:shared_folder"
) ;
const unc = resourceCatalog . data . catalog . definitions . find (
( item ) = > item . stockKey . getOrUndefined ( ) === "field:unc"
) ;
assert . ok ( template && unc ) ;
const shared = await f . resourceUseCases . save (
company ,
undefined ,
{
name : "Docs" ,
templateId : template.id.toPrimitive ( ) ,
active : true ,
notes : "" ,
characteristics : { [ unc . id . toPrimitive ( ) ] : String . raw ` \\ NAS \ Docs ` } ,
} ,
actor
) ;
assert . ok ( shared . isSuccess ) ;
const resourceId = shared . data . resource . id . toPrimitive ( ) ;
const resourceValues = shared . data . resource . values . toPrimitive ( ) ;
assert . ok ( resourceValues . integration ? . kind === "access" ) ;
const resourceTypeId = resourceValues . integration . resourceTypeId ;
const accountBase = {
kind : "account" as const ,
systemId : system.id.toPrimitive ( ) ,
environmentId ,
usage : "shared" as const ,
active : true ,
expiresOn : null ,
notes : null ,
} ;
const firstAccount = await add ( { . . . accountBase , login : "perfil" } ) ;
const secondAccount = await add ( { . . . accountBase , login : "alternativa" } ) ;
const stranger = await add ( { . . . accountBase , login : "otra persona" } ) ;
const technical = await add ( { . . . accountBase , login : "servicio" , usage : "technical" } ) ;
const period = { startDate : "2020-01-01" , endDate : null } ;
const firstRelation = await add ( {
kind : "account_person" ,
accountId : firstAccount.id.toPrimitive ( ) ,
personId : person ,
. . . period ,
configuration : "configured" ,
} ) ;
const secondRelation = await add ( {
kind : "account_person" ,
accountId : secondAccount.id.toPrimitive ( ) ,
personId : person ,
. . . period ,
configuration : "configured" ,
} ) ;
await add ( {
kind : "account_person" ,
accountId : stranger.id.toPrimitive ( ) ,
personId : otherPerson ,
. . . period ,
configuration : "configured" ,
} ) ;
await add ( {
kind : "account_person" ,
accountId : technical.id.toPrimitive ( ) ,
personId : person ,
. . . period ,
configuration : null ,
} ) ;
const permission = await add ( {
kind : "permission" ,
name : "Lectura" ,
active : true ,
resourceTypeId ,
description : null ,
} ) ;
const need = await add ( {
kind : "need" ,
personId : person ,
resourceId ,
permissionIds : [ permission . id . toPrimitive ( ) ] ,
. . . period ,
notes : null ,
} ) ;
const grant = await add ( {
kind : "grant" ,
accountId : firstAccount.id.toPrimitive ( ) ,
groupId : null ,
permissionId : permission.id.toPrimitive ( ) ,
resourceId ,
. . . period ,
configuration : "configured" ,
} ) ;
await add ( {
kind : "coverage" ,
needId : need.id.toPrimitive ( ) ,
grantId : grant.id.toPrimitive ( ) ,
accountPersonId : firstRelation.id.toPrimitive ( ) ,
membershipId : null ,
. . . period ,
} ) ;
const station = await workstations . save (
company ,
undefined ,
{
name : "Puesto fixture" ,
active : true ,
siteId : null ,
personId : null ,
computerAssetId : desktop.id.toPrimitive ( ) ,
assetIds : [ desktop . id . toPrimitive ( ) ] ,
} ,
actor
) ;
assert . ok ( station . isSuccess ) ;
workstationId = station . data . workstation . id . toPrimitive ( ) ;
const profile = await profiles . save (
company ,
undefined ,
{
name : "Perfil local fixture" ,
personId : person ,
assetId : desktop.id.toPrimitive ( ) ,
accountId : firstAccount.id.toPrimitive ( ) ,
active : true ,
notes : null ,
} ,
actor
) ;
assert . ok ( profile . isSuccess , profile . isSuccess ? "" : profile . error . code ) ;
const folderInput = {
profileId : profile.data.profile.id.toPrimitive ( ) ,
needId : need.id.toPrimitive ( ) ,
path : String.raw ` \\ NAS \ Docs ` ,
driveLetter : "F:" ,
state : "configured" as const ,
notes : null ,
} ;
const original = await folders . save ( company , undefined , folderInput , actor ) ;
assert . ok ( original . isSuccess ) ;
const mappingId = original . data . mapping . id . toPrimitive ( ) ;
2026-10-21 10:37:59 +00:00
await t . test (
"UI 3.5: propietario local por lote y revisión obsoleta no sobrescribe un mapeo" ,
async ( ) = > {
const snapshot = await access . get ( company ) ;
assert . ok ( snapshot . isSuccess ) ;
const response = buildAccessResponse ( snapshot . data ) ;
assert . equal (
response . localEnvironments ? . find ( ( item ) = > item . environmentId === environmentId ) ? . assetId ,
nas . id . toPrimitive ( )
) ;
const rejected = await folders . save (
company ,
mappingId ,
{ . . . folderInput , notes : "No guardar" } ,
actor ,
UniqueID . generateNewID ( ) . toPrimitive ( )
) ;
assert . ok ( ! rejected . isSuccess ) ;
assert . equal ( rejected . error . code , "FOLDER_MAPPING_CONFLICT" ) ;
const unchanged = await folders . get ( company ) ;
assert . ok ( unchanged . isSuccess ) ;
assert . equal (
unchanged . data . mappings . find ( ( item ) = > item . id . toPrimitive ( ) === mappingId ) ? . history
. length ,
1
) ;
const accepted = await folders . save (
company ,
mappingId ,
folderInput ,
actor ,
original . data . mapping . history . at ( - 1 ) ? . id . toPrimitive ( )
) ;
assert . ok ( accepted . isSuccess ) ;
}
) ;
2026-10-21 09:25:23 +00:00
const read = async ( ) = > {
const snapshot = await folders . get ( company ) ;
assert . ok ( snapshot . isSuccess ) ;
const mapping = snapshot . data . mappings . find ( ( item ) = > item . id . toPrimitive ( ) === mappingId ) ;
assert . ok ( mapping ) ;
return buildFolderResponse ( mapping , snapshot . data ) ;
} ;
await t . test (
"mapeo antiguo desconocido; cuenta del perfil y alternativa sin atribuir cobertura de otra cuenta" ,
async ( ) = > {
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "unknown" ) ;
assert . ok (
(
await folders . save (
company ,
mappingId ,
{ . . . folderInput , accessAccountId : firstAccount.id.toPrimitive ( ) } ,
actor
)
) . isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "covered" ) ;
assert . ok (
(
await folders . save (
company ,
mappingId ,
{ . . . folderInput , accessAccountId : secondAccount.id.toPrimitive ( ) } ,
actor
)
) . isSuccess
) ;
const response = await read ( ) ;
assert . equal ( response . permissionsCovered , true ) ;
assert . equal ( response . accessAccountCoverage , "not-covered" ) ;
assert . equal ( response . values . accessAccountId , secondAccount . id . toPrimitive ( ) ) ;
assert . equal ( response . history [ 0 ] ? . values . accessAccountId , null ) ;
assert . equal ( response . history . length , 3 ) ;
assert . equal ( response . history [ 0 ] ? . id , original . data . mapping . history [ 0 ] ? . id . toPrimitive ( ) ) ;
}
) ;
await t . test (
"actualización ausente conserva, null retira; selecciones inválidas y cuentas técnicas documentales" ,
async ( ) = > {
assert . ok (
( await folders . save ( company , mappingId , { . . . folderInput , notes : "Solo notas" } , actor ) )
. isSuccess
) ;
assert . equal ( ( await read ( ) ) . values . accessAccountId , secondAccount . id . toPrimitive ( ) ) ;
for ( const id of [
stranger . id . toPrimitive ( ) ,
system . id . toPrimitive ( ) ,
UniqueID . generateNewID ( ) . toPrimitive ( ) ,
] ) {
assert . equal (
( await folders . save ( company , mappingId , { . . . folderInput , accessAccountId : id } , actor ) )
. isSuccess ,
false
) ;
}
const foreignSystem = await add (
{ kind : "system" , name : "Sistema ajeno" , active : true } ,
otherCompany
) ;
const foreignAccount = await add (
{
. . . accountBase ,
systemId : foreignSystem.id.toPrimitive ( ) ,
environmentId : null ,
login : "ajena" ,
} ,
otherCompany
) ;
assert . equal (
(
await folders . save (
company ,
mappingId ,
{ . . . folderInput , accessAccountId : foreignAccount.id.toPrimitive ( ) } ,
actor
)
) . isSuccess ,
false
) ;
assert . ok (
(
await folders . save (
company ,
mappingId ,
{ . . . folderInput , accessAccountId : technical.id.toPrimitive ( ) } ,
actor
)
) . isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "not-covered" ) ;
assert . ok (
( await folders . save ( company , mappingId , { . . . folderInput , accessAccountId : null } , actor ) )
. isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "unknown" ) ;
assert . equal ( ( await read ( ) ) . values . accessAccountId , null ) ;
const foreignWorkspace = await db . query < { id : string } > (
"SELECT id FROM access_workspaces WHERE companyId=:otherCompany" ,
{ replacements : { otherCompany } , type : QueryTypes . SELECT }
) ;
await assert . rejects (
db . query (
"UPDATE folder_mappings SET accessAccountId=:id,accessAccountWorkspaceId=:workspace WHERE id=:mappingId" ,
{
replacements : {
id : foreignAccount.id.toPrimitive ( ) ,
workspace : foreignWorkspace [ 0 ] ? . id ,
mappingId ,
} ,
}
)
) ;
const workspace = await db . query < { id : string } > (
"SELECT id FROM access_workspaces WHERE companyId=:company" ,
{ replacements : { company } , type : QueryTypes . SELECT }
) ;
await assert . rejects (
db . query (
"UPDATE folder_mappings SET accessAccountId=:id,accessAccountWorkspaceId=:workspace WHERE id=:mappingId" ,
{
replacements : { id : system.id.toPrimitive ( ) , workspace : workspace [ 0 ] ? . id , mappingId } ,
}
)
) ;
}
) ;
await t . test ( "revisiones conservan ámbito y subtipo de cuenta en MariaDB" , async ( ) = > {
const scope = await db . query < { id : string } > (
"SELECT id FROM access_workspaces WHERE companyId=:company" ,
{ replacements : { company } , type : QueryTypes . SELECT }
) ;
const revision = original . data . mapping . history [ 0 ] ;
assert . ok ( revision && scope [ 0 ] ) ;
await assert . rejects (
db . query (
"UPDATE folder_mapping_revisions SET accessAccountId=:account,accessAccountWorkspaceId=:workspace WHERE id=:id" ,
{
replacements : {
account : system.id.toPrimitive ( ) ,
workspace : scope [ 0 ] . id ,
id : revision.id.toPrimitive ( ) ,
} ,
}
)
) ;
} ) ;
await t . test (
"cobertura de grupo solo por la cuenta seleccionada y pertenencia vigente; caducidad documental derivada" ,
async ( ) = > {
const group = await add ( {
kind : "group" ,
name : "Grupo NAS" ,
identifier : "nas" ,
systemId : system.id.toPrimitive ( ) ,
environmentId ,
templateId : null ,
description : null ,
active : true ,
} ) ;
assert . equal (
(
await folders . save (
company ,
mappingId ,
{ . . . folderInput , accessAccountId : group.id.toPrimitive ( ) } ,
actor
)
) . isSuccess ,
false
) ;
const membership = await add ( {
kind : "membership" ,
accountId : secondAccount.id.toPrimitive ( ) ,
groupId : group.id.toPrimitive ( ) ,
. . . period ,
configuration : "configured" ,
} ) ;
const groupGrant = await add ( {
kind : "grant" ,
accountId : null ,
groupId : group.id.toPrimitive ( ) ,
permissionId : permission.id.toPrimitive ( ) ,
resourceId ,
. . . period ,
configuration : "configured" ,
} ) ;
await add ( {
kind : "coverage" ,
needId : need.id.toPrimitive ( ) ,
grantId : groupGrant.id.toPrimitive ( ) ,
accountPersonId : secondRelation.id.toPrimitive ( ) ,
membershipId : membership.id.toPrimitive ( ) ,
. . . period ,
} ) ;
assert . ok (
(
await folders . save (
company ,
mappingId ,
{ . . . folderInput , accessAccountId : secondAccount.id.toPrimitive ( ) } ,
actor
)
) . isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "covered" ) ;
assert . ok (
(
await access . save (
company ,
membership . id . toPrimitive ( ) ,
{
kind : "membership" ,
accountId : secondAccount.id.toPrimitive ( ) ,
groupId : group.id.toPrimitive ( ) ,
startDate : "2020-01-01" ,
endDate : "2021-01-01" ,
configuration : "removal_pending" ,
} ,
actor
)
) . isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "not-covered" ) ;
assert . ok (
(
await access . save (
company ,
secondAccount . id . toPrimitive ( ) ,
{ . . . accountBase , login : "alternativa" , active : false } ,
actor
)
) . isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "not-covered" ) ;
const preserved = await folders . save (
company ,
mappingId ,
{ . . . folderInput , notes : "Cuenta inactiva conservada" } ,
actor
) ;
assert . ok ( preserved . isSuccess ) ;
assert . equal ( ( await read ( ) ) . values . accessAccountId , secondAccount . id . toPrimitive ( ) ) ;
assert . ok (
( await f . resourceUseCases . setActive ( company , resourceId , false , actor ) ) . isSuccess
) ;
assert . equal ( ( await read ( ) ) . accessAccountCoverage , "not-covered" ) ;
assert . equal ( ( await read ( ) ) . permissionsCovered , false ) ;
}
) ;
await t . test (
"HTTP con sesión, CSRF, validación estricta, filtros y lectura de cuenta/cobertura" ,
async ( ) = > {
const http = f . app . listen ( 0 , "127.0.0.1" ) ;
try {
await once ( http , "listening" ) ;
const address = http . address ( ) ;
assert . ok ( address && typeof address !== "string" ) ;
const base = ` http://127.0.0.1: ${ address . port } ` ;
const endpoint = ` ${ base } /api/local-identity-environments/ ${ company } ` ;
assert . equal ( ( await fetch ( endpoint ) ) . status , 401 ) ;
const login = await fetch ( ` ${ base } /fixture-session ` ) ;
const cookie = login . headers . get ( "set-cookie" ) ? . split ( ";" ) [ 0 ] ;
assert . ok ( cookie ) ;
const body = { action : "associate" , assetId : desktop.id.toPrimitive ( ) , environmentId } ;
const request = (
value : unknown ,
token = "a" . repeat ( 64 ) ,
origin = "http://localhost:5173"
) = >
fetch ( endpoint , {
method : "POST" ,
headers : {
cookie ,
origin ,
"x-csrf-token" : token ,
"content-type" : "application/json" ,
} ,
body : JSON.stringify ( value ) ,
} ) ;
assert . equal ( ( await request ( body , "invalid" ) ) . status , 403 ) ;
assert . equal ( ( await request ( body , "a" . repeat ( 64 ) , "https://wrong.invalid" ) ) . status , 403 ) ;
assert . equal ( ( await request ( { . . . body , operatorId : actor } ) ) . status , 400 ) ;
assert . equal ( ( await request ( body ) ) . status , 409 ) ;
assert . equal (
(
await fetch (
` ${ base } /api/local-identity-environments/ ${ UniqueID . generateNewID ( ) . toPrimitive ( ) } ` ,
{ headers : { cookie } }
)
) . status ,
404
) ;
const page = await fetch ( ` ${ endpoint } ?pageSize=1&includeEnded=true ` , {
headers : { cookie } ,
} ) ;
assert . equal ( page . status , 200 ) ;
const data = LocalIdentityPageSchema . parse ( await page . json ( ) ) ;
assert . ok ( data . nextAfterId ) ;
const next = LocalIdentityPageSchema . parse (
await (
await fetch ( ` ${ endpoint } ?pageSize=1&includeEnded=true&afterId= ${ data . nextAfterId } ` , {
headers : { cookie } ,
} )
) . json ( )
) ;
assert . notEqual ( data . environments [ 0 ] ? . id , next . environments [ 0 ] ? . id ) ;
assert . equal (
( await fetch ( ` ${ endpoint } ?operatorId= ${ actor } ` , { headers : { cookie } } ) ) . status ,
400
) ;
const update = await fetch ( ` ${ base } /api/folder-mappings/ ${ company } / ${ mappingId } /update ` , {
method : "POST" ,
headers : {
cookie ,
origin : "http://localhost:5173" ,
"x-csrf-token" : "a" . repeat ( 64 ) ,
"content-type" : "application/json" ,
} ,
body : JSON.stringify ( { values : { . . . folderInput , notes : "HTTP" } } ) ,
} ) ;
assert . equal ( update . status , 200 ) ;
const response = FolderMappingResponseSchema . parse ( await update . json ( ) ) ;
assert . equal ( response . mapping . values . accessAccountId , secondAccount . id . toPrimitive ( ) ) ;
assert . equal ( response . mapping . accessAccountCoverage , "not-covered" ) ;
} finally {
await new Promise < void > ( ( resolve , reject ) = >
http . close ( ( error ) = > ( error ? reject ( error ) : resolve ( ) ) )
) ;
}
}
) ;
} finally {
try {
if ( ready ) {
await cleanupLocalFixture (
db ,
company ,
otherCompany ,
person ,
otherPerson ,
actor ,
workstations ,
workstationId
) ;
}
} finally {
await db . close ( ) ;
}
}
} ) ;
async function cleanupLocalFixture (
db : Sequelize ,
company : string ,
otherCompany : string ,
person : string ,
otherPerson : string ,
actor : string ,
workstations : WorkstationUseCases ,
workstationId : string | undefined
) {
for ( const table of [
"folder_mapping_revisions" ,
"folder_mappings" ,
"work_profile_revisions" ,
"work_profiles" ,
] ) {
const clause = table . endsWith ( "revisions" )
? table === "folder_mapping_revisions"
? "mappingId IN (SELECT id FROM folder_mappings WHERE companyId=:company)"
: "profileId IN (SELECT id FROM work_profiles WHERE companyId=:company)"
: "companyId=:company" ;
await db . query ( ` DELETE FROM ${ table } WHERE ${ clause } ` , { replacements : { company } } ) ;
}
if ( workstationId ) {
assert . ok ( ( await workstations . remove ( company , workstationId ) ) . isSuccess ) ;
}
await db . 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 IN (:companies)" ,
{ replacements : { companies : [ company , otherCompany ] } }
) ;
await db . 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 IN (:companies)" ,
{ replacements : { companies : [ company , otherCompany ] } }
) ;
for ( const kind of AccessKindSchema . options ) {
await db . 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 IN (:companies) ` ,
{ replacements : { companies : [ company , otherCompany ] } }
) ;
await db . 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 IN (:companies) ` ,
{ replacements : { companies : [ company , otherCompany ] } }
) ;
}
await db . query ( "DELETE FROM access_person_references WHERE personId IN (:people)" , {
replacements : { people : [ person , otherPerson ] } ,
} ) ;
await db . query ( "DELETE FROM company_contacts WHERE id IN (:people)" , {
replacements : { people : [ person , otherPerson ] } ,
} ) ;
await cleanupMembershipFixture ( db , [ company , otherCompany ] , actor ) ;
}