@@ -516,6 +516,10 @@ describe('ToastManager', () => {
516
516
} ) ;
517
517
expect ( updateSuccess ) . toBe ( true ) ;
518
518
} , [ toast ] ) ;
519
+ const handleClickUpdateInvalidToast = useCallback ( ( ) => {
520
+ const updateSuccess = toast . update ( null , { } ) ;
521
+ expect ( updateSuccess ) . toBe ( false ) ;
522
+ } , [ toast ] ) ;
519
523
520
524
return (
521
525
< >
@@ -525,6 +529,9 @@ describe('ToastManager', () => {
525
529
< Button onClick = { handleClickUpdateToast } >
526
530
Update Toast
527
531
</ Button >
532
+ < Button onClick = { handleClickUpdateInvalidToast } >
533
+ Update Invalid Toast
534
+ </ Button >
528
535
</ >
529
536
) ;
530
537
} ;
@@ -540,9 +547,165 @@ describe('ToastManager', () => {
540
547
541
548
// Update the toast
542
549
await user . click ( screen . getByText ( 'Update Toast' ) ) ;
550
+ await user . click ( screen . getByText ( 'Update Invalid Toast' ) ) ;
543
551
544
552
// Check if the content has been updated
545
553
const toastElement = screen . getByTestId ( toastId ) ;
546
554
expect ( toastElement ) . toHaveTextContent ( updatedMessage ) ;
547
555
} ) ;
556
+
557
+ it ( 'should not create a toast and return false for invalid placement' , async ( ) => {
558
+ const user = userEvent . setup ( ) ;
559
+ const toastId = 'toast-id' ;
560
+ const placement = 'center' ; // "center" is not a supported placement
561
+ const message = 'This is a toast message' ;
562
+
563
+ // Spy on console.error to capture and check the error message
564
+ const consoleErrorSpy = jest . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
565
+
566
+ const WrapperComponent = ( props ) => (
567
+ < ToastManager { ...props } />
568
+ ) ;
569
+
570
+ const TestComponent = ( ) => {
571
+ const toast = useToastManager ( ) ;
572
+ const handleClick = useCallback ( ( ) => {
573
+ const result = toast ( ( { onClose } ) => (
574
+ < Toast
575
+ appearance = "error"
576
+ isClosable
577
+ onClose = { onClose }
578
+ data-testid = { toastId }
579
+ >
580
+ { message }
581
+ </ Toast >
582
+ ) , { placement } ) ;
583
+ expect ( result ) . toBe ( false ) ;
584
+ } , [ toast ] ) ;
585
+
586
+ return (
587
+ < Button onClick = { handleClick } >
588
+ Add Toast
589
+ </ Button >
590
+ ) ;
591
+ } ;
592
+
593
+ render (
594
+ < WrapperComponent >
595
+ < TestComponent />
596
+ </ WrapperComponent >
597
+ ) ;
598
+
599
+ const button = await screen . findByText ( 'Add Toast' ) ;
600
+ await user . click ( button ) ;
601
+
602
+ // Check that console.error was called with the expected error message
603
+ const placements = [
604
+ 'bottom' ,
605
+ 'bottom-right' ,
606
+ 'bottom-left' ,
607
+ 'top' ,
608
+ 'top-left' ,
609
+ 'top-right' ,
610
+ ] ;
611
+ const expectedErrorMessage = `[ToastManager] Error: Invalid toast placement "${ placement } ". Please provide a valid placement from the following options: ${ placements . join ( ', ' ) } .` ;
612
+ expect ( consoleErrorSpy ) . toHaveBeenCalledWith ( expectedErrorMessage ) ;
613
+
614
+ // Assert that no toast element with the invalid placement was created
615
+ const toastElement = screen . queryByTestId ( toastId ) ;
616
+ expect ( toastElement ) . not . toBeInTheDocument ( ) ;
617
+
618
+ // Restore console.error to its original implementation
619
+ consoleErrorSpy . mockRestore ( ) ;
620
+ } ) ;
621
+
622
+ it ( 'should create toasts in the correct order for top and bottom placements in the state' , async ( ) => {
623
+ const user = userEvent . setup ( ) ;
624
+ const topPlacement = 'top' ;
625
+ const bottomPlacement = 'bottom' ;
626
+ const message = 'This is a toast message' ;
627
+
628
+ const WrapperComponent = ( props ) => (
629
+ < ToastManager { ...props } />
630
+ ) ;
631
+
632
+ const TestComponent = ( ) => {
633
+ const toast = useToastManager ( ) ;
634
+ const handleClickAddToasts = useCallback ( ( ) => {
635
+ // Add toast for top-right placement
636
+ toast ( ( { onClose } ) => (
637
+ < Toast
638
+ appearance = "success"
639
+ isClosable
640
+ onClose = { onClose }
641
+ >
642
+ { message }
643
+ </ Toast >
644
+ ) , { placement : topPlacement } ) ;
645
+
646
+ // Add toast for bottom-right placement
647
+ toast ( ( { onClose } ) => (
648
+ < Toast
649
+ appearance = "success"
650
+ isClosable
651
+ onClose = { onClose }
652
+ >
653
+ { message }
654
+ </ Toast >
655
+ ) , { placement : bottomPlacement } ) ;
656
+ } , [ toast ] ) ;
657
+
658
+ return (
659
+ < >
660
+ < Button onClick = { handleClickAddToasts } > Add Toasts</ Button >
661
+ { /* Access toast.state here to check order */ }
662
+ { toast . state && (
663
+ < pre data-testid = "toast-state" > { JSON . stringify ( toast . state , null , 2 ) } </ pre >
664
+ ) }
665
+ </ >
666
+ ) ;
667
+ } ;
668
+
669
+ render (
670
+ < WrapperComponent >
671
+ < TestComponent />
672
+ </ WrapperComponent >
673
+ ) ;
674
+
675
+ const button = await screen . findByText ( 'Add Toasts' ) ;
676
+ await user . click ( button ) ;
677
+ await user . click ( button ) ;
678
+
679
+ // Wait for the state to be updated with toasts
680
+ await screen . findByTestId ( 'toast-state' ) ;
681
+
682
+ // Get the state of the toasts
683
+ const toastState = JSON . parse ( screen . getByTestId ( 'toast-state' ) . textContent ) ;
684
+
685
+ // Check that toasts with top-right and bottom-right placements exist in the state
686
+ const topToasts = toastState [ topPlacement ] ;
687
+ const bottomToasts = toastState [ bottomPlacement ] ;
688
+
689
+ // top-right
690
+ //
691
+ // ```js
692
+ // [
693
+ // { id: '3', placement: 'top-right' },
694
+ // { id: '1', placement: 'top-right' },
695
+ // ]
696
+ // ```
697
+ expect ( topToasts ) . toHaveLength ( 2 ) ;
698
+ expect ( topToasts [ 0 ] . id > topToasts [ 1 ] . id ) . toBeTruthy ( ) ;
699
+
700
+ // bottom-right
701
+ //
702
+ // ```js
703
+ // [
704
+ // { id: '2', placement: 'bottom-right' },
705
+ // { id: '4', placement: 'bottom-right' },
706
+ // ]
707
+ // ```
708
+ expect ( bottomToasts ) . toHaveLength ( 2 ) ;
709
+ expect ( bottomToasts [ 0 ] . id < bottomToasts [ 1 ] . id ) . toBeTruthy ( ) ;
710
+ } ) ;
548
711
} ) ;
0 commit comments