-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add additional logging for file uploads and refactor handler lo…
…gic (#1286) * refactor: refactor handleUploadRequest into a standalone handler, instead of a uploadService function. refactor prehandlers into their own directory * feat: add `showFilenamesOnSummaryPage` to formModel * fix: display previously uploaded file on file upload pages
- Loading branch information
1 parent
c25fed2
commit a0017fd
Showing
18 changed files
with
517 additions
and
176 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Feature: File upload fields | ||
|
||
Background: | ||
Given the form "files" exists | ||
And the form "files-show-filenames-enabled" exists | ||
|
||
|
||
Scenario Outline: showFilenamesOnSummaryPage shows "Uploaded" or the filename correctly on summary pages | ||
And I navigate to the "<form>" form | ||
When I upload the file "passes.png" | ||
Then I see "<summaryValue>" | ||
Examples: | ||
| form | summaryValue | | ||
| files | Uploaded | | ||
| files-show-filenames-enabled | passes.png | | ||
|
||
|
||
Scenario: Uploading a file shows "You previously uploaded" message | ||
And I navigate to the "files" form | ||
When I upload the file "passes.png" | ||
And I navigate to "/files/file-one" | ||
Then I see "You previously uploaded the file ‘passes.png’" |
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,6 @@ | ||
import { When } from "@badeball/cypress-cucumber-preprocessor"; | ||
|
||
When("I upload the file {string}", (filename) => { | ||
cy.get("input[type=file]").attachFile(filename); | ||
cy.findByRole("button", { name: /continue/i }).click(); | ||
}); |
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,48 @@ | ||
{ | ||
"startPage": "/file-one", | ||
"pages": [ | ||
{ | ||
"path": "/file-one", | ||
"components": [ | ||
{ | ||
"type": "FileUploadField", | ||
"name": "file1", | ||
"title": "File 1", | ||
"options": { | ||
"required": true | ||
}, | ||
"schema": {} | ||
} | ||
], | ||
"section": "checkBeforeYouStart", | ||
"next": [ | ||
{ | ||
"path": "/summary" | ||
} | ||
], | ||
"title": "Upload file 1" | ||
}, | ||
{ | ||
"path": "/summary", | ||
"controller": "./pages/summary.js", | ||
"title": "Summary", | ||
"components": [], | ||
"next": [] | ||
} | ||
], | ||
"lists": [], | ||
"sections": [ | ||
{ | ||
"name": "checkBeforeYouStart", | ||
"title": "Check before you start" | ||
} | ||
], | ||
"phaseBanner": {}, | ||
"fees": [], | ||
"payApiKey": "", | ||
"outputs": [], | ||
"declaration": "<p class=\"govuk-body\">All the answers you have provided are true to the best of your knowledge.</p>", | ||
"version": 2, | ||
"conditions": [], | ||
"showFilenamesOnSummaryPage": true | ||
} |
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 @@ | ||
{ | ||
"startPage": "/file-one", | ||
"pages": [ | ||
{ | ||
"path": "/file-one", | ||
"components": [ | ||
{ | ||
"type": "FileUploadField", | ||
"name": "file1", | ||
"title": "File 1", | ||
"options": { | ||
"required": true | ||
}, | ||
"schema": {} | ||
} | ||
], | ||
"section": "checkBeforeYouStart", | ||
"next": [ | ||
{ | ||
"path": "/summary" | ||
} | ||
], | ||
"title": "Upload file 1" | ||
}, | ||
{ | ||
"path": "/summary", | ||
"controller": "./pages/summary.js", | ||
"title": "Summary", | ||
"components": [], | ||
"next": [] | ||
} | ||
], | ||
"lists": [], | ||
"sections": [ | ||
{ | ||
"name": "checkBeforeYouStart", | ||
"title": "Check before you start" | ||
} | ||
], | ||
"phaseBanner": {}, | ||
"fees": [], | ||
"payApiKey": "", | ||
"outputs": [], | ||
"declaration": "<p class=\"govuk-body\">All the answers you have provided are true to the best of your knowledge.</p>", | ||
"version": 2, | ||
"conditions": [] | ||
} |
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
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
18 changes: 18 additions & 0 deletions
18
runner/src/server/plugins/engine/pluginHandlers/files/prehandlers/getFiles.ts
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,18 @@ | ||
import { HapiRequest, HapiResponseToolkit } from "server/types"; | ||
|
||
/** | ||
* Prehandler that parses the payload and finds Buffers (i.e. files). | ||
*/ | ||
export function getFiles(request: HapiRequest, _h: HapiResponseToolkit) { | ||
const { uploadService } = request.services([]); | ||
const files = uploadService.fileStreamsFromPayload(request.payload); | ||
if (files.length) { | ||
request.server.logger.info( | ||
{ id: request.yar.id, path: request.path }, | ||
`Found ${uploadService.fileSummary(files)} to process on ${request.path}` | ||
); | ||
return files; | ||
} | ||
|
||
return null; | ||
} |
119 changes: 119 additions & 0 deletions
119
runner/src/server/plugins/engine/pluginHandlers/files/prehandlers/handleUpload.ts
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,119 @@ | ||
import { HapiRequest, HapiResponseToolkit } from "server/types"; | ||
|
||
const parsedError = (key: string, error?: string) => { | ||
return { | ||
path: key, | ||
href: `#${key}`, | ||
name: key, | ||
text: error, | ||
}; | ||
}; | ||
|
||
export async function handleUpload( | ||
request: HapiRequest, | ||
h: HapiResponseToolkit | ||
) { | ||
const { cacheService, uploadService } = request.services([]); | ||
const state = await cacheService.getState(request); | ||
let originalFilenames = state?.originalFilenames ?? {}; | ||
let logger = request.server.logger; | ||
const files = request.pre.files; | ||
|
||
if (!files) { | ||
return h.continue; | ||
} | ||
|
||
/** | ||
* files is an array of tuples containing key and value. | ||
* value may be an array of file data where multiple files have been uploaded | ||
*/ | ||
const validFiles = request.pre.validFiles; | ||
|
||
for (const entry of validFiles) { | ||
const [fieldName, streams] = entry; | ||
const loggerIdentifier = uploadService.getLoggerIdentifier(request, { | ||
fieldName, | ||
}); | ||
const previousUpload = originalFilenames[fieldName]; | ||
|
||
if (previousUpload) { | ||
logger.info( | ||
loggerIdentifier, | ||
`User is attempting to overwrite ${fieldName} with location ${previousUpload.location}` | ||
); | ||
} | ||
|
||
let response; | ||
|
||
try { | ||
response = await uploadService.uploadDocuments(streams); | ||
} catch (err) { | ||
if (err.data?.res) { | ||
const { error } = uploadService.parsedDocumentUploadResponse(err.data); | ||
request.pre.errors = [ | ||
...request.pre.errors, | ||
parsedError(fieldName, error), | ||
]; | ||
} else if (err.code === "EPIPE") { | ||
// ignore this error, it happens when the request is responded to by the doc upload service before the | ||
// body has finished being sent. A valid response is still received. | ||
logger.warn(loggerIdentifier, `Ignoring EPIPE response ${err.message}`); | ||
} else { | ||
logger.error( | ||
{ ...loggerIdentifier, err }, | ||
`Error uploading document: ${err.message}` | ||
); | ||
request.pre.errors = [ | ||
...(h.request.pre.errors || []), | ||
parsedError(fieldName, err), | ||
]; | ||
} | ||
} | ||
|
||
const { location, warning, error } = response; | ||
|
||
if (location) { | ||
const originalFilename = streams | ||
.map((stream) => stream.hapi?.filename) | ||
.join(", "); | ||
|
||
logger.info( | ||
loggerIdentifier, | ||
`Uploaded ${fieldName} successfully to ${location}` | ||
); | ||
|
||
originalFilenames[fieldName] = { location, originalFilename }; | ||
const { | ||
originalFilenames: updatedFilenames, | ||
} = await cacheService.mergeState(request, { originalFilenames }); | ||
|
||
logger.info( | ||
{ ...loggerIdentifier, allFiles: updatedFilenames }, | ||
`Updated originalFileNames for user` | ||
); | ||
request.payload[fieldName] = location; | ||
originalFilenames = updatedFilenames; | ||
} | ||
|
||
if (warning) { | ||
request.pre.warning = warning; | ||
logger.warn( | ||
loggerIdentifier, | ||
`File was uploaded successfully but there was a warning ${warning}` | ||
); | ||
} | ||
|
||
if (error) { | ||
logger.error( | ||
loggerIdentifier, | ||
`Document upload API responded with an error ${error}` | ||
); | ||
request.pre.errors = [ | ||
...(request.pre.errors || []), | ||
parsedError(fieldName, error), | ||
]; | ||
} | ||
} | ||
|
||
return h.continue; | ||
} |
3 changes: 3 additions & 0 deletions
3
runner/src/server/plugins/engine/pluginHandlers/files/prehandlers/index.ts
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,3 @@ | ||
export { getFiles } from "./getFiles"; | ||
export { validateContentTypes } from "./validateContentTypes"; | ||
export { handleUpload } from "./handleUpload"; |
Oops, something went wrong.