Skip to content

Commit

Permalink
SIR-932 : Story – Odour – Remit - Can you give details about the sour…
Browse files Browse the repository at this point in the history
…ce of the smell? (#175)

* Technical implementation for SIR-932

* fixing flakey date test

* Fixed sonar issue

* Fixed lint issue

* Fixed sonar issue

---------

Co-authored-by: Tedd Mason <teddmason@gmail.com>
  • Loading branch information
sujithvg and teddmason committed Sep 17, 2024
1 parent da0fdc2 commit 15e50c2
Show file tree
Hide file tree
Showing 6 changed files with 393 additions and 10 deletions.
160 changes: 160 additions & 0 deletions server/routes/__tests__/smell/source-details.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { submitGetRequest, submitPostRequest } from '../../../__test-helpers__/server.js'
import { questionSets } from '../../../utils/question-sets.js'
import constants from '../../../utils/constants.js'

const url = constants.routes.SMELL_SOURCE_DETAILS
const question = questionSets.SMELL.questions.SMELL_SOURCE_DETAILS
const header = question.text
const baseAnswer = {
questionId: question.questionId,
questionAsked: question.text,
questionResponse: true
}

const payload = {
answerId: 'yes',
siteName: 'Site name',
sourceAddress: 'Address Line',
sourceTown: 'town or city',
sourcePostcode: 'WA4 1HT'
}

describe(url, () => {
describe('GET', () => {
it(`Should return success response and correct view for ${url}`, async () => {
await submitGetRequest({ url }, header)
})
})

describe('POST', () => {
it('Happy: accepts valid answerId no and redirects to smell/contact-local-council', async () => {
const answerId = 'no'
const options = {
url,
payload: {
answerId
}
}
const response = await submitPostRequest(options)
expect(response.headers.location).toEqual(constants.routes.SMELL_CONTACT_LOCAL_COUNCIL)
})

// Happy: Accepts a complete address
it('Happy: accepts valid answerId yes and complete address with valid postcode', async () => {
const options = {
url,
payload
}
const response = await submitPostRequest(options)
expect(response.headers.location).toEqual(constants.routes.SMELL_LOCATION_HOME)
expect(response.request.yar.get(constants.redisKeys.SMELL_SOURCE_DETAILS)).toEqual([{
...baseAnswer,
answerId: question.answers.siteName.answerId,
otherDetails: payload.siteName
}, {
...baseAnswer,
answerId: question.answers.sourceAddress.answerId,
otherDetails: payload.sourceAddress
}, {
...baseAnswer,
answerId: question.answers.sourceTown.answerId,
otherDetails: payload.sourceTown
}, {
...baseAnswer,
answerId: question.answers.sourcePostcode.answerId,
otherDetails: payload.sourcePostcode
}])
})
// Happy: Accepts a partial address, but with complete mandatory fields
it('Happy: accepts valid answerId yes and complete address with valid postcode', async () => {
const partialPayload = JSON.parse(JSON.stringify(payload))
partialPayload.sourceAddress = ''

const options = {
url,
payload: partialPayload
}
const response = await submitPostRequest(options)
expect(response.headers.location).toEqual(constants.routes.SMELL_LOCATION_HOME)
expect(response.request.yar.get(constants.redisKeys.SMELL_SOURCE_DETAILS)).toEqual([{
...baseAnswer,
answerId: question.answers.siteName.answerId,
otherDetails: payload.siteName
}, {
...baseAnswer,
answerId: question.answers.sourceAddress.answerId,
otherDetails: ''
}, {
...baseAnswer,
answerId: question.answers.sourceTown.answerId,
otherDetails: payload.sourceTown
}, {
...baseAnswer,
answerId: question.answers.sourcePostcode.answerId,
otherDetails: payload.sourcePostcode
}])
})
it('Happy: accepts valid answerId yes and strips out postcode with special characters', async () => {
const partialPayload = JSON.parse(JSON.stringify(payload))
partialPayload.sourcePostcode = 'WA4 &^%$%$--1HT'

const options = {
url,
payload: partialPayload
}
const response = await submitPostRequest(options)
expect(response.headers.location).toEqual(constants.routes.SMELL_LOCATION_HOME)
expect(response.request.yar.get(constants.redisKeys.SMELL_SOURCE_DETAILS)).toEqual([{
...baseAnswer,
answerId: question.answers.siteName.answerId,
otherDetails: payload.siteName
}, {
...baseAnswer,
answerId: question.answers.sourceAddress.answerId,
otherDetails: payload.sourceAddress
}, {
...baseAnswer,
answerId: question.answers.sourceTown.answerId,
otherDetails: payload.sourceTown
}, {
...baseAnswer,
answerId: question.answers.sourcePostcode.answerId,
otherDetails: 'WA4 1HT'
}])
})
it('Sad: errors on no fields provided', async () => {
const options = {
url,
payload: {}
}
const response = await submitPostRequest(options, constants.statusCodes.OK)
expect(response.payload).toContain('There is a problem')
expect(response.payload).toContain('Answer yes if you can give details about where the smell is coming from')
})
it('Sad: valid answerId yes but errors on no fields provided', async () => {
const options = {
url,
payload: {
answerId: 'yes'
}
}
const response = await submitPostRequest(options, constants.statusCodes.OK)
expect(response.payload).toContain('There is a problem')
expect(response.payload).toContain('Enter a name')
expect(response.payload).toContain('Enter a town or city')
expect(response.payload).toContain('Enter a postcode')
})
it('Sad: errors on invalid postcode provided', async () => {
const options = {
url,
payload: {
...payload,
sourcePostcode: 'sdgfsfdgfdsgfdg'
}
}
const response = await submitPostRequest(options, constants.statusCodes.OK)
expect(response.payload).toContain('There is a problem')
expect(response.payload).toContain('Enter a full UK postcode')
})
})
})
3 changes: 2 additions & 1 deletion server/routes/__tests__/smell/start-date-time.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,15 @@ describe(url, () => {
it('Happy: accept a valid time for today and continue to SMELL_CURRENT', async () => {
const date = new Date()
const period = date.getHours() > 11 ? 'pm' : 'am'
const hours = date.getHours() > 12 ? date.getHours() - 12 : date.getHours()
const options = {
url,
payload: {
current: '0',
'date-day': '1',
'date-month': '1',
'date-year': '2024',
hour: [date.getHours().toString(), '1', '1'],
hour: [hours.toString(), '1', '1'],
minute: ['0', '1', '1'],
period: [period, 'am', 'am']
}
Expand Down
117 changes: 116 additions & 1 deletion server/routes/smell/source-details.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,130 @@
import constants from '../../utils/constants.js'
import { getErrorSummary } from '../../utils/helpers.js'
import { questionSets } from '../../utils/question-sets.js'

const question = questionSets.SMELL.questions.SMELL_SOURCE_DETAILS
const postcodeRegExp = /^([A-Za-z][A-Ha-hJ-Yj-y]?\d[A-Za-z0-9]? ?\d[A-Za-z]{2}|[Gg][Ii][Rr] ?0[Aa]{2})$/ // https://stackoverflow.com/a/51885364

const baseAnswer = {
questionId: question.questionId,
questionAsked: question.text,
questionResponse: true
}

const handlers = {
get: async (_request, h) => {
return h.view(constants.views.SMELL_SOURCE_DETAILS)
return h.view(constants.views.SMELL_SOURCE_DETAILS, {
...getContext()
})
},
post: async (request, h) => {
// cleanse postcode for special characters https://design-system.service.gov.uk/patterns/addresses/#allow-different-postcode-formats
if (request.payload.sourcePostcode) {
request.payload.sourcePostcode = request.payload.sourcePostcode.replace(/[^\w\s]/gi, '')
}

// validate payload for errors
const errorSummary = validatePayload(request.payload)
if (errorSummary.errorList.length > 0) {
return h.view(constants.views.SMELL_SOURCE_DETAILS, {
...getContext(),
errorSummary,
...request.payload,
yesChecked: request.payload.answerId === 'yes'
})
}

// handle redirects
if (request.payload.answerId === 'yes') {
// set answer in session
request.yar.set(constants.redisKeys.SMELL_SOURCE_DETAILS, buildAnswers(request.payload))
return h.redirect(constants.routes.SMELL_LOCATION_HOME)
} else if (request.payload.answerId === 'no') {
return h.redirect(constants.routes.SMELL_CONTACT_LOCAL_COUNCIL)
} else {
// do nothing
}

return null
}
}

const getContext = () => {
return {
question
}
}

const validatePayload = payload => {
const errorSummary = getErrorSummary()
if (!payload.answerId) {
errorSummary.errorList.push({
text: 'Answer yes if you can give details about where the smell is coming from',
href: '#answerId'
})
} else if (payload.answerId === 'yes') {
if (!payload.siteName) {
errorSummary.errorList.push({
text: 'Enter a name',
href: '#siteName'
})
}
if (!payload.sourceTown) {
errorSummary.errorList.push({
text: 'Enter a town or city',
href: '#sourceTown'
})
}
if (!payload.sourcePostcode) {
errorSummary.errorList.push({
text: 'Enter a postcode',
href: '#sourcePostcode'
})
} else if (!postcodeRegExp.test(payload.sourcePostcode)) {
errorSummary.errorList.push({
text: 'Enter a full UK postcode',
href: '#sourcePostcode'
})
} else {
// do nothing
}
} else {
// do nothing
}

return errorSummary
}

const buildAnswers = payload => {
return [{
...baseAnswer,
answerId: question.answers.siteName.answerId,
otherDetails: payload.siteName
}, {
...baseAnswer,
answerId: question.answers.sourceAddress.answerId,
otherDetails: payload.sourceAddress
}, {
...baseAnswer,
answerId: question.answers.sourceTown.answerId,
otherDetails: payload.sourceTown
},
{
...baseAnswer,
answerId: question.answers.sourcePostcode.answerId,
otherDetails: payload.sourcePostcode
}]
}

export default [
{
method: 'GET',
path: constants.routes.SMELL_SOURCE_DETAILS,
handler: handlers.get
},
{
method: 'POST',
path: constants.routes.SMELL_SOURCE_DETAILS,
handler: handlers.post
}
]
1 change: 1 addition & 0 deletions server/routes/smell/source.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const handlers = {
// set answer in session
request.yar.set(constants.redisKeys.SMELL_SOURCE, buildAnswers(answerId))

// handle redirects
if (answerId === question.answers.local.answerId || answerId === question.answers.neighbour.answerId || answerId === question.answers.rubbish.answerId) {
return h.redirect(constants.routes.SMELL_REPORT_LOCAL_COUNCIL)
} else if (answerId === question.answers.unknown.answerId) {
Expand Down
23 changes: 23 additions & 0 deletions server/utils/question-sets.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,29 @@ const questionSets = {
}
}
},
SMELL_SOURCE_DETAILS: {
questionId: 200,
key: constants.redisKeys.SMELL_SOURCE_DETAILS,
text: 'Can you give details about where the smell is coming from?',
answers: {
siteName: {
answerId: 203,
text: 'Name of person or site'
},
sourceAddress: {
answerId: 204,
text: 'Street name and number (if known)'
},
sourceTown: {
answerId: 205,
text: 'Town or city'
},
sourcePostcode: {
answerId: 205,
text: 'Postcode (if known)'
}
}
},
SMELL_LOCATION_HOME: {
questionId: 1,
key: constants.redisKeys.SMELL_LOCATION_HOME,
Expand Down
Loading

0 comments on commit 15e50c2

Please sign in to comment.