Files
FRASA-CAS/apps/alta-clientes/src/pages/AltaClientePage.test.tsx
Consult AS Technology 89d95eb53b feat(purga): Monday eliminado completamente del sistema
14 servicios eliminados, 7 controllers local-only, crons locales,
config sin MONDAY_*, frontend sin banners/avisos Monday.
552 tests API + 7 apps construidas.
2026-09-11 11:47:17 +00:00

121 lines
4.5 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import AltaClientePage from './AltaClientePage'
import type { LeadResumen } from '../services/api'
type FetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>
const LEAD: LeadResumen = {
id: 'lead-9',
nombre: 'María Fernanda López',
telefono: '4771234567',
email: 'maria@correo.com',
estado: 'NUEVO',
origen: 'Web',
fuente: 'lead',
}
const respuestaOk = (data: unknown) =>
new Response(JSON.stringify(data), { status: 200, headers: { 'Content-Type': 'application/json' } })
let fetchMock: ReturnType<typeof vi.fn<FetchFn>>
beforeEach(() => {
fetchMock = vi.fn<FetchFn>().mockImplementation((input) => {
const url = String(input)
if (url.includes('/borradores')) {
// Un borrador para que la pantalla inicial sea el picker
return Promise.resolve(
respuestaOk([{ id: 'b-1', nombre: 'Borrador previo', paso: 0, updatedAt: '2026-08-20T10:00:00Z' }]),
)
}
if (url.includes('/leads/buscar')) return Promise.resolve(respuestaOk([LEAD]))
return Promise.reject(new Error(`fetch inesperado: ${url}`))
})
vi.stubGlobal('fetch', fetchMock)
})
afterEach(() => {
cleanup()
vi.unstubAllGlobals()
})
describe('AltaClientePage — pantalla de entrada', () => {
it('muestra las dos opciones de alta', async () => {
render(<AltaClientePage />)
expect(await screen.findByRole('button', { name: /Alta Afluencia/ })).toBeTruthy()
expect(screen.getByRole('button', { name: /Alta de Cliente/ })).toBeTruthy()
})
it('"Alta de Cliente" navega al picker (borradores + búsqueda de lead)', async () => {
render(<AltaClientePage />)
fireEvent.click(await screen.findByRole('button', { name: /Alta de Cliente/ }))
expect(await screen.findByLabelText(/Buscar lead/)).toBeTruthy()
expect(screen.getByText('Borrador previo')).toBeTruthy()
})
it('"Alta Afluencia" muestra el formulario y "Volver" regresa a la entrada', async () => {
render(<AltaClientePage />)
fireEvent.click(await screen.findByRole('button', { name: /Alta Afluencia/ }))
expect(await screen.findByLabelText(/^Nombre/)).toBeTruthy()
fireEvent.click(screen.getByRole('button', { name: 'Volver' }))
expect(await screen.findByRole('button', { name: /Alta de Cliente/ })).toBeTruthy()
})
})
describe('AltaClientePage — alta desde lead capturado', () => {
it('al elegir un lead el wizard arranca con datosGenerales prellenados', async () => {
render(<AltaClientePage />)
// Entrada → Alta de Cliente → picker con la sección de búsqueda
fireEvent.click(await screen.findByRole('button', { name: /Alta de Cliente/ }))
const busqueda = await screen.findByLabelText(/Buscar lead/)
fireEvent.change(busqueda, { target: { value: 'maria' } })
fireEvent.click(await screen.findByText('María Fernanda López'))
// Wizard paso 1 con los campos del lead ya capturados
const nombre = (await screen.findByLabelText(/Nombre completo/)) as HTMLInputElement
expect(nombre.value).toBe('MARÍA FERNANDA LÓPEZ')
expect((screen.getByLabelText(/Correo electrónico|Email/i) as HTMLInputElement).value).toBe('maria@correo.com')
expect((screen.getByLabelText(/Celular/i) as HTMLInputElement).value).toBe('4771234567')
})
})
describe('AltaClientePage — alta desde cotización (?cotizacion=<id>)', () => {
it('se salta la entrada y va directo al wizard prellenado', async () => {
window.history.pushState({}, '', '/?cotizacion=cot-1')
fetchMock.mockImplementation((input) => {
const url = String(input)
if (url.includes('/cotizaciones/cot-1')) {
return Promise.resolve(
respuestaOk({
clienteNombre: 'Cliente Prueba',
clienteEmail: 'cliente@correo.com',
clienteTelefono: '6645550000',
desarrollo: 'SENDA',
unidadCodigo: 'U-101',
precioFinal: 1500000,
enganche: 150000,
}),
)
}
return Promise.reject(new Error(`fetch inesperado: ${url}`))
})
try {
render(<AltaClientePage />)
// Wizard directo, sin pasar por la entrada
const nombre = (await screen.findByLabelText(/Nombre completo/)) as HTMLInputElement
expect(nombre.value).toBe('CLIENTE PRUEBA')
expect(screen.queryByRole('button', { name: /Alta Afluencia/ })).toBeNull()
} finally {
window.history.pushState({}, '', '/')
}
})
})