Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent path prefix from being incorrectly applied #3233

Merged
merged 10 commits into from
Dec 22, 2017
76 changes: 76 additions & 0 deletions packages/gatsby/cache-dir/__tests__/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import loader from "../loader.js"

describe(`Loader`, () => {
beforeEach(() => {
delete global.__PATH_PREFIX__
delete global.__PREFIX_PATHS__

// Workaround for Node 6 issue: https://github.com/facebook/jest/issues/5159
if (global.hasOwnProperty(`__PATH_PREFIX__`)) global.__PATH_PREFIX__ = undefined
if (global.hasOwnProperty(`__PREFIX_PATHS__`)) global.__PREFIX_PATHS__ = undefined

loader.empty()
loader.addPagesArray([
{
Expand Down Expand Up @@ -68,3 +75,72 @@ describe(`Loader`, () => {
expect(loader.getResources()).toMatchSnapshot()
})
})

describe(`Loader path prefixing`, () => {
let pagesArray

beforeEach(() => {
delete global.__PATH_PREFIX__
delete global.__PREFIX_PATHS__

// Workaround for Node 6 issue: https://github.com/facebook/jest/issues/5159
if (global.hasOwnProperty(`__PATH_PREFIX__`)) global.__PATH_PREFIX__ = undefined
if (global.hasOwnProperty(`__PREFIX_PATHS__`)) global.__PREFIX_PATHS__ = undefined

pagesArray = [
{
path: `/about/`,
componentChunkName: `page-component---src-pages-test-js`,
jsonName: `about.json`,
},
{
path: `/about/me/`,
componentChunkName: `page-component---src-pages-test-js`,
jsonName: `about-me.json`,
},
]

loader.empty()
})

test(`Path prefix present and enabled`, () => {
global.__PATH_PREFIX__ = `/foo`
global.__PREFIX_PATHS__ = true
loader.addPagesArray(pagesArray)
loader.enqueue(`/foo/about/`)
expect(loader.has(`/about/`)).toEqual(true)
expect(loader.has(`/foo/about/`)).toEqual(false)
})

test(`Path prefix present but not enabled`, () => {
global.__PATH_PREFIX__ = `/foo`
delete global.__PREFIX_PATHS__
loader.addPagesArray(pagesArray)

// don't enqueue prefixed paths
loader.enqueue(`/foo/about/`)
expect(loader.has(`/about/`)).toEqual(false)
expect(loader.has(`/foo/about/`)).toEqual(false)

// do enqueue unprefixed paths
loader.enqueue(`/about/`)
expect(loader.has(`/about/`)).toEqual(true)
expect(loader.has(`/foo/about/`)).toEqual(false)
})

test(`Path prefix missing but enabled`, () => {
delete global.__PATH_PREFIX__
global.__PREFIX_PATHS__ = true
loader.addPagesArray(pagesArray)

// don't enqueue prefixed paths
loader.enqueue(`/foo/about/`)
expect(loader.has(`/about/`)).toEqual(false)
expect(loader.has(`/foo/about/`)).toEqual(false)

// do enqueue unprefixed paths
loader.enqueue(`/about/`)
expect(loader.has(`/about/`)).toEqual(true)
expect(loader.has(`/foo/about/`)).toEqual(false)
})
})
23 changes: 23 additions & 0 deletions packages/gatsby/cache-dir/__tests__/strip-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const stripPrefix = require(`../strip-prefix`).default

describe(`strip-prefix`, () => {
it(`strips a prefix`, () => {
expect(stripPrefix(`/foo/bar/`, `/foo`)).toBe(`/bar/`)
})

it(`strips first instance only`, () => {
expect(stripPrefix(`/foo/foo/bar/`, `/foo`)).toBe(`/foo/bar/`)
})

it(`ignores prefix appearing elsewhere in the string`, () => {
expect(stripPrefix(`/foo/bar/`, `bar`)).toBe(`/foo/bar/`)
})

it(`ignores a non-existent prefix`, () => {
expect(stripPrefix(`/bar`, `/foo`)).toBe(`/bar`)
})

it(`returns input str if no prefix is provided`, () => {
expect(stripPrefix(`/bar`)).toBe(`/bar`)
})
})
4 changes: 3 additions & 1 deletion packages/gatsby/cache-dir/find-page.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// TODO add tests especially for handling prefixed links.
import { matchPath } from "react-router-dom"
import stripPrefix from "./strip-prefix"

const pageCache = {}

module.exports = (pages, pathPrefix = ``) => rawPathname => {
let pathname = decodeURIComponent(rawPathname)

// Remove the pathPrefix from the pathname.
let trimmedPathname = pathname.slice(pathPrefix.length)
let trimmedPathname = stripPrefix(pathname, pathPrefix)

// Remove any hashfragment
if (trimmedPathname.split(`#`).length > 1) {
Expand Down
16 changes: 11 additions & 5 deletions packages/gatsby/cache-dir/loader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { createElement } from "react"
import pageFinderFactory from "./find-page"
import emitter from "./emitter"
import stripPrefix from "./strip-prefix"
let findPage

let syncRequires = {}
Expand All @@ -14,6 +15,7 @@ let pages = []
// we load all resources for likely-to-be-visited paths.
let pathArray = []
let pathCount = {}
let pathPrefix = ``
let resourcesArray = []
let resourcesCount = {}
const preferDefault = m => (m && m.default) || m
Expand Down Expand Up @@ -153,12 +155,15 @@ const queue = {
resourcesCount = {}
resourcesArray = []
pages = []
pathPrefix = ``
},
addPagesArray: newPages => {
pages = newPages
let pathPrefix = ``
if (typeof __PREFIX_PATHS__ !== `undefined`) {
pathPrefix = __PATH_PREFIX__
if (
typeof __PREFIX_PATHS__ !== `undefined` &&
typeof __PATH_PREFIX__ !== `undefined`
) {
if (__PREFIX_PATHS__ === true) pathPrefix = __PATH_PREFIX__
}
findPage = pageFinderFactory(newPages, pathPrefix)
},
Expand All @@ -168,9 +173,10 @@ const queue = {
addProdRequires: prodRequires => {
asyncRequires = prodRequires
},
dequeue: path => pathArray.pop(),
enqueue: path => {
dequeue: () => pathArray.pop(),
enqueue: rawPath => {
// Check page exists.
const path = stripPrefix(rawPath, pathPrefix)
if (!pages.some(p => p.path === path)) {
return false
}
Expand Down
9 changes: 9 additions & 0 deletions packages/gatsby/cache-dir/strip-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Remove a prefix from a string. Return the input string if the given prefix
* isn't found.
*/

export default (str, prefix = ``) => {
if (str.substr(0, prefix.length) === prefix) return str.slice(prefix.length)
return str
}