@@ -28,6 +28,25 @@ jest.mock('@/components/ui/date-picker', () => ({
2828 ) ,
2929} ) ) ;
3030
31+ jest . mock ( '@/components/ui/date-time-picker' , ( ) => ( {
32+ DateTimePicker : ( { onDateTimeChange, placeholder } : any ) => (
33+ < div >
34+ < input
35+ data-testid = "date-time-picker"
36+ placeholder = { placeholder }
37+ onChange = { ( e ) => {
38+ if ( e . target . value ) {
39+ const hasTime = e . target . value . includes ( 'T' ) ;
40+ onDateTimeChange ( new Date ( e . target . value ) , hasTime ) ;
41+ } else {
42+ onDateTimeChange ( undefined , false ) ;
43+ }
44+ } }
45+ />
46+ </ div >
47+ ) ,
48+ } ) ) ;
49+
3150jest . mock ( '@/components/ui/select' , ( ) => {
3251 return {
3352 Select : ( { children, onValueChange, value } : any ) => {
@@ -374,102 +393,188 @@ describe('AddTaskDialog Component', () => {
374393 } ) ;
375394
376395 describe ( 'Date Fields' , ( ) => {
377- const dateFields = [
378- { name : 'due' , label : 'Due' , placeholder : 'Select a due date' } ,
379- { name : 'start' , label : 'Start' , placeholder : 'Select a start date' } ,
380- { name : 'end' , label : 'End' , placeholder : 'Select an end date' } ,
381- { name : 'entry' , label : 'Entry' , placeholder : 'Select an entry date' } ,
382- { name : 'wait' , label : 'Wait' , placeholder : 'Select a wait date' } ,
383- ] ;
384-
385- test . each ( dateFields . filter ( ( field ) => field . name !== 'due' ) ) (
386- 'renders $name date picker with correct placeholder' ,
387- ( { placeholder } ) => {
388- mockProps . isOpen = true ;
389- render ( < AddTaskdialog { ...mockProps } /> ) ;
390-
391- const datePicker = screen . getByPlaceholderText ( placeholder ) ;
392- expect ( datePicker ) . toBeInTheDocument ( ) ;
393- }
394- ) ;
395-
396- test ( 'renders due date picker with correct placeholder' , ( ) => {
397- mockProps . isOpen = true ;
398- render ( < AddTaskdialog { ...mockProps } /> ) ;
396+ describe ( 'DateTime Fields' , ( ) => {
397+ const dateTimeFields = [
398+ { name : 'due' , label : 'Due' , placeholder : 'Select due date and time' } ,
399+ {
400+ name : 'start' ,
401+ label : 'Start' ,
402+ placeholder : 'Select start date and time' ,
403+ } ,
404+ ] ;
399405
400- const dueDateButton = screen . getByText ( 'Select due date and time' ) ;
401- expect ( dueDateButton ) . toBeInTheDocument ( ) ;
402- } ) ;
406+ test . each ( dateTimeFields ) (
407+ 'renders $name date-time picker with correct placeholder' ,
408+ ( { placeholder } ) => {
409+ mockProps . isOpen = true ;
410+ render ( < AddTaskdialog { ...mockProps } /> ) ;
403411
404- test . each ( dateFields . filter ( ( field ) => field . name !== 'due' ) ) (
405- 'updates $name when user selects a date' ,
406- ( { name, placeholder } ) => {
407- mockProps . isOpen = true ;
408- render ( < AddTaskdialog { ...mockProps } /> ) ;
412+ const picker = screen . getByPlaceholderText ( placeholder ) ;
413+ expect ( picker ) . toBeInTheDocument ( ) ;
414+ }
415+ ) ;
409416
410- const datePicker = screen . getByPlaceholderText ( placeholder ) ;
411- fireEvent . change ( datePicker , { target : { value : '2025-12-25' } } ) ;
417+ test . each ( dateTimeFields ) (
418+ 'updates $name with date only when no time is selected' ,
419+ ( { name, placeholder } ) => {
420+ mockProps . isOpen = true ;
421+ render ( < AddTaskdialog { ...mockProps } /> ) ;
412422
413- expect ( mockProps . setNewTask ) . toHaveBeenCalledWith ( {
414- ...mockProps . newTask ,
415- [ name ] : '2025-12-25' ,
416- } ) ;
417- }
418- ) ;
423+ const picker = screen . getByPlaceholderText ( placeholder ) ;
424+ fireEvent . change ( picker , { target : { value : '2025-12-25' } } ) ;
419425
420- // Special test for due date with DateTimePicker
421- test ( 'updates due when user selects a date and time' , ( ) => {
422- mockProps . isOpen = true ;
423- render ( < AddTaskdialog { ...mockProps } /> ) ;
426+ expect ( mockProps . setNewTask ) . toHaveBeenLastCalledWith ( {
427+ ...mockProps . newTask ,
428+ [ name ] : '2025-12-25' ,
429+ } ) ;
430+ }
431+ ) ;
432+
433+ test . each ( dateTimeFields ) (
434+ 'updates $name with full datetime when time is selected' ,
435+ ( { name, placeholder } ) => {
436+ mockProps . isOpen = true ;
437+ render ( < AddTaskdialog { ...mockProps } /> ) ;
438+ const picker = screen . getByPlaceholderText ( placeholder ) ;
439+
440+ fireEvent . change ( picker , {
441+ target : { value : '2025-12-25T14:30:00' } ,
442+ } ) ;
443+ expect ( mockProps . setNewTask ) . toHaveBeenLastCalledWith (
444+ expect . objectContaining ( {
445+ [ name ] : expect . any ( String ) ,
446+ } )
447+ ) ;
448+
449+ const callArgs = mockProps . setNewTask . mock . calls . at ( - 1 ) ! [ 0 ] ;
450+ expect ( callArgs [ name ] ) . toContain ( 'T' ) ;
451+ }
452+ ) ;
453+
454+ test . each ( dateTimeFields ) (
455+ 'allows empty $name date (optional field)' ,
456+ ( { name, placeholder } ) => {
457+ mockProps . isOpen = true ;
458+ render ( < AddTaskdialog { ...mockProps } /> ) ;
459+
460+ const picker = screen . getByPlaceholderText ( placeholder ) ;
461+
462+ fireEvent . change ( picker , {
463+ target : { value : '2025-12-25T14:30:00' } ,
464+ } ) ;
465+ mockProps . setNewTask . mockClear ( ) ;
466+ fireEvent . change ( picker , { target : { value : '' } } ) ;
424467
425- const dueDateButton = screen . getByText ( 'Select due date and time' ) ;
426- expect ( dueDateButton ) . toBeInTheDocument ( ) ;
468+ expect ( mockProps . setNewTask ) . toHaveBeenLastCalledWith ( {
469+ ...mockProps . newTask ,
470+ [ name ] : '' ,
471+ } ) ;
472+ }
473+ ) ;
474+
475+ test . each ( dateTimeFields ) (
476+ 'submits task with $name date when provided' ,
477+ ( { name } ) => {
478+ mockProps . isOpen = true ;
479+ mockProps . newTask = {
480+ ...mockProps . newTask ,
481+ [ name ] : '2025-12-25T14:30:00.000Z' ,
482+ } ;
483+ render ( < AddTaskdialog { ...mockProps } /> ) ;
484+
485+ const picker = screen . getByPlaceholderText (
486+ `Select ${ name } date and time`
487+ ) ;
488+ fireEvent . change ( picker , {
489+ target : { value : '2025-12-25T14:30:00' } ,
490+ } ) ;
491+
492+ const submitButton = screen . getByRole ( 'button' , {
493+ name : / a d d t a s k / i,
494+ } ) ;
495+ fireEvent . click ( submitButton ) ;
496+
497+ expect ( mockProps . onSubmit ) . toHaveBeenLastCalledWith (
498+ expect . objectContaining ( {
499+ [ name ] : '2025-12-25T14:30:00.000Z' ,
500+ } )
501+ ) ;
502+ }
503+ ) ;
427504 } ) ;
428505
429- test . each ( dateFields . filter ( ( field ) => field . name !== 'due' ) ) (
430- 'allows empty $name date (optional field)' ,
431- ( { name, placeholder } ) => {
432- mockProps . isOpen = true ;
433- render ( < AddTaskdialog { ...mockProps } /> ) ;
506+ describe ( 'DatePicker fields' , ( ) => {
507+ const dateOnlyFields = [
508+ { name : 'end' , label : 'End' , placeholder : 'Select an end date' } ,
509+ { name : 'entry' , label : 'Entry' , placeholder : 'Select an entry date' } ,
510+ { name : 'wait' , label : 'Wait' , placeholder : 'Select a wait date' } ,
511+ ] ;
434512
435- const datePicker = screen . getByPlaceholderText ( placeholder ) ;
513+ test . each ( dateOnlyFields ) (
514+ 'renders $name date picker with correct placeholder' ,
515+ ( { placeholder } ) => {
516+ mockProps . isOpen = true ;
517+ render ( < AddTaskdialog { ...mockProps } /> ) ;
436518
437- fireEvent . change ( datePicker , { target : { value : '2025-12-25' } } ) ;
438- mockProps . setNewTask . mockClear ( ) ;
439- fireEvent . change ( datePicker , { target : { value : '' } } ) ;
519+ const datePicker = screen . getByPlaceholderText ( placeholder ) ;
520+ expect ( datePicker ) . toBeInTheDocument ( ) ;
521+ }
522+ ) ;
440523
441- expect ( mockProps . setNewTask ) . toHaveBeenCalledWith ( {
442- ...mockProps . newTask ,
443- [ name ] : '' ,
444- } ) ;
445- }
446- ) ;
524+ test . each ( dateOnlyFields ) (
525+ 'updates $name when user selects a date' ,
526+ ( { name, placeholder } ) => {
527+ mockProps . isOpen = true ;
528+ render ( < AddTaskdialog { ...mockProps } /> ) ;
447529
448- // Special test for due date with DateTimePicker
449- test ( 'allows empty due date (optional field)' , ( ) => {
450- mockProps . isOpen = true ;
451- render ( < AddTaskdialog { ...mockProps } /> ) ;
530+ const datePicker = screen . getByPlaceholderText ( placeholder ) ;
531+ fireEvent . change ( datePicker , { target : { value : '2025-12-25' } } ) ;
452532
453- const dueDateButton = screen . getByText ( 'Select due date and time' ) ;
454- expect ( dueDateButton ) . toBeInTheDocument ( ) ;
455- } ) ;
533+ expect ( mockProps . setNewTask ) . toHaveBeenCalledWith ( {
534+ ...mockProps . newTask ,
535+ [ name ] : '2025-12-25' ,
536+ } ) ;
537+ }
538+ ) ;
539+
540+ test . each ( dateOnlyFields ) (
541+ 'allows empty $name date (optional field)' ,
542+ ( { name, placeholder } ) => {
543+ mockProps . isOpen = true ;
544+ render ( < AddTaskdialog { ...mockProps } /> ) ;
545+
546+ const datePicker = screen . getByPlaceholderText ( placeholder ) ;
456547
457- test . each ( dateFields ) (
458- 'submits task with $name date when provided' ,
459- ( { name } ) => {
460- mockProps . isOpen = true ;
461- mockProps . newTask = {
462- ...mockProps . newTask ,
463- [ name ] : '2025-12-25' ,
464- } ;
465- render ( < AddTaskdialog { ...mockProps } /> ) ;
548+ fireEvent . change ( datePicker , { target : { value : '2025-12-25' } } ) ;
549+ mockProps . setNewTask . mockClear ( ) ;
550+ fireEvent . change ( datePicker , { target : { value : '' } } ) ;
466551
467- const submitButton = screen . getByRole ( 'button' , { name : / a d d t a s k / i } ) ;
468- fireEvent . click ( submitButton ) ;
552+ expect ( mockProps . setNewTask ) . toHaveBeenCalledWith ( {
553+ ...mockProps . newTask ,
554+ [ name ] : '' ,
555+ } ) ;
556+ }
557+ ) ;
469558
470- expect ( mockProps . onSubmit ) . toHaveBeenCalledWith ( mockProps . newTask ) ;
471- }
472- ) ;
559+ test . each ( dateOnlyFields ) (
560+ 'submits task with $name date when provided' ,
561+ ( { name } ) => {
562+ mockProps . isOpen = true ;
563+ mockProps . newTask = {
564+ ...mockProps . newTask ,
565+ [ name ] : '2025-12-25' ,
566+ } ;
567+ render ( < AddTaskdialog { ...mockProps } /> ) ;
568+
569+ const submitButton = screen . getByRole ( 'button' , {
570+ name : / a d d t a s k / i,
571+ } ) ;
572+ fireEvent . click ( submitButton ) ;
573+
574+ expect ( mockProps . onSubmit ) . toHaveBeenCalledWith ( mockProps . newTask ) ;
575+ }
576+ ) ;
577+ } ) ;
473578 } ) ;
474579
475580 describe ( 'Depends Field' , ( ) => {
0 commit comments