Skip to content

Commit

Permalink
DOP-1965: Enforce trailing slash on internal links (#348)
Browse files Browse the repository at this point in the history
  • Loading branch information
sophstad authored Feb 3, 2021
1 parent 7ff5267 commit 25cc91e
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 22 deletions.
4 changes: 4 additions & 0 deletions src/components/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const Link = ({ children, to, activeClassName, partiallyActive, ...other }) => {
// Use Gatsby Link for internal links, and <a> for others
if (to && !external && !anchor) {
if (!to.startsWith('/')) to = `/${to}`;

// Ensure trailing slash
to = to.replace(/\/?(\?|#|$)/, '/$1');

return (
<GatsbyLink to={to} activeClassName={activeClassName} partiallyActive={partiallyActive} {...other}>
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/components/RefRole.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const RefRole = ({ nodeData: { children, domain, fileid, name, url }, slug }) =>
// :doc: link
link = filename;
} else {
link = `${filename}#${html_id}`;
link = `${filename}/#${html_id}`;
}
}

Expand Down
15 changes: 15 additions & 0 deletions tests/unit/Link.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,19 @@ describe('Link component renders a variety of strings correctly', () => {
const tree = setup({ to: 'drivers/c', text: 'C Driver', className: 'test-class' });
expect(tree).toMatchSnapshot();
});

it('internal link with hash', () => {
const tree = setup({ to: 'drivers/pymongo#installation', text: 'C Driver', className: 'test-class' });
expect(tree).toMatchSnapshot();
});

it('internal link query param', () => {
const tree = setup({ to: 'drivers/ruby?site=drivers', text: 'C Driver', className: 'test-class' });
expect(tree).toMatchSnapshot();
});

it('internal link that already includes trailing slash', () => {
const tree = setup({ to: 'drivers/nodejs/#installation', text: 'C Driver', className: 'test-class' });
expect(tree).toMatchSnapshot();
});
});
4 changes: 2 additions & 2 deletions tests/unit/__snapshots__/Breadcrumbs.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exports[`renders correctly 1`] = `
<ul>
<li>
<a
href="/drivers"
href="/drivers/"
>
MongoDB Drivers and ODM
</a>
Expand All @@ -25,7 +25,7 @@ exports[`renders correctly 1`] = `
</li>
<li>
<a
href="/drivers/php"
href="/drivers/php/"
>
MongoDB PHP Driver
</a>
Expand Down
14 changes: 7 additions & 7 deletions tests/unit/__snapshots__/Card.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
class="guide__entry"
>
<a
href="/server/insert"
href="/server/insert/"
>
Insert Data into MongoDB
</a>
Expand All @@ -25,7 +25,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
class="guide__entry"
>
<a
href="/server/read"
href="/server/read/"
>
Read Data from MongoDB
</a>
Expand All @@ -34,7 +34,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
class="guide__entry"
>
<a
href="/server/read_queries"
href="/server/read_queries/"
>
Read Data from MongoDB With Queries
</a>
Expand All @@ -43,7 +43,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
class="guide__entry"
>
<a
href="/server/read_operators"
href="/server/read_operators/"
>
Read Data using Operators and Compound Queries
</a>
Expand All @@ -52,7 +52,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
class="guide__entry"
>
<a
href="/server/update"
href="/server/update/"
>
Update Data in MongoDB
</a>
Expand All @@ -61,7 +61,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
class="guide__entry"
>
<a
href="/server/delete"
href="/server/delete/"
>
Delete Data from MongoDB
</a>
Expand All @@ -73,7 +73,7 @@ exports[`Card component when a multi card is mounted renders correctly 1`] = `
exports[`Card component when a standard card is mounted renders correctly 1`] = `
<a
class="guide guide--regular"
href="/server/install"
href="/server/install/"
>
<div
class="guide__title"
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/__snapshots__/InternalPageNav.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports[`renders a page with next and previous links correctly 1`] = `
</span>
<a
class="btn-prev-text"
href="/drivers/csharp"
href="/drivers/csharp/"
title="Previous Section"
>
<span>
Expand All @@ -20,7 +20,7 @@ exports[`renders a page with next and previous links correctly 1`] = `
</a>
<a
class="btn-next-text"
href="/drivers/java"
href="/drivers/java/"
title="Next Section"
>
<span>
Expand All @@ -46,7 +46,7 @@ exports[`renders a page with no next link correctly 1`] = `
</span>
<a
class="btn-prev-text"
href="/drivers/go"
href="/drivers/go/"
title="Previous Section"
>
<span>
Expand All @@ -62,7 +62,7 @@ exports[`renders a page with no previous link correctly 1`] = `
>
<a
class="btn-next-text"
href="/drivers/go"
href="/drivers/go/"
title="Next Section"
>
<span>
Expand Down
29 changes: 28 additions & 1 deletion tests/unit/__snapshots__/Link.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,34 @@ exports[`Link component renders a variety of strings correctly external URL 1`]
exports[`Link component renders a variety of strings correctly internal link 1`] = `
<a
class="test-class"
href="/drivers/c"
href="/drivers/c/"
>
C Driver
</a>
`;

exports[`Link component renders a variety of strings correctly internal link query param 1`] = `
<a
class="test-class"
href="/drivers/ruby/?site=drivers"
>
C Driver
</a>
`;

exports[`Link component renders a variety of strings correctly internal link that already includes trailing slash 1`] = `
<a
class="test-class"
href="/drivers/nodejs/#installation"
>
C Driver
</a>
`;

exports[`Link component renders a variety of strings correctly internal link with hash 1`] = `
<a
class="test-class"
href="/drivers/pymongo/#installation"
>
C Driver
</a>
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/__snapshots__/TableOfContents.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,12 @@ exports[`Table of Contents testing Table of Contents unit tests renders correctl
<mockConstructor
aria-expanded={false}
className="reference internal"
to="/drivers"
to="/drivers/"
>
<a
aria-expanded={false}
className="reference internal"
href="/drivers"
href="/drivers/"
>
MongoDB Drivers and ODM
</a>
Expand Down Expand Up @@ -389,12 +389,12 @@ exports[`Table of Contents testing Table of Contents unit tests renders correctl
<mockConstructor
aria-expanded={false}
className="reference internal"
to="/tools"
to="/tools/"
>
<a
aria-expanded={false}
className="reference internal"
href="/tools"
href="/tools/"
>
MongoDB Integration and Tools
</a>
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/__snapshots__/Target.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ configuration file is the preferred method for runtime configuration of
<a
class="reference internal"
href="/reference/program/mongos#std-program-mongos"
href="/reference/program/mongos/#std-program-mongos"
>
<code>
mongos
Expand All @@ -35,7 +35,7 @@ configuration file is the preferred method for runtime configuration of
configuration options. See
<a
class="reference internal"
href="/reference/configuration-options"
href="/reference/configuration-options/"
>
Configuration File Options
</a>
Expand All @@ -46,7 +46,7 @@ more information.
Ensure the configuration file uses ASCII encoding. The
<a
class="reference internal"
href="/reference/program/mongos#std-program-mongos"
href="/reference/program/mongos/#std-program-mongos"
>
<code>
mongos
Expand Down

0 comments on commit 25cc91e

Please sign in to comment.