-
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement util functions to match internal routes
To handle the logic of conditionally rendering a Gatsby Link or a basic `<a>`, based on the passed target URL (internal & external), this commit implements the `isRouteInternal` and `isRoutePartiallyMatch` functions to evaluate the passed target URL. Associated epic: GH-69 GH-70
- Loading branch information
1 parent
208c9ac
commit cb9000e
Showing
7 changed files
with
191 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright (C) 2018-present Arctic Ice Studio <development@arcticicestudio.com> | ||
* Copyright (C) 2018-present Sven Greb <development@svengreb.de> | ||
* | ||
* Project: Nord Docs | ||
* Repository: https://github.com/arcticicestudio/nord-docs | ||
* License: MIT | ||
*/ | ||
|
||
/* eslint-disable no-useless-escape */ | ||
|
||
/** | ||
* Validates if the given route is internal. | ||
* Matches exactly one slash or hash, anything else is external including relative routes starting with two slahes. | ||
* The hash allows to link to anchors within the same document. | ||
* | ||
* @method isRouteInternal | ||
* @param {string} route The route to validate. | ||
* @return {Boolean} `true` if the given route is internal, `false` otherwise. | ||
* @since 0.3.0 | ||
*/ | ||
const isRouteInternal = route => /^[\/#](?!\/)/.test(route); | ||
|
||
export default isRouteInternal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright (C) 2018-present Arctic Ice Studio <development@arcticicestudio.com> | ||
* Copyright (C) 2018-present Sven Greb <development@svengreb.de> | ||
* | ||
* Project: Nord Docs | ||
* Repository: https://github.com/arcticicestudio/nord-docs | ||
* License: MIT | ||
*/ | ||
|
||
import isRouteInternal from "./isRouteInternal"; | ||
|
||
/** | ||
* Validates if the given path element partially matches the route. | ||
* | ||
* @method isRoutePartiallyMatch | ||
* @param {string} route The route to check. | ||
* @param {string} pathElement The path element to check against the route. | ||
* @return {Boolean} `true` if the given path element is partially matching, `false` otherwise. | ||
* @since 0.3.0 | ||
*/ | ||
const isRoutePartiallyMatch = (route, pathElement) => { | ||
/* Don't match exact and external routes. */ | ||
if (route === pathElement) return false; | ||
if (!isRouteInternal(pathElement)) return false; | ||
|
||
/* Split into path elements and filter out leading and pending slashes. */ | ||
const routeTokens = route.split("/").filter(t => t.length); | ||
const pathElementTokens = pathElement.split("/").filter(t => t.length); | ||
|
||
const isMatch = pathElementTokens.every((t, idx) => routeTokens[idx] === t); | ||
/* Prevent false-positive match by only allowing the path element as exact root when current route is not the root. */ | ||
const isPathElementExactRoot = pathElement === "/" && route !== "/"; | ||
|
||
return isPathElementExactRoot ? false : isMatch; | ||
}; | ||
|
||
export default isRoutePartiallyMatch; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (C) 2018-present Arctic Ice Studio <development@arcticicestudio.com> | ||
* Copyright (C) 2018-present Sven Greb <development@svengreb.de> | ||
* | ||
* Project: Nord Docs | ||
* Repository: https://github.com/arcticicestudio/nord-docs | ||
* License: MIT | ||
*/ | ||
|
||
import { isRouteInternal } from "utils"; | ||
import { ROUTE_BLOG, ROUTE_DOCS, ROUTE_COMMUNITY, ROUTE_PORTS, ROUTE_ROOT } from "config/routes/mappings"; | ||
import { metadataNordDocs } from "data/project"; | ||
|
||
describe("internal routes are", () => { | ||
test("matching", () => { | ||
[ | ||
"#", | ||
ROUTE_ROOT, | ||
`${ROUTE_ROOT}#`, | ||
`${ROUTE_ROOT}?port=atom`, | ||
ROUTE_BLOG, | ||
ROUTE_DOCS, | ||
ROUTE_COMMUNITY, | ||
ROUTE_PORTS | ||
].forEach(route => expect(isRouteInternal(route)).toBeTruthy()); | ||
}); | ||
|
||
test("not matching", () => { | ||
[ | ||
`${metadataNordDocs.homepage}`, | ||
`${metadataNordDocs.repository.url}`, | ||
"https://github.com/arcticicestudio", | ||
"https://www.nordtheme.com", | ||
"https://nordtheme.com", | ||
"https://nordtheme.com", | ||
"//nordtheme.com", | ||
"file:///etc/hosts", | ||
"mailto:support@nordtheme.com" | ||
].forEach(route => expect(isRouteInternal(route)).toBeFalsy()); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright (C) 2018-present Arctic Ice Studio <development@arcticicestudio.com> | ||
* Copyright (C) 2018-present Sven Greb <development@svengreb.de> | ||
* | ||
* Project: Nord Docs | ||
* Repository: https://github.com/arcticicestudio/nord-docs | ||
* License: MIT | ||
*/ | ||
|
||
import { isRoutePartiallyMatch } from "utils"; | ||
import { ROUTE_BLOG, ROUTE_DOCS, ROUTE_COMMUNITY, ROUTE_PORTS, ROUTE_ROOT } from "config/routes/mappings"; | ||
import { metadataNordDocs } from "data/project"; | ||
|
||
describe("partial routes are", () => { | ||
test("matching", () => { | ||
[ | ||
{ route: `${ROUTE_BLOG}/2018/12/06/snow-winter`, pathElement: ROUTE_BLOG }, | ||
{ route: `${ROUTE_DOCS}${ROUTE_PORTS}/vim`, pathElement: ROUTE_DOCS }, | ||
{ route: `${ROUTE_COMMUNITY}/slack`, pathElement: ROUTE_COMMUNITY } | ||
].forEach(({ route, pathElement }) => expect(isRoutePartiallyMatch(route, pathElement)).toBeTruthy()); | ||
}); | ||
|
||
test("not matching", () => { | ||
[ | ||
{ route: ROUTE_ROOT, pathElement: ROUTE_ROOT }, | ||
{ route: ROUTE_ROOT, pathElement: ROUTE_BLOG }, | ||
{ route: `${ROUTE_BLOG}/2018`, pathElement: `${ROUTE_BLOG}/2018/12/06/snow-winter` }, | ||
{ route: `${ROUTE_BLOG}/2018/12/06/snow-winter`, pathElement: `${ROUTE_BLOG}/2018/12/06/snow-winter` } | ||
].forEach(({ route, pathElement }) => expect(isRoutePartiallyMatch(route, pathElement)).toBeFalsy()); | ||
}); | ||
|
||
test("not matching exact and external routes", () => { | ||
[ | ||
{ route: ROUTE_ROOT, pathElement: ROUTE_ROOT }, | ||
{ route: metadataNordDocs.homepage, pathElement: ROUTE_DOCS }, | ||
{ route: metadataNordDocs.repository.url, pathElement: ROUTE_COMMUNITY }, | ||
{ route: "https://www.nordtheme.com", pathElement: ROUTE_ROOT } | ||
].forEach(({ route, pathElement }) => expect(isRoutePartiallyMatch(route, pathElement)).toBeFalsy()); | ||
}); | ||
}); | ||
|
||
test("prevents false-positive match by only allowing the path element as exact root when current route is not the root", () => { | ||
[ | ||
{ route: ROUTE_ROOT, pathElement: ROUTE_BLOG }, | ||
{ route: ROUTE_ROOT, pathElement: `${ROUTE_BLOG}/2018/12/06/snow-winter` } | ||
].forEach(({ route, pathElement }) => expect(isRoutePartiallyMatch(route, pathElement)).toBeFalsy()); | ||
}); |