Skip to content

Commit

Permalink
fix(react-router): take from into account when building urls (#1595)
Browse files Browse the repository at this point in the history
* test: link generation tests

* test: more tests

* fix: take dest.from into account when building urls
  • Loading branch information
TkDodo committed May 15, 2024
1 parent 7e9509d commit fa25b3c
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/react-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ export class Router<
} = {},
matches?: Array<MakeRouteMatch<TRouteTree>>,
): ParsedLocation => {
let fromPath = this.latestLocation.pathname
let fromPath = dest.from || this.latestLocation.pathname
let fromSearch = dest.fromSearch || this.latestLocation.search

const fromMatches = this.matchRoutes(
Expand Down
144 changes: 136 additions & 8 deletions packages/react-router/tests/link.test.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from 'react'
import { describe, it, expect, afterEach } from 'vitest'
import { render, cleanup } from '@testing-library/react'
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import * as React from 'react'

import { afterEach, describe, expect, it } from 'vitest'
import { cleanup, render } from '@testing-library/react'

import {
createRouter,
createRootRoute,
createRoute,
createMemoryHistory,
Link,
RouterProvider,
createLink,
Link,
createMemoryHistory,
createRootRoute,
createRoute,
createRouter,
} from '../src'

afterEach(() => {
Expand Down Expand Up @@ -40,6 +42,132 @@ describe('Link', () => {

expect(customElement!.hasAttribute('disabled')).toBe(false)
})
describe('building urls', () => {
const buildRouter = async (
component: React.ReactNode,
opts?: { page?: string },
) => {
const rootRoute = createRootRoute()
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
})

const invoicesRoute = createRoute({
getParentRoute: () => rootRoute,
path: 'invoices',
})

const invoicesIndexRoute = createRoute({
getParentRoute: () => invoicesRoute,
path: '/',
})

const invoiceRoute = createRoute({
getParentRoute: () => invoicesRoute,
path: '$invoiceId',
})

const subInvoiceRoute = createRoute({
getParentRoute: () => invoiceRoute,
path: 'sub',
})

const postsRoute = createRoute({
getParentRoute: () => rootRoute,
path: 'posts',
})

const postsIndexRoute = createRoute({
getParentRoute: () => postsRoute,
path: '/',
})

const postRoute = createRoute({
getParentRoute: () => postsRoute,
path: '$postId',
})

const router = createRouter({
defaultComponent: () => component,
routeTree: rootRoute.addChildren([
invoicesRoute.addChildren([
invoicesIndexRoute,
invoiceRoute.addChildren([subInvoiceRoute]),
]),
postsRoute.addChildren([postsIndexRoute, postRoute]),
indexRoute,
]),
history: createMemoryHistory({ initialEntries: [opts?.page ?? '/'] }),
})

await router.load()

return router
}

it('should build correct url for absolute to property', async () => {
const router = await buildRouter(<Link to="/invoices/123/sub">Link</Link>)

const rendered = render(<RouterProvider router={router} />)

const link = rendered.getByText('Link')

expect(link.getAttribute('href')).toBe('/invoices/123/sub')
})

it('should build correct url for relative to property', async () => {
const router = await buildRouter(
<Link from="/invoices/123" to="./sub">
Link
</Link>,
{ page: '/invoices/123' },
)

const rendered = render(<RouterProvider router={router} />)

const link = rendered.getByText('Link')

expect(link.getAttribute('href')).toBe('/invoices/123/sub')
})

it('should ignore from for absolute links', async () => {
const router = await buildRouter(
<Link from="/invoices/123" to="/invoices/123/sub">
Link
</Link>,
{ page: '/' },
)

const rendered = render(<RouterProvider router={router} />)

const link = rendered.getByText('Link')

expect(link.getAttribute('href')).toBe('/invoices/123/sub')
})

it('should take from into account for building relative urls', async () => {
const router = await buildRouter(
<div>
<Link from="/invoices/123" to="sub">
sub
</Link>
<Link from="/invoices/123" to="./sub">
dot-sub
</Link>
</div>,
{ page: '/' },
)

const rendered = render(<RouterProvider router={router} />)

const sub = rendered.getByText('sub')
const dotSub = rendered.getByText('dot-sub')

expect(sub.getAttribute('href')).toBe('/invoices/123/sub')
expect(dotSub.getAttribute('href')).toBe('/invoices/123/sub')
})
})
})

describe('createLink', () => {
Expand Down

0 comments on commit fa25b3c

Please sign in to comment.