@@ -200,4 +200,152 @@ describe('FieldRendererTests', () => {
200200
201201 expect ( container . querySelector ( `#${ fieldData . name } -error` ) . textContent ) . toEqual ( 'You must agree to our Honor Code' ) ;
202202 } ) ;
203+
204+ it ( 'should render placeholder for text field' , ( ) => {
205+ const fieldData = {
206+ type : 'text' ,
207+ label : 'Company' ,
208+ name : 'company-field' ,
209+ placeholder : 'Enter your company name' ,
210+ } ;
211+
212+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
213+ const input = container . querySelector ( 'input#company-field' ) ;
214+
215+ expect ( input . placeholder ) . toEqual ( 'Enter your company name' ) ;
216+ } ) ;
217+
218+ it ( 'should render placeholder for textarea field' , ( ) => {
219+ const fieldData = {
220+ type : 'textarea' ,
221+ label : 'Goals' ,
222+ name : 'goals-field' ,
223+ placeholder : 'Share your learning goals' ,
224+ } ;
225+
226+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
227+ const input = container . querySelector ( '#goals-field' ) ;
228+
229+ expect ( input . placeholder ) . toEqual ( 'Share your learning goals' ) ;
230+ } ) ;
231+
232+ it ( 'should apply maxLength restriction to text field' , ( ) => {
233+ const fieldData = {
234+ type : 'text' ,
235+ label : 'Company' ,
236+ name : 'company-field' ,
237+ restrictions : {
238+ max_length : 50 ,
239+ } ,
240+ } ;
241+
242+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
243+ const input = container . querySelector ( 'input#company-field' ) ;
244+
245+ expect ( input . maxLength ) . toEqual ( 50 ) ;
246+ } ) ;
247+
248+ it ( 'should apply maxLength restriction to textarea field' , ( ) => {
249+ const fieldData = {
250+ type : 'textarea' ,
251+ label : 'Goals' ,
252+ name : 'goals-field' ,
253+ restrictions : {
254+ max_length : 200 ,
255+ } ,
256+ } ;
257+
258+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
259+ const input = container . querySelector ( '#goals-field' ) ;
260+
261+ expect ( input . maxLength ) . toEqual ( 200 ) ;
262+ } ) ;
263+
264+ it ( 'should show help text when field has focus and instructions are provided' , ( ) => {
265+ const fieldData = {
266+ type : 'text' ,
267+ label : 'Username' ,
268+ name : 'username-field' ,
269+ instructions : 'Username must be between 2-30 characters' ,
270+ } ;
271+
272+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
273+ const input = container . querySelector ( 'input#username-field' ) ;
274+
275+ // Help text should not be visible initially
276+ expect ( container . textContent ) . not . toContain ( 'Username must be between 2-30 characters' ) ;
277+
278+ // Focus the field
279+ fireEvent . focus ( input ) ;
280+
281+ // Help text should now be visible
282+ expect ( container . textContent ) . toContain ( 'Username must be between 2-30 characters' ) ;
283+
284+ // Blur the field
285+ fireEvent . blur ( input ) ;
286+
287+ // Help text should be hidden again
288+ expect ( container . textContent ) . not . toContain ( 'Username must be between 2-30 characters' ) ;
289+ } ) ;
290+
291+ it ( 'should show help text for textarea when focused' , ( ) => {
292+ const fieldData = {
293+ type : 'textarea' ,
294+ label : 'Goals' ,
295+ name : 'goals-field' ,
296+ instructions : 'Please describe your learning goals in detail' ,
297+ } ;
298+
299+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
300+ const input = container . querySelector ( '#goals-field' ) ;
301+
302+ // Help text should not be visible initially
303+ expect ( container . textContent ) . not . toContain ( 'Please describe your learning goals in detail' ) ;
304+
305+ // Focus the field
306+ fireEvent . focus ( input ) ;
307+
308+ // Help text should now be visible
309+ expect ( container . textContent ) . toContain ( 'Please describe your learning goals in detail' ) ;
310+ } ) ;
311+
312+ it ( 'should not show help text if instructions are not provided' , ( ) => {
313+ const fieldData = {
314+ type : 'text' ,
315+ label : 'Company' ,
316+ name : 'company-field' ,
317+ } ;
318+
319+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
320+ const input = container . querySelector ( 'input#company-field' ) ;
321+
322+ // Focus the field
323+ fireEvent . focus ( input ) ;
324+
325+ // No help text should be rendered since instructions are not provided
326+ const feedbackElement = container . querySelector ( '.form-control-feedback' ) ;
327+ expect ( feedbackElement ) . toBeNull ( ) ;
328+ } ) ;
329+
330+ it ( 'should show help text for select field when focused' , ( ) => {
331+ const fieldData = {
332+ type : 'select' ,
333+ label : 'Country' ,
334+ name : 'country-field' ,
335+ options : [ [ 'us' , 'United States' ] , [ 'ca' , 'Canada' ] ] ,
336+ instructions : 'Select your country of residence' ,
337+ } ;
338+
339+ const { container } = render ( < FieldRenderer value = { value } fieldData = { fieldData } onChangeHandler = { changeHandler } /> ) ;
340+ const select = container . querySelector ( 'select#country-field' ) ;
341+
342+ // Help text should not be visible initially
343+ expect ( container . textContent ) . not . toContain ( 'Select your country of residence' ) ;
344+
345+ // Focus the field
346+ fireEvent . focus ( select ) ;
347+
348+ // Note: Select fields don't show help text in the current implementation
349+ // This test documents the current behavior
350+ } ) ;
203351} ) ;
0 commit comments