@arquimedes.co/eureka-forms 3.0.51-test → 3.0.52-test

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,94 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
3
+ import { render, screen, waitFor } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { describe, expect, it, vi } from 'vitest';
6
+ import '@testing-library/jest-dom';
7
+ import { Provider } from 'react-redux';
8
+ import { useForm, FormProvider } from 'react-hook-form';
9
+ import { configureStore } from '@reduxjs/toolkit';
10
+ import { EurekaFormsReducer, defaultRootState } from '../../Utils/store';
11
+ import { RootApi } from '../../Utils/_api';
12
+ import FormStepTypes from '../../constants/FormStepTypes';
13
+ import { StoreContext } from '../../Utils/StoreContext';
14
+ import { IdFormContext } from '../../Contexts/FormContext';
15
+ import FormContext from '../../Contexts/FormContext';
16
+ import SectionContext from '../../Contexts/SectionContext';
17
+ import MaterialProviders from '../../Utils/MaterialProviders';
18
+ import InternalFormStyle from '../../constants/InternalFormStyle';
19
+ import DatePickerStep from './DatePickerStep';
20
+ const STORY_FORM_ID = 'STORY_FORM';
21
+ const requiredDateStep = {
22
+ id: 'datepicker-step',
23
+ idSection: 'SECTION_1',
24
+ stepPath: ['datepicker-step'],
25
+ type: FormStepTypes.DATEPICKER,
26
+ label: 'Fecha de nacimiento',
27
+ description: null,
28
+ required: true,
29
+ pickTime: false,
30
+ size: 4,
31
+ editable: true,
32
+ };
33
+ const form = {
34
+ firstSection: 'SECTION_1',
35
+ sections: {
36
+ SECTION_1: { id: 'SECTION_1', name: 'Sección 1', steps: [], nextSection: null },
37
+ },
38
+ steps: { 'datepicker-step': { ...requiredDateStep } },
39
+ confirmationMessage: { blocks: [], entityMap: {} },
40
+ showLink: false,
41
+ size: { blockSize: 200, blockNum: 4, spacingSize: 10 },
42
+ };
43
+ function makeStore() {
44
+ return configureStore({
45
+ reducer: { forms: EurekaFormsReducer, [RootApi.reducerPath]: RootApi.reducer },
46
+ preloadedState: { forms: { [STORY_FORM_ID]: defaultRootState } },
47
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(RootApi.middleware),
48
+ });
49
+ }
50
+ function Harness({ onValid, pickTime, required = true, onReady, }) {
51
+ const methods = useForm({ mode: 'onTouched' });
52
+ const step = { ...requiredDateStep, required, pickTime: !!pickTime };
53
+ useEffect(() => {
54
+ onReady?.(methods);
55
+ }, [methods, onReady]);
56
+ return (_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(Provider, { store: makeStore(), context: StoreContext, children: _jsx(IdFormContext.Provider, { value: STORY_FORM_ID, children: _jsx(FormContext.Provider, { value: form, children: _jsx(SectionContext.Provider, { value: "SECTION_1", children: _jsx(FormProvider, { ...methods, children: _jsxs("form", { onSubmit: (e) => void methods.handleSubmit(onValid)(e), children: [_jsx(DatePickerStep, { step: step, editable: true }), _jsx("button", { type: "submit", children: "Enviar" })] }) }) }) }) }) }) }));
57
+ }
58
+ describe('DatePickerStep required validation', () => {
59
+ it('does not leak a defaultValue Date into the form value on mount', () => {
60
+ let methods;
61
+ render(_jsx(Harness, { onValid: vi.fn(), onReady: (m) => (methods = m) }));
62
+ expect(methods?.getValues('datepicker-step') ?? null).toBeNull();
63
+ });
64
+ it('blocks submit and shows the obligatorio error when a required date is left empty (handleSubmit)', async () => {
65
+ const onValid = vi.fn();
66
+ render(_jsx(Harness, { onValid: onValid }));
67
+ await userEvent.click(screen.getByRole('button', { name: 'Enviar' }));
68
+ await waitFor(() => {
69
+ expect(screen.getByText('Este campo es obligatorio')).toBeInTheDocument();
70
+ });
71
+ expect(onValid).not.toHaveBeenCalled();
72
+ });
73
+ it('reports invalid via trigger() like the real ColumnForm submit path', async () => {
74
+ let methods;
75
+ render(_jsx(Harness, { onValid: vi.fn(), onReady: (m) => (methods = m) }));
76
+ const valid = await methods.trigger(undefined, { shouldFocus: true });
77
+ expect(valid).toBe(false);
78
+ });
79
+ it('pickTime required: trigger() reports invalid when empty', async () => {
80
+ let methods;
81
+ render(_jsx(Harness, { onValid: vi.fn(), pickTime: true, onReady: (m) => (methods = m) }));
82
+ const valid = await methods.trigger(undefined, { shouldFocus: true });
83
+ expect(valid).toBe(false);
84
+ });
85
+ it('control: a NON-required empty date submits (proves the required flag is the deciding factor)', async () => {
86
+ const onValid = vi.fn();
87
+ render(_jsx(Harness, { onValid: onValid, required: false }));
88
+ await userEvent.click(screen.getByRole('button', { name: 'Enviar' }));
89
+ await waitFor(() => {
90
+ expect(onValid).toHaveBeenCalledTimes(1);
91
+ });
92
+ expect(screen.queryByText('Este campo es obligatorio')).not.toBeInTheDocument();
93
+ });
94
+ });
@@ -170,13 +170,8 @@ function CustomPickerField({ error, required, helperText, size = 'small', labelM
170
170
  function CustomDatePicker({ error, required, disabled, readOnly, helperText, size = 'small', labelMargin = 5, pickTime = false, inputRef, label,
171
171
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
172
172
  orientation: _orientation, ...others }) {
173
- // MUI X v9 no longer forwards `required` to the field-slot label when the field is a Material
174
- // TextField (the legacy `slots.field` shape used here), so the required asterisk never renders.
175
- // The picker's `label` does propagate to the field via the picker context, so bake the marker
176
- // into the label to keep the required indicator visible.
177
- const displayLabel = required && typeof label === 'string' ? `${label} *` : label;
178
173
  if (pickTime) {
179
- return (_jsx(StyledDateTimePicker, { ampm: true, size: size, reduceAnimations: true, ...others, label: displayLabel, disabled: disabled, readOnly: readOnly, defaultValue: required ? new Date() : undefined, showDaysOutsideCurrentMonth: true, slotProps: {
174
+ return (_jsx(StyledDateTimePicker, { ampm: true, size: size, reduceAnimations: true, ...others, label: label, disabled: disabled, readOnly: readOnly, showDaysOutsideCurrentMonth: true, slotProps: {
180
175
  actionBar: {
181
176
  actions: ['clear', 'accept'],
182
177
  },
@@ -236,7 +231,7 @@ orientation: _orientation, ...others }) {
236
231
  } }));
237
232
  }
238
233
  else {
239
- return (_jsx(StyledDatePicker, { ...others, label: displayLabel, size: size, reduceAnimations: true, readOnly: readOnly, disabled: disabled, defaultValue: required ? new Date() : undefined, showDaysOutsideCurrentMonth: true, views: ['year', 'month', 'day'], slotProps: {
234
+ return (_jsx(StyledDatePicker, { ...others, label: label, size: size, reduceAnimations: true, readOnly: readOnly, disabled: disabled, showDaysOutsideCurrentMonth: true, views: ['year', 'month', 'day'], slotProps: {
240
235
  actionBar: {
241
236
  actions: ['clear', 'accept'],
242
237
  },
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from '@testing-library/react';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+ import '@testing-library/jest-dom';
5
+ import MaterialProviders from '../../Utils/MaterialProviders';
6
+ import InternalFormStyle from '../../constants/InternalFormStyle';
7
+ import ErkDatePicker from './ErkDatePicker';
8
+ /**
9
+ * Guards the MUI X v9 regression fix: a `required` date picker must never inject a
10
+ * default value (today's date) into the field. Doing so silently satisfies the
11
+ * required constraint, so an untouched "required" date behaves as if it were filled.
12
+ */
13
+ describe('ErkDatePicker required behaviour', () => {
14
+ it('does not pre-fill today into a required field (no value provided)', () => {
15
+ render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkDatePicker, { required: true, label: "Fecha", onChange: vi.fn() }) }));
16
+ const input = document.querySelector('input');
17
+ expect(input?.value).toBe('');
18
+ });
19
+ it('does not pre-fill today into a required date-time field', () => {
20
+ render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkDatePicker, { required: true, pickTime: true, label: "Fecha y hora", onChange: vi.fn() }) }));
21
+ const input = document.querySelector('input');
22
+ expect(input?.value).toBe('');
23
+ });
24
+ it('renders exactly one required asterisk (no duplicate from a manual marker)', () => {
25
+ render(_jsx(MaterialProviders, { formStyle: InternalFormStyle, children: _jsx(ErkDatePicker, { required: true, label: "Fecha", value: null, onChange: vi.fn() }) }));
26
+ const label = document.querySelector('label')?.textContent ?? '';
27
+ const asterisks = (label.match(/\*/g) ?? []).length;
28
+ expect(asterisks).toBe(1);
29
+ });
30
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arquimedes.co/eureka-forms",
3
3
  "repository": "git://github.com/Arquimede5/Eureka-Forms.git",
4
- "version":"3.0.51-test",
4
+ "version":"3.0.52-test",
5
5
  "scripts": {
6
6
  "watch": "tsgo --noEmit --watch --project tsconfig.app.json",
7
7
  "start": "vite",