import type { Request } from 'express'; import type { AuditWriter } from '../audit/audit.service'; import { AdminUsersController } from './admin-users.controller'; import type { AdminUsersReader, AdminUsersPage } from './admin-users-reader.service'; import type { AdminUsersQueryDto } from './users-query.dto'; const PAGE: AdminUsersPage = { items: [ { oid: 'user-oid', tid: 'tenant-1', audience: 'workforce', username: 'jane.doe@apf.example', displayName: 'Jane Doe', firstSeenAt: '2026-05-10T10:00:00.000Z', lastSeenAt: '2026-05-14T08:30:00.000Z', }, ], total: 137, limit: 50, offset: 0, }; function makeReq(user?: { oid: string }): Request { return { session: user !== undefined ? { user } : {} } as unknown as Request; } function makeFixture() { const usersReader = { findUsers: jest.fn().mockResolvedValue(PAGE) }; const auditWriter = { adminUsersQuery: jest.fn().mockResolvedValue(undefined) }; const controller = new AdminUsersController( usersReader as unknown as AdminUsersReader, auditWriter as unknown as AuditWriter, ); return { controller, usersReader, auditWriter }; } describe('AdminUsersController.list', () => { it('returns the page from AdminUsersReader', async () => { const { controller } = makeFixture(); const page = await controller.list(makeReq({ oid: 'admin-oid' }), {} as AdminUsersQueryDto); expect(page).toBe(PAGE); }); it('forwards the validated DTO to AdminUsersReader as-is', async () => { const { controller, usersReader } = makeFixture(); const filters: AdminUsersQueryDto = { username: 'jane', audience: 'workforce', lastSeenAtFrom: '2026-05-01T00:00:00.000Z', limit: 25, offset: 0, }; await controller.list(makeReq({ oid: 'admin-oid' }), filters); expect(usersReader.findUsers).toHaveBeenCalledWith(filters); }); it('emits admin.users.query with filters + result count', async () => { const { controller, auditWriter } = makeFixture(); const filters: AdminUsersQueryDto = { username: 'jane', limit: 50 }; await controller.list(makeReq({ oid: 'admin-oid' }), filters); expect(auditWriter.adminUsersQuery).toHaveBeenCalledWith({ actor: { oid: 'admin-oid' }, filters: { username: 'jane', limit: 50 }, resultCount: PAGE.items.length, }); }); it('captures an empty filter object verbatim', async () => { const { controller, auditWriter } = makeFixture(); await controller.list(makeReq({ oid: 'admin-oid' }), {} as AdminUsersQueryDto); expect(auditWriter.adminUsersQuery).toHaveBeenCalledWith( expect.objectContaining({ filters: {} }), ); }); it('still returns the page when no session.user (defensive — guard normally catches)', async () => { const { controller, auditWriter } = makeFixture(); const page = await controller.list(makeReq(), {} as AdminUsersQueryDto); expect(page).toBe(PAGE); expect(auditWriter.adminUsersQuery).not.toHaveBeenCalled(); }); it('propagates audit write failures (blocking per ADR-0013)', async () => { const { controller, auditWriter } = makeFixture(); auditWriter.adminUsersQuery.mockRejectedValueOnce(new Error('audit_writer denied')); await expect( controller.list(makeReq({ oid: 'admin-oid' }), {} as AdminUsersQueryDto), ).rejects.toThrow('audit_writer denied'); }); });