Skip to content

Commit

Permalink
feat(redirects): allow multiple redirects from same path when they ha…
Browse files Browse the repository at this point in the history
…ve different options (#19048)

This updates how the redirects reducer prevents duplicates so that it
allows redirects with the same fromPath when the other options are
different.
  • Loading branch information
bsonntag authored and GatsbyJS Bot committed Oct 28, 2019
1 parent 95e908e commit 84f8aea
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 5 deletions.
58 changes: 58 additions & 0 deletions packages/gatsby/src/redux/reducers/__tests__/redirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,62 @@ describe(`redirects`, () => {
])
})
})

it(`prevents duplicate redirects`, () => {
function createRedirect(fromPath, toPath) {
return {
type: `CREATE_REDIRECT`,
payload: { fromPath, toPath },
}
}

let state = reducer(undefined, createRedirect(`/page`, `/other-page`))
state = reducer(state, createRedirect(`/page`, `/other-page`))

expect(state).toEqual([
{
fromPath: `/page`,
toPath: `/other-page`,
},
])
})

it(`allows multiple redirects with same "fromPath" but different options`, () => {
function createRedirect(redirect) {
return {
type: `CREATE_REDIRECT`,
payload: redirect,
}
}

let state = reducer(
undefined,
createRedirect({
fromPath: `/page`,
toPath: `/en/page`,
Language: `en`,
})
)
state = reducer(
state,
createRedirect({
fromPath: `/page`,
toPath: `/pt/page`,
Language: `pt`,
})
)

expect(state).toEqual([
{
fromPath: `/page`,
toPath: `/en/page`,
Language: `en`,
},
{
fromPath: `/page`,
toPath: `/pt/page`,
Language: `pt`,
},
])
})
})
33 changes: 28 additions & 5 deletions packages/gatsby/src/redux/reducers/redirects.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
const fromPaths = new Set()
const _ = require(`lodash`)

const redirects = new Map()

function exists(newRedirect) {
if (!redirects.has(newRedirect.fromPath)) {
return false
}

return redirects
.get(newRedirect.fromPath)
.some(redirect => _.isEqual(redirect, newRedirect))
}

function add(redirect) {
let samePathRedirects = redirects.get(redirect.fromPath)

if (!samePathRedirects) {
samePathRedirects = []
redirects.set(redirect.fromPath, samePathRedirects)
}

samePathRedirects.push(redirect)
}

module.exports = (state = [], action) => {
switch (action.type) {
case `CREATE_REDIRECT`: {
const { fromPath } = action.payload
const redirect = action.payload

// Add redirect only if it wasn't yet added to prevent duplicates
if (!fromPaths.has(fromPath)) {
fromPaths.add(fromPath)
if (!exists(redirect)) {
add(redirect)

state.push(action.payload)
state.push(redirect)
}

return state
Expand Down

0 comments on commit 84f8aea

Please sign in to comment.