2026-10-03 10:36:03 +00:00
import assert from "node:assert/strict" ;
import { once } from "node:events" ;
import { test } from "node:test" ;
import {
CompaniesResponseSchema ,
CompanyErrorResponseSchema ,
CompanyResponseSchema ,
} from "@metis/companies/common" ;
2026-10-03 11:13:15 +00:00
import { createCompanyModule } from "@metis/companies/module" ;
2026-10-03 10:36:03 +00:00
import {
IdentityErrorResponseSchema ,
SessionResponseSchema ,
UserResponseSchema ,
UsersResponseSchema ,
} from "@metis/identity/common" ;
import { QueryTypes } from "sequelize" ;
2026-10-03 13:19:20 +00:00
import { verifyAccess } from "./access.integration" ;
2026-10-03 10:36:03 +00:00
import { createApp } from "./app" ;
import { createDatabase , readDatabaseEnvironment } from "./config/database" ;
import { createIdentityRuntime } from "./infrastructure/http/identity-runtime" ;
test ( "HTTP y MariaDB: configuración única, usuarios, sesiones y protección del administrador" , async ( ) = > {
const environment = readDatabaseEnvironment ( process . env ) ;
// Este proceso solo puede limpiar la base de pruebas dedicada.
assert . equal ( environment . DB_NAME , "metis_desk_test" ) ;
const database = createDatabase ( environment ) ;
const identity = await createIdentityRuntime ( database , environment ) ;
const server = createApp ( ( ) = > undefined , identity ) . listen ( 0 , "127.0.0.1" ) ;
try {
await once ( server , "listening" ) ;
await database . query ( "UPDATE identity_state SET initialAdminId = NULL WHERE id = 1" ) ;
await database . query ( "DELETE FROM http_sessions" ) ;
2026-10-03 13:19:20 +00:00
await database . query ( "DELETE FROM access_person_references" ) ;
await database . query ( "DELETE FROM access_references" ) ;
await database . query ( "DELETE FROM access_revisions" ) ;
await database . query ( "DELETE FROM access_items" ) ;
await database . query ( "DELETE FROM access_workspaces WHERE companyId IS NOT NULL" ) ;
2026-10-03 10:36:03 +00:00
await database . query ( "DELETE FROM users" ) ;
2026-10-03 11:13:15 +00:00
await database . query ( "DELETE FROM department_assignment_revisions" ) ;
await database . query ( "DELETE FROM person_department_assignments" ) ;
2026-10-03 10:36:03 +00:00
await database . query ( "DELETE FROM company_contacts" ) ;
2026-10-03 11:13:15 +00:00
await database . query ( "DELETE FROM company_departments" ) ;
2026-10-03 10:36:03 +00:00
await database . query ( "DELETE FROM company_sites" ) ;
await database . query ( "DELETE FROM companies" ) ;
2026-10-03 11:13:15 +00:00
// Simular la tabla de contactos de la versión anterior solo en la base de pruebas.
const legacyCompanyId = "48f13545-1529-4ba1-a353-a5f844141411" ;
const legacyPersonId = "4ec8f8c5-3ad9-4e22-abf3-b95370400898" ;
await database . query ( "INSERT INTO companies (id,name,active) VALUES (:id,'Legacy',1)" , {
replacements : { id : legacyCompanyId } ,
} ) ;
await database . query (
"INSERT INTO company_contacts (id,companyId,name,position,email,phone,active,isContact) VALUES (:id,:companyId,'Contacto anterior','Compras','legacy@example.test','900123456',1,1)" ,
{ replacements : { id : legacyPersonId , companyId : legacyCompanyId } }
) ;
await database . query (
"ALTER TABLE company_contacts DROP COLUMN isContact, MODIFY position VARCHAR(100) NOT NULL, MODIFY email VARCHAR(254) NOT NULL, MODIFY phone VARCHAR(50) NOT NULL"
) ;
await createCompanyModule ( database , ( _request , _response , next ) = > next ( ) ) ;
await createCompanyModule ( database , ( _request , _response , next ) = > next ( ) ) ;
const legacy = await database . query < { id : string ; email : string ; isContact : number } > (
"SELECT id,email,isContact FROM company_contacts WHERE id=:id" ,
{ replacements : { id : legacyPersonId } , type : QueryTypes . SELECT }
) ;
assert . equal ( legacy [ 0 ] ? . id , legacyPersonId ) ;
assert . equal ( legacy [ 0 ] ? . email , "legacy@example.test" ) ;
assert . equal ( Number ( legacy [ 0 ] ? . isContact ) , 1 ) ;
await database . query ( "DELETE FROM company_contacts WHERE id=:id" , {
replacements : { id : legacyPersonId } ,
} ) ;
await database . query ( "DELETE FROM companies WHERE id=:id" , {
replacements : { id : legacyCompanyId } ,
} ) ;
2026-10-03 10:36:03 +00:00
const address = server . address ( ) ;
assert . ok ( address && typeof address !== "string" ) ;
const baseUrl = ` http://127.0.0.1: ${ address . port } /api ` ;
function browser() {
let cookie = "" ;
let csrf = "" ;
return {
async request (
path : string ,
body? : unknown ,
origin = environment . APP_ORIGIN ,
token? : string
) {
const response = await fetch ( ` ${ baseUrl } ${ path } ` , {
method : body === undefined ? "GET" : "POST" ,
headers : {
cookie ,
origin ,
"content-type" : "application/json" ,
"x-csrf-token" : token ? ? csrf ,
} ,
. . . ( body === undefined ? { } : { body : JSON.stringify ( body ) } ) ,
} ) ;
const newCookie = response . headers . get ( "set-cookie" ) ;
if ( newCookie ) {
cookie = newCookie . split ( ";" ) [ 0 ] ? ? "" ;
}
return response ;
} ,
async session() {
const response = await this . request ( "/auth/session" ) ;
assert . equal ( response . status , 200 ) ;
const data = SessionResponseSchema . parse ( await response . json ( ) ) ;
csrf = data . csrfToken ;
return data ;
} ,
cookie : ( ) = > cookie ,
} ;
}
async function expectError ( response : Response , status : number , code : string ) {
assert . equal ( response . status , status ) ;
assert . equal ( IdentityErrorResponseSchema . parse ( await response . json ( ) ) . code , code ) ;
}
const admin = browser ( ) ;
const competitor = browser ( ) ;
assert . equal ( ( await admin . session ( ) ) . setupRequired , true ) ;
await competitor . session ( ) ;
await expectError ( await admin . request ( "/users" ) , 401 , "UNAUTHENTICATED" ) ;
const first = {
name : "Admin test" ,
email : "ADMIN@example.test" ,
password : "Admin123" ,
} ;
await expectError (
await admin . request ( "/auth/bootstrap" , first , "https://other.example" ) ,
403 ,
"FORBIDDEN"
) ;
await expectError (
await admin . request ( "/auth/bootstrap" , first , environment . APP_ORIGIN , "á" . repeat ( 64 ) ) ,
403 ,
"FORBIDDEN"
) ;
await expectError (
await admin . request ( "/auth/bootstrap" , { . . . first , password : "1234567" } ) ,
400 ,
"INVALID_REQUEST"
) ;
const beforeCookie = admin . cookie ( ) ;
const attempts = await Promise . all ( [
admin . request ( "/auth/bootstrap" , first ) ,
competitor . request ( "/auth/bootstrap" , { . . . first , email : "other@example.test" } ) ,
] ) ;
assert . deepEqual ( attempts . map ( ( response ) = > response . status ) . sort ( ) , [ 201 , 409 ] ) ;
const winnerIndex = attempts . findIndex ( ( response ) = > response . status === 201 ) ;
const administrator = winnerIndex === 0 ? admin : competitor ;
const winnerResponse = attempts [ winnerIndex ] ;
assert . ok ( winnerResponse ) ;
const initial = UserResponseSchema . parse ( await winnerResponse . json ( ) ) . user ;
assert . equal ( initial . isInitialAdmin , true ) ;
assert . equal ( initial . id . charAt ( 14 ) , "7" ) ;
if ( winnerIndex === 0 ) {
assert . notEqual ( admin . cookie ( ) , beforeCookie ) ;
}
assert . equal ( ( await administrator . session ( ) ) . setupRequired , false ) ;
await expectError ( await administrator . request ( "/auth/bootstrap" , first ) , 409 , "SETUP_CLOSED" ) ;
await expectError (
await administrator . request ( ` /users/ ${ initial . id } /update ` , {
name : initial.name ,
email : initial.email ,
active : false ,
} ) ,
409 ,
"ADMIN_PROTECTED"
) ;
await expectError (
await administrator . request ( "/users" , {
name : "Intruso" ,
email : "intruder@example.test" ,
password : first.password ,
isInitialAdmin : true ,
} ) ,
400 ,
"INVALID_REQUEST"
) ;
await expectError (
await administrator . request ( ` /users/ ${ initial . id . toUpperCase ( ) } /reset-password ` , {
password : "Admin123" ,
} ) ,
409 ,
"ADMIN_PROTECTED"
) ;
const person = {
name : "Operador test" ,
email : "operator@example.test" ,
password : "User1234" ,
} ;
const created = await administrator . request ( "/users" , person ) ;
assert . equal ( created . status , 201 ) ;
const user = UserResponseSchema . parse ( await created . json ( ) ) . user ;
assert . equal ( user . isInitialAdmin , false ) ;
await expectError (
await administrator . request ( "/users" , { . . . person , email : "OPERATOR@example.test" } ) ,
409 ,
"EMAIL_EXISTS"
) ;
const list = UsersResponseSchema . parse ( await ( await administrator . request ( "/users" ) ) . json ( ) ) ;
assert . equal ( list . users . length , 2 ) ;
assert . equal ( JSON . stringify ( list ) . includes ( "passwordHash" ) , false ) ;
const operator = browser ( ) ;
await operator . session ( ) ;
await expectError (
await operator . request ( "/auth/login" , { email : person.email , password : "incorrect" } ) ,
401 ,
"INVALID_CREDENTIALS"
) ;
assert . equal (
( await operator . request ( "/auth/login" , { email : person.email , password : person.password } ) )
. status ,
200
) ;
await operator . session ( ) ;
await expectError ( await operator . request ( "/users" ) , 403 , "FORBIDDEN" ) ;
await expectError (
await operator . request ( "/auth/change-password" , {
currentPassword : "incorrect" ,
password : "Nuevo123" ,
} ) ,
401 ,
"INVALID_CREDENTIALS"
) ;
const oldSession = browser ( ) ;
await oldSession . session ( ) ;
assert . equal (
( await oldSession . request ( "/auth/login" , { email : person.email , password : person.password } ) )
. status ,
200
) ;
await oldSession . session ( ) ;
const changedPassword = "Nuevo123" ;
assert . equal (
(
await operator . request ( "/auth/change-password" , {
currentPassword : person.password ,
password : changedPassword ,
} )
) . status ,
200
) ;
assert . equal ( ( await operator . session ( ) ) . user ? . id , user . id ) ;
assert . equal ( ( await oldSession . session ( ) ) . user , null ) ;
const resetPassword = "Reset123" ;
assert . equal (
( await administrator . request ( ` /users/ ${ user . id } /reset-password ` , { password : resetPassword } ) )
. status ,
200
) ;
assert . equal ( ( await operator . session ( ) ) . user , null ) ;
await expectError (
await operator . request ( "/auth/login" , { email : person.email , password : changedPassword } ) ,
401 ,
"INVALID_CREDENTIALS"
) ;
assert . equal (
( await operator . request ( "/auth/login" , { email : person.email , password : resetPassword } ) )
. status ,
200
) ;
await operator . session ( ) ;
assert . equal (
(
await administrator . request ( ` /users/ ${ user . id } /update ` , {
name : "Operador editado" ,
email : person.email ,
active : false ,
} )
) . status ,
200
) ;
assert . equal ( ( await operator . session ( ) ) . user , null ) ;
await expectError (
await operator . request ( "/auth/login" , { email : person.email , password : resetPassword } ) ,
401 ,
"INVALID_CREDENTIALS"
) ;
assert . equal (
(
await administrator . request ( ` /users/ ${ user . id } /update ` , {
name : person.name ,
email : person.email ,
active : true ,
} )
) . status ,
200
) ;
assert . equal (
( await operator . request ( "/auth/login" , { email : person.email , password : resetPassword } ) )
. status ,
200
) ;
await operator . session ( ) ;
const anonymousCompanyBrowser = browser ( ) ;
await anonymousCompanyBrowser . session ( ) ;
await expectError ( await anonymousCompanyBrowser . request ( "/companies" ) , 401 , "UNAUTHENTICATED" ) ;
const companyCreated = await operator . request ( "/companies" , {
name : "Compañía de pruebas" ,
active : true ,
} ) ;
assert . equal ( companyCreated . status , 201 ) ;
const customer = CompanyResponseSchema . parse ( await companyCreated . json ( ) ) . company ;
assert . equal ( customer . id . charAt ( 14 ) , "7" ) ;
const secondCreated = await operator . request ( "/companies" , {
name : "Segunda compañía" ,
active : true ,
} ) ;
const secondCompany = CompanyResponseSchema . parse ( await secondCreated . json ( ) ) . company ;
const personContact = {
name : "Ana Test" ,
position : "Responsable IT" ,
email : "ANA@example.test" ,
phone : "+34 900 123 456" ,
active : true ,
} ;
await expectError (
await operator . request (
` /companies/ ${ customer . id } /contacts ` ,
personContact ,
"https://other.example"
) ,
403 ,
"FORBIDDEN"
) ;
await expectError (
await operator . request ( ` /companies/ ${ customer . id } /contacts ` , {
. . . personContact ,
phone : "invalid" ,
} ) ,
400 ,
"INVALID_REQUEST"
) ;
const addedContact = await operator . request (
` /companies/ ${ customer . id } /contacts ` ,
personContact
) ;
assert . equal ( addedContact . status , 201 ) ;
const afterContact = CompanyResponseSchema . parse ( await addedContact . json ( ) ) . company ;
const contact = afterContact . contacts [ 0 ] ;
assert . ok ( contact ) ;
assert . equal ( contact . companyId , customer . id ) ;
assert . equal ( contact . id . charAt ( 14 ) , "7" ) ;
assert . equal ( contact . email , "ana@example.test" ) ;
const crossContact = await operator . request (
` /companies/ ${ secondCompany . id } /contacts/ ${ contact . id } /update ` ,
personContact
) ;
assert . equal ( crossContact . status , 404 ) ;
assert . equal (
CompanyErrorResponseSchema . parse ( await crossContact . json ( ) ) . code ,
"CONTACT_NOT_FOUND"
) ;
const changedContact = await operator . request (
` /companies/ ${ customer . id } /contacts/ ${ contact . id } /update ` ,
{ . . . personContact , name : "Ana Actualizada" , active : false }
) ;
assert . equal ( changedContact . status , 200 ) ;
assert . equal (
CompanyResponseSchema . parse ( await changedContact . json ( ) ) . company . contacts [ 0 ] ? . active ,
false
) ;
const noAddressSite = await operator . request ( ` /companies/ ${ customer . id } /sites ` , {
name : "Almacén" ,
} ) ;
assert . equal ( noAddressSite . status , 201 ) ;
const emptySite = CompanyResponseSchema . parse ( await noAddressSite . json ( ) ) . company . sites [ 0 ] ;
assert . ok ( emptySite ) ;
assert . equal ( emptySite . address , null ) ;
const siteAddress = "Calle Mayor, 10\n28001 Madrid" ;
const changedSite = await operator . request (
` /companies/ ${ customer . id } /sites/ ${ emptySite . id } /update ` ,
{ name : "Sede central" , address : siteAddress }
) ;
assert . equal ( changedSite . status , 200 ) ;
assert . equal (
CompanyResponseSchema . parse ( await changedSite . json ( ) ) . company . sites [ 0 ] ? . address ,
siteAddress
) ;
const crossSite = await operator . request (
` /companies/ ${ secondCompany . id } /sites/ ${ emptySite . id } /update ` ,
{ name : "Ajena" , address : null }
) ;
assert . equal ( crossSite . status , 404 ) ;
const largeAddress = "Á" . repeat ( 10000 ) ;
assert . equal (
(
await operator . request ( ` /companies/ ${ customer . id } /sites ` , {
name : "Oficina" ,
address : largeAddress ,
} )
) . status ,
201
) ;
assert . equal (
(
await operator . request ( ` /companies/ ${ customer . id } /sites ` , {
name : "Demasiado" ,
address : "a" . repeat ( 10001 ) ,
} )
) . status ,
400
) ;
const editedCompany = await operator . request ( ` /companies/ ${ customer . id } /update ` , {
name : "Compañía actualizada" ,
active : false ,
} ) ;
assert . equal ( editedCompany . status , 200 ) ;
const details = CompanyResponseSchema . parse (
await ( await operator . request ( ` /companies/ ${ customer . id } ` ) ) . json ( )
) . company ;
assert . equal ( details . id , customer . id ) ;
assert . equal ( details . active , false ) ;
assert . equal ( details . contacts [ 0 ] ? . id , contact . id ) ;
assert . equal ( details . sites . length , 2 ) ;
const companiesList = CompaniesResponseSchema . parse (
await ( await operator . request ( "/companies" ) ) . json ( )
) ;
assert . equal ( companiesList . companies . length , 2 ) ;
await assert . rejects (
database . query ( "DELETE FROM companies WHERE id = :id" , { replacements : { id : customer.id } } )
) ;
const clearedSite = await operator . request (
` /companies/ ${ customer . id } /sites/ ${ emptySite . id } /update ` ,
{ name : "Sede central" , address : null }
) ;
assert . equal ( clearedSite . status , 200 ) ;
2026-10-03 11:13:15 +00:00
// Personas y departamentos: mismas fronteras de sesión, UUID y compañía.
const peoplePath = ` /companies/ ${ customer . id } ` ;
async function companyData ( response : Response ) {
assert . ok ( response . status === 200 || response . status === 201 ) ;
return CompanyResponseSchema . parse ( await response . json ( ) ) . company ;
}
async function companyError ( response : Response , status : number , code : string ) {
assert . equal ( response . status , status ) ;
assert . equal ( CompanyErrorResponseSchema . parse ( await response . json ( ) ) . code , code ) ;
}
const personBody = {
name : "Persona sin correo" ,
position : null ,
email : null ,
phone : null ,
active : true ,
isContact : false ,
} ;
const personResponse = await companyData (
await operator . request ( ` ${ peoplePath } /people ` , personBody )
) ;
const companyPerson = personResponse . people . find ( ( item ) = > item . name === personBody . name ) ;
assert . ok ( companyPerson ) ;
assert . equal ( companyPerson . email , null ) ;
assert . equal ( companyPerson . id . charAt ( 14 ) , "7" ) ;
assert . equal (
personResponse . contacts . some ( ( item ) = > item . id === companyPerson . id ) ,
false
) ;
await companyError (
await operator . request ( ` ${ peoplePath } /people ` , { . . . personBody , isInitialAdmin : true } ) ,
400 ,
"INVALID_REQUEST"
) ;
await companyError (
await operator . request (
` ${ peoplePath } /departments ` ,
{ name : "Forbidden" , active : true } ,
"https://other.example"
) ,
403 ,
"FORBIDDEN"
) ;
const departmentResponse = await companyData (
await operator . request ( ` ${ peoplePath } /departments ` , { name : " Compras " , active : true } )
) ;
const department = departmentResponse . departments . find ( ( item ) = > item . name === "Compras" ) ;
assert . ok ( department ) ;
await companyError (
await operator . request ( ` ${ peoplePath } /departments ` , { name : "COMPRAS" , active : true } ) ,
409 ,
"DEPARTMENT_NAME_EXISTS"
) ;
const otherDepartmentResponse = await companyData (
await operator . request ( ` /companies/ ${ secondCompany . id } /departments ` , {
name : "Compras" ,
active : true ,
} )
) ;
const foreignDepartment = otherDepartmentResponse . departments [ 0 ] ;
assert . ok ( foreignDepartment ) ;
const assignmentBody = {
departmentId : department.id ,
position : "Responsable" ,
startDate : "2026-01-01" ,
endDate : null ,
isPrimary : true ,
} ;
await companyError (
await operator . request ( ` ${ peoplePath } /people/ ${ companyPerson . id } /assignments ` , {
. . . assignmentBody ,
departmentId : foreignDepartment.id ,
} ) ,
404 ,
"DEPARTMENT_NOT_FOUND"
) ;
const assignmentResponse = await companyData (
await operator . request ( ` ${ peoplePath } /people/ ${ companyPerson . id } /assignments ` , assignmentBody )
) ;
const membership = assignmentResponse . assignments . find (
( item ) = > item . personId === companyPerson . id
) ;
assert . ok ( membership ) ;
assert . equal ( membership . id . charAt ( 14 ) , "7" ) ;
assert . equal ( membership . history . length , 1 ) ;
await companyError (
await operator . request (
` ${ peoplePath } /people/ ${ companyPerson . id } /assignments ` ,
assignmentBody
) ,
409 ,
"ASSIGNMENT_CONFLICT"
) ;
const secondResponse = await companyData (
await operator . request ( ` ${ peoplePath } /departments ` , { name : "Administración" , active : true } )
) ;
const secondDepartment = secondResponse . departments . find (
( item ) = > item . name === "Administración"
) ;
assert . ok ( secondDepartment ) ;
await companyError (
await operator . request ( ` ${ peoplePath } /people/ ${ companyPerson . id } /assignments ` , {
. . . assignmentBody ,
departmentId : secondDepartment.id ,
} ) ,
409 ,
"ASSIGNMENT_CONFLICT"
) ;
await companyData (
await operator . request ( ` ${ peoplePath } /people/ ${ companyPerson . id } /assignments ` , {
. . . assignmentBody ,
departmentId : secondDepartment.id ,
isPrimary : false ,
} )
) ;
const editedAssignment = {
position : "Supervisor" ,
startDate : "2026-01-01" ,
endDate : null ,
isPrimary : true ,
} ;
const editedMembership = await companyData (
await operator . request (
` ${ peoplePath } /people/ ${ companyPerson . id } /assignments/ ${ membership . id } /update ` ,
editedAssignment
)
) ;
const history = editedMembership . assignments . find ( ( item ) = > item . id === membership . id ) ? . history ;
assert . equal ( history ? . length , 2 ) ;
assert . equal ( history ? . [ 0 ] ? . position , "Responsable" ) ;
const repeatedMembership = await companyData (
await operator . request (
` ${ peoplePath } /people/ ${ companyPerson . id } /assignments/ ${ membership . id } /update ` ,
editedAssignment
)
) ;
assert . equal (
repeatedMembership . assignments . find ( ( item ) = > item . id === membership . id ) ? . history . length ,
2
) ;
await companyError (
await operator . request (
` ${ peoplePath } /people/ ${ contact . id } /assignments/ ${ membership . id } /update ` ,
editedAssignment
) ,
404 ,
"ASSIGNMENT_NOT_FOUND"
) ;
await companyError (
await operator . request (
` ${ peoplePath } /people/ ${ companyPerson . id } /assignments/ ${ membership . id } /update ` ,
{ . . . editedAssignment , endDate : "2025-12-31" , isPrimary : false }
) ,
400 ,
"INVALID_REQUEST"
) ;
await companyData (
await operator . request ( ` ${ peoplePath } /departments/ ${ secondDepartment . id } /update ` , {
name : secondDepartment.name ,
active : false ,
} )
) ;
await companyError (
await operator . request ( ` ${ peoplePath } /people/ ${ contact . id } /assignments ` , {
. . . assignmentBody ,
departmentId : secondDepartment.id ,
isPrimary : false ,
} ) ,
409 ,
"INACTIVE_ASSIGNMENT_TARGET"
) ;
await companyData (
await operator . request ( ` ${ peoplePath } /people/ ${ companyPerson . id } /update ` , {
. . . personBody ,
active : false ,
} )
) ;
await companyError (
await operator . request ( ` ${ peoplePath } /people/ ${ companyPerson . id } /assignments ` , {
. . . assignmentBody ,
startDate : "2025-01-01" ,
endDate : "2025-02-01" ,
isPrimary : false ,
} ) ,
409 ,
"INACTIVE_ASSIGNMENT_TARGET"
) ;
const closed = await companyData (
await operator . request (
` ${ peoplePath } /people/ ${ companyPerson . id } /assignments/ ${ membership . id } /update ` ,
{ . . . editedAssignment , endDate : "2026-03-01" , isPrimary : false }
)
) ;
assert . equal ( closed . assignments . find ( ( item ) = > item . id === membership . id ) ? . history . length , 3 ) ;
await companyData (
await operator . request ( ` ${ peoplePath } /people/ ${ contact . id } /update ` , {
name : contact.name ,
position : contact.position ,
email : contact.email ,
phone : contact.phone ,
active : true ,
isContact : true ,
} )
) ;
// Concurrencia: el bloqueo de compañía evita dos asignaciones abiertas al mismo departamento.
const concurrent = await Promise . all ( [
operator . request ( ` ${ peoplePath } /people/ ${ contact . id } /assignments ` , {
. . . assignmentBody ,
isPrimary : false ,
} ) ,
operator . request ( ` ${ peoplePath } /people/ ${ contact . id } /assignments ` , {
. . . assignmentBody ,
isPrimary : false ,
} ) ,
] ) ;
assert . deepEqual ( concurrent . map ( ( response ) = > response . status ) . sort ( ) , [ 201 , 409 ] ) ;
// La FK compuesta impide pertenencias cruzadas aunque se intente escribir SQL directamente.
await assert . rejects (
database . query (
"INSERT INTO person_department_assignments (id, companyId, personId, departmentId, position, startDate, endDate, isPrimary) VALUES (:id, :companyId, :personId, :departmentId, NULL, '2026-01-01', NULL, 0)" ,
{
replacements : {
id : "a2349bc1-8c29-4d8b-b53a-5ec40e37a002" ,
companyId : customer.id ,
personId : companyPerson.id ,
departmentId : foreignDepartment.id ,
} ,
}
)
) ;
const userCount = await database . query < { total : number } > (
"SELECT COUNT(*) AS total FROM users" ,
{ type : QueryTypes . SELECT }
) ;
assert . equal ( Number ( userCount [ 0 ] ? . total ) , 2 ) ;
2026-10-03 13:19:20 +00:00
const accessCompany = CompanyResponseSchema . parse (
await ( await operator . request ( peoplePath ) ) . json ( )
) . company ;
const accessOther = CompanyResponseSchema . parse (
await ( await operator . request ( ` /companies/ ${ secondCompany . id } ` ) ) . json ( )
) . company ;
await verifyAccess ( ( . . . args ) = > operator . request ( . . . args ) , accessCompany , accessOther ) ;
const countAfterAccess = await database . query < { total : number } > (
"SELECT COUNT(*) AS total FROM users" ,
{ type : QueryTypes . SELECT }
) ;
assert . equal ( Number ( countAfterAccess [ 0 ] ? . total ) , 2 ) ;
2026-10-03 10:36:03 +00:00
assert . equal ( ( await operator . request ( "/auth/logout" , { } ) ) . status , 200 ) ;
2026-10-03 13:19:20 +00:00
await expectError ( await operator . request ( "/access/global" ) , 401 , "UNAUTHENTICATED" ) ;
2026-10-03 10:36:03 +00:00
assert . equal ( ( await operator . session ( ) ) . user , null ) ;
await expectError ( await operator . request ( "/users" ) , 401 , "UNAUTHENTICATED" ) ;
await expectError ( await operator . request ( "/companies" ) , 401 , "UNAUTHENTICATED" ) ;
await assert . rejects (
database . query ( "UPDATE users SET active = 0 WHERE id = :id" , {
replacements : { id : initial.id } ,
} )
) ;
await assert . rejects (
database . query ( "DELETE FROM users WHERE id = :id" , { replacements : { id : initial.id } } )
) ;
const stored = await database . query < { passwordHash : string } > (
"SELECT passwordHash FROM users WHERE id = :id" ,
{ replacements : { id : user.id } , type : QueryTypes . SELECT }
) ;
assert . ok ( stored [ 0 ] ? . passwordHash . startsWith ( "scrypt-v1$" ) ) ;
assert . equal ( JSON . stringify ( stored ) . includes ( resetPassword ) , false ) ;
// Al acumular fallos se rechazan los siguientes intentos.
let limited = false ;
for ( let index = 0 ; index < 12 ; index += 1 ) {
const response = await operator . request ( "/auth/login" , {
email : "missing@example.test" ,
password : "wrong" ,
} ) ;
if ( response . status === 429 ) {
limited = true ;
break ;
}
assert . equal ( response . status , 401 ) ;
}
assert . equal ( limited , true ) ;
} finally {
identity . stop ( ) ;
await new Promise < void > ( ( resolve , reject ) = > {
server . close ( ( error ) = > ( error ? reject ( error ) : resolve ( ) ) ) ;
server . closeAllConnections ( ) ;
} ) ;
await database . close ( ) ;
}
} ) ;