-
Notifications
You must be signed in to change notification settings - Fork 334
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
Organise review app middleware #3223
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR description mentions unit testing as a rationale for the change – would it make sense for us to add unit tests for these files as we go?
Generally when code is moved around I find it a lot easier to review if the moves happen in a separate commit with minimal other changes.
const BANNER_COOKIE_NAME = 'dismissed-app-banner' | ||
|
||
module.exports = function (app) { | ||
// Detect if banner should be shown based on cookies set | ||
app.use(cookieParser()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we split this change out into a separate commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Done
app/common/middleware/request.js
Outdated
cookies(), | ||
|
||
// Turn form POSTs into data that can be used for validation | ||
express.urlencoded({ extended: true }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we split this change out into a separate commit?
It looks like we no longer need body-parser
because the functionality is now built into express – is that right? Would be good to capture in the commit message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Done
It looks like we no longer need body-parser because the functionality is now built into express – is that right?
Yeah, the express.urlencoded()
middleware was added to Express.js in v4.16.0
https://expressjs.com/en/api.html#express.urlencoded
app/common/middleware/locals.js
Outdated
* Legacy query handling | ||
*/ | ||
const locals = (req, res, next) => { | ||
res.locals.legacy = ['1', 'true'].includes(req.query.legacy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also consider splitting this refactor out into a separate commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Done
I've configured Express.js with the standard URLSearchParams()
too ready for Express.js v5
const { query } = req
// Check for query
query.has('example')
// Get query value
query.get(example')
// Set query value
query.set('example', 'value')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that because of the change of the default query parser to simple
?
I think the simple query parser would still work for our use case as we're not doing anything fancy with nested params etc. Do you think there's advantages to using URLSearchParams
over it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I remember that, there was a security vulnerability wasn't there
Primarily because we've now got the WHATWG URL and Fetch standards so it's all in Node.js too:
Query to string
// 'example1=value1&example2=value2'
req.query.toString()
Query to object
// { example1: 'value1', example2: 'value2' }
Object.fromEntries(req.query)
Query via URL object
const url = new URL('http://localhost')
url.search = '?example1=value1&example2=value2'
url.searchParams.get('example1') // 'value1'
url.searchParams.get('example2') // 'value2'
Express.js has said they'll also switch in future
expressjs/express#4990 (comment)
Happy to put it back to objects again
app/common/middleware/request.js
Outdated
/** | ||
* Request handling | ||
*/ | ||
const request = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not 100% sure about this file as it's just bringing in middleware from dependencies?
Could we just include these in middleware/index.js
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's an option too
I'll explain my thinking in terms of testing GET or POST requests:
HTTP GET request
- Cookies are added to
req.cookies
- Form submission
req.body
empty
HTTP POST request
- Cookies are added to
req.cookies
- Form submission
req.body
populated
We're left with a nice way to test everything "HTTP request related" in one middleware
Hypothetically you'd put things like Content-Encoding gzip
and application/json
handling here too
import compression from 'compression'
export const request = [
compression(),
express.json(),
express.urlencoded({
extended: true
})
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added tests for this
@36degrees Sounds good One commit per middleware, with a basic test per commit? Thanks for taking a look |
08cf40f
to
38d8d14
Compare
Sounds sensible 👍🏻 Doesn't have to be strict though – the main thing for me is to try and avoid moving and changing code in the same commit as it makes it harder to review. |
2c94598
to
5f2bf41
Compare
@36degrees Tests added which found a few broken things Let me know if you want them on a separate PR
|
@@ -338,21 +338,21 @@ describe(`http://localhost:${PORT}/full-page-examples/`, () => { | |||
const body = await response.text() | |||
const $ = cheerio.load(body) | |||
// Check the results are correct | |||
expect($.html()).toContain('822,411 results') | |||
expect($.html()).toContain('121,842 results') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were building the seed string with:
// 'most-viewedundefinedundefined'
const seed = order + brexit + organisation
So these are newly-shuffled random totals using the query string instead:
// 'order=most-viewed'
const seed = query.toString()
|
||
// Make the total more readable | ||
total: Number(randomizedTotal) | ||
.toLocaleString('en', { useGrouping: true }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where useGrouping
(in en locale) adds commas to numbers
} | ||
] | ||
], | ||
values: values["organisation"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@36degrees Your nice feature definitely saved a lot of code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tidy 👍🏻 Great to have those tests!
The `express.urlencoded()` middleware was added to Express.js in v4.16.0 https://expressjs.com/en/api.html#express.urlencoded
From the URL web standard https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
Consolidates request body and cookie parsing
The query `?legacy=true` is lost when clicking back
They were out of sync with the JavaScript and didn’t update correctly via query string
Include search text input and sort options in form so they’re submitted when the button is pressed
5f2bf41
to
e7cf0b2
Compare
We started organising our middleware into small exports for unit testing in 807f533
This PR adds a few more whilst I was working on the code