Backend (10 endpoints nuevos): - Recordatorios personales (CRUD + tabla RecordatorioVendedor) - Lead scoring 0-100 (etapa+recencia+datos) - Dashboard mora (pagos vencidos, monto, días atraso) - Timeline de pagos (pagado/vence/futuro) - Perfil completo contacto (pagos+cotizaciones+docs+score) - Exportar contactos a CSV Frontend Mi día: - Resumen matutino (saludo+KPIs) - Historial visual lead (timeline) - Score badge 0-100 (verde/amarillo/rojo) - Vista kanban (drag & drop) Frontend Cobranza: - Dashboard mora (tabla+WhatsApp) - Timeline pagos visual (nodos coloreados) Frontend Alta Clientes: - Checklist documentos visual - Foto cliente (cámara) Frontend Landing: - Perfil contacto completo - Exportar contactos CSV Frontend Mi día (extras): - Comparativa mensual - KPIs dashboard (leads hoy, ventas, conversión) 806 tests, 5 apps construidas.
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const prismaMock = vi.hoisted(() => ({
|
|
cliente: { findMany: vi.fn() },
|
|
leadCaptura: { findMany: vi.fn() },
|
|
}))
|
|
|
|
vi.mock('../services/prisma.js', () => ({ prisma: prismaMock }))
|
|
|
|
import { exportarCSV } from './contactos-local.service.js'
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
prismaMock.cliente.findMany.mockResolvedValue([])
|
|
prismaMock.leadCaptura.findMany.mockResolvedValue([])
|
|
})
|
|
|
|
describe('exportarCSV', () => {
|
|
it('genera CSV con encabezados cuando no hay contactos', async () => {
|
|
const csv = await exportarCSV()
|
|
expect(csv).toContain('Nombre,Teléfono,Email,Desarrollo,Estatus,Última actividad')
|
|
})
|
|
|
|
it('incluye clientes y capturas en el CSV', async () => {
|
|
prismaMock.cliente.findMany.mockResolvedValue([
|
|
{
|
|
nombreCompleto: 'Juan Pérez',
|
|
celular: '4771234567',
|
|
email: 'juan@correo.mx',
|
|
proyecto: 'SENDA',
|
|
createdAt: new Date('2026-09-01'),
|
|
},
|
|
])
|
|
prismaMock.leadCaptura.findMany.mockResolvedValue([
|
|
{
|
|
nombreLead: 'Ana López',
|
|
telefono: '6649998877',
|
|
email: 'ana@test.com',
|
|
desarrollo: 'DIAGONAL',
|
|
etapa: 'NUEVO',
|
|
updatedAt: new Date('2026-09-05'),
|
|
},
|
|
])
|
|
|
|
const csv = await exportarCSV()
|
|
const lineas = csv.split('\n')
|
|
expect(lineas).toHaveLength(3) // header + 2 rows
|
|
expect(lineas[1]).toContain('Juan Pérez')
|
|
expect(lineas[1]).toContain('Cliente')
|
|
expect(lineas[2]).toContain('Ana López')
|
|
expect(lineas[2]).toContain('NUEVO')
|
|
})
|
|
|
|
it('filtra por desarrollo', async () => {
|
|
prismaMock.cliente.findMany.mockResolvedValue([
|
|
{ nombreCompleto: 'A', celular: null, email: null, proyecto: 'SENDA', createdAt: new Date() },
|
|
{ nombreCompleto: 'B', celular: null, email: null, proyecto: 'DIAGONAL', createdAt: new Date() },
|
|
])
|
|
prismaMock.leadCaptura.findMany.mockResolvedValue([])
|
|
|
|
const csv = await exportarCSV({ desarrollo: 'SENDA' })
|
|
expect(csv).toContain('A')
|
|
expect(csv).not.toContain('B')
|
|
})
|
|
|
|
it('escapa comas y comillas en los campos', async () => {
|
|
prismaMock.cliente.findMany.mockResolvedValue([
|
|
{
|
|
nombreCompleto: 'Pérez, Juan',
|
|
celular: null,
|
|
email: null,
|
|
proyecto: 'SENDA',
|
|
createdAt: new Date(),
|
|
},
|
|
])
|
|
prismaMock.leadCaptura.findMany.mockResolvedValue([])
|
|
|
|
const csv = await exportarCSV()
|
|
expect(csv).toContain('"Pérez, Juan"')
|
|
})
|
|
})
|