Skip to main content

Casos de prueba: Usuarios y Departamentos

Documenta los tests de los módulos user y departments. Los specs de controladores y servicios usan mocks; los marcados como integración usan MongoDB en memoria (mongodb-memory-server) con el repositorio y el modelo reales.

Specs fuente (bajo src/app/modules/):

  • user/controllers/user.controller.spec.ts
  • user/controllers/user.controller.permissions.spec.ts
  • user/controllers/user.controller.integration.spec.ts
  • user/dtos/create-user.dto.spec.ts
  • user/repositories/user.repository.filter-agents.spec.ts
  • user/services/user.service.spec.ts
  • departments/controllers/department.controller.spec.ts
  • departments/repositories/department.repository.spec.ts
  • departments/repositories/department-user.repository.spec.ts
  • departments/services/department.service.spec.ts
  • departments/services/department-user.service.spec.ts

Resumen: 11 specs, 132 tests (87 en user, 45 en departments). Los it.each se cuentan por fila.


Módulo user

user.controller.spec.ts​

UserController / create​

TestEscenarioResultado esperadoMocks
should return message and created userSe crea un usuario con un DTO válido; el usuario autenticado tiene tenantIdEl servicio recibe username, email y el tenantId del usuario autenticado; responde { message: 'user.created', data }UserService.create, AuthGuard (permite todo)

UserController / getMe​

TestEscenarioResultado esperadoMocks
returns the resolved permission acronyms merged into the user payloadEl resolver devuelve CONTACT_CREATE y CONTACT_READResuelve con (tenantId, roleId); results[0].permissions contiene ambos acrónimos y no incluye passwordPermissionResolverService.resolve, TenantSettingsService.getOrCreate
returns an empty permissions array when the resolver returns no acronymsEl resolver devuelve un Set vacíopermissions es []PermissionResolverService.resolve
exposes scheduledMessagesEnabled from tenant settings without leaking the rest of the config (CRITICAL-A fix)Settings con scheduledMessages.enabled = truefeatureFlags es { scheduledMessagesEnabled: true }; no aparecen general ni scheduledMessages en la respuestaPermissionResolverService.resolve, TenantSettingsService.getOrCreate
defaults scheduledMessagesEnabled to false when the tenant has not enabled the featureSettings con scheduledMessages.enabled = falsefeatureFlags es { scheduledMessagesEnabled: false }PermissionResolverService.resolve, TenantSettingsService.getOrCreate
exposes tenantPreferences with the tenant language and timezoneSettings con language: 'en', timezone: 'America/Bogota'tenantPreferences es { language: 'en', timezone: 'America/Bogota' }PermissionResolverService.resolve, TenantSettingsService.getOrCreate
does not leak the admin-only settings sections alongside tenantPreferencesSettings incluyen businessHours, autoResolution y csatLa respuesta no contiene esas secciones; tenantPreferences solo trae idioma y zona horariaPermissionResolverService.resolve, TenantSettingsService.getOrCreate

UserController / findAll​

TestEscenarioResultado esperadoMocks
should return message and array of usersEl servicio devuelve una listaLlama findAll(tenantId) y responde { message: 'user.findAll', data: { results } }UserService.findAll
should return message and empty array when no usersEl servicio devuelve []data.results es []UserService.findAll

UserController / findOne​

TestEscenarioResultado esperadoMocks
should return message and user when foundEl usuario existeLlama findOne(id, tenantId, lang) y responde { message: 'user.findOne', data: { results: [user] } }UserService.findOne
should propagate NotFoundException when user not foundEl servicio rechaza con NotFoundExceptionSe propaga NotFoundExceptionUserService.findOne

UserController / update​

TestEscenarioResultado esperadoMocks
should return message and updated user scoped to the authenticated tenantdto = { firstname: 'Jane' }Llama updateById(id, tenantId, dto, lang) y responde { message: 'user.updated', data }UserService.updateById
should propagate NotFoundException when user not foundEl servicio rechaza con NotFoundExceptionSe propaga NotFoundExceptionUserService.updateById

UserController / remove​

TestEscenarioResultado esperadoMocks
should return message and removed user scoped to the authenticated tenantEl usuario existe en el tenantLlama removeById(id, tenantId, lang) y responde { message: 'user.deleted', data }UserService.removeById
should propagate NotFoundException when user not foundEl servicio rechaza con NotFoundExceptionSe propaga NotFoundExceptionUserService.removeById

user.controller.permissions.spec.ts​

Integración del guard real PermissionsGuard + Reflector a través del pipeline HTTP (supertest). Un FakeAuthGuard inyecta tenantId y roleId; el resolver de permisos está mockeado.

UserController: exento self-service vs CRUD protegido​

TestEscenarioResultado esperadoMocks
allows GET /get-me with zero granted permissions (self-service, no metadata)GET /v1/users/get-me sin permisos concedidosHTTP 200 (endpoint exento del guard)FakeAuthGuard, PermissionResolverService.resolve, TenantSettingsService.getOrCreate, UserService
allows PATCH me/avatar with zero granted permissions (self-service, no metadata)PATCH /v1/users/me/avatar con archivo adjunto y sin permisosHTTP 200 y se invoca updateAvatarFakeAuthGuard, PermissionResolverService.resolve, UserService.updateAvatar
returns 403 Forbidden for DELETE remove/:id when USER_DELETE is missingDELETE /v1/users/remove/:id con solo USER_READHTTP 403 y removeById no se invocaFakeAuthGuard, PermissionResolverService.resolve, UserService.removeById
returns 200 OK for DELETE remove/:id when USER_DELETE is grantedMismo endpoint con USER_DELETE concedidoHTTP 200 y se invoca removeByIdFakeAuthGuard, PermissionResolverService.resolve, UserService.removeById

user.controller.integration.spec.ts​

Integración con MongoDB en memoria; solo se mockean permisos, settings, procesador de media y storage.

UserController: signature integration (raíz)​

TestEscenarioResultado esperadoMocks
persists the signature via PATCH and returns it on a subsequent get-me callupdateSignature con signature, luego getMe sobre el usuario releídoLa firma persiste en Mongo, la respuesta no trae password y getMe devuelve la firmaPermissionResolverService, TenantSettingsService
never leaks the password field in the PATCH responseupdateSignature con 'Saludos'Las claves de data no incluyen passwordPermissionResolverService, TenantSettingsService

updateAvatar​

TestEscenarioResultado esperadoMocks
uploads a valid JPG and reflects avatarUrl on a subsequent get-me callSe sube un JPG válidoavatarUrl contiene avatars/{tenantId}/{userId}.webp y getMe devuelve la misma URLMediaProcessorService.processImage, StorageService.uploadPublic
overwrites the same storage key on re-upload and changes the cache-busterSe sube el avatar dos vecesLa URL base es igual y el parámetro ?v= cambiaMediaProcessorService, StorageService.uploadPublic
rejects a non-JPG file with no storage write and no persisted changeArchivo image/pngRechaza y avatarUrl sigue siendo ''MediaProcessorService, StorageService
rejects an oversized file with no storage write and no persisted changeArchivo de 2 MB + 1 byteRechaza y avatarUrl sigue siendo ''MediaProcessorService, StorageService
never leaks the password field in the PATCH responseSubida válidaLas claves de data no incluyen passwordMediaProcessorService, StorageService.uploadPublic

create​

TestEscenarioResultado esperadoMocks
creates the user with the authenticated tenant, without a tenantId in the bodyAlta sin tenantId en el bodyEl usuario queda en el tenant del autenticado, con isPlatformAdmin = falseNinguno de dominio (Mongo real)
ignores a tenantId injected in the body and keeps the authenticated oneEl body incluye un tenantId ajenoSe conserva el tenant del autenticado; el ajeno se ignoraNinguno de dominio (Mongo real)

toggleActive​

TestEscenarioResultado esperadoMocks
flips isActive from true to false and persists itUsuario activoisActive pasa a false y se persisteNinguno de dominio (Mongo real)
flips isActive back from false to trueSe alterna dos vecesTermina en isActive: trueNinguno de dominio (Mongo real)

findAll​

TestEscenarioResultado esperadoMocks
returns only users from the authenticated tenantExiste un usuario de otro tenantLa lista incluye johndoe y excluye ajenoNinguno de dominio (Mongo real)

tenant isolation (SEC-014)​

TestEscenarioResultado esperadoMocks
does not return a user that belongs to another tenantfindOne con el identifier de un usuario de otro tenantNotFoundExceptionMongo real
does not change the password of a user that belongs to another tenantupdate con password sobre usuario ajenoNotFoundException y el hash de la víctima permanece intactoMongo real
does not toggle a user that belongs to another tenanttoggleActive sobre usuario ajenoNotFoundException y isActive sigue en trueMongo real
does not delete a user that belongs to another tenantremove sobre usuario ajenoNotFoundException y el usuario sigue existiendoMongo real
still reads and updates users of the authenticated tenantfindOne y update sobre usuarios propiosLectura correcta y firstname actualizado a JohnnyMongo real
responds NotFound for a malformed id instead of a cast errorremove('not-an-object-id')NotFoundException (no un error de cast)Mongo real
rejects persisting a userType outside the allowed valuesupdate con userType: 'atc'Rechaza y el userType sigue siendo agentMongo real

password hash never reaches serialized responses (B2.1)​

TestEscenarioResultado esperadoMocks
omits the password from every user CRUD responseSe ejecutan create, findOne, findAll, update, toggleActive y removeNingún JSON de respuesta contiene "password"Mongo real
keeps the password hash available internally for authenticationSe relee el usuario desde el modelopassword y toObject().password conservan el hashMongo real

hasOperationalTenant (B4)​

TestEscenarioResultado esperadoMocks
reads the real state of a %s tenant (it.each: active, deactivated, with inactive status)Tenant creado en Mongo con isActive/status distintosDevuelve true solo si está activo y con status: 'active'; false en los otros dos casosMongo real
returns false when the tenant does not existTenant con id inexistenteDevuelve falseMongo real

user.dtos: create-user.dto.spec.ts​

Validación con class-validator y class-transformer.

CreateUserDto: userType​

TestEscenarioResultado esperadoMocks
accepts %s (it.each: admin, agent)Payload válido con ese userTypeSin errores de validación en userTypeNinguno
rejects %p (it.each: atc, external, superadmin, cadena vacía)Payload válido con un userType no permitidoExactamente un error en userTypeNinguno

UpdateUserDto: userType​

TestEscenarioResultado esperadoMocks
allows omitting userTypePayload solo con firstnameSin errores en userTypeNinguno
rejects a userType outside the allowed valuesuserType: 'atc'Un error en userTypeNinguno

User DTOs: isPlatformAdmin is not assignable through the API​

TestEscenarioResultado esperadoMocks
rejects isPlatformAdmin on createCreate con isPlatformAdmin: true y whitelist + forbidNonWhitelistedLa propiedad isPlatformAdmin aparece entre los erroresNinguno
rejects isPlatformAdmin on updateUpdate con isPlatformAdmin: true y las mismas opcionesLa propiedad isPlatformAdmin aparece entre los erroresNinguno

user.repository.filter-agents.spec.ts​

Integración con MongoDB en memoria.

UserRepository.findFilterableByTenant (D11)​

TestEscenarioResultado esperadoMocks
returns only _id, firstname, lastName, username — no email/password/roleIdUn usuario con todos los camposLa proyección solo trae _id, firstname, lastName, username (ignorando __v)Mongo real
scopes strictly by tenant — excludes users from other tenantsUsuarios en dos tenantsSolo devuelve el usuario del tenant consultadoMongo real
returns all tenant users regardless of userType/isActive — same result set as today's unfiltered get-allUn admin y un agente inactivo en el mismo tenantDevuelve ambosMongo real

filterAssignableByIds​

TestEscenarioResultado esperadoMocks
keeps active users of any userType, admins includedUn agente y un admin activosDevuelve ambos idsMongo real
drops inactive users regardless of their userTypeUn activo, un agente inactivo y un admin inactivoSolo devuelve el id del activoMongo real
returns an empty list without querying when no ids are givenLista de ids vacíaResuelve []Mongo real

user.service.spec.ts​

UserService / create​

TestEscenarioResultado esperadoMocks
should hash password and create userEl email no existeBusca por email, hashea con bcrypt.hash(password, 10) y crea con el hashUserRepository, bcrypt
should throw ConflictException when email already existsfindByEmail devuelve un usuarioConflictExceptionUserRepository.findByEmail

UserService / findAll​

TestEscenarioResultado esperadoMocks
should return an array of usersEl repositorio devuelve una listaLlama findAll(tenantId) y devuelve la listaUserRepository.findAll
should return an empty array when no users existEl repositorio devuelve []Devuelve []UserRepository.findAll

UserService / hasOperationalTenant​

TestEscenarioResultado esperadoMocks
reports a %s tenant correctly (it.each: active, deactivated, with inactive status, missing)El repositorio devuelve el estado operativo (o null)true solo para activo con status: 'active'; false para desactivado, inactivo o inexistente; consulta findOperationalStateById(tenantId)TenantRepository.findOperationalStateById

UserService / findOne​

TestEscenarioResultado esperadoMocks
should look the user up scoped to the tenantEl usuario existeLlama findByIdentifierAndTenant(id, tenantId) y lo devuelveUserRepository.findByIdentifierAndTenant
should throw NotFoundException when the user is not in the tenantEl repositorio devuelve nullNotFoundExceptionUserRepository.findByIdentifierAndTenant

UserService / updateById​

TestEscenarioResultado esperadoMocks
should update scoped to the tenant without hashing when no passwordDTO sin passwordNo se llama a bcrypt.hash; actualiza con (id, tenantId, dto)UserRepository.updateByIdAndTenant, bcrypt
should hash password when password is providedDTO con passwordHashea con costo 10 y envía el hash al repositorioUserRepository.updateByIdAndTenant, bcrypt.hash
should throw NotFoundException when the user is not in the tenantEl repositorio devuelve nullNotFoundExceptionUserRepository.updateByIdAndTenant
should throw NotFoundException for a malformed id without queryingId que no es ObjectIdNotFoundException y no se consulta el repositorioUserRepository.updateByIdAndTenant

UserService / removeById​

TestEscenarioResultado esperadoMocks
should remove scoped to the tenantEl usuario existeLlama removeByIdAndTenant(id, tenantId) y lo devuelveUserRepository.removeByIdAndTenant
should throw NotFoundException when the user is not in the tenantEl repositorio devuelve nullNotFoundExceptionUserRepository.removeByIdAndTenant

UserService / toggleActive​

TestEscenarioResultado esperadoMocks
should toggle scoped to the tenantEl usuario existeLlama toggleActiveByIdAndTenant(id, tenantId) y lo devuelveUserRepository.toggleActiveByIdAndTenant
should throw NotFoundException when the user is not in the tenantEl repositorio devuelve nullNotFoundExceptionUserRepository.toggleActiveByIdAndTenant

UserService / updateSignature​

TestEscenarioResultado esperadoMocks
should scope the update to the currently authenticated user idActualiza la firma del usuario actualLlama updateSignatureById(userId, signature)UserRepository.updateSignatureById
should return the updated user without the password fieldEl repositorio devuelve un documento con toObjectEl resultado incluye la firma y no contiene passwordUserRepository.updateSignatureById
should throw NotFoundException when the current user no longer existsEl repositorio devuelve nullNotFoundExceptionUserRepository.updateSignatureById

UserService / updateAvatar​

TestEscenarioResultado esperadoMocks
rejects a non-JPG file without touching storageArchivo image/pngBadRequestException; no se procesa, sube ni persiste nadaMediaProcessorService, StorageService, UserRepository
rejects an oversized JPG without touching storageJPG de 2 MB + 1 byteBadRequestException; no se procesa, sube ni persiste nadaMediaProcessorService, StorageService, UserRepository
converts a valid JPG to WEBP and uploads it under the stable per-user keyJPG válidoLlama processImage(buffer) y uploadPublic('avatars/{tenantId}/{userId}.webp', buffer, 'image/webp')MediaProcessorService.processImage, StorageService.uploadPublic, UserRepository.updateAvatarUrlById
persists the avatar URL with a cache-busting query paramLa subida devuelve la URL basePersiste la URL con ?v= seguido de dígitosStorageService.uploadPublic, UserRepository.updateAvatarUrlById
returns the updated user without the password fieldSubida válidaEl resultado no contiene passwordStorageService.uploadPublic, UserRepository.updateAvatarUrlById
throws NotFoundException when the current user no longer existsupdateAvatarUrlById devuelve nullNotFoundExceptionStorageService.uploadPublic, UserRepository.updateAvatarUrlById

Módulo departments

department.controller.spec.ts​

DepartmentController / create​

TestEscenarioResultado esperadoMocks
delegates to service and returns { message, data }DTO { name: 'Soporte' }Llama create(dto, tenantId) y responde { message: 'department.created', data }DepartmentService.create, AuthGuard, PermissionsGuard (permiten todo)

DepartmentController / findAll​

TestEscenarioResultado esperadoMocks
returns { message, data: { results } } scoped to tenantListado sin paginación ni filtrosLlama findAll(tenantId, undefined, undefined, {}) y responde department.find_all con resultsDepartmentService.findAll

DepartmentController / findOne​

TestEscenarioResultado esperadoMocks
returns { message, data: { results: [department] } }El departamento existeLlama findOne(id, tenantId, lang) y responde department.find_oneDepartmentService.findOne
propagates NotFoundExceptionEl servicio rechaza con NotFoundExceptionSe propaga NotFoundExceptionDepartmentService.findOne

DepartmentController / update​

TestEscenarioResultado esperadoMocks
returns { message, data }DTO { name: 'Modificado' }Llama update(id, tenantId, dto, lang) y responde department.updatedDepartmentService.update
propagates NotFoundExceptionEl servicio rechaza con NotFoundExceptionSe propaga NotFoundExceptionDepartmentService.update

DepartmentController / getDepartmentUsers​

TestEscenarioResultado esperadoMocks
returns { message, data: { results } }El servicio devuelve usuarios con sus flagsLlama getUsersForDepartment(ObjectId(id), tenantId) y responde department.find_allDepartmentUserService.getUsersForDepartment

DepartmentController / updateDepartmentUsers​

TestEscenarioResultado esperadoMocks
returns { message, data: { results } }DTO { users: [] }Llama updateUsersForDepartment(ObjectId(id), tenantId, dto) y responde department.updatedDepartmentUserService.updateUsersForDepartment

DepartmentController / remove​

TestEscenarioResultado esperadoMocks
returns { message, data }El departamento existeLlama remove(id, tenantId, lang) y responde department.deletedDepartmentService.remove
propagates NotFoundExceptionEl servicio rechaza con NotFoundExceptionSe propaga NotFoundExceptionDepartmentService.remove

department.repository.spec.ts​

Integración con MongoDB en memoria.

DepartmentRepository / create​

TestEscenarioResultado esperadoMocks
stores document with tenantId and returns itCrea Soporte en el tenant ADevuelve el documento con _id, tenantId y nameMongo real
applies schema defaults (color, autoAssignment)Crea solo con namecolor es #000000 y autoAssignment es falseMongo real

DepartmentRepository / findAll​

TestEscenarioResultado esperadoMocks
returns only departments belonging to the tenantDos departamentos en A y uno en BDevuelve solo los 2 del tenant AMongo real
returns empty array when tenant has no departmentsTenant sin departamentosDevuelve []Mongo real

DepartmentRepository / findById​

TestEscenarioResultado esperadoMocks
returns document when _id and tenantId matchId y tenant correctosDevuelve el documentoMongo real
returns null when tenantId does not match (cross-tenant)Id válido pero tenant BDevuelve nullMongo real
returns null when id does not existId inexistenteDevuelve nullMongo real

DepartmentRepository / update​

TestEscenarioResultado esperadoMocks
updates and returns updated documentCambia el nombre en el tenant correctoDevuelve el documento con el nombre nuevoMongo real
returns null when id does not belong to tenantActualiza con el tenant BDevuelve nullMongo real

DepartmentRepository / delete​

TestEscenarioResultado esperadoMocks
removes document and returns itBorra en el tenant correctoDevuelve el documento y findById posterior devuelve nullMongo real
returns null when id does not belong to tenantBorra con el tenant BDevuelve nullMongo real

department-user.repository.spec.ts​

Integración con MongoDB en memoria.

DepartmentUserRepository / upsert​

TestEscenarioResultado esperadoMocks
creates a new record when one does not existUpsert de un par departamento-usuario nuevoDevuelve el registro con ids y flags indicadosMongo real
updates existing record on second upsertSe hace upsert dos veces sobre el mismo parLos flags se actualizan y solo existe 1 documentoMongo real

DepartmentUserRepository / findByDepartment​

TestEscenarioResultado esperadoMocks
returns only records for the given department and tenantRegistros mezclados de otros departamentos y tenantsSolo devuelve los 2 del departamento y tenant pedidosMongo real
returns empty array when no assignments existSin asignacionesDevuelve []Mongo real

DepartmentUserRepository / findAutoAssignUserIds​

TestEscenarioResultado esperadoMocks
returns only userIds with autoAssign true for the department and tenantMezcla de flags, departamentos y tenantsSolo devuelve el usuario con autoAssign: true del departamento y tenantMongo real
returns empty array when the department has no queueNadie con autoAssignDevuelve []Mongo real

DepartmentUserRepository / findDepartmentIdsByUser​

TestEscenarioResultado esperadoMocks
returns only the departments where the user has assignToDepartmentUn departamento con assignToDepartment true y otro falseSolo devuelve el primeroMongo real
does not leak memberships from another tenantMembresía en el tenant BDevuelve [] para el tenant AMongo real
returns an empty list for a user with no membershipsUsuario sin membresíasDevuelve []Mongo real

DepartmentUserRepository / deleteByDepartment​

TestEscenarioResultado esperadoMocks
removes all records for the department within the tenantRegistros del mismo departamento en dos tenantsBorra los del tenant A y conserva el del tenant BMongo real

department.service.spec.ts​

DepartmentService / create​

TestEscenarioResultado esperadoMocks
delegates to repository and returns resultAlta de SoporteLlama create(tenantId, dto) y devuelve el resultadoDepartmentRepository.create

DepartmentService / findAll​

TestEscenarioResultado esperadoMocks
returns all departments for tenantSin filtrosLlama findAll(tenantId, undefined) y devuelve { results }DepartmentRepository.findAll
restricts the listing to the departments the userId filter belongs toFiltro userIdResuelve membresías con findDepartmentIdsByUser y las pasa a findAllDepartmentUserRepository.findDepartmentIdsByUser, DepartmentRepository.findAll
passes the resolved membership ids down to the paginated queryPágina 1, límite 10, filtro userIdLlama findAllPaginated(tenantId, 1, 10, filter, memberOf) y devuelve { results, total }DepartmentUserRepository.findDepartmentIdsByUser, DepartmentRepository.findAllPaginated

DepartmentService / findOne​

TestEscenarioResultado esperadoMocks
returns department when foundfindById devuelve el departamentoLo devuelveDepartmentRepository.findById
throws NotFoundException when not foundfindById devuelve nullNotFoundExceptionDepartmentRepository.findById

DepartmentService / update​

TestEscenarioResultado esperadoMocks
returns updated departmentupdate devuelve el documento nuevoLo devuelveDepartmentRepository.update
throws NotFoundException when record not found for tenantupdate devuelve nullNotFoundExceptionDepartmentRepository.update

DepartmentService / remove​

TestEscenarioResultado esperadoMocks
deletes department and cascades department-user recordsEl departamento existeBorra el departamento y llama deleteByDepartment (cascada) con los mismos idsDepartmentRepository.delete, DepartmentUserRepository.deleteByDepartment
throws NotFoundException when department not found and does not cascadedelete devuelve nullNotFoundException y no se ejecuta la cascadaDepartmentRepository.delete, DepartmentUserRepository.deleteByDepartment

department-user.service.spec.ts​

DepartmentUserService / getUsersForDepartment​

TestEscenarioResultado esperadoMocks
merges all tenant users with department assignments, defaulting flags to falseDos usuarios del tenant y una asignación existenteDevuelve 2 entradas: la asignada con sus flags en true y la otra con ambos en falseUserRepository.findAll, DepartmentUserRepository.findByDepartment
scopes the user lookup to the requesting tenantSin asignacionesfindAll se llama con el tenantId y el resultado solo contiene usuarios del tenantUserRepository.findAll, DepartmentUserRepository.findByDepartment

DepartmentUserService / updateUsersForDepartment​

TestEscenarioResultado esperadoMocks
upserts each user entry and returns updated listDTO con 2 usuariosSe llama upsert 2 veces, con los flags de cada entrada, y se recompone la listaDepartmentUserRepository.upsert, UserRepository.findAll, DepartmentUserRepository.findByDepartment

DepartmentUserService / deleteUsersForDepartment​

TestEscenarioResultado esperadoMocks
delegates to repositoryBorrado de asignaciones de un departamentoLlama deleteByDepartment(deptId, tenantId)DepartmentUserRepository.deleteByDepartment