feat(auditoria): mostrar el nombre del usuario en lugar del id (tabla y filtro)
This commit is contained in:
@@ -8,6 +8,9 @@ const prismaMock = vi.hoisted(() => ({
|
||||
auditoriaLog: {
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
usuario: {
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('../services/prisma.js', () => ({ prisma: prismaMock }))
|
||||
@@ -29,13 +32,14 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
describe('listarAuditoriaEndpoint (GET /api/auditoria)', () => {
|
||||
it('retorna logs de auditoría para admin', async () => {
|
||||
it('retorna logs de auditoría para admin (con el nombre del usuario)', async () => {
|
||||
const logsFake = [{ id: 'log-1', usuarioId: 'u1', accion: 'CREAR_LEAD', entidad: 'lead', entidadId: 'l1', detalle: null, createdAt: new Date() }]
|
||||
prismaMock.auditoriaLog.findMany.mockResolvedValue(logsFake)
|
||||
prismaMock.usuario.findMany.mockResolvedValue([{ id: 'u1', nombre: 'Martin Zavala' }])
|
||||
const { res, json } = resFake()
|
||||
|
||||
await listarAuditoriaEndpoint(reqFake({}, { sub: 'admin1', rol: 'admin' }), res)
|
||||
expect(json).toHaveBeenCalledWith(logsFake)
|
||||
expect(json).toHaveBeenCalledWith([{ ...logsFake[0], usuarioNombre: 'Martin Zavala' }])
|
||||
})
|
||||
|
||||
it('aplica filtros de entidad y usuarioId', async () => {
|
||||
|
||||
@@ -7,6 +7,9 @@ const prismaMock = vi.hoisted(() => ({
|
||||
create: vi.fn(),
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
usuario: {
|
||||
findMany: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('./prisma.js', () => ({ prisma: prismaMock }))
|
||||
@@ -48,9 +51,10 @@ describe('registrar', () => {
|
||||
})
|
||||
|
||||
describe('buscar', () => {
|
||||
it('sin filtros: retorna todos los logs ordenados por createdAt desc', async () => {
|
||||
const logsFake = [{ id: 'log-1' }]
|
||||
it('sin filtros: retorna los logs con el nombre del usuario resuelto', async () => {
|
||||
const logsFake = [{ id: 'log-1', usuarioId: 'u1' }]
|
||||
prismaMock.auditoriaLog.findMany.mockResolvedValue(logsFake)
|
||||
prismaMock.usuario.findMany.mockResolvedValue([{ id: 'u1', nombre: 'Martin Zavala' }])
|
||||
|
||||
const resultado = await buscar({})
|
||||
expect(prismaMock.auditoriaLog.findMany).toHaveBeenCalledWith({
|
||||
@@ -58,11 +62,23 @@ describe('buscar', () => {
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 100,
|
||||
})
|
||||
expect(resultado).toEqual(logsFake)
|
||||
expect(resultado).toEqual([{ id: 'log-1', usuarioId: 'u1', usuarioNombre: 'Martin Zavala' }])
|
||||
})
|
||||
|
||||
it('si el usuario ya no existe usa el id; "sistema" se muestra como Sistema', async () => {
|
||||
prismaMock.auditoriaLog.findMany.mockResolvedValue([
|
||||
{ id: 'log-2', usuarioId: 'fantasma' },
|
||||
{ id: 'log-3', usuarioId: 'sistema' },
|
||||
])
|
||||
prismaMock.usuario.findMany.mockResolvedValue([])
|
||||
|
||||
const resultado = await buscar({})
|
||||
expect(resultado.map((r) => r.usuarioNombre)).toEqual(['fantasma', 'Sistema'])
|
||||
})
|
||||
|
||||
it('con filtros de entidad y usuarioId', async () => {
|
||||
prismaMock.auditoriaLog.findMany.mockResolvedValue([])
|
||||
prismaMock.usuario.findMany.mockResolvedValue([])
|
||||
await buscar({ entidad: 'lead', usuarioId: 'u1' })
|
||||
expect(prismaMock.auditoriaLog.findMany).toHaveBeenCalledWith({
|
||||
where: { entidad: 'lead', usuarioId: 'u1' },
|
||||
@@ -75,6 +91,7 @@ describe('buscar', () => {
|
||||
const desde = new Date('2026-09-01')
|
||||
const hasta = new Date('2026-09-07')
|
||||
prismaMock.auditoriaLog.findMany.mockResolvedValue([])
|
||||
prismaMock.usuario.findMany.mockResolvedValue([])
|
||||
await buscar({ desde, hasta })
|
||||
expect(prismaMock.auditoriaLog.findMany).toHaveBeenCalledWith({
|
||||
where: { createdAt: { gte: desde, lte: hasta } },
|
||||
@@ -85,6 +102,7 @@ describe('buscar', () => {
|
||||
|
||||
it('respeta el límite personalizado', async () => {
|
||||
prismaMock.auditoriaLog.findMany.mockResolvedValue([])
|
||||
prismaMock.usuario.findMany.mockResolvedValue([])
|
||||
await buscar({ entidad: 'lead' }, 10)
|
||||
expect(prismaMock.auditoriaLog.findMany).toHaveBeenCalledWith({
|
||||
where: { entidad: 'lead' },
|
||||
|
||||
@@ -30,6 +30,11 @@ export function registrar(
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Lista registros de auditoría con el NOMBRE del usuario resuelto (la UI
|
||||
* muestra nombres, no ids). Si el usuario ya no existe se devuelve el id como
|
||||
* respaldo ('sistema' se muestra como 'Sistema').
|
||||
*/
|
||||
export async function buscar(filtros: FiltrosAuditoria, limite = 100) {
|
||||
const where: Record<string, unknown> = {}
|
||||
if (filtros.entidad !== undefined) where['entidad'] = filtros.entidad
|
||||
@@ -41,9 +46,22 @@ export async function buscar(filtros: FiltrosAuditoria, limite = 100) {
|
||||
...(filtros.hasta !== undefined ? { lte: filtros.hasta } : {}),
|
||||
}
|
||||
}
|
||||
return prisma.auditoriaLog.findMany({
|
||||
const logs = await prisma.auditoriaLog.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: limite,
|
||||
})
|
||||
|
||||
const ids = [...new Set(logs.map((l) => l.usuarioId))]
|
||||
const usuarios = ids.length > 0
|
||||
? await prisma.usuario.findMany({ where: { id: { in: ids } }, select: { id: true, nombre: true } })
|
||||
: []
|
||||
const nombrePorId = new Map(usuarios.map((u) => [u.id, u.nombre]))
|
||||
|
||||
return logs.map((l) => ({
|
||||
...l,
|
||||
usuarioNombre:
|
||||
nombrePorId.get(l.usuarioId) ??
|
||||
(l.usuarioId === 'sistema' || l.usuarioId === 'desconocido' ? 'Sistema' : l.usuarioId),
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user