From 935ea1338b254e47b6aeb0402c50bc89dbeafa55 Mon Sep 17 00:00:00 2001 From: Rhodine Orleans-Lindsay Date: Tue, 3 May 2022 17:16:29 +0100 Subject: [PATCH] BRP-61: Amend application type on all forms * add application type to email subject header * add unit tests * add character limit for 'other' freetext --- apps/collection/fields/index.js | 4 +- .../translations/src/en/fields.json | 2 +- .../collection/translations/src/en/pages.json | 1 + apps/collection/views/application-type.html | 2 - apps/collection/views/confirm.html | 2 - apps/collection/views/contact-details.html | 2 - apps/collection/views/nominated-person.html | 2 - apps/collection/views/personal-details.html | 2 - apps/collection/views/reasons.html | 2 - apps/collection/views/where.html | 2 - apps/common/behaviours/email.js | 27 ++++++-- apps/common/fields/application-type.js | 60 ++++++++++++++---- apps/common/translations/src/en/fields.json | 2 +- .../fields/application-type.js | 4 +- .../translations/src/en/fields.json | 2 +- apps/correct-mistakes/views/about-error.html | 2 - .../views/application-type.html | 2 - apps/correct-mistakes/views/confirm.html | 2 - .../views/contact-details.html | 2 - .../views/location-applied.html | 2 - .../views/personal-details-brp.html | 2 - apps/correct-mistakes/views/same-address.html | 2 - apps/correct-mistakes/views/uk-address.html | 2 - apps/lost-stolen/fields/application-type.js | 4 +- .../translations/src/en/fields.json | 2 +- .../translations/src/en/pages.json | 1 + apps/lost-stolen/views/application-type.html | 2 - apps/lost-stolen/views/confirm.html | 38 ++++++------ apps/lost-stolen/views/contact-details.html | 2 - apps/lost-stolen/views/date-lost.html | 2 - apps/lost-stolen/views/personal-details.html | 2 - apps/lost-stolen/views/where.html | 2 - apps/not-arrived/fields/application-type.js | 4 +- .../translations/src/en/fields.json | 2 +- apps/not-arrived/views/application-type.html | 2 - apps/not-arrived/views/confirm.html | 2 - apps/not-arrived/views/contact-details.html | 2 - apps/not-arrived/views/letter-received.html | 2 - apps/not-arrived/views/personal-details.html | 2 - .../views/same-address-details.html | 2 - apps/someone-else/fields/application-type.js | 4 +- .../translations/src/en/fields.json | 2 +- apps/someone-else/views/application-type.html | 2 - apps/someone-else/views/arrange.html | 2 - apps/someone-else/views/confirm.html | 2 - apps/someone-else/views/contact-details.html | 2 - apps/someone-else/views/personal-details.html | 2 - apps/someone-else/views/reason.html | 2 - package.json | 2 +- .../apps/common/behaviours/email.spec.js | 61 ++++++++++++++++++- .../apps/common/validation/validation.spec.js | 28 ++++++++- yarn.lock | 9 ++- 52 files changed, 198 insertions(+), 125 deletions(-) diff --git a/apps/collection/fields/index.js b/apps/collection/fields/index.js index 26a8d265..ab35d558 100644 --- a/apps/collection/fields/index.js +++ b/apps/collection/fields/index.js @@ -90,10 +90,10 @@ module.exports = { validate: ['required', 'notUrl'] }, 'application-type-other': { - validate: ['required'], + validate: ['required', {type: 'maxlength', arguments: 50}], dependent: { field: 'application-type', - value: 'other' + value: 'application-type-other' } } }; diff --git a/apps/collection/translations/src/en/fields.json b/apps/collection/translations/src/en/fields.json index 782bcc26..78003e2d 100644 --- a/apps/collection/translations/src/en/fields.json +++ b/apps/collection/translations/src/en/fields.json @@ -211,7 +211,7 @@ "legend": "Dependant", "label": "Dependant" }, - "other": { + "application-type-other": { "legend":"Other", "label": "Other" } diff --git a/apps/collection/translations/src/en/pages.json b/apps/collection/translations/src/en/pages.json index c1adb636..ab4ff438 100644 --- a/apps/collection/translations/src/en/pages.json +++ b/apps/collection/translations/src/en/pages.json @@ -49,6 +49,7 @@ }, "org-details-group": { "header": "What are your details?", + "subheader": "We will attempt to contact the BRP holder directly. We will only use these details to contact you if needed.", "type": "Type of support" }, "footer": { diff --git a/apps/collection/views/application-type.html b/apps/collection/views/application-type.html index ecab1234..b0f3b519 100644 --- a/apps/collection/views/application-type.html +++ b/apps/collection/views/application-type.html @@ -1,6 +1,4 @@ {{ a.value === apptype), 'label', ''); + if (apptype === 'application-type-other') { + applicationType = _.get( _.find(applicationTypeOptions, a => a.value === apptype), 'label', '') + + ' - ' + otherFreetext; + } + return applicationType; +} const serviceMap = { '/not-arrived': data => { return { template: 'delivery', - subject: 'Form submitted: Your BRP hasn\'t arrived. Ref: ' + setRef(data) + subject: 'Form submitted: Your BRP hasn\'t arrived. Ref: ' + setRef(data) + + ' (Application Type: ' + appType(data) + ')' }; }, '/correct-mistakes': data => { @@ -47,26 +58,30 @@ const serviceMap = { const suffix = data.triage ? '-triage' : ''; return { template: 'error' + suffix, - subject: 'Form submitted: Report a problem with your new BRP (' + subjectErrors + ') Ref: ' + setRef(data) + subject: 'Form submitted: Report a problem with your new BRP (' + subjectErrors + ') Ref: ' + setRef(data) + + ' (Application Type: ' + appType(data) + ')' }; }, '/lost-stolen': data => { const suffix = (data['inside-uk'] === 'yes') ? '-uk' : '-abroad'; return { template: 'lost-or-stolen' + suffix, - subject: 'Form submitted: Report a lost or stolen BRP. Ref: ' + setRef(data) + subject: 'Form submitted: Report a lost or stolen BRP. Ref: ' + setRef(data) + + ' (Application Type: ' + appType(data) + ')' }; }, '/collection': data => { return { template: 'collection', - subject: 'Form submitted: Report a collection problem. Ref: ' + setRef(data) + subject: 'Form submitted: Report a collection problem. Ref: ' + setRef(data) + + ' (Application Type: ' + appType(data) + ')' }; }, '/someone-else': data => { return { template: 'someone-else', - subject: 'Form submitted: Report someone else collecting your BRP. Ref: ' + setRef(data) + subject: 'Form submitted: Report someone else collecting your BRP. Ref: ' + setRef(data) + + ' (Application Type: ' + appType(data) + ')' }; } }; diff --git a/apps/common/fields/application-type.js b/apps/common/fields/application-type.js index f2e0931c..06f27769 100644 --- a/apps/common/fields/application-type.js +++ b/apps/common/fields/application-type.js @@ -9,19 +9,53 @@ module.exports = { className: 'visuallyhidden' }, options: [ - { value: 'work' }, - { value: 'study-academic-visit' }, - { value: 'graduate' }, - { value: 'settlement' }, - { value: 'asylum-humanitarian-protection' }, - { value: 'joining-family-human-rights' }, - { value: 'marriage-civil-partnership' }, - { value: 'business' }, - { value: 'uk-ancestry-youth-mobility' }, - { value: 'medical-treatment' }, - { value: 'dependant' }, - { - value: 'other', + { + value: 'work', + label: 'Work' + }, + { + value: 'study-academic-visit', + label: 'Study/Academic Visit' + }, + { + value: 'graduate', + label: 'Graduate' + }, + { + value: 'settlement', + label: 'Settlement' + }, + { + value: 'asylum-humanitarian-protection', + label: 'Asylum/Humanitarian Protection' + }, + { + value: 'joining-family-human-rights', + label: 'Joining Family/Human Rights' + }, + { + value: 'marriage-civil-partnership', + label: 'Marriage/Civil Partnership' + }, + { + value: 'business', + label: 'Business' + }, + { + value: 'uk-ancestry-youth-mobility', + label: 'UK Ancestry/Youth Mobility' + }, + { + value: 'medical-treatment', + label: 'Medical Treatment' + }, + { + value: 'dependant', + label: 'Dependant' + }, + { + value: 'application-type-other', + label: 'Other', toggle: 'application-type-other', child: 'input-text' } diff --git a/apps/common/translations/src/en/fields.json b/apps/common/translations/src/en/fields.json index 6dba202e..994fb86c 100644 --- a/apps/common/translations/src/en/fields.json +++ b/apps/common/translations/src/en/fields.json @@ -114,7 +114,7 @@ "legend": "Dependant", "label": "Dependant" }, - "other": { + "application-type-other": { "legend":"Other", "label": "Other" } diff --git a/apps/correct-mistakes/fields/application-type.js b/apps/correct-mistakes/fields/application-type.js index f0b9d250..0613139e 100644 --- a/apps/correct-mistakes/fields/application-type.js +++ b/apps/correct-mistakes/fields/application-type.js @@ -2,10 +2,10 @@ module.exports = { 'application-type-other': { - validate: ['required'], + validate: ['required', {type: 'maxlength', arguments: 50}], dependent: { field: 'application-type', - value: 'other' + value: 'application-type-other' } } }; diff --git a/apps/correct-mistakes/translations/src/en/fields.json b/apps/correct-mistakes/translations/src/en/fields.json index 13b019df..5115bf98 100644 --- a/apps/correct-mistakes/translations/src/en/fields.json +++ b/apps/correct-mistakes/translations/src/en/fields.json @@ -277,7 +277,7 @@ "legend": "Dependant", "label": "Dependant" }, - "other": { + "application-type-other": { "legend":"Other", "label": "Other" } diff --git a/apps/correct-mistakes/views/about-error.html b/apps/correct-mistakes/views/about-error.html index 3d362a07..dbd4e738 100644 --- a/apps/correct-mistakes/views/about-error.html +++ b/apps/correct-mistakes/views/about-error.html @@ -4,8 +4,6 @@ {{#t}}journeys.error.header{{/t}} {{/journeyHeader}} -{{$step}}Step 2 of 7{{/step}} - {{$validationSummary}} {{> partials-validation-summary}} {{/validationSummary}} diff --git a/apps/correct-mistakes/views/application-type.html b/apps/correct-mistakes/views/application-type.html index 4191ce91..cc9a980e 100644 --- a/apps/correct-mistakes/views/application-type.html +++ b/apps/correct-mistakes/views/application-type.html @@ -1,6 +1,4 @@ {{ partials-validation-summary}} {{/validationSummary}} diff --git a/apps/correct-mistakes/views/personal-details-brp.html b/apps/correct-mistakes/views/personal-details-brp.html index d2b1933d..623e9d17 100644 --- a/apps/correct-mistakes/views/personal-details-brp.html +++ b/apps/correct-mistakes/views/personal-details-brp.html @@ -1,6 +1,4 @@ {{{{#t}}buttons.change.brp-card{{/t}} {{/values.brp-card}} - {{#values.application-type}} - - {{#t}}pages.check-details.table.headers.application-type{{/t}} - - {{#t}}fields.application-type.options.{{values.application-type}}.label{{/t}} -
- - {{#values.application-type-other}} - {{values.application-type-other}} - {{/values.application-type-other}} - - - {{#t}}buttons.change.application-type{{/t}} - - {{/values.application-type}} {{#values.email}} {{#t}}pages.check-details.table.headers.email{{/t}} @@ -105,6 +88,27 @@ {{/values.phone}} +

{{#t}}pages.check-details.table.headers.application-details{{/t}}

+ + + {{#values.application-type}} + + + + + + {{/values.application-type}} + +
{{#t}}pages.check-details.table.headers.application-type{{/t}} + {{#t}}fields.application-type.options.{{values.application-type}}.label{{/t}} +
+ + {{#values.application-type-other}} + {{values.application-type-other}} + {{/values.application-type-other}} + +
{{#t}}buttons.change.application-type{{/t}}
+ {{{{#t}}footer.title{{/t}} diff --git a/apps/lost-stolen/views/contact-details.html b/apps/lost-stolen/views/contact-details.html index c7acb9f5..caabd358 100644 --- a/apps/lost-stolen/views/contact-details.html +++ b/apps/lost-stolen/views/contact-details.html @@ -1,6 +1,4 @@ {{ partials-validation-summary}} {{/validationSummary}} diff --git a/package.json b/package.json index e61b8475..a7a440fd 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "author": "HomeOffice", "dependencies": { "express": "^4.17.1", - "hof": "^19.13.15", + "hof": "^19.13.21", "hogan.js": "^3.0.2", "hot-shots": "^5.9.0", "i18n-future": "^2.0.1", diff --git a/test/_unit/apps/common/behaviours/email.spec.js b/test/_unit/apps/common/behaviours/email.spec.js index f2a7f123..a5fd9884 100644 --- a/test/_unit/apps/common/behaviours/email.spec.js +++ b/test/_unit/apps/common/behaviours/email.spec.js @@ -98,15 +98,72 @@ describe('apps/common/controllers/confirm', () => { }); }); - it('sets errors in the subject for the correct mistakes journey', () => { + it('sets errors and application type in the subject for the correct mistakes journey', () => { req.baseUrl = '/correct-mistakes'; req.sessionModel.set('test-error-checkbox', 'true'); req.sessionModel.set('test-error', 'testerror'); req.sessionModel.set('submission-reference', 'fpgyxSgw7'); + req.sessionModel.set('application-type', 'work'); controller.saveValues(req, res, err => { expect(err).not.to.be.ok; setStub.should.have.been.calledWith('subject', - 'Form submitted: Report a problem with your new BRP (test-error) Ref: fpgyxSgw7'); + 'Form submitted: Report a problem with your new BRP (test-error) Ref: fpgyxSgw7 (Application Type: Work)'); + }); + }); + + it('sets application type in the subject for the collection journey', () => { + req.baseUrl = '/collection'; + req.sessionModel.set('submission-reference', 'fpgyxSgw7'); + req.sessionModel.set('application-type', 'study-academic-visit'); + controller.saveValues(req, res, err => { + expect(err).not.to.be.ok; + setStub.should.have.been.calledWith('subject', + 'Form submitted: Report a collection problem. Ref: fpgyxSgw7 (Application Type: Study/Academic Visit)'); + }); + }); + + it('sets application type in the subject for the lost-stolen journey', () => { + req.baseUrl = '/lost-stolen'; + req.sessionModel.set('submission-reference', 'fpgyxSgw7'); + req.sessionModel.set('application-type', 'graduate'); + controller.saveValues(req, res, err => { + expect(err).not.to.be.ok; + setStub.should.have.been.calledWith('subject', + 'Form submitted: Report a lost or stolen BRP. Ref: fpgyxSgw7 (Application Type: Graduate)'); + }); + }); + + it('sets application type in the subject for the not-arrived journey', () => { + req.baseUrl = '/not-arrived'; + req.sessionModel.set('submission-reference', 'fpgyxSgw7'); + req.sessionModel.set('application-type', 'joining-family-human-rights'); + controller.saveValues(req, res, err => { + expect(err).not.to.be.ok; + setStub.should.have.been.calledWith('subject', + 'Form submitted: Your BRP hasn\'t arrived. Ref: fpgyxSgw7 (Application Type: Joining Family/Human Rights)'); + }); + }); + + it('sets application type in the subject for the someone-else journey', () => { + req.baseUrl = '/someone-else'; + req.sessionModel.set('submission-reference', 'fpgyxSgw7'); + req.sessionModel.set('application-type', 'business'); + controller.saveValues(req, res, err => { + expect(err).not.to.be.ok; + setStub.should.have.been.calledWith('subject', + 'Form submitted: Report someone else collecting your BRP. Ref: fpgyxSgw7 (Application Type: Business)'); + }); + }); + + it('sets freetext in the subject if the application type is `Other`', () => { + req.baseUrl = '/collection'; + req.sessionModel.set('submission-reference', 'fpgyxSgw7'); + req.sessionModel.set('application-type', 'application-type-other'); + req.sessionModel.set('application-type-other', 'Test'); + controller.saveValues(req, res, err => { + expect(err).not.to.be.ok; + setStub.should.have.been.calledWith('subject', + 'Form submitted: Report a collection problem. Ref: fpgyxSgw7 (Application Type: Other - Test)'); }); }); diff --git a/test/_unit/apps/common/validation/validation.spec.js b/test/_unit/apps/common/validation/validation.spec.js index 57b32fba..8e5af675 100644 --- a/test/_unit/apps/common/validation/validation.spec.js +++ b/test/_unit/apps/common/validation/validation.spec.js @@ -9,7 +9,7 @@ const DummyController = class DummyControllerBase extends Controller { } }; -describe('apps/commong/validation', () => { +describe('apps/common/validation', () => { let controller; let req; let res; @@ -33,6 +33,12 @@ describe('apps/commong/validation', () => { req.form.options.fields = { ImAURL: { validate: 'notUrl' + }, + 'application-type': { + validate: ['required'] + }, + 'application-type-other': { + validate: ['required', {type: 'maxlength', arguments: 50}] } }; @@ -51,6 +57,26 @@ describe('apps/commong/validation', () => { err.ImAURL.should.have.property('type').and.equal('notUrl'); }); }); + + it('adds a `required` validator if the application type is not selected', () => { + req.sessionModel.set('application-type'); + controller.configure(req, res, () => { + req.form.options.fields['application-type'].should.have.property('validate'); + expect(req.form.options.fields['application-type'].validate).to.deep.eql(['required' ]); + }); + }); + + it('adds a`required and maxlength` validator to the `other` input box', () => { + req.sessionModel.set('application-type', 'other'); + controller.configure(req, res, () => { + req.form.options.fields['application-type-other'].should.have.property('validate'); + expect(req.form.options.fields['application-type-other'].validate).to.deep.eql( + [ + 'required', + {type: 'maxlength', arguments: 50} + ]); + }); + }); }); }); }); diff --git a/yarn.lock b/yarn.lock index 28160639..6e95f529 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2779,10 +2779,10 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hof@^19.13.15: - version "19.13.15" - resolved "https://registry.yarnpkg.com/hof/-/hof-19.13.15.tgz#f9162659959c433b507c7bb297852e7e5249bdca" - integrity sha512-xywgUvLsORkEZwFGEpv14vFmesm+XHKg2B8xM3AWwredZ+AJ68dXu1UugzwR14otJts+HDdr0sWJxEudFzBR6Q== +hof@19.13.21: + version "19.13.21" + resolved "https://registry.yarnpkg.com/hof/-/hof-19.13.21.tgz#f5345d00b918feb90b821efe93411fcfa3422b0e" + integrity sha512-9tNa87dwwDEiKqH0+aa0y1b9OsF6BKULa5Y04oLABzSpopNZ/W0mEAi4hr9xpUb5thnwycu8b1CUveoRIlTLig== dependencies: aliasify "^2.1.0" bluebird "^3.7.2" @@ -5696,7 +5696,6 @@ winston-transport@^4.5.0: readable-stream "^3.6.0" triple-beam "^1.3.0" - winston@^3.3.0, winston@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/winston/-/winston-3.7.2.tgz#95b4eeddbec902b3db1424932ac634f887c400b1"