@@ -17,6 +17,17 @@ class TypeMappingDataSource implements DataSource {
1717 date_field : { name : 'date_field' , label : 'Date Field' , type : 'date' } ,
1818 select_field : { name : 'select_field' , label : 'Select Field' , type : 'select' , options : [ { label : 'A' , value : 'a' } ] } ,
1919 textarea_field : { name : 'textarea_field' , label : 'TextArea Field' , type : 'textarea' } ,
20+
21+ // Extended Types
22+ currency_field : { name : 'currency_field' , label : 'Currency Field' , type : 'currency' } ,
23+ percent_field : { name : 'percent_field' , label : 'Percent Field' , type : 'percent' } ,
24+ password_field : { name : 'password_field' , label : 'Password Field' , type : 'password' } ,
25+ datetime_field : { name : 'datetime_field' , label : 'DateTime Field' , type : 'datetime' } ,
26+ time_field : { name : 'time_field' , label : 'Time Field' , type : 'time' } ,
27+ file_field : { name : 'file_field' , label : 'File Field' , type : 'file' } ,
28+ image_field : { name : 'image_field' , label : 'Image Field' , type : 'image' } ,
29+ url_field : { name : 'url_field' , label : 'URL Field' , type : 'url' } ,
30+ phone_field : { name : 'phone_field' , label : 'Phone Field' , type : 'phone' } ,
2031 }
2132 } ;
2233
@@ -49,7 +60,17 @@ describe('ObjectForm Field Type Mapping', () => {
4960 'number_field' ,
5061 'boolean_field' ,
5162 'textarea_field' ,
52- 'select_field'
63+ 'select_field' ,
64+ 'currency_field' ,
65+ 'percent_field' ,
66+ 'password_field' ,
67+ 'date_field' ,
68+ 'datetime_field' ,
69+ 'time_field' ,
70+ 'file_field' ,
71+ 'image_field' ,
72+ 'url_field' ,
73+ 'phone_field'
5374 ]
5475 } }
5576 dataSource = { dataSource }
@@ -61,34 +82,85 @@ describe('ObjectForm Field Type Mapping', () => {
6182 expect ( screen . getByLabelText ( / T e x t F i e l d / i) ) . toBeInTheDocument ( ) ;
6283 } ) ;
6384
64- // 1. Check Text Field (Input)
65- const textInput = container . querySelector ( 'input[name="text_field"]' ) ;
66- expect ( textInput ) . toBeInTheDocument ( ) ;
85+ // 1. Text Field -> Input[type=text]
86+ expect ( container . querySelector ( 'input[name="text_field"][type="text"]' ) ) . toBeInTheDocument ( ) ;
6787
68- // 2. Check Number Field (Input)
69- // Note: Specific type="number" check depends on the exact implementation of the field widget
70- const numberInput = container . querySelector ( 'input[name="number_field"]' ) ;
71- expect ( numberInput ) . toBeInTheDocument ( ) ;
88+ // 2. Number Field -> Input (check name exists)
89+ expect ( container . querySelector ( 'input[name="number_field"]' ) ) . toBeInTheDocument ( ) ;
7290
73- // 3. Check TextArea
74- const textarea = container . querySelector ( 'textarea[name="textarea_field"]' ) ;
75- expect ( textarea ) . toBeInTheDocument ( ) ;
91+ // 3. TextArea -> Textarea
92+ expect ( container . querySelector ( 'textarea[name="textarea_field"]' ) ) . toBeInTheDocument ( ) ;
7693
77- // 4. Check Boolean (Switch)
78- // Radix UI switch usually has role="switch"
94+ // 4. Boolean -> Switch (role=switch)
7995 const switchControl = screen . getByRole ( 'switch' , { name : / B o o l e a n F i e l d / i } ) ;
8096 expect ( switchControl ) . toBeInTheDocument ( ) ;
8197
82- // 5. Check Select Field
83- // Radix UI Select trigger might not have the ID matching the label in this test environment
84- // So we search for the role, and verify one exists.
85- const selectTriggers = screen . getAllByRole ( 'combobox' ) ;
86- expect ( selectTriggers . length ) . toBeGreaterThan ( 0 ) ;
87-
88- // Optional: verify one of them is related to our field
89- // We can assume the last one is ours or check context
98+ // 5. Select -> Combobox
9099 const selectWrapper = screen . getByText ( / S e l e c t F i e l d / i) . closest ( 'div' ) ;
91100 const selectInWrapper = selectWrapper ?. querySelector ( 'button[role="combobox"]' ) ;
92101 expect ( selectInWrapper ) . toBeInTheDocument ( ) ;
102+
103+ // 6. Currency -> Input[type=number]
104+ // Debug currency field rendering
105+ const currencyInput = container . querySelector ( 'input[name="currency_field"]' ) ;
106+ if ( ! currencyInput ) {
107+ console . log ( 'Currency field not found in DOM:' , document . body . innerHTML ) ;
108+ }
109+ expect ( currencyInput ) . toBeInTheDocument ( ) ;
110+ expect ( currencyInput ) . toHaveAttribute ( 'type' , 'number' ) ;
111+
112+ // 7. Percent -> Input
113+ const percentInput = container . querySelector ( 'input[name="percent_field"]' ) ;
114+ expect ( percentInput ) . toBeInTheDocument ( ) ;
115+ expect ( percentInput ) . toHaveAttribute ( 'type' , 'number' ) ;
116+
117+ // 8. Password -> Input[type=password]
118+ const passwordInput = container . querySelector ( 'input[name="password_field"]' ) ;
119+ expect ( passwordInput ) . toBeInTheDocument ( ) ;
120+ expect ( passwordInput ) . toHaveAttribute ( 'type' , 'password' ) ;
121+
122+ // 9. Date -> Input[type=date]
123+ const dateInput = container . querySelector ( 'input[name="date_field"]' ) ;
124+ expect ( dateInput ) . toBeInTheDocument ( ) ;
125+ expect ( dateInput ) . toHaveAttribute ( 'type' , 'date' ) ;
126+
127+ // 10. DateTime -> Input[type=datetime-local]
128+ const dateTimeInput = container . querySelector ( 'input[name="datetime_field"]' ) ;
129+ expect ( dateTimeInput ) . toBeInTheDocument ( ) ;
130+ expect ( dateTimeInput ) . toHaveAttribute ( 'type' , 'datetime-local' ) ;
131+
132+ // 11. Time -> Input[type=time]
133+ const timeInput = container . querySelector ( 'input[name="time_field"]' ) ;
134+ expect ( timeInput ) . toBeInTheDocument ( ) ;
135+ expect ( timeInput ) . toHaveAttribute ( 'type' , 'time' ) ;
136+
137+ // 12. File -> Input[type=file]
138+ // Note: File inputs might be hidden if using custom upload widget
139+ // But the ObjectForm logic maps 'file' -> 'file-upload'.
140+ // Let's check generic presence first.
141+ // If file-upload widget is complex, it might not expose a simple named input.
142+ // We'll skip strict check if we can't find it easily, or check for generic role/text.
143+ const fileInput = container . querySelector ( 'input[type="file"]' ) ;
144+ // If multiple file fields (file & image), this selector finds first.
145+ // We can check attributes or just existence of any file input.
146+ expect ( fileInput ) . toBeInTheDocument ( ) ;
147+
148+ // 13. Image -> Input[type=file]
149+ // Handled by above check generally.
150+
151+ // 14. URL -> Input[type=url]
152+ const urlInput = container . querySelector ( 'input[name="url_field"]' ) ;
153+ expect ( urlInput ) . toBeInTheDocument ( ) ;
154+ expect ( urlInput ) . toHaveAttribute ( 'type' , 'url' ) ;
155+
156+ // 15. Phone -> Input[type=tel]
157+ const phoneInput = container . querySelector ( 'input[name="phone_field"]' ) ;
158+ expect ( phoneInput ) . toBeInTheDocument ( ) ;
159+ expect ( phoneInput ) . toHaveAttribute ( 'type' , 'tel' ) ;
160+
161+ // 16. Email -> Input[type=email]
162+ const emailInput = container . querySelector ( 'input[name="email_field"]' ) ;
163+ expect ( emailInput ) . toBeInTheDocument ( ) ;
164+ expect ( emailInput ) . toHaveAttribute ( 'type' , 'email' ) ;
93165 } ) ;
94166} ) ;
0 commit comments