Skip to content

Commit

Permalink
Merge pull request #51 from DEFRA/DSFAAP-577
Browse files Browse the repository at this point in the history
DSFAAP-577: filter payload in answer model
  • Loading branch information
hughfdjackson authored Dec 6, 2024
2 parents df5f042 + e45c251 commit 0d2bac6
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 33 deletions.
16 changes: 16 additions & 0 deletions src/server/common/model/answer/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ export class Address extends AnswerModel {
return validateAnswerAgainstSchema(addressPayloadSchema, this._data ?? {})
}

_extractFields({
addressLine1,
addressLine2,
addressTown,
addressCounty,
addressPostcode
}) {
return {
addressLine1,
...(addressLine2 !== undefined && { addressLine2 }),
addressTown,
...(addressCounty !== undefined && { addressCounty }),
addressPostcode
}
}

/**
* @param {AddressData | undefined} state
* @returns {Address}
Expand Down
20 changes: 20 additions & 0 deletions src/server/common/model/answer/address.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@ const validAddress = {
addressPostcode: 'RG24 8RR'
}

describe('Address.new', () => {
it('should strip away any irrelevant values', () => {
const payload = { ...validAddress, nextPage: '/other/page' }
const address = new Address(payload)

expect(address._data).toEqual(validAddress)
})

it('should graceully handle optional values', () => {
const validAddressWithOptionalsMissing = {
addressLine1: validAddress.addressLine1,
addressTown: validAddress.addressTown,
addressPostcode: validAddress.addressPostcode
}
const address = new Address(validAddressWithOptionalsMissing)

expect(address._data).toEqual(validAddressWithOptionalsMissing)
})
})

describe('Address.validate', () => {
it('should return true for valid address', () => {
const address = new Address(validAddress)
Expand Down
16 changes: 11 additions & 5 deletions src/server/common/model/answer/answer-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class AnswerModel {
* @param {Payload | undefined } [data]
*/
constructor(data) {
this._data = data
this._data = data === undefined ? undefined : this._extractFields(data)
Object.seal(this)
}

Expand All @@ -35,6 +35,15 @@ export class AnswerModel {
throw new NotImplementedError()
}

/**
* @param {Payload} _data
* @returns {Payload}
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_extractFields(_data) {
throw new NotImplementedError()
}

/**
* @returns {AnswerValidationResult}
*/
Expand All @@ -47,17 +56,14 @@ export class AnswerModel {
throw new NotImplementedError()
}

/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* @param {unknown} _data
* @returns {unknown}
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static fromState(_data) {
throw new NotImplementedError()
}

/* eslint-enable @typescript-eslint/no-unused-vars */
}

/**
Expand Down
7 changes: 6 additions & 1 deletion src/server/common/model/answer/answer-model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ describe('AnswerModel', () => {
})

it('should seal the object to prevent property additions or deletions', () => {
answer = new AnswerModel({ key: 'value' })
class AnswerModelBasic extends AnswerModel {
_extractFields(data) {
return data
}
}
answer = new AnswerModelBasic({ key: 'value' })

expect(() => {
answer.something = 'should fail'
Expand Down
4 changes: 4 additions & 0 deletions src/server/common/model/answer/confirmation/confirmation.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export class Confirmation extends AnswerModel {
})
}

_extractFields({ confirmation }) {
return { confirmation }
}

/**
* @param {ConfirmationData | undefined} state
* @returns {Confirmation}
Expand Down
11 changes: 11 additions & 0 deletions src/server/common/model/answer/confirmation/confirmation.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { Confirmation } from './confirmation.js'

describe('#ConfirmationModel', () => {
describe('Confirmation.new', () => {
it('should strip away any irrelevant values', () => {
const validConfirmation = { confirmation: ['confirm', 'other'] }

const payload = { ...validConfirmation, nextPage: '/other/page' }
const confirmation = new Confirmation(payload)

expect(confirmation._data).toEqual(validConfirmation)
})
})

describe('validate', () => {
it('should return valid when only confirmed', () => {
const confirmation = new Confirmation({ confirmation: ['confirm'] })
Expand Down
4 changes: 4 additions & 0 deletions src/server/common/model/answer/cph-number.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export class CphNumber extends AnswerModel {
return validateAnswerAgainstSchema(cphNumberPayloadSchema, this._data ?? {})
}

_extractFields({ cphNumber }) {
return { cphNumber }
}

/**
* @param {CphNumberData | undefined} state
* @returns {CphNumber}
Expand Down
9 changes: 9 additions & 0 deletions src/server/common/model/answer/cph-number.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ const validCphNumberPayload = {
cphNumber: '12/456/7899'
}

describe('CphNumber.new', () => {
it('should strip away any irrelevant values', () => {
const payload = { ...validCphNumberPayload, nextPage: '/other/page' }
const cphNumber = new CphNumber(payload)

expect(cphNumber._data).toEqual(validCphNumberPayload)
})
})

describe('#CphNumber.validate', () => {
it('should return true for valid cphNumber', () => {
const cphNumber = new CphNumber(validCphNumberPayload)
Expand Down
4 changes: 4 additions & 0 deletions src/server/common/model/answer/email-address.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export class EmailAddress extends AnswerModel {
return validateAnswerAgainstSchema(emailAddressPayloadSchema, this._data)
}

_extractFields({ emailAddress }) {
return { emailAddress }
}

/**
* @param {EmailAddressData | undefined} state
* @returns {EmailAddress}
Expand Down
9 changes: 9 additions & 0 deletions src/server/common/model/answer/email-address.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ const invalidEmailAddresses = [
]

describe('EmailAddress', () => {
describe('new', () => {
it('should strip away any irrelevant values', () => {
const payload = { ...validEmailAddressPayload, nextPage: '/other/page' }
const emailAddress = new EmailAddress(payload)

expect(emailAddress._data).toEqual(validEmailAddressPayload)
})
})

describe('validate', () => {
validEmailAddresses.forEach((email) => {
it(`should return true for valid email address ${email}`, () => {
Expand Down
4 changes: 4 additions & 0 deletions src/server/common/model/answer/on-off-farm.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ export class OnOffFarm extends AnswerModel {
validate() {
return validateAnswerAgainstSchema(onOffFarmPayloadSchema, this._data ?? {})
}

_extractFields({ onOffFarm }) {
return { onOffFarm }
}
}
9 changes: 9 additions & 0 deletions src/server/common/model/answer/on-off-farm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ const validOnOffRadio = {
onOffFarm: 'on'
}

describe('OnOffFarm.new', () => {
it('should strip away any irrelevant values', () => {
const payload = { ...validOnOffRadio, nextPage: '/other/page' }
const onOffFarm = new OnOffFarm(payload)

expect(onOffFarm._data).toEqual(validOnOffRadio)
})
})

describe('#OnOffFarm.validate', () => {
test('should return true for on', () => {
const { isValid, errors } = new OnOffFarm({
Expand Down
44 changes: 22 additions & 22 deletions src/server/common/model/section/validation.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { validateSection } from './validation.js'
import { AnswerModel } from '../answer/answer-model.js'

const baseMockAnswer = {
toState: jest.fn(),
value: 'value',
html: '',
_data: {}
class MockAnswer extends AnswerModel {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_extractFields(data) {
return data
}
}

const validAnswer = {
...baseMockAnswer,
validate: jest.fn().mockReturnValue({ isValid: true })
class ValidAnswer extends MockAnswer {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
validate(_) {
return { isValid: true, errors: {} }
}
}

const invalidAnswer = {
...baseMockAnswer,
validate: jest.fn().mockReturnValue({ isValid: false })
class InvalidAnswer extends MockAnswer {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
validate(_) {
return { isValid: false, errors: { field1: { text: 'Invalid' } } }
}
}
const validAnswer = new ValidAnswer()

const invalidAnswer = new InvalidAnswer()

describe('validateSection', () => {
it('should return isValid as true when all answers are valid', () => {
Expand Down Expand Up @@ -46,16 +54,8 @@ describe('validateSection', () => {

it('should return the correct validation result for each answer', () => {
const data = {
answer1: {
...baseMockAnswer,
validate: jest.fn().mockReturnValue({ isValid: true, errors: {} })
},
answer2: {
...baseMockAnswer,
validate: jest
.fn()
.mockReturnValue({ isValid: false, errors: { field1: 'Invalid' } })
}
answer1: validAnswer,
answer2: invalidAnswer
}

const { isValid, result } = validateSection(data)
Expand All @@ -64,7 +64,7 @@ describe('validateSection', () => {
expect(result.answer1).toEqual({ isValid: true, errors: {} })
expect(result.answer2).toEqual({
isValid: false,
errors: { field1: 'Invalid' }
errors: { field1: { text: 'Invalid' } }
})
})
})
16 changes: 11 additions & 5 deletions user-journey-tests/helpers/testHelpers/checkAnswers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import checkAnswersPage from '../../page-objects/origin/checkAnswersPage.js'
import newAddressPage from '../../page-objects/origin/newAddressPage.js'
import parishHoldingNumberPage from '../../page-objects/origin/parishHoldingNumberPage.js'
import toFromFarmPage from '../../page-objects/origin/toFromFarmPage.js'
Expand Down Expand Up @@ -59,11 +60,16 @@ export const validateAndAdjustAddress = async (
postcode
})

await validateElementVisibleAndText(valueElement, lineOne)
await validateElementVisibleAndText(valueElement, lineTwo)
await validateElementVisibleAndText(valueElement, townOrCity)
await validateElementVisibleAndText(valueElement, county)
await validateElementVisibleAndText(valueElement, postcode)
// Expected text must be kept to the left of the page to ensure accuracy in the check
const elementText = await checkAnswersPage.addressValue
.getHTML(false)
.then((text) => text.replace(/<br\s*\/?>/g, '\n').trim())
const expectedText = `${lineOne}
${lineTwo}
${townOrCity}
${county}
${postcode}`
expect(elementText).toBe(expectedText)
}

export const validateAndAdjustEmail = async (
Expand Down

0 comments on commit 0d2bac6

Please sign in to comment.