@defra-fish/gafl-webapp-service 1.65.0-rc.1 → 1.65.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/package.json +4 -4
  2. package/src/handlers/__tests__/cancel-recurring-payment-authentication-handler.spec.js +62 -45
  3. package/src/handlers/cancel-recurring-payment-authentication-handler.js +33 -25
  4. package/src/handlers/result-functions.js +5 -2
  5. package/src/locales/cy.json +33 -7
  6. package/src/locales/en.json +38 -0
  7. package/src/pages/journey-goal/__tests__/result-function.spec.js +33 -0
  8. package/src/pages/journey-goal/__tests__/route.spec.js +50 -0
  9. package/src/pages/journey-goal/journey-goal.njk +52 -0
  10. package/src/pages/journey-goal/result-function.js +21 -0
  11. package/src/pages/journey-goal/route.js +10 -0
  12. package/src/pages/recurring-payments/cancel/agreement-not-found/__tests__/route.spec.js +129 -0
  13. package/src/pages/recurring-payments/cancel/agreement-not-found/cancel-rp-agreement-not-found.njk +15 -0
  14. package/src/pages/recurring-payments/cancel/agreement-not-found/route.js +23 -0
  15. package/src/pages/recurring-payments/cancel/already-cancelled/__tests__/route.spec.js +115 -0
  16. package/src/pages/recurring-payments/cancel/already-cancelled/already-cancelled.njk +28 -0
  17. package/src/pages/recurring-payments/cancel/already-cancelled/route.js +25 -0
  18. package/src/pages/recurring-payments/cancel/confirm/__tests__/route.spec.js +11 -1
  19. package/src/pages/recurring-payments/cancel/confirm/cancel-rp-confirm.njk +12 -10
  20. package/src/pages/recurring-payments/cancel/confirm/route.js +3 -3
  21. package/src/pages/recurring-payments/cancel/details/__tests__/route.spec.js +70 -8
  22. package/src/pages/recurring-payments/cancel/details/route.js +12 -4
  23. package/src/pages/recurring-payments/cancel/licence-not-found/__tests__/route.spec.js +21 -0
  24. package/src/pages/recurring-payments/cancel/licence-not-found/licence-not-found.njk +27 -0
  25. package/src/pages/recurring-payments/cancel/licence-not-found/route.js +4 -0
  26. package/src/routes/__tests__/__snapshots__/telesales-routes.spec.js.snap +96 -0
  27. package/src/routes/__tests__/back-links.spec.js +67 -2
  28. package/src/routes/journey-definition.js +75 -11
  29. package/src/routes/telesales-routes.js +15 -5
  30. package/src/uri.js +11 -0
@@ -0,0 +1,129 @@
1
+ import pageRoute from '../../../../../routes/page-route.js'
2
+ import { CANCEL_RP_AGREEMENT_NOT_FOUND, CANCEL_RP_IDENTIFY } from '../../../../../uri.js'
3
+
4
+ require('../route.js')
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [[_v, _p, validator, completion, getData]] = pageRoute.mock.calls
7
+
8
+ jest.mock('../../../../../routes/page-route.js')
9
+ jest.mock('../../../../../uri.js', () => ({
10
+ ...jest.requireActual('../../../../../uri.js'),
11
+ CANCEL_RP_IDENTIFY: { page: Symbol('cancel-rp-identify-page') },
12
+ CANCEL_RP_AGREEMENT_NOT_FOUND: { page: Symbol('cancel-rp-agreement-not-found-page'), uri: Symbol('cancel-rp-agreement-not-found-uri') }
13
+ }))
14
+ jest.mock('../../../../../processors/uri-helper.js')
15
+
16
+ const getSampleRequest = (referenceNumber = 'RP12345678') => ({
17
+ cache: jest.fn(() => ({
18
+ helpers: {
19
+ page: {
20
+ getCurrentPermission: jest.fn(() => ({ payload: { referenceNumber } }))
21
+ }
22
+ }
23
+ }))
24
+ })
25
+
26
+ describe('pageRoute receives expected arguments', () => {
27
+ it('passes CANCEL_RP_AGREEMENT_NOT_FOUND.page as the view name', () => {
28
+ jest.isolateModules(() => {
29
+ require('../route.js')
30
+ expect(pageRoute).toHaveBeenCalledWith(
31
+ CANCEL_RP_AGREEMENT_NOT_FOUND.page,
32
+ expect.anything(),
33
+ expect.anything(),
34
+ expect.anything(),
35
+ expect.anything()
36
+ )
37
+ })
38
+ })
39
+
40
+ it('passes CANCEL_RP_AGREEMENT_NOT_FOUND.uri as the path', () => {
41
+ jest.isolateModules(() => {
42
+ require('../route.js')
43
+ expect(pageRoute).toHaveBeenCalledWith(
44
+ expect.anything(),
45
+ CANCEL_RP_AGREEMENT_NOT_FOUND.uri,
46
+ expect.anything(),
47
+ expect.anything(),
48
+ expect.anything()
49
+ )
50
+ })
51
+ })
52
+
53
+ it('passes a function as the validator', () => {
54
+ jest.isolateModules(() => {
55
+ require('../route.js')
56
+ expect(pageRoute).toHaveBeenCalledWith(
57
+ expect.anything(),
58
+ expect.anything(),
59
+ expect.any(Function),
60
+ expect.anything(),
61
+ expect.anything()
62
+ )
63
+ })
64
+ })
65
+
66
+ it('passes a function to generate redirect location on completion', () => {
67
+ jest.isolateModules(() => {
68
+ require('../route.js')
69
+ expect(pageRoute).toHaveBeenCalledWith(
70
+ expect.anything(),
71
+ expect.anything(),
72
+ expect.anything(),
73
+ expect.any(Function),
74
+ expect.anything()
75
+ )
76
+ })
77
+ })
78
+
79
+ it('passes a function to get the page data', () => {
80
+ jest.isolateModules(() => {
81
+ require('../route.js')
82
+ expect(pageRoute).toHaveBeenCalledWith(
83
+ expect.anything(),
84
+ expect.anything(),
85
+ expect.anything(),
86
+ expect.anything(),
87
+ expect.any(Function)
88
+ )
89
+ })
90
+ })
91
+ })
92
+
93
+ describe('getData', () => {
94
+ it('passes call charges link in list of urls', async () => {
95
+ expect(await getData(getSampleRequest())).toEqual(
96
+ expect.objectContaining({
97
+ links: expect.objectContaining({
98
+ callCharges: 'https://www.gov.uk/call-charges'
99
+ })
100
+ })
101
+ )
102
+ })
103
+
104
+ it('passes contact us email in list of urls', async () => {
105
+ expect(await getData(getSampleRequest())).toEqual(
106
+ expect.objectContaining({
107
+ links: expect.objectContaining({
108
+ contactUs: 'mailto:enquiries@environment-agency.gov.uk'
109
+ })
110
+ })
111
+ )
112
+ })
113
+
114
+ it('requests page data from CANCEL_RP_IDENTIFY page', async () => {
115
+ const request = getSampleRequest()
116
+ await getData(request)
117
+ const [{ value: pageCache }] = request.cache.mock.results
118
+ expect(pageCache.helpers.page.getCurrentPermission).toHaveBeenCalledWith(CANCEL_RP_IDENTIFY.page)
119
+ })
120
+
121
+ it('passes reference number from CANCEL_RP_IDENTIFY page data', async () => {
122
+ const referenceNumber = 'RP87654321'
123
+ expect(await getData(getSampleRequest(referenceNumber))).toEqual(
124
+ expect.objectContaining({
125
+ referenceNumber
126
+ })
127
+ )
128
+ })
129
+ })
@@ -0,0 +1,15 @@
1
+ {% extends "layout.njk" %}
2
+ {% extends "standard-form.njk" %}
3
+
4
+ {% set title = mssgs.rp_cancel_no_agreement_found_title %}
5
+
6
+ {% block content %}
7
+ <div class="govuk-grid-row">
8
+ <div class="govuk-grid-column-two-thirds">
9
+ <h1 class="govuk-heading-l">{{ mssgs.rp_cancel_no_agreement_found_heading }}</h1>
10
+ <p class="govuk-body">{{ mssgs.rp_cancel_no_agreement_found_licence_will_not_renew_1 }}{{ data.referenceNumber }}{{ mssgs.rp_cancel_no_agreement_found_licence_will_not_renew_2 }}</p>
11
+ <p class="govuk-body"><a class="govuk-link" href="{{ backRef }}">{{ mssgs.rp_cancel_no_agreement_found_go_back_link }}</a>{{ mssgs.rp_cancel_no_agreement_found_go_back_instruction }}</p>
12
+ <p class="govuk-body">{{ mssgs.rp_cancel_no_agreement_found_need_help_1 }}<a class="govuk-link" href="mailto:{{ data.links.contactUs }}">{{ mssgs.rp_cancel_no_agreement_found_need_help_email }}</a>{{ mssgs.rp_cancel_no_agreement_found_need_help_2 }}<a class="govuk-link" href="{{ data.links.callCharges }}" target="_blank">{{ mssgs.rp_cancel_no_agreement_found_call_charges_link }}</a></p>
13
+ </div>
14
+ </div>
15
+ {% endblock %}
@@ -0,0 +1,23 @@
1
+ import pageRoute from '../../../../routes/page-route.js'
2
+ import { CANCEL_RP_AGREEMENT_NOT_FOUND, CANCEL_RP_IDENTIFY } from '../../../../uri.js'
3
+
4
+ const getData = async request => {
5
+ const {
6
+ payload: { referenceNumber }
7
+ } = await request.cache().helpers.page.getCurrentPermission(CANCEL_RP_IDENTIFY.page)
8
+ return {
9
+ referenceNumber,
10
+ links: {
11
+ callCharges: 'https://www.gov.uk/call-charges',
12
+ contactUs: 'mailto:enquiries@environment-agency.gov.uk'
13
+ }
14
+ }
15
+ }
16
+
17
+ export default pageRoute(
18
+ CANCEL_RP_AGREEMENT_NOT_FOUND.page,
19
+ CANCEL_RP_AGREEMENT_NOT_FOUND.uri,
20
+ () => {},
21
+ () => {},
22
+ getData
23
+ )
@@ -0,0 +1,115 @@
1
+ import pageRoute from '../../../../../routes/page-route.js'
2
+ import { CANCEL_RP_ALREADY_CANCELLED } from '../../../../../uri.js'
3
+
4
+ require('../route.js')
5
+
6
+ // eslint-disable-next-line no-unused-vars
7
+ const getData = pageRoute.mock.calls[0][4]
8
+
9
+ jest.mock('../../../../../routes/page-route.js', () => jest.fn())
10
+ jest.mock('../../../../../uri.js', () => ({
11
+ ...jest.requireActual('../../../../../uri.js'),
12
+ CANCEL_RP_ALREADY_CANCELLED: {
13
+ page: Symbol('cancel-rp-already-cancelled page'),
14
+ uri: Symbol('cancel-rp-already-cancelled uri')
15
+ }
16
+ }))
17
+ jest.mock('../../../../../processors/uri-helper.js')
18
+
19
+ const getSampleRequest = referenceNumber => ({
20
+ cache: jest.fn(() => ({
21
+ helpers: {
22
+ page: {
23
+ getCurrentPermission: jest.fn(() => ({ payload: { referenceNumber, endDate: '2025:10:03:03:33:33' } }))
24
+ }
25
+ }
26
+ }))
27
+ })
28
+
29
+ describe('pageRoute receives expected arguments', () => {
30
+ it('passes CANCEL_RP_ALREADY_CANCELLED.page as the view name', () => {
31
+ jest.isolateModules(() => {
32
+ require('../route.js')
33
+ expect(pageRoute).toHaveBeenCalledWith(
34
+ CANCEL_RP_ALREADY_CANCELLED.page,
35
+ expect.anything(),
36
+ expect.anything(),
37
+ expect.anything(),
38
+ expect.anything()
39
+ )
40
+ })
41
+ })
42
+
43
+ it('passes CANCEL_RP_ALREADY_CANCELLED.uri as the path', () => {
44
+ jest.isolateModules(() => {
45
+ require('../route.js')
46
+ expect(pageRoute).toHaveBeenCalledWith(
47
+ expect.anything(),
48
+ CANCEL_RP_ALREADY_CANCELLED.uri,
49
+ expect.anything(),
50
+ expect.anything(),
51
+ expect.anything()
52
+ )
53
+ })
54
+ })
55
+
56
+ it('passes a function as the validator', () => {
57
+ jest.isolateModules(() => {
58
+ require('../route.js')
59
+ expect(pageRoute).toHaveBeenCalledWith(
60
+ expect.anything(),
61
+ expect.anything(),
62
+ expect.any(Function),
63
+ expect.anything(),
64
+ expect.anything()
65
+ )
66
+ })
67
+ })
68
+
69
+ it('passes a function to generate redirect location on completion', () => {
70
+ jest.isolateModules(() => {
71
+ require('../route.js')
72
+ expect(pageRoute).toHaveBeenCalledWith(
73
+ expect.anything(),
74
+ expect.anything(),
75
+ expect.anything(),
76
+ expect.any(Function),
77
+ expect.anything()
78
+ )
79
+ })
80
+ })
81
+
82
+ it('passes getData to pageRoute', () => {
83
+ jest.isolateModules(() => {
84
+ require('../route.js')
85
+ expect(pageRoute).toHaveBeenCalledWith(
86
+ expect.anything(),
87
+ expect.anything(),
88
+ expect.anything(),
89
+ expect.anything(),
90
+ expect.any(Function)
91
+ )
92
+ })
93
+ })
94
+ })
95
+
96
+ describe('getData', () => {
97
+ it('returns reference number from payload', async () => {
98
+ const referenceNumber = 'RP0310'
99
+ expect(await getData(getSampleRequest(referenceNumber))).toEqual(
100
+ expect.objectContaining({
101
+ referenceNumber
102
+ })
103
+ )
104
+ })
105
+
106
+ it('transforms end date to display format', async () => {
107
+ const endDate = '2025-10-03T03:33:33.000Z'
108
+ const request = getSampleRequest()
109
+ request.cache().helpers.page.getCurrentPermission.mockResolvedValueOnce({
110
+ payload: { referenceNumber: 'RP0310', endDate }
111
+ })
112
+ const data = await getData(request)
113
+ expect(data.endDate).toEqual('3 October 2025')
114
+ })
115
+ })
@@ -0,0 +1,28 @@
1
+ {% extends "layout.njk" %}
2
+ {% from "page-title.njk" import pageTitle %}
3
+
4
+ {% set title = mssgs.rp_cancel_already_cancelled_title %}
5
+ {% block pageTitle %}{{ pageTitle(title, mssgs) }}{% endblock %}
6
+
7
+ {% block content %}
8
+ <div class="govuk-grid-row">
9
+ <div class="govuk-grid-column-two-thirds">
10
+ <h1 class="govuk-heading-l">{{ mssgs.rp_licence_already_cancelled_heading }}</h1>
11
+ <p class="govuk-body">
12
+ {{ mssgs.rp_licence_already_cancelled_body_1 }}{{ data.referenceNumber }}{{ mssgs.rp_licence_already_cancelled_body_1_1 }}{{ data.endDate }}{{ mssgs.rp_licence_already_cancelled_body_1_2 }}
13
+ <a href="/" class="govuk-link" target="_blank" rel="noopener"> {{ mssgs.rp_licence_already_cancelled_body_link }}</a>{{ mssgs.full_stop }}
14
+ </p>
15
+ <p class="govuk-body">
16
+ {{ mssgs.rp_licence_already_cancelled_body_2_1 }}
17
+ <a href="mailto:enquiries@environment-agency.gov.uk"> {{ mssgs.rp_licence_already_cancelled_body_ea_link }}</a>
18
+ {{ mssgs.rp_licence_already_cancelled_body_2_2 }}
19
+ <a href="https://www.gov.uk/call-charges" target="_blank" rel="noopener"> {{ mssgs.licence_not_found_body_call_charges_link }}</a>{{ mssgs.full_stop }}
20
+ </p>
21
+ <p class="govuk-body">
22
+ <a class="govuk-link" href="/buy/cancel-recurring-payment/identify"> {{ mssgs.rp_licence_already_cancelled_body_3_1 }}
23
+ </a>{{ mssgs.rp_licence_already_cancelled_body_3_2 }}
24
+ </p>
25
+
26
+ </div>
27
+ </div>
28
+ {% endblock %}
@@ -0,0 +1,25 @@
1
+ import pageRoute from '../../../../routes/page-route.js'
2
+ import { SERVICE_LOCAL_TIME } from '@defra-fish/business-rules-lib'
3
+ import { CANCEL_RP_ALREADY_CANCELLED, CANCEL_RP_IDENTIFY } from '../../../../uri.js'
4
+ import { cacheDateFormat, dateDisplayFormat } from '../../../../processors/date-and-time-display.js'
5
+ import moment from 'moment-timezone'
6
+
7
+ const getData = async request => {
8
+ const {
9
+ payload: { referenceNumber, endDate }
10
+ } = await request.cache().helpers.page.getCurrentPermission(CANCEL_RP_IDENTIFY.page)
11
+ const endDateString = moment(endDate, cacheDateFormat).tz(SERVICE_LOCAL_TIME).format(dateDisplayFormat)
12
+
13
+ return {
14
+ referenceNumber,
15
+ endDate: endDateString
16
+ }
17
+ }
18
+
19
+ export default pageRoute(
20
+ CANCEL_RP_ALREADY_CANCELLED.page,
21
+ CANCEL_RP_ALREADY_CANCELLED.uri,
22
+ () => {},
23
+ () => {},
24
+ getData
25
+ )
@@ -2,6 +2,7 @@ import pageRoute from '../../../../../routes/page-route.js'
2
2
  import { CANCEL_RP_CONFIRM, CANCEL_RP_COMPLETE, CANCEL_RP_IDENTIFY } from '../../../../../uri.js'
3
3
  import { addLanguageCodeToUri } from '../../../../../processors/uri-helper.js'
4
4
  import moment from 'moment-timezone'
5
+ import { dateDisplayFormat } from '../../../../../processors/date-and-time-display.js'
5
6
 
6
7
  require('../route.js')
7
8
 
@@ -17,6 +18,10 @@ jest.mock('../../../../../uri.js', () => ({
17
18
  }))
18
19
  jest.mock('../../../../../processors/uri-helper.js')
19
20
  jest.mock('moment-timezone')
21
+ jest.mock('../../../../../processors/date-and-time-display.js', () => ({
22
+ cacheDateFormat: Symbol('cache date format'),
23
+ dateDisplayFormat: Symbol('date display format')
24
+ }))
20
25
 
21
26
  describe('pageRoute receives expected arguments', () => {
22
27
  it('passes expected arguments to pageRoute', () => {
@@ -64,7 +69,7 @@ describe('getData function', () => {
64
69
  })
65
70
 
66
71
  const mockRequest = () => {
67
- const getCurrentPermission = jest.fn(() => ({ recurringPayment: { endDate: '2025-02-15' } }))
72
+ const getCurrentPermission = jest.fn(() => ({ permission: { endDate: '2025-02-15' } }))
68
73
 
69
74
  return {
70
75
  locale: 'en',
@@ -109,4 +114,9 @@ describe('getData function', () => {
109
114
 
110
115
  expect(data.licenceExpiry).toEqual('19th November, 2025')
111
116
  })
117
+
118
+ it('uses expected date format', async () => {
119
+ await getData(mockRequest())
120
+ expect(moment.mock.results[0].value.format).toHaveBeenCalledWith(dateDisplayFormat)
121
+ })
112
122
  })
@@ -21,21 +21,23 @@
21
21
  }
22
22
  }) %}
23
23
 
24
- <p class="govuk-body-m">{{ mssgs.rp_cancel_confirm_body }}</p>
24
+ <p class="govuk-body-m">{{ mssgs.rp_cancel_confirm_body }}{{ data.licenceExpiry }}</p>
25
25
 
26
26
  <div class="govuk-grid-row">
27
27
  <div class="govuk-grid-column-two-thirds">
28
28
  <form method="post" class="govuk-!-margin-bottom-6">
29
- {{ govukButton({
30
- attributes: { id: 'continue' },
31
- preventDoubleClick: true,
32
- name: "continue",
33
- text: mssgs.rp_cancel_confirm_accept,
34
- classes: "govuk-!-margin-top-1"
35
- }) }}
36
- {{ csrf() }}
29
+ <div class="govuk-button-group">
30
+ {{ govukButton({
31
+ attributes: { id: 'continue' },
32
+ preventDoubleClick: true,
33
+ name: "continue",
34
+ text: mssgs.rp_cancel_confirm_accept,
35
+ classes: "govuk-!-margin-top-1"
36
+ }) }}
37
+ {{ csrf() }}
38
+ <p class="govuk-body no-print"><a class="govuk-link" href="{{ data.uri.cancelRpIdentify }}">{{ mssgs.rp_cancel_confirm_reject }}</a></p>
39
+ </div>
37
40
  </form>
38
- <p class="govuk-body no-print"><a class="govuk-link" href="{{ data.uri.cancelRpIdentify }}">{{ mssgs.rp_cancel_confirm_reject }}</a></p>
39
41
  </div>
40
42
  </div>
41
43
 
@@ -1,14 +1,14 @@
1
1
  import pageRoute from '../../../../routes/page-route.js'
2
2
  import { CANCEL_RP_COMPLETE, CANCEL_RP_CONFIRM, CANCEL_RP_IDENTIFY } from '../../../../uri.js'
3
3
  import { addLanguageCodeToUri } from '../../../../processors/uri-helper.js'
4
- import { cacheDateFormat } from '../../../../processors/date-and-time-display.js'
4
+ import { cacheDateFormat, dateDisplayFormat } from '../../../../processors/date-and-time-display.js'
5
5
  import moment from 'moment-timezone'
6
6
 
7
7
  const getData = async request => {
8
- const permission = await request.cache().helpers.transaction.getCurrentPermission()
8
+ const { permission } = await request.cache().helpers.transaction.getCurrentPermission()
9
9
 
10
10
  return {
11
- licenceExpiry: moment(permission.recurringPayment.endDate, cacheDateFormat, request.locale).format('Do MMMM, YYYY'),
11
+ licenceExpiry: moment(permission.endDate, cacheDateFormat, request.locale).format(dateDisplayFormat),
12
12
  uri: {
13
13
  cancelRpIdentify: addLanguageCodeToUri(request, CANCEL_RP_IDENTIFY.uri)
14
14
  }
@@ -2,6 +2,8 @@ import pageRoute from '../../../../../routes/page-route.js'
2
2
  import { CANCEL_RP_DETAILS, CANCEL_RP_CONFIRM } from '../../../../../uri.js'
3
3
  import { addLanguageCodeToUri } from '../../../../../processors/uri-helper.js'
4
4
  import { getData } from '../route.js'
5
+ import moment from 'moment-timezone'
6
+ import { cacheDateFormat, dateDisplayFormat } from '../../../../../processors/date-and-time-display.js'
5
7
 
6
8
  jest.mock('../../../../../routes/page-route.js')
7
9
  jest.mock('../../../../../uri.js', () => ({
@@ -10,6 +12,15 @@ jest.mock('../../../../../uri.js', () => ({
10
12
  CANCEL_RP_CONFIRM: { uri: Symbol('cancel-rp-confirm-uri') }
11
13
  }))
12
14
  jest.mock('../../../../../processors/uri-helper.js')
15
+ jest.mock('moment-timezone', () =>
16
+ jest.fn(() => ({
17
+ format: jest.fn()
18
+ }))
19
+ )
20
+ jest.mock('../../../../../processors/date-and-time-display.js', () => ({
21
+ cacheDateFormat: Symbol('cache-date-format'),
22
+ dateDisplayFormat: Symbol('date-display-format')
23
+ }))
13
24
 
14
25
  describe('route', () => {
15
26
  beforeEach(jest.clearAllMocks)
@@ -82,7 +93,7 @@ describe('route', () => {
82
93
  referenceNumber: 'abc123'
83
94
  },
84
95
  recurringPayment: {
85
- lastDigitsCardNumbers: 1234
96
+ lastDigitsCardNumbers: '1234'
86
97
  }
87
98
  })
88
99
 
@@ -96,7 +107,8 @@ describe('route', () => {
96
107
  }),
97
108
  i18n: {
98
109
  getCatalog: () => catalog
99
- }
110
+ },
111
+ locale: Symbol('en-GB')
100
112
  })
101
113
 
102
114
  describe('getData', () => {
@@ -115,17 +127,67 @@ describe('route', () => {
115
127
 
116
128
  it('returns summaryTable with expected data', async () => {
117
129
  const mssgs = getSampleCatalog()
118
- const mockRequest = createMockRequest({ catalog: mssgs })
130
+ const sampleData = {
131
+ permission: {
132
+ licensee: {
133
+ firstName: 'Brenin',
134
+ lastName: 'Pysgotwr'
135
+ },
136
+ permit: {
137
+ description: 'Wellies and old shopping trollies'
138
+ },
139
+ endDate: '21-03-2026',
140
+ referenceNumber: 'aaa-111-bbb-222'
141
+ },
142
+ recurringPayment: {
143
+ lastDigitsCardNumbers: '9999'
144
+ }
145
+ }
146
+ const sampleFormattedDate = Symbol('formatted-end-date')
147
+ const mockRequest = createMockRequest({ catalog: mssgs, currentPermission: sampleData })
148
+ moment.mockReturnValueOnce({
149
+ format: () => sampleFormattedDate
150
+ })
119
151
 
120
152
  const result = await getData(mockRequest)
121
153
 
122
154
  expect(result.summaryTable).toEqual([
123
- { key: { text: mssgs.rp_cancel_details_licence_holder }, value: { text: 'John Smith' } },
124
- { key: { text: mssgs.rp_cancel_details_licence_type }, value: { text: 'Salmon and sea trout' } },
125
- { key: { text: mssgs.rp_cancel_details_payment_card }, value: { text: 1234 } },
126
- { key: { text: mssgs.rp_cancel_details_last_purchased }, value: { text: 'abc123' } },
127
- { key: { text: mssgs.rp_cancel_details_licence_valid_until }, value: { text: '01-01-2026' } }
155
+ {
156
+ key: { text: mssgs.rp_cancel_details_licence_holder },
157
+ value: { text: `${sampleData.permission.licensee.firstName} ${sampleData.permission.licensee.lastName}` }
158
+ },
159
+ { key: { text: mssgs.rp_cancel_details_licence_type }, value: { text: sampleData.permission.permit.description } },
160
+ {
161
+ key: { text: mssgs.rp_cancel_details_payment_card },
162
+ value: { text: `**** **** **** ${sampleData.recurringPayment.lastDigitsCardNumbers}` }
163
+ },
164
+ { key: { text: mssgs.rp_cancel_details_last_purchased }, value: { text: sampleData.permission.referenceNumber } },
165
+ { key: { text: mssgs.rp_cancel_details_licence_valid_until }, value: { text: sampleFormattedDate } }
128
166
  ])
129
167
  })
168
+
169
+ it('passes cache date format and request locale to moment', async () => {
170
+ const data = getSamplePermission()
171
+ data.permission.endDate = Symbol('end-date')
172
+ const mockRequest = createMockRequest({ currentPermission: data })
173
+
174
+ await getData(mockRequest)
175
+
176
+ expect(moment).toHaveBeenCalledWith(data.permission.endDate, cacheDateFormat, mockRequest.locale)
177
+ })
178
+
179
+ it('requests correct date format', async () => {
180
+ const data = getSamplePermission()
181
+ data.permission.endDate = Symbol('end-date')
182
+ const mockRequest = createMockRequest({ currentPermission: data })
183
+ const format = jest.fn()
184
+ moment.mockReturnValueOnce({
185
+ format
186
+ })
187
+
188
+ await getData(mockRequest)
189
+
190
+ expect(format).toHaveBeenCalledWith(dateDisplayFormat)
191
+ })
130
192
  })
131
193
  })
@@ -1,16 +1,24 @@
1
1
  import pageRoute from '../../../../routes/page-route.js'
2
2
  import { CANCEL_RP_DETAILS, CANCEL_RP_CONFIRM } from '../../../../uri.js'
3
3
  import { addLanguageCodeToUri } from '../../../../processors/uri-helper.js'
4
+ import moment from 'moment-timezone'
5
+ import { cacheDateFormat, dateDisplayFormat } from '../../../../processors/date-and-time-display.js'
4
6
 
5
- const getLicenseeDetailsSummaryRows = (currentPermission, mssgs) => [
7
+ const getLicenseeDetailsSummaryRows = (currentPermission, mssgs, locale) => [
6
8
  {
7
9
  key: { text: mssgs.rp_cancel_details_licence_holder },
8
10
  value: { text: `${currentPermission.permission.licensee.firstName} ${currentPermission.permission.licensee.lastName}` }
9
11
  },
10
12
  { key: { text: mssgs.rp_cancel_details_licence_type }, value: { text: currentPermission.permission.permit.description } },
11
- { key: { text: mssgs.rp_cancel_details_payment_card }, value: { text: currentPermission.recurringPayment.lastDigitsCardNumbers } },
13
+ {
14
+ key: { text: mssgs.rp_cancel_details_payment_card },
15
+ value: { text: `**** **** **** ${currentPermission.recurringPayment.lastDigitsCardNumbers}` }
16
+ },
12
17
  { key: { text: mssgs.rp_cancel_details_last_purchased }, value: { text: currentPermission.permission.referenceNumber } },
13
- { key: { text: mssgs.rp_cancel_details_licence_valid_until }, value: { text: currentPermission.permission.endDate } }
18
+ {
19
+ key: { text: mssgs.rp_cancel_details_licence_valid_until },
20
+ value: { text: moment(currentPermission.permission.endDate, cacheDateFormat, locale).format(dateDisplayFormat) }
21
+ }
14
22
  ]
15
23
 
16
24
  export const getData = async request => {
@@ -19,7 +27,7 @@ export const getData = async request => {
19
27
 
20
28
  return {
21
29
  mssgs,
22
- summaryTable: getLicenseeDetailsSummaryRows(currentPermission, mssgs)
30
+ summaryTable: getLicenseeDetailsSummaryRows(currentPermission, mssgs, request.locale)
23
31
  }
24
32
  }
25
33
 
@@ -0,0 +1,21 @@
1
+ import pageRoute from '../../../../../routes/page-route.js'
2
+ import { CANCEL_RP_LICENCE_NOT_FOUND } from '../../../../../uri.js'
3
+ import '../route.js'
4
+
5
+ jest.mock('../../../../../routes/page-route.js', () => jest.fn())
6
+ jest.mock('../../../../../uri.js', () => ({
7
+ CANCEL_RP_LICENCE_NOT_FOUND: {
8
+ page: Symbol('licence-not-found page'),
9
+ uri: Symbol('licence-not-found uri')
10
+ }
11
+ }))
12
+
13
+ describe('CANCEL_RP_LICENCE_NOT_FOUND route', () => {
14
+ it('passes CANCEL_RP_LICENCE_NOT_FOUND.page as the first argument to pageRoute', () => {
15
+ expect(pageRoute).toHaveBeenCalledWith(CANCEL_RP_LICENCE_NOT_FOUND.page, expect.anything())
16
+ })
17
+
18
+ it('passes CANCEL_RP_LICENCE_NOT_FOUND.uri as the second argument to pageRoute', () => {
19
+ expect(pageRoute).toHaveBeenCalledWith(expect.anything(), CANCEL_RP_LICENCE_NOT_FOUND.uri)
20
+ })
21
+ })
@@ -0,0 +1,27 @@
1
+ {% extends "layout.njk" %}
2
+ {% extends "standard-form.njk" %}
3
+
4
+ {% set title = mssgs.licence_not_found_title %}
5
+
6
+ {% block content %}
7
+ <div class="govuk-grid-row">
8
+ <div class="govuk-grid-column-two-thirds">
9
+ <h1 class="govuk-heading-l">{{ mssgs.licence_not_found_title }}</h1>
10
+ <p class="govuk-body">
11
+ {{ mssgs.licence_not_found_body_1 }}
12
+ <a class="govuk-link" href="/buy/renew/identify">{{ mssgs.licence_not_found_body_previous_page }}</a>{{ mssgs.full_stop }}
13
+ </p>
14
+ <p class="govuk-body">
15
+ {{ mssgs.licence_not_found_rp_body_1}}
16
+ </p>
17
+ <ul class="govuk-list govuk-list--bullet">
18
+ <li> {{ mssgs.licence_not_found_rp_bullet_point_1 }} <a href="mailto:enquiries@environment-agency.gov.uk"> {{ mssgs.licence_not_found_body_ea_link }}
19
+ </a> {{ mssgs.licence_not_found_rp_bullet_point_1_2 }} </li>
20
+
21
+ <li> {{ mssgs.licence_not_found_rp_bullet_point_2 }} <a href="https://www.gov.uk/call-charges" target="_blank" rel="noopener"> {{ mssgs.licence_not_found_body_call_charges_link }}
22
+ </a>{{ mssgs.full_stop }} </li>
23
+ </ul>
24
+
25
+ </div>
26
+ </div>
27
+ {% endblock %}
@@ -0,0 +1,4 @@
1
+ import { CANCEL_RP_LICENCE_NOT_FOUND } from '../../../../uri.js'
2
+ import pageRoute from '../../../../routes/page-route.js'
3
+
4
+ export default pageRoute(CANCEL_RP_LICENCE_NOT_FOUND.page, CANCEL_RP_LICENCE_NOT_FOUND.uri)