Files
FRASA-CAS/api-gateway/src/controllers/cliente-maestro.controller.test.ts
Consult AS Technology 9021733455 feat(clientes-maestro): importar y exportar clientes del archivo maestro
- Tabla ClienteMaestro (27 campos, unique numCliente)
- Importador Excel: 1535 clientes del Reporte maestro
- API: listar/filtros/exportar/detalle/importar
- Frontend: tabla paginada, filtros, exportar Excel
- Dark mode completo, 52 tests verdes
2026-09-07 09:11:09 +00:00

135 lines
4.4 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { Request, Response } from 'express'
// ---------- Servicio mockeado ----------
const servicioMock = vi.hoisted(() => ({
listar: vi.fn(),
obtener: vi.fn(),
contar: vi.fn(),
exportar: vi.fn(),
importarDesdeExcel: vi.fn(),
}))
vi.mock('../services/cliente-maestro.service.js', () => servicioMock)
import {
listarEndpoint,
exportarEndpoint,
obtenerEndpoint,
importarEndpoint,
} from './cliente-maestro.controller.js'
function reqFake(overrides: Partial<Request> = {}): Request {
return {
body: {},
params: {},
query: {},
usuarioToken: { sub: 'u-1', username: 'admin', rol: 'admin' },
...overrides,
} as Request
}
function resFake() {
const json = vi.fn()
const end = vi.fn()
const status = vi.fn().mockReturnValue({ json, end })
return { res: { json, status, end } as unknown as Response, status, json, end }
}
beforeEach(() => {
vi.clearAllMocks()
})
// ── GET /api/clientes-maestro ────────────────────────────────────────
describe('listarEndpoint', () => {
it('200 con datos paginados', async () => {
servicioMock.listar.mockResolvedValue({
datos: [{ id: '1', numCliente: 'C001' }],
total: 1,
pagina: 1,
limite: 50,
})
const { res, json } = resFake()
await listarEndpoint(reqFake(), res)
expect(json).toHaveBeenCalledWith({
datos: [{ id: '1', numCliente: 'C001' }],
total: 1,
pagina: 1,
limite: 50,
})
})
it('pasa filtros de query al servicio', async () => {
servicioMock.listar.mockResolvedValue({ datos: [], total: 0, pagina: 1, limite: 50 })
const { res } = resFake()
await listarEndpoint(
reqFake({ query: { busqueda: 'Juan', desarrollo: 'SENDA', estatus: 'VENDIDO', pagina: '2', limite: '25' } }),
res,
)
expect(servicioMock.listar).toHaveBeenCalledWith({
busqueda: 'Juan',
desarrollo: 'SENDA',
estatus: 'VENDIDO',
pagina: 2,
limite: 25,
})
})
})
// ── GET /api/clientes-maestro/exportar ───────────────────────────────
describe('exportarEndpoint', () => {
it('200 con array de datos', async () => {
servicioMock.exportar.mockResolvedValue([{ id: '1', numCliente: 'C001' }])
const { res, json } = resFake()
await exportarEndpoint(reqFake(), res)
expect(json).toHaveBeenCalledWith([{ id: '1', numCliente: 'C001' }])
})
})
// ── GET /api/clientes-maestro/:numCliente ────────────────────────────
describe('obtenerEndpoint', () => {
it('200 con el cliente', async () => {
servicioMock.obtener.mockResolvedValue({ id: '1', numCliente: 'C001', nombre: 'Juan' })
const { res, json } = resFake()
await obtenerEndpoint(reqFake({ params: { numCliente: 'C001' } }), res)
expect(json).toHaveBeenCalledWith({ id: '1', numCliente: 'C001', nombre: 'Juan' })
})
it('404 si no existe', async () => {
servicioMock.obtener.mockResolvedValue(null)
const { res } = resFake()
await expect(
obtenerEndpoint(reqFake({ params: { numCliente: 'NOPE' } }), res),
).rejects.toThrow('Cliente no encontrado')
})
it('400 si numCliente vacío', async () => {
const { res } = resFake()
await expect(obtenerEndpoint(reqFake({ params: { numCliente: '' } }), res)).rejects.toThrow('numCliente requerido')
})
})
// ── POST /api/clientes-maestro/importar ──────────────────────────────
describe('importarEndpoint', () => {
it('200 con resultado de importación', async () => {
servicioMock.importarDesdeExcel.mockResolvedValue({ insertados: 5, actualizados: 2, errores: 1 })
const { res, json } = resFake()
await importarEndpoint(reqFake({ body: [{ numCliente: 'C001', nombre: 'Juan' }] }), res)
expect(json).toHaveBeenCalledWith({ insertados: 5, actualizados: 2, errores: 1 })
})
it('400 si body no es array', async () => {
const { res } = resFake()
await expect(importarEndpoint(reqFake({ body: {} }), res)).rejects.toThrow('Se esperaba un array')
})
it('400 si array vacío', async () => {
const { res } = resFake()
await expect(importarEndpoint(reqFake({ body: [] }), res)).rejects.toThrow('Se esperaba un array')
})
})