Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encourage users to choose digital reminders #1821

Merged
merged 8 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions packages/gafl-webapp-service/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -285,25 +285,31 @@
"identify_title": "Renew your rod fishing licence?",
"important_info_contact_error_choose": "Choose how we should contact the licence holder",
"important_info_contact_error_email": "Enter an email address in the correct format",
"important_info_contact_error_mobile": "Enter a UK mobile phone number",
"important_info_contact_error_mobile": "Enter a UK mobile number",
"important_info_contact_input_email_hint": "For example [email protected]",
"important_info_contact_input_email": "Email address",
"important_info_contact_input_mobile_hint": "For example 07700 900 900",
"important_info_contact_input_mobile_note": "Mobile phone number",
"important_info_contact_input_mobile": "UK mobile phone number",
"important_info_contact_input_mobile_note": "UK mobile number",
"important_info_contact_input_mobile": "UK mobile number",
"important_info_contact_item_email": "Email",
"important_info_contact_item_email_value": "Email ",
"important_info_contact_item_txt": "Text message",
"important_info_contact_item_txt_value": "Text message to ",
"important_info_contact_licence_needed": "The rod licence holder will need to confirm the licence number if asked by an enforcement officer.",
"important_info_contact_none_msg": "We will show you the licence number on confirmation.",
"important_info_contact_note_tip": "Make a note of the licence number",
"important_info_contact_post_hint_you": "By choosing post, you will not get a personalised link to renew your licence online before it expires.",
"important_info_contact_post_hint_other": "By choosing post, the licence holder will not get a personalised link to renew their licence online before it expires.",
"important_info_contact_post_confirm_8d": "We don’t provide physical cards for 1 or 8 day licences.",
"important_info_contact_post_confirm_jr": "We don’t provide physical cards for junior licences.",
"important_info_contact_post_confirm": "This is where we will send renewal reminders when the licence is ending.",
"important_info_contact_post_confirm2": "We will also send important information like byelaw updates.",
"important_info_contact_post_salmon_you": "We will send a renewal reminder before your licence expires and a reminder to report a catch return. We will also send other important updates, like rod fishing byelaw changes.",
"important_info_contact_post_not_salmon_you": "We will send a renewal reminder before your licence expires. We will also send other important updates, like rod fishing byelaw changes.",
"important_info_contact_post_salmon_other": "We will send a renewal reminder before the licence expires and a reminder to report a catch return. We will also send other important updates, like rod fishing byelaw changes.",
"important_info_contact_post_not_salmon_other": "We will send a renewal reminder before the licence expires. We will also send other important updates, like rod fishing byelaw changes.",
"important_info_contact_post_msg": "If you want to fish before you receive the card you should make a note of the licence number after payment.",
"important_info_contact_post": "Post",
"important_info_contact_title_other": "How should we contact the licence holder about reminders and important changes?",
"important_info_contact_title_you": "How should we contact you with reminders and important changes?",
"important_info_contact_title_other": "How should we contact the licence holder about updates affecting their licence?",
"important_info_contact_title_you": "How should we contact you about updates affecting your licence?",
"licence_confirm_method_error_choose": "Choose how we should send the licence",
"licence_confirm_method_how_body_item": "I will make a note of the licence number",
"licence_confirm_method_how_body_text": "This is where we will send confirmation of the fishing licence",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getData, validator } from '../route'
import pageRoute from '../../../../routes/page-route.js'
import { nextPage } from '../../../../routes/next-page.js'
import { isPhysical } from '../../../../processors/licence-type-display.js'
import { hasJunior } from '../../../../processors/concession-helper.js'

jest.mock('../../../../routes/next-page.js', () => ({
nextPage: jest.fn()
Expand All @@ -15,46 +16,115 @@ jest.mock('../../../../uri.js', () => ({
}
}))
jest.mock('../../../../processors/licence-type-display.js')
jest.mock('../../../../processors/concession-helper.js')

describe('name > route', () => {
const getMockRequest = (isLicenceForYou = true) => ({
const getMockRequest = ({ isLicenceForYou, licenceType, email, mobilePhone }) => ({
cache: () => ({
helpers: {
transaction: {
getCurrentPermission: () => ({
licensee: {
birthDate: 'birthDate'
birthDate: 'birthDate',
email,
mobilePhone
},
licenceLength: 'licenceLength',
licenceStartDate: 'licenceStartDate',
isLicenceForYou
isLicenceForYou,
licenceType
})
}
}
})
}),
i18n: {
getCatalog: () => getMessages()
}
})

const getMessages = () => ({
important_info_contact_title_you: 'You title',
important_info_contact_title_other: 'Other title',
important_info_contact_item_email: 'Email',
important_info_contact_item_email_value: 'Email ',
important_info_contact_item_txt_value: 'Text to ',
important_info_contact_item_txt: 'Text',
important_info_contact_post_hint_you: 'Post hint you',
important_info_contact_post_hint_other: 'Post hint other',
important_info_contact_post_salmon_you: 'Salmon you',
important_info_contact_post_not_salmon_you: 'Not salmon you',
important_info_contact_post_salmon_other: 'Salmon other',
important_info_contact_post_not_salmon_other: 'Not salmon other'
})

describe('getData', () => {
it('should return isLicenceForYou as true, if isLicenceForYou is true on the transaction cache', async () => {
const result = await getData(getMockRequest(true))
expect(result.isLicenceForYou).toBeTruthy()
it.each([
[true, 'You title'],
[false, 'Other title']
])('title return method is %s if isLicenceForYou is same', async (isLicenceForYou, expected) => {
const result = await getData(getMockRequest({ isLicenceForYou }))
expect(result.title).toBe(expected)
})

it('should return isLicenceForYou as false, if isLicenceForYou is false on the transaction cache', async () => {
const result = await getData(getMockRequest(false))
expect(result.isLicenceForYou).toBeFalsy()
it.each([
['[email protected]', 'Email [email protected]'],
[null, 'Email']
])('emailText has correct value depending on if permission has an email', async (email, expected) => {
const result = await getData(getMockRequest({ email }))
expect(result.emailText).toBe(expected)
})

it.each([
['07123456789', 'Text to 07123456789'],
[null, 'Text']
])('mobileText has correct value depending on if permission has a phone number', async (mobilePhone, expected) => {
const result = await getData(getMockRequest({ mobilePhone }))
expect(result.mobileText).toBe(expected)
})

it.each([
[true, 'Post hint you'],
[false, 'Post hint other']
])('postHint wording depending on whether isLicenceForYou is %s', async (isLicenceForYou, expected) => {
const result = await getData(getMockRequest({ isLicenceForYou }))
expect(result.postHint).toBe(expected)
})

it.each([
[true, 'Salmon and sea trout', 'Salmon you'],
[true, 'Trout and coarse', 'Not salmon you'],
[false, 'Salmon and sea trout', 'Salmon other'],
[false, 'Trout and coarse', 'Not salmon other']
])(
'content has correct value depending on isLicenceForYou is %s and licenceType is %s',
async (isLicenceForYou, licenceType, expected) => {
const result = await getData(getMockRequest({ isLicenceForYou, licenceType }))
expect(result.content).toBe(expected)
}
)

it.each([
[true, true],
[false, false]
])('result.isPhysical matches return method of isPhysical', async (physical, expected) => {
isPhysical.mockReturnValueOnce(physical)
const result = await getData(getMockRequest({}))
expect(result.isPhysical).toBe(expected)
})

it('return isPhysical as true, if isPhysical is true for the permission', async () => {
isPhysical.mockReturnValueOnce(true)
const result = await getData(getMockRequest())
expect(result.isPhysical).toBeTruthy()
it.each([
[true, true],
[false, false]
])('isJunior matches return method of hasJunior', async (physical, expected) => {
hasJunior.mockReturnValueOnce(physical)
const result = await getData(getMockRequest({}))
expect(result.isJunior).toBe(expected)
})

it('return isPhysical as false, if isPhysical is false for the permission', async () => {
isPhysical.mockReturnValueOnce(false)
const result = await getData(getMockRequest())
expect(result.isPhysical).toBeFalsy()
it('howContacted returns the value of HOW_CONTACTED', async () => {
const expectedValue = { email: 'Email', text: 'Text', letter: 'Letter', none: 'Prefer not to be contacted' }
const result = await getData(getMockRequest({}))
expect(result.howContacted).toEqual(expectedValue)
})
})

Expand Down
72 changes: 48 additions & 24 deletions packages/gafl-webapp-service/src/pages/contact/contact/contact.njk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{% from "input/macro.njk" import govukInput %}
{% from "warning-text/macro.njk" import govukWarningText %}

{% set title = mssgs.important_info_contact_title_you if data.isLicenceForYou else mssgs.important_info_contact_title_other %}
{% set title = data.title %}
{% set errorMsg = mssgs.important_info_contact_error_choose %}
{% set emailError = mssgs.important_info_contact_error_email %}
{% set mobileError = mssgs.important_info_contact_error_mobile %}
Expand Down Expand Up @@ -52,7 +52,6 @@
<div id="email-ro" class="govuk-body-m initially-hidden">
{{ mssgs.important_info_contact_input_email }}</br>
<span class="govuk-body-m govuk-!-font-weight-bold">{{ data.licensee.email }}
&nbsp;&nbsp;<a id="change-email" href="#" class="govuk-link">{{ mssgs.licence_summary_change }}</a>
</span>
</div>
{% endset -%}
Expand Down Expand Up @@ -81,7 +80,6 @@
<div id="text-ro" class="govuk-body-m initially-hidden">
{{ mssgs.important_info_contact_input_mobile_note }}</br>
<span class="govuk-body-m govuk-!-font-weight-bold">{{ data.licensee.mobilePhone }}
&nbsp;&nbsp;<a id="change-text" href="#" class="govuk-link">{{ mssgs.licence_summary_change }}</a>
</span>
</div>
{% endset -%}
Expand All @@ -94,32 +92,59 @@
<p class="govuk-body-m">{{ mssgs.important_info_contact_none_msg }}</p>
{% endset -%}

{% set itemsArray = [
{
value: "email",
text: mssgs.important_info_contact_item_email,
checked: payload['how-contacted'] === 'email',
conditional: {
html: emailHtml
}
},
{
value: "text",
text: mssgs.important_info_contact_item_txt,
checked: payload['how-contacted'] === 'text',
conditional: {
html: textMessageHtml
}
}
] %}
{% set itemsArray = [] %}
{% if data.licensee.email %}
{% set itemsArray = (itemsArray.push(
{
value: "email",
text: data.emailText,
checked: payload['how-contacted'] === 'email'
}), itemsArray)
%}
{% else %}
{% set itemsArray = (itemsArray.push(
{
value: "email",
text: data.emailText,
checked: payload['how-contacted'] === 'email',
conditional: {
html: emailHtml
}
}), itemsArray)
%}
{% endif %}

{% if data.licensee.mobilePhone %}
{% set itemsArray = (itemsArray.push(
{
value: "text",
text: data.mobileText,
checked: payload['how-contacted'] === 'text'
}), itemsArray)
%}
{% else %}
{% set itemsArray = (itemsArray.push(
{
value: "text",
text: data.mobileText,
checked: payload['how-contacted'] === 'text',
conditional: {
html: textMessageHtml
}
}), itemsArray)
%}
{% endif %}
jaucourt marked this conversation as resolved.
Show resolved Hide resolved

{% if data.isPhysical %}
{% if data.licensee.postalFulfilment %}
{% set itemsArray = (itemsArray.push(
{
value: "none",
text: mssgs.important_info_contact_post,
checked: payload['how-contacted'] === 'post'
checked: payload['how-contacted'] === 'post',
hint: {
text: data.postHint
}
}), itemsArray)
%}
{% endif %}
Expand All @@ -138,8 +163,7 @@

{% block pageContent %}
{% if data.isPhysical %}
<p class="govuk-body-m">{{ mssgs.important_info_contact_post_confirm }}</p>
<p class="govuk-body-m">{{ mssgs.important_info_contact_post_confirm2 }}</p>
<p class="govuk-body-m">{{ data.content }}</p>
{% else %}
{% if data.isJunior %}
<p class="govuk-body-m">{{ mssgs.important_info_contact_post_confirm_jr }}</p>
Expand Down
34 changes: 33 additions & 1 deletion packages/gafl-webapp-service/src/pages/contact/contact/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { mobilePhoneValidator } from '../../../processors/contact-validator.js'

export const getData = async request => {
const permission = await request.cache().helpers.transaction.getCurrentPermission()
const mssgs = request.i18n.getCatalog()

// We need to have set the licence length, dob and start date here to determining the contact
// messaging
Expand All @@ -27,14 +28,45 @@ export const getData = async request => {
}

return {
isLicenceForYou: permission.isLicenceForYou,
title: getTitle(permission, mssgs),
postHint: getPostHint(permission, mssgs),
content: getContent(permission, mssgs),
emailText: getEmailText(permission, mssgs),
mobileText: getMobileText(permission, mssgs),
licensee: permission.licensee,
isPhysical: isPhysical(permission),
isJunior: hasJunior(permission),
howContacted: HOW_CONTACTED
}
}

const getTitle = (permission, messages) =>
permission.isLicenceForYou
? messages.important_info_contact_title_you
: messages.important_info_contact_title_other

const getPostHint = (permission, messages) =>
permission.isLicenceForYou
? messages.important_info_contact_post_hint_you
: messages.important_info_contact_post_hint_other

const getContent = (permission, messages) => {
if (permission.licenceType === 'Salmon and sea trout') {
return permission.isLicenceForYou ? messages.important_info_contact_post_salmon_you : messages.important_info_contact_post_salmon_other
}
return permission.isLicenceForYou ? messages.important_info_contact_post_not_salmon_you : messages.important_info_contact_post_not_salmon_other
}

const getMobileText = (permission, messages) =>
permission.licensee.mobilePhone
? `${messages.important_info_contact_item_txt_value}${permission.licensee.mobilePhone}`
: messages.important_info_contact_item_txt

const getEmailText = (permission, messages) =>
permission.licensee.email
? `${messages.important_info_contact_item_email_value}${permission.licensee.email}`
: messages.important_info_contact_item_email

export const validator = Joi.object({
'how-contacted': Joi.string().valid('email', 'text', 'none').required(),
email: Joi.alternatives().conditional('how-contacted', {
Expand Down
Loading