// @vitest-environment happy-dom import { useState } from 'react' import { afterEach, describe, expect, it, vi } from 'vitest' import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (k: string, o?: { defaultValue?: string }) => o?.defaultValue ?? k, i18n: { language: 'es' }, }), })) import { DocumentLinesGrid, LineItemsEditor } from '../business/line-items-editor' import { makeLine, type LineItem } from '../business/line-items' import type { ProductResult } from '../business/product-search' afterEach(cleanup) function Harness({ initial = [], search, priceSource, mode, }: { initial?: LineItem[] search?: (q: any, signal: AbortSignal) => Promise priceSource?: 'sale' | 'cost' | 'origin' mode?: 'free' | 'from_source' }) { const [lines, setLines] = useState(initial) return ( <> {JSON.stringify(lines)} ) } const state = () => JSON.parse(screen.getByTestId('state').textContent ?? '[]') as LineItem[] const tire: ProductResult = { id: 'p1', name: 'Llanta X', sku: 'LX', price: 1200, cost: 800, tax_rate: 0.16 } describe('DocumentLinesGrid', () => { it('es el mismo componente que LineItemsEditor', () => { expect(LineItemsEditor).toBe(DocumentLinesGrid) }) it('al elegir un producto carga cantidad 1 y el stepper actualiza el importe', async () => { const search = vi.fn(async () => [tire]) render() fireEvent.change(screen.getByLabelText('Buscar producto'), { target: { value: 'llan' } }) // RecordPicker: la opción del producto es role="option" clicable (sin