// @vitest-environment jsdom import { describe, expect, it, vi, beforeEach } from 'vitest' import type { LeadMiDia, OportunidadMiDia, ApartadoMiDia } from '../lib/mi-dia' // Mock xlsx before importing the module under test vi.mock('xlsx', () => { const ws = { '!cols': [], } const wb = { SheetNames: [] as string[], Sheets: {} as Record, } return { utils: { book_new: () => ({ ...wb, SheetNames: [], Sheets: {} }), json_to_sheet: (_data: unknown[]) => ({ ...ws }), book_append_sheet: (workbook: typeof wb, worksheet: typeof ws, name: string) => { workbook.SheetNames.push(name) workbook.Sheets[name] = worksheet }, }, write: (_workbook: unknown, _opts: unknown) => new ArrayBuffer(8), } }) import { exportarLeads, exportarOportunidades, exportarApartados } from './exportar' const leadFake: LeadMiDia = { id: '1', nombre: 'Juan Pérez', telefono: '6641234567', email: 'juan@test.com', estado: 'CONTACTADO', origen: 'PASE', vendedor: 'Martin Zavala', updatedAt: '2026-09-01T10:00:00Z', creadoEn: '2026-09-01T09:00:00Z', fuente: 'lead', ultimoCambio: { fechaISO: '2026-09-01T10:00:00Z', usuario: 'Admin', detalle: 'Lead creado' }, } const opFake: OportunidadMiDia = { id: '2', nombre: 'María López', telefono: '6649876543', email: 'maria@test.com', etapa: 'Agendo Cita', desarrollo: 'DIAGONAL', modeloInteres: 'Modelo A', afluenciaCompleta: false, vendedor: 'Martin Zavala', unidadCodigo: 'D-101', origen: '', updatedAt: '2026-09-02T12:00:00Z', creadoEn: '2026-09-01T09:00:00Z', ultimoCambio: { fechaISO: '2026-09-02T12:00:00Z', usuario: 'Admin', detalle: 'Etapa cambiada' }, } const apartadoFake: ApartadoMiDia = { id: '3', nombre: 'Carlos Ruiz', telefono: '6641234567', email: 'carlos@example.com', origen: 'REFERIDO', vendedor: 'Martin Zavala', desarrollo: 'ESTANZA', unidadCodigo: 'E-202', estado: 'En proceso', fechaLimite: '2026-09-15', creadoEn: '2026-09-01T09:00:00Z', ultimoCambio: null, } let clickSpy: ReturnType beforeEach(() => { clickSpy = vi.fn() // Mock document.createElement('a').click const originalCreateElement = document.createElement.bind(document) vi.spyOn(document, 'createElement').mockImplementation((tag: string) => { const el = originalCreateElement(tag) if (tag === 'a') { el.click = clickSpy } return el }) // Stub URL.createObjectURL / revokeObjectURL (jsdom may not have them) if (typeof URL.createObjectURL !== 'function') { Object.defineProperty(URL, 'createObjectURL', { value: () => 'blob:mock', configurable: true }) } else { vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock') } if (typeof URL.revokeObjectURL !== 'function') { Object.defineProperty(URL, 'revokeObjectURL', { value: () => {}, configurable: true }) } else { vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => {}) } }) describe('exportarLeads', () => { it('genera buffer xlsx válido y dispara descarga', () => { const leads = [leadFake] exportarLeads(leads, 'test_leads.xlsx') expect(clickSpy).toHaveBeenCalledOnce() expect(document.createElement).toHaveBeenCalledWith('a') }) it('usa nombre de archivo por defecto cuando no se proporciona', () => { exportarLeads([leadFake]) expect(clickSpy).toHaveBeenCalledOnce() }) }) describe('exportarOportunidades', () => { it('genera buffer xlsx válido y dispara descarga', () => { exportarOportunidades([opFake], 'test_ops.xlsx') expect(clickSpy).toHaveBeenCalledOnce() }) }) describe('exportarApartados', () => { it('genera buffer xlsx válido y dispara descarga', () => { exportarApartados([apartadoFake], 'test_aparts.xlsx') expect(clickSpy).toHaveBeenCalledOnce() }) })