@@ -348,4 +348,135 @@ describe('FieldRendererTests', () => {
348348 // Note: Select fields don't show help text in the current implementation
349349 // This test documents the current behavior
350350 } ) ;
351+
352+ it ( 'should render select field with options as object format' , ( ) => {
353+ const fieldData = {
354+ type : 'select' ,
355+ label : 'Favorite Language' ,
356+ name : 'favorite-language-field' ,
357+ options : {
358+ '' : '---------' ,
359+ python : 'Python' ,
360+ javascript : 'JavaScript' ,
361+ java : 'Java' ,
362+ go : 'Go' ,
363+ } ,
364+ } ;
365+
366+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
367+ const select = container . querySelector ( 'select#favorite-language-field' ) ;
368+ const label = container . querySelector ( 'label' ) ;
369+
370+ expect ( select . type ) . toEqual ( 'select-one' ) ;
371+ expect ( label . textContent ) . toContain ( fieldData . label ) ;
372+
373+ // Verify all options are rendered
374+ const options = select . querySelectorAll ( 'option' ) ;
375+ expect ( options . length ) . toBeGreaterThan ( 0 ) ;
376+
377+ // Check if specific options exist
378+ const pythonOption = Array . from ( options ) . find ( ( opt ) => opt . value === 'python' ) ;
379+ expect ( pythonOption ) . toBeTruthy ( ) ;
380+ expect ( pythonOption . textContent ) . toEqual ( 'Python' ) ;
381+
382+ const javascriptOption = Array . from ( options ) . find ( ( opt ) => opt . value === 'javascript' ) ;
383+ expect ( javascriptOption ) . toBeTruthy ( ) ;
384+ expect ( javascriptOption . textContent ) . toEqual ( 'JavaScript' ) ;
385+ } ) ;
386+
387+ it ( 'should handle selection change with object format options' , ( ) => {
388+ const fieldData = {
389+ type : 'select' ,
390+ label : 'Favorite Language' ,
391+ name : 'favorite-language-field' ,
392+ options : {
393+ '' : '---------' ,
394+ python : 'Python' ,
395+ javascript : 'JavaScript' ,
396+ java : 'Java' ,
397+ go : 'Go' ,
398+ } ,
399+ } ;
400+
401+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
402+ const select = container . querySelector ( 'select#favorite-language-field' ) ;
403+
404+ fireEvent . change ( select , { target : { value : 'python' } } ) ;
405+ expect ( value ) . toEqual ( 'python' ) ;
406+
407+ fireEvent . change ( select , { target : { value : 'javascript' } } ) ;
408+ expect ( value ) . toEqual ( 'javascript' ) ;
409+ } ) ;
410+
411+ it ( 'should render all options correctly from object format' , ( ) => {
412+ const fieldData = {
413+ type : 'select' ,
414+ label : 'Programming Language' ,
415+ name : 'language-field' ,
416+ options : {
417+ '' : '---------' ,
418+ python : 'Python' ,
419+ javascript : 'JavaScript' ,
420+ java : 'Java' ,
421+ go : 'Go' ,
422+ } ,
423+ } ;
424+
425+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
426+ const select = container . querySelector ( 'select#language-field' ) ;
427+ const options = select . querySelectorAll ( 'option' ) ;
428+
429+ // Should have default option + 5 from object (including empty string)
430+ const optionValues = Array . from ( options ) . map ( ( opt ) => opt . value ) ;
431+ const optionLabels = Array . from ( options ) . map ( ( opt ) => opt . textContent ) ;
432+
433+ // Check that all expected values are present
434+ expect ( optionValues ) . toContain ( 'python' ) ;
435+ expect ( optionValues ) . toContain ( 'javascript' ) ;
436+ expect ( optionValues ) . toContain ( 'java' ) ;
437+ expect ( optionValues ) . toContain ( 'go' ) ;
438+
439+ // Check that all expected labels are present
440+ expect ( optionLabels ) . toContain ( 'Python' ) ;
441+ expect ( optionLabels ) . toContain ( 'JavaScript' ) ;
442+ expect ( optionLabels ) . toContain ( 'Java' ) ;
443+ expect ( optionLabels ) . toContain ( 'Go' ) ;
444+ } ) ;
445+
446+ it ( 'should handle select field with array format options (backwards compatibility)' , ( ) => {
447+ const fieldData = {
448+ type : 'select' ,
449+ label : 'Year' ,
450+ name : 'year-field' ,
451+ options : [
452+ [ '2020' , '2020' ] ,
453+ [ '2021' , '2021' ] ,
454+ [ '2022' , '2022' ] ,
455+ ] ,
456+ } ;
457+
458+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
459+ const select = container . querySelector ( 'select#year-field' ) ;
460+
461+ fireEvent . change ( select , { target : { value : '2021' } } ) ;
462+ expect ( value ) . toEqual ( '2021' ) ;
463+
464+ // Verify options are rendered correctly
465+ const options = select . querySelectorAll ( 'option' ) ;
466+ const yearOption = Array . from ( options ) . find ( ( opt ) => opt . value === '2021' ) ;
467+ expect ( yearOption ) . toBeTruthy ( ) ;
468+ expect ( yearOption . textContent ) . toEqual ( '2021' ) ;
469+ } ) ;
470+
471+ it ( 'should return null if options is not an array or object' , ( ) => {
472+ const fieldData = {
473+ type : 'select' ,
474+ label : 'Invalid Options' ,
475+ name : 'invalid-field' ,
476+ options : 'invalid-string' ,
477+ } ;
478+
479+ const { container } = render ( < FieldRenderer fieldData = { fieldData } onChangeHandler = { ( ) => { } } /> ) ;
480+ expect ( container . innerHTML ) . toEqual ( '' ) ;
481+ } ) ;
351482} ) ;
0 commit comments