@@ -751,6 +751,118 @@ describe('Link', () => {
751
751
expect ( updatedFilter ) . toHaveTextContent ( 'Filter: inactive' )
752
752
} )
753
753
754
+ test ( 'when navigation to . from /posts while updating search from / and using base path' , async ( ) => {
755
+ const RootComponent = ( ) => {
756
+ return (
757
+ < >
758
+ < div data-testid = "root-nav" >
759
+ < Link
760
+ to = "."
761
+ search = { { page : 2 , filter : 'inactive' } }
762
+ data-testid = "update-search"
763
+ >
764
+ Update Search
765
+ </ Link >
766
+ </ div >
767
+ < Outlet />
768
+ </ >
769
+ )
770
+ }
771
+
772
+ const rootRoute = createRootRoute ( {
773
+ component : RootComponent ,
774
+ } )
775
+
776
+ const indexRoute = createRoute ( {
777
+ getParentRoute : ( ) => rootRoute ,
778
+ path : '/' ,
779
+ component : ( ) => {
780
+ return (
781
+ < >
782
+ < h1 > Index</ h1 >
783
+ < Link
784
+ to = "/posts"
785
+ search = { { page : 1 , filter : 'active' } }
786
+ data-testid = "to-posts"
787
+ >
788
+ Go to Posts
789
+ </ Link >
790
+ </ >
791
+ )
792
+ } ,
793
+ } )
794
+
795
+ const PostsComponent = ( ) => {
796
+ const search = useSearch ( { strict : false } )
797
+ return (
798
+ < >
799
+ < h1 > Posts</ h1 >
800
+ < span data-testid = "current-page" > Page: { search . page } </ span >
801
+ < span data-testid = "current-filter" > Filter: { search . filter } </ span >
802
+ </ >
803
+ )
804
+ }
805
+
806
+ const postsRoute = createRoute ( {
807
+ getParentRoute : ( ) => rootRoute ,
808
+ path : 'posts' ,
809
+ validateSearch : ( input : Record < string , unknown > ) => {
810
+ return {
811
+ page : input . page ? Number ( input . page ) : 1 ,
812
+ filter : ( input . filter as string ) || 'all' ,
813
+ }
814
+ } ,
815
+ component : PostsComponent ,
816
+ } )
817
+
818
+ const router = createRouter ( {
819
+ routeTree : rootRoute . addChildren ( [ indexRoute , postsRoute ] ) ,
820
+ history,
821
+ } )
822
+
823
+ render ( < RouterProvider router = { router } basepath = { '/Dashboard' } /> )
824
+
825
+ // Start at index page
826
+ const toPostsLink = await screen . findByTestId ( 'to-posts' )
827
+ expect ( toPostsLink ) . toHaveAttribute (
828
+ 'href' ,
829
+ '/Dashboard/posts?page=1&filter=active' ,
830
+ )
831
+
832
+ // Navigate to posts with initial search params
833
+ await act ( ( ) => fireEvent . click ( toPostsLink ) )
834
+
835
+ // Verify we're on posts with initial search
836
+ const postsHeading = await screen . findByRole ( 'heading' , { name : 'Posts' } )
837
+ expect ( postsHeading ) . toBeInTheDocument ( )
838
+ expect ( window . location . pathname ) . toBe ( '/Dashboard/posts' )
839
+ expect ( window . location . search ) . toBe ( '?page=1&filter=active' )
840
+
841
+ const currentPage = await screen . findByTestId ( 'current-page' )
842
+ const currentFilter = await screen . findByTestId ( 'current-filter' )
843
+ expect ( currentPage ) . toHaveTextContent ( 'Page: 1' )
844
+ expect ( currentFilter ) . toHaveTextContent ( 'Filter: active' )
845
+
846
+ // Navigate to current route (.) with updated search
847
+ const updateSearchLink = await screen . findByTestId ( 'update-search' )
848
+
849
+ expect ( updateSearchLink ) . toHaveAttribute (
850
+ 'href' ,
851
+ '/Dashboard/posts?page=2&filter=inactive' ,
852
+ )
853
+
854
+ await act ( ( ) => fireEvent . click ( updateSearchLink ) )
855
+
856
+ // Verify search was updated
857
+ expect ( window . location . pathname ) . toBe ( '/Dashboard/posts' )
858
+ expect ( window . location . search ) . toBe ( '?page=2&filter=inactive' )
859
+
860
+ const updatedPage = await screen . findByTestId ( 'current-page' )
861
+ const updatedFilter = await screen . findByTestId ( 'current-filter' )
862
+ expect ( updatedPage ) . toHaveTextContent ( 'Page: 2' )
863
+ expect ( updatedFilter ) . toHaveTextContent ( 'Filter: inactive' )
864
+ } )
865
+
754
866
test ( 'when navigating to /posts with invalid search' , async ( ) => {
755
867
const rootRoute = createRootRoute ( )
756
868
const onError = vi . fn ( )
0 commit comments