Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/react/src/reactrouterv6-compat-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,10 @@ function getNormalizedName(
// If path is not a wildcard and has no child routes, append the path
if (path && !pathIsWildcardAndHasChildren(path, branch)) {
const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`;
pathBuilder += newPath;
pathBuilder = trimSlash(pathBuilder) + prefixWithSlash(newPath);

// If the path matches the current location, return the path
if (location.pathname.endsWith(basename + branch.pathname)) {
if (trimSlash(location.pathname) === trimSlash(basename + branch.pathname)) {
if (
// If the route defined on the element is something like
// <Route path="/stores/:storeId/products/:productId" element={<div>Product</div>} />
Expand Down
156 changes: 156 additions & 0 deletions packages/react/test/reactrouterv6.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,84 @@ describe('reactRouterV6BrowserTracingIntegration', () => {
});
});

it('works under a slash route with a trailing slash', () => {
const client = createMockBrowserClient();
setCurrentClient(client);

client.addIntegration(
reactRouterV6BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
);
const SentryRoutes = withSentryReactRouterV6Routing(Routes);

render(
<MemoryRouter initialEntries={['/']}>
<SentryRoutes>
<Route index element={<Navigate to="/issues/123/" />} />
<Route path="/" element={<div>root</div>}>
<Route path="/issues/:groupId/" element={<div>issues group</div>}>
<Route index element={<div>index</div>} />
</Route>
</Route>
</SentryRoutes>
</MemoryRouter>,
);

expect(mockStartBrowserTracingNavigationSpan).toHaveBeenCalledTimes(1);
expect(mockStartBrowserTracingNavigationSpan).toHaveBeenLastCalledWith(expect.any(BrowserClient), {
name: '/issues/:groupId/',
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v6',
},
});
});

it('works nested under a slash root without a trailing slash', () => {
const client = createMockBrowserClient();
setCurrentClient(client);

client.addIntegration(
reactRouterV6BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
);
const SentryRoutes = withSentryReactRouterV6Routing(Routes);

render(
<MemoryRouter initialEntries={['/']}>
<SentryRoutes>
<Route index element={<Navigate to="/issues/123" />} />
<Route path="/" element={<div>root</div>}>
<Route path="/issues/:groupId/" element={<div>issues group</div>}>
<Route index element={<div>index</div>} />
</Route>
</Route>
</SentryRoutes>
</MemoryRouter>,
);

expect(mockStartBrowserTracingNavigationSpan).toHaveBeenCalledTimes(1);
expect(mockStartBrowserTracingNavigationSpan).toHaveBeenLastCalledWith(expect.any(BrowserClient), {
name: '/issues/:groupId/',
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v6',
},
});
});

it("updates the scope's `transactionName` on a navigation", () => {
const client = createMockBrowserClient();
setCurrentClient(client);
Expand Down Expand Up @@ -1397,6 +1475,84 @@ describe('reactRouterV6BrowserTracingIntegration', () => {
expect(mockRootSpan.setAttribute).toHaveBeenCalledWith(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
});

it('works under a slash route with a trailing slash', () => {
const client = createMockBrowserClient();
setCurrentClient(client);

client.addIntegration(
reactRouterV6BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
);
const SentryRoutes = withSentryReactRouterV6Routing(Routes);

render(
<MemoryRouter initialEntries={['/']}>
<SentryRoutes>
<Route index element={<Navigate to="/issues/123/" />} />
<Route path="/" element={<div>root</div>}>
<Route path="/issues/:groupId/" element={<div>issues group</div>}>
<Route index element={<div>index</div>} />
</Route>
</Route>
</SentryRoutes>
</MemoryRouter>,
);

expect(mockStartBrowserTracingNavigationSpan).toHaveBeenCalledTimes(1);
expect(mockStartBrowserTracingNavigationSpan).toHaveBeenLastCalledWith(expect.any(BrowserClient), {
name: '/issues/:groupId/',
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v6',
},
});
});

it('works nested under a slash root without a trailing slash', () => {
const client = createMockBrowserClient();
setCurrentClient(client);

client.addIntegration(
reactRouterV6BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
);
const SentryRoutes = withSentryReactRouterV6Routing(Routes);

render(
<MemoryRouter initialEntries={['/']}>
<SentryRoutes>
<Route index element={<Navigate to="/issues/123" />} />
<Route path="/" element={<div>root</div>}>
<Route path="/issues/:groupId/" element={<div>issues group</div>}>
<Route index element={<div>index</div>} />
</Route>
</Route>
</SentryRoutes>
</MemoryRouter>,
);

expect(mockStartBrowserTracingNavigationSpan).toHaveBeenCalledTimes(1);
expect(mockStartBrowserTracingNavigationSpan).toHaveBeenLastCalledWith(expect.any(BrowserClient), {
name: '/issues/:groupId/',
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v6',
},
});
});

it("updates the scope's `transactionName` on a navigation", () => {
const client = createMockBrowserClient();
setCurrentClient(client);
Expand Down
Loading