@@ -603,6 +603,164 @@ describe("special character tests", () => {
603
603
) ;
604
604
}
605
605
} ) ;
606
+
607
+ it ( "handles encoded question marks in ancestor splat route segments" , async ( ) => {
608
+ let ctx = render (
609
+ < BrowserRouter window = { getWindow ( "/parent/child/question-%3F-mark" ) } >
610
+ < App />
611
+ </ BrowserRouter > ,
612
+ ) ;
613
+
614
+ expect ( getHtml ( ctx . container ) ) . toMatchInlineSnapshot ( `
615
+ "<div>
616
+ <a
617
+ data-discover="true"
618
+ href="/parent/child/question-%3F-mark/grandchild"
619
+ >
620
+ Link to grandchild
621
+ </a>
622
+ </div>"
623
+ ` ) ;
624
+
625
+ await fireEvent . click ( screen . getByText ( "Link to grandchild" ) ) ;
626
+ await waitFor ( ( ) => screen . getByText ( "Grandchild" ) ) ;
627
+
628
+ expect ( getHtml ( ctx . container ) ) . toMatchInlineSnapshot ( `
629
+ "<div>
630
+ <a
631
+ data-discover="true"
632
+ href="/parent/child/question-%3F-mark/grandchild"
633
+ >
634
+ Link to grandchild
635
+ </a>
636
+ <h1>
637
+ Grandchild
638
+ </h1>
639
+ <pre>
640
+ {"*":"grandchild","param":"question-?-mark"}
641
+ </pre>
642
+ </div>"
643
+ ` ) ;
644
+
645
+ function App ( ) {
646
+ return (
647
+ < Routes >
648
+ < Route path = "/parent/*" element = { < Parent /> } />
649
+ </ Routes >
650
+ ) ;
651
+ }
652
+
653
+ function Parent ( ) {
654
+ return (
655
+ < Routes >
656
+ < Route path = "child/:param/*" element = { < Child /> } />
657
+ </ Routes >
658
+ ) ;
659
+ }
660
+
661
+ function Child ( ) {
662
+ let location = useLocation ( ) ;
663
+ let to = location . pathname . endsWith ( "grandchild" )
664
+ ? "."
665
+ : "./grandchild" ;
666
+ return (
667
+ < >
668
+ < Link to = { to } > Link to grandchild</ Link >
669
+ < Routes >
670
+ < Route path = "grandchild" element = { < Grandchild /> } />
671
+ </ Routes >
672
+ </ >
673
+ ) ;
674
+ }
675
+
676
+ function Grandchild ( ) {
677
+ return (
678
+ < >
679
+ < h1 > Grandchild</ h1 >
680
+ < pre > { JSON . stringify ( useParams ( ) ) } </ pre >
681
+ </ >
682
+ ) ;
683
+ }
684
+ } ) ;
685
+
686
+ it ( "handles encoded hashes in ancestor splat route segments" , async ( ) => {
687
+ let ctx = render (
688
+ < BrowserRouter window = { getWindow ( "/parent/child/hash-%23-char" ) } >
689
+ < App />
690
+ </ BrowserRouter > ,
691
+ ) ;
692
+
693
+ expect ( getHtml ( ctx . container ) ) . toMatchInlineSnapshot ( `
694
+ "<div>
695
+ <a
696
+ data-discover="true"
697
+ href="/parent/child/hash-%23-char/grandchild"
698
+ >
699
+ Link to grandchild
700
+ </a>
701
+ </div>"
702
+ ` ) ;
703
+
704
+ await fireEvent . click ( screen . getByText ( "Link to grandchild" ) ) ;
705
+ await waitFor ( ( ) => screen . getByText ( "Grandchild" ) ) ;
706
+
707
+ expect ( getHtml ( ctx . container ) ) . toMatchInlineSnapshot ( `
708
+ "<div>
709
+ <a
710
+ data-discover="true"
711
+ href="/parent/child/hash-%23-char/grandchild"
712
+ >
713
+ Link to grandchild
714
+ </a>
715
+ <h1>
716
+ Grandchild
717
+ </h1>
718
+ <pre>
719
+ {"*":"grandchild","param":"hash-#-char"}
720
+ </pre>
721
+ </div>"
722
+ ` ) ;
723
+
724
+ function App ( ) {
725
+ return (
726
+ < Routes >
727
+ < Route path = "/parent/*" element = { < Parent /> } />
728
+ </ Routes >
729
+ ) ;
730
+ }
731
+
732
+ function Parent ( ) {
733
+ return (
734
+ < Routes >
735
+ < Route path = "child/:param/*" element = { < Child /> } />
736
+ </ Routes >
737
+ ) ;
738
+ }
739
+
740
+ function Child ( ) {
741
+ let location = useLocation ( ) ;
742
+ let to = location . pathname . endsWith ( "grandchild" )
743
+ ? "."
744
+ : "./grandchild" ;
745
+ return (
746
+ < >
747
+ < Link to = { to } > Link to grandchild</ Link >
748
+ < Routes >
749
+ < Route path = "grandchild" element = { < Grandchild /> } />
750
+ </ Routes >
751
+ </ >
752
+ ) ;
753
+ }
754
+
755
+ function Grandchild ( ) {
756
+ return (
757
+ < >
758
+ < h1 > Grandchild</ h1 >
759
+ < pre > { JSON . stringify ( useParams ( ) ) } </ pre >
760
+ </ >
761
+ ) ;
762
+ }
763
+ } ) ;
606
764
} ) ;
607
765
608
766
describe ( "when matching as part of the defined route path" , ( ) => {
0 commit comments