// @vitest-environment happy-dom // // Client-side validateValues must paint invalid fields (border + message) so a // toast "Revisa los campos marcados" is never orphaned when the field exists // in the schema. ensureFields merges host-injected keys (e.g. branch_id) into // the loaded modal before seed/render. import { afterEach, describe, expect, it, vi } from 'vitest' import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import { I18nextProvider } from 'react-i18next' import i18next from 'i18next' import { DynamicRecordDialog } from '../dialogs/dynamic-record' import { ApiProvider } from '../api-context' afterEach(cleanup) vi.mock('sonner', () => ({ toast: { error: vi.fn(), success: vi.fn(), }, })) function makeI18n() { const inst = i18next.createInstance() void inst.init({ lng: 'es', fallbackLng: 'es', react: { useSuspense: false }, resources: { es: { translation: {} } }, }) return inst } const api = { get: vi.fn(async (url: string) => { if (String(url).includes('/metadata/modal/')) { return { data: { data: { title: 'Nuevo pedido', fields: [{ key: 'name', label: 'Nombre', type: 'text', required: true }], }, }, } } return { data: { data: {} } } }), post: vi.fn(async () => ({ data: { success: true } })), put: async () => ({ data: { success: true } }), delete: async () => ({ data: { success: true } }), } as never describe('DynamicRecordDialog field validation UX', () => { it('marks required empty fields invalid on submit', async () => { render( {}} mode="create" model="SalesOrder" schema={{ title: 'Nuevo pedido', fields: [{ key: 'name', label: 'Nombre', type: 'text', required: true }], } as never} /> , ) await waitFor(() => expect(screen.getByText('Nombre')).toBeTruthy()) fireEvent.click(screen.getByRole('button', { name: 'Crear' })) await waitFor(() => { const input = document.querySelector('input[aria-invalid="true"]') expect(input).toBeTruthy() expect(input!.className).toMatch(/border-destructive/) expect(screen.getByText(/obligatorio|required/i)).toBeTruthy() }) }) it('merges ensureFields into fetched modal schema', async () => { render( {}} mode="create" model="SalesOrder" ensureFields={[ { key: 'branch_id', label: 'Sucursal', type: 'dynamic_select', ref: 'Branch', required: true, }, ]} /> , ) await waitFor(() => expect(screen.getByText('Sucursal')).toBeTruthy()) expect(screen.getByText('Nombre')).toBeTruthy() }) })