Skip to content

Commit

Permalink
Merge pull request #8 from digital-land/inputChecks
Browse files Browse the repository at this point in the history
Input checks
  • Loading branch information
GeorgeGoodall authored Nov 13, 2023
2 parents 07bece2 + 2db1302 commit 02c7164
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 46 deletions.
3 changes: 2 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint
npm run lint:fix
npm run lint
46 changes: 28 additions & 18 deletions src/controllers/uploadController.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,40 @@ class UploadController extends Controller {
}

async post (req, res, next) {
if (req.file !== undefined) {
try {
const jsonResult = await this.validateFile({
filePath: req.file.path,
fileName: req.file.originalname,
dataset: req.sessionModel.get('dataset'),
dataSubject: req.sessionModel.get('data-subject'),
organization: 'mockOrg'
})
req.body.validationResult = jsonResult
} catch (error) {
console.log(error)
}
}
super.post(req, res, next)
}

async validateFile ({ filePath, fileName, dataset, dataSubject, organization }) {
const formData = new FormData()
formData.append('dataset', req.sessionModel.get('dataset'))
formData.append('collection', req.sessionModel.get('data-subject'))
formData.append('organization', 'mockOrg')
formData.append('dataset', dataset)
formData.append('collection', dataSubject)
formData.append('organization', organization)

const filePath = req.file.path
const file = new Blob([await readFile(filePath)], { type: lookup(filePath) })

formData.append('upload_file', file, req.file.originalname)
formData.append('upload_file', file, fileName)

try {
// post the data to the api
const result = await fetch(apiRoute, {
method: 'POST',
body: formData
})
// post the data to the api
const result = await fetch(apiRoute, {
method: 'POST',
body: formData
})

const json = await result.json()

req.sessionModel.set('validationResult', json)
super.post(req, res, next)
} catch (e) {
res.send(e)
}
return await result.json()
}
}

Expand Down
1 change: 1 addition & 0 deletions src/routes/form-wizard/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
},
'/upload': {
controller: require('../../controllers/uploadController'),
fields: ['validationResult'],
next: 'errors'
},
'/errors': {
Expand Down
35 changes: 34 additions & 1 deletion src/views/data-subject.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,28 @@
{% from 'govuk/components/back-link/macro.njk' import govukBackLink %}
{% from 'govuk/components/button/macro.njk' import govukButton %}
{% from 'govuk/components/radios/macro.njk' import govukRadios %}
{% from 'govuk/components/error-message/macro.njk' import govukErrorMessage %}
{% from 'govuk/components/error-summary/macro.njk' import govukErrorSummary %}



{% set pageName = 'Data subject' %}

{% set errorMessage = 'Please select a data subject' %}

{% if 'data-subject' in errors %}
{% set dataSubjectError = true %}
{% endif %}

{% block pageTitle %}
{% if dataSubjectError %}
Error: {{super()}}
{% else %}
{{super()}}
{% endif %}
{% endblock %}


{% block beforeContent %}
{{ govukBackLink({
text: "Back",
Expand All @@ -16,6 +35,17 @@
{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
{% if dataSubjectError %}
{{ govukErrorSummary({
titleText: "There is a problem",
errorList: [
{
text: errorMessage,
href: "#data-subject"
}
]
}) }}
{% endif %}
<form novalidate method="post">

{{ govukRadios({
Expand Down Expand Up @@ -46,7 +76,10 @@
text: "Tree preservation order"
}
],
value: data.check.dataSubject
value: data.check.dataSubject,
errorMessage: {
text: errorMessage
} if dataSubjectError else undefined
}) }}

{{ govukButton({
Expand Down
77 changes: 54 additions & 23 deletions src/views/dataset.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,26 @@
{% from 'govuk/components/back-link/macro.njk' import govukBackLink %}
{% from 'govuk/components/button/macro.njk' import govukButton %}
{% from 'govuk/components/radios/macro.njk' import govukRadios %}
{% from 'govuk/components/error-message/macro.njk' import govukErrorMessage %}
{% from 'govuk/components/error-summary/macro.njk' import govukErrorSummary %}

{% set pageName = 'Dataset' %}

{% set errorMessage = 'Please select a dataset' %}


{% if 'dataset' in errors %}
{% set datasetError = true %}
{% endif %}

{% block pageTitle %}
{% if datasetError %}
Error: {{super()}}
{% else %}
{{super()}}
{% endif %}
{% endblock %}

{% block beforeContent %}
{{ govukBackLink({
text: "Back",
Expand All @@ -13,28 +30,42 @@
{% endblock %}

{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<form novalidate method="post">

{{ govukRadios({
idPrefix: "dataset",
name: "dataset",
fieldset: {
legend: {
text: pageName,
isPageHeading: true,
classes: "govuk-fieldset__legend--l"
}
},
items: options.datasetItems,
value: data.check.dataset
}) }}

{{ govukButton({
text: "Continue"
}) }}
</form>
</div>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
{% if datasetError %}
{{ govukErrorSummary({
titleText: "There is a problem",
errorList: [
{
text: errorMessage,
href: "#dataset"
}
]
}) }}
{% endif %}
<form novalidate method="post">

{{ govukRadios({
idPrefix: "dataset",
name: "dataset",
fieldset: {
legend: {
text: pageName,
isPageHeading: true,
classes: "govuk-fieldset__legend--l"
}
},
items: options.datasetItems,
value: data.check.dataset,
errorMessage: {
text: errorMessage
} if datasetError else undefined
}) }}

{{ govukButton({
text: "Continue"
}) }}
</form>
</div>
</div>
{% endblock %}
Empty file.
34 changes: 33 additions & 1 deletion src/views/upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,27 @@
{% from "govuk/components/back-link/macro.njk" import govukBackLink %}
{% from "govuk/components/file-upload/macro.njk" import govukFileUpload %}
{% from "govuk/components/button/macro.njk" import govukButton %}
{% from 'govuk/components/error-message/macro.njk' import govukErrorMessage %}
{% from 'govuk/components/error-summary/macro.njk' import govukErrorSummary %}


{% set pageName = 'Upload data' %}

{% set errorMessage = 'Please select a file' %}


{% if 'validationResult' in errors %}
{% set datasetError = true %}
{% endif %}

{% block pageTitle %}
{% if datasetError %}
Error: {{super()}}
{% else %}
{{super()}}
{% endif %}
{% endblock %}

{% block beforeContent %}
{{ govukBackLink({
text: "Back",
Expand All @@ -16,6 +34,17 @@
{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
{% if datasetError %}
{{ govukErrorSummary({
titleText: "There is a problem",
errorList: [
{
text: errorMessage,
href: "#datafile"
}
]
}) }}
{% endif %}
<form novalidate method="post" enctype="multipart/form-data">

{{ govukFileUpload({
Expand All @@ -28,7 +57,10 @@
},
hint: {
text: "You can upload a CSV, GeoJSON, GML or Geopackage file"
}
},
errorMessage: {
text: errorMessage
} if datasetError else undefined
}) }}
{{ govukButton({
text: "Continue"
Expand Down
82 changes: 82 additions & 0 deletions test/acceptance/validation_errors.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { test, expect } from '@playwright/test'

test('when the user clicks continue on the data subject page without entering a data subject, the page correctly indicates there\'s an error', async ({ page }) => {
await page.goto('/')
await page.getByRole('button', { name: 'Start now' }).click()
await page.getByRole('button', { name: 'Continue' }).click()

await page.waitForSelector('input#data-subject.govuk-radios__input')

const errorLink = await page.getByRole('link', { name: 'Please select a data subject' })
const fieldError = await page.getByText('Error: Please select a data subject')
const errorSummary = await page.getByText('There is a problem')

expect(await errorSummary.isVisible(), 'Page should show the error summary').toBeTruthy()
expect(await errorLink.isVisible(), 'Page should the error message that is a link to the problem field').toBeTruthy()
expect(await fieldError.isVisible(), 'Page should show the error message next to the problem field').toBeTruthy()
await errorLink.click()
const problemFieldIsFocused = await page.$eval('input#data-subject.govuk-radios__input', (el) => el === document.activeElement)
expect(problemFieldIsFocused, 'The focus should be on the problem field').toBeTruthy()

expect(await page.title(), 'Page title should indicate there\'s an error').toMatch(/Error: .*/)
})

test('when the user clicks continue on the dataset page without entering a dataset, the page correctly indicates there\'s an error', async ({ page }) => {
await page.goto('/')
// start page
await page.getByRole('button', { name: 'Start now' }).click()

// data subject page
await page.getByLabel('Conservation area').check()
await page.getByRole('button', { name: 'Continue' }).click()

// dataset page
await page.getByRole('button', { name: 'Continue' }).click()

await page.waitForSelector('input#dataset.govuk-radios__input')

const errorLink = await page.getByRole('link', { name: 'Please select a dataset' })
const fieldError = await page.getByText('Error: Please select a dataset')
const errorSummary = await page.getByText('There is a problem')

expect(await errorSummary.isVisible(), 'Page should show the error summary').toBeTruthy()
expect(await errorLink.isVisible(), 'Page should the error message that is a link to the problem field').toBeTruthy()
expect(await fieldError.isVisible(), 'Page should show the error message next to the problem field').toBeTruthy()
await errorLink.click()
const problemFieldIsFocused = await page.$eval('input#dataset.govuk-radios__input', (el) => el === document.activeElement)
expect(problemFieldIsFocused, 'The focus should be on the problem field').toBeTruthy()

expect(await page.title(), 'Page title should indicate there\'s an error').toMatch(/Error: .*/)
})

test('when the user clicks continue on the file upload page without selecting a file, the page correctly indicates there\'s an error', async ({ page }) => {
await page.goto('/')
// start page
await page.getByRole('button', { name: 'Start now' }).click()

// data subject page
await page.getByLabel('Conservation area').check()
await page.getByRole('button', { name: 'Continue' }).click()

// dataset page
await page.getByLabel('Conservation area dataset').check()
await page.getByRole('button', { name: 'Continue' }).click()

// file upload page
await page.getByRole('button', { name: 'Continue' }).click()
await page.waitForSelector('input#datafile.govuk-file-upload')

const errorLink = await page.getByRole('link', { name: 'Please select a file' })
const fieldError = await page.getByText('Error: Please select a file')
const errorSummary = await page.getByText('There is a problem')

expect(await errorSummary.isVisible(), 'Page should show the error summary').toBeTruthy()
expect(await errorLink.isVisible(), 'Page should the error message that is a link to the problem field').toBeTruthy()
expect(await fieldError.isVisible(), 'Page should show the error message next to the problem field').toBeTruthy()
await errorLink.click()

const problemFieldIsFocused = await page.$eval('input#datafile.govuk-file-upload', (el) => el === document.activeElement)
expect(problemFieldIsFocused, 'The focus should be on the problem field').toBeTruthy()

expect(await page.title(), 'Page title should indicate there\'s an error').toMatch(/Error: .*/)
})
5 changes: 3 additions & 2 deletions test/unit/uploadController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ describe('UploadController', () => {
sessionModel: {
get: () => 'test',
set: vi.fn()
}
},
body: {}
}
const res = {
send: vi.fn(),
Expand All @@ -34,6 +35,6 @@ describe('UploadController', () => {

await uploadController.post(req, res, next)

expect(req.sessionModel.set).toHaveBeenCalledWith('validationResult', mockApiValue)
expect(req.body.validationResult).toEqual(mockApiValue)
})
})

0 comments on commit 02c7164

Please sign in to comment.