Skip to content

Commit

Permalink
Add support for nested routes
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrobertlloyd committed Feb 13, 2024
1 parent 48279f4 commit 86a6304
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 8 deletions.
5 changes: 4 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { join } = require('node:path')
const get = require('lodash.get')
const toPath = require('lodash.topath')

Expand Down Expand Up @@ -48,9 +49,10 @@ const getFork = (forks, req) => {
* Get path with combined search params
* @param {string} originalUrl - Original URL path
* @param {string} path - Path to add params to
* @param {string} [baseUrl] - Base URL
* @returns {string} Path with combined search params
*/
const getPathWithSearchParams = (originalUrl, path) => {
const getPathWithSearchParams = (originalUrl, path, baseUrl) => {
if (!path) {
return ''
}
Expand All @@ -64,6 +66,7 @@ const getPathWithSearchParams = (originalUrl, path) => {

// Remove query string from path
path = path.split('?')[0]
path = baseUrl ? join(baseUrl, path) : path

return pathParams.size ? `${path}?${pathParams.toString()}` : path
}
Expand Down
96 changes: 96 additions & 0 deletions test/wizard-with-base-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const assert = require('node:assert/strict')
const { describe, it } = require('node:test')
const wizard = require('../wizard.js')

describe('GOV.UK Prototype Wizard (with baseUrl)', () => {
const journey = {
'/name': {},
'/do-you-have-a-national-insurance-number': {
'/email': { data: 'have-nino', value: 'No' }
},
'/what-is-your-national-insurance-number': {},
'/email': {}
}

it('Returns current, next and previous paths', () => {
const req = {
baseUrl: '/questions',
method: 'POST',
originalUrl: '/questions/do-you-have-a-national-insurance-number',
path: '/do-you-have-a-national-insurance-number',
session: { data: { 'have-nino': 'No' } }
}

assert.deepEqual(wizard(journey, req), {
back: '/questions/name',
current: '/questions/do-you-have-a-national-insurance-number',
next: '/questions/email'
})
})

it('Returns next path with modified query string', () => {
const journey = {
'/filter/location': {},
'/list?success=1': {}
}

const req = {
baseUrl: '/results',
method: 'POST',
originalUrl: '/results/filter/location?page=2&sort=asc',
path: '/filter/location',
query: {
page: '2',
sort: 'asc'
},
session: { data: {} }
}

assert.deepEqual(wizard(journey, req), {
back: '',
current: '/results/filter/location?page=2&sort=asc',
next: '/results/list?success=1&page=2&sort=asc'
})
})

it('Adds fork data pointing back to where user forked from', () => {
const req = {
baseUrl: '/questions',
method: 'GET',
originalUrl: '/questions/email',
path: '/email',
session: {
data: {
'forked-to': '/email',
'forked-from': '/do-you-have-a-national-insurance-number'
}
}
}

assert.deepEqual(wizard(journey, req), {
back: '/questions/do-you-have-a-national-insurance-number',
current: '/questions/email',
next: ''
})
})

it('Removes fork data when returning to page that created it', () => {
const req = {
baseUrl: '/questions',
method: 'GET',
session: {
data: {
'forked-from': '/do-you-have-a-national-insurance-number',
'forked-to': '/email'
}
},
originalUrl: '/questions/do-you-have-a-national-insurance-number',
path: '/do-you-have-a-national-insurance-number'
}

wizard(journey, req)

assert.equal(req.session.data['forked-from'], undefined)
assert.equal(req.session.data['forked-to'], undefined)
})
})
13 changes: 6 additions & 7 deletions wizard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ const utils = require('./lib/utils.js')

/**
* Get next, back and current paths in user journey.
*
* @param {Object} journey - Sequence of paths in user journey
* @param {Object} req - Express request
* @returns {Object} Next and back paths
* @param {object} journey - Sequence of paths in user journey
* @param {object} req - Express request
* @returns {object} Next and back paths
*/
const wizard = (journey, req) => {
const { method, originalUrl, path, session } = req
const { baseUrl, method, originalUrl, path, session } = req
const { data } = session
const paths = Object.keys(journey)
const index = paths.indexOf(path)
Expand Down Expand Up @@ -40,8 +39,8 @@ const wizard = (journey, req) => {
}

return {
next: utils.getPathWithSearchParams(originalUrl, next),
back: utils.getPathWithSearchParams(originalUrl, back),
next: utils.getPathWithSearchParams(originalUrl, next, baseUrl),
back: utils.getPathWithSearchParams(originalUrl, back, baseUrl),
current: originalUrl
}
}
Expand Down

2 comments on commit 86a6304

@paulmsmith
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wishing for this yesterday when I discovered this nice little plugin you've created @paulrobertlloyd - Did you read my mind?

@paulrobertlloyd
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn’t read your mind, but perhaps @fofr did? It was he who originally put this plugin together – I’ve been tending to it as I push the limits of Express and find various path related bugs!

Please sign in to comment.