@defra-fish/gafl-webapp-service 1.65.0-rc.5 → 1.65.0-rc.7
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.
- package/package.json +4 -4
- package/src/handlers/result-functions.js +5 -2
- package/src/locales/en.json +12 -0
- package/src/pages/journey-goal/__tests__/result-function.spec.js +33 -0
- package/src/pages/journey-goal/__tests__/route.spec.js +50 -0
- package/src/pages/journey-goal/journey-goal.njk +52 -0
- package/src/pages/journey-goal/result-function.js +21 -0
- package/src/pages/journey-goal/route.js +10 -0
- package/src/routes/__tests__/__snapshots__/telesales-routes.spec.js.snap +48 -0
- package/src/routes/__tests__/back-links.spec.js +67 -2
- package/src/routes/journey-definition.js +52 -7
- package/src/routes/telesales-routes.js +3 -1
- package/src/uri.js +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/gafl-webapp-service",
|
|
3
|
-
"version": "1.65.0-rc.
|
|
3
|
+
"version": "1.65.0-rc.7",
|
|
4
4
|
"description": "The websales frontend for the GAFL service",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"prepare": "gulp --gulpfile build/gulpfile.cjs"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@defra-fish/business-rules-lib": "1.65.0-rc.
|
|
40
|
-
"@defra-fish/connectors-lib": "1.65.0-rc.
|
|
39
|
+
"@defra-fish/business-rules-lib": "1.65.0-rc.7",
|
|
40
|
+
"@defra-fish/connectors-lib": "1.65.0-rc.7",
|
|
41
41
|
"@defra/hapi-gapi": "2.0.0",
|
|
42
42
|
"@hapi/boom": "9.1.2",
|
|
43
43
|
"@hapi/catbox-redis": "6.0.2",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"./gafl-jest-matchers.js"
|
|
80
80
|
]
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "721154c38cb9bfb554f3a3ff428ccd18cc7351c3"
|
|
83
83
|
}
|
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
LICENCE_SUMMARY,
|
|
19
19
|
NAME,
|
|
20
20
|
TERMS_AND_CONDITIONS,
|
|
21
|
-
CHOOSE_PAYMENT
|
|
21
|
+
CHOOSE_PAYMENT,
|
|
22
|
+
JOURNEY_GOAL
|
|
22
23
|
} from '../uri.js'
|
|
23
24
|
|
|
24
25
|
import dateOfBirth from '../pages/concessions/date-of-birth/result-function.js'
|
|
@@ -38,6 +39,7 @@ import addressEntry from '../pages/contact/address/entry/result-function.js'
|
|
|
38
39
|
import licenceSummary from '../pages/summary/licence-summary/result-function.js'
|
|
39
40
|
import termsAndConditions from '../pages/terms-and-conditions/result-function.js'
|
|
40
41
|
import choosePayment from '../pages/recurring-payments/choose-payment/result-function.js'
|
|
42
|
+
import journeyGoal from '../pages/journey-goal/result-function.js'
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
* The result function determines the navigation in the route definition
|
|
@@ -59,5 +61,6 @@ export default {
|
|
|
59
61
|
[NAME.page]: name,
|
|
60
62
|
[LICENCE_SUMMARY.page]: licenceSummary,
|
|
61
63
|
[TERMS_AND_CONDITIONS.page]: termsAndConditions,
|
|
62
|
-
[CHOOSE_PAYMENT.page]: choosePayment
|
|
64
|
+
[CHOOSE_PAYMENT.page]: choosePayment,
|
|
65
|
+
[JOURNEY_GOAL.page]: journeyGoal
|
|
63
66
|
}
|
package/src/locales/en.json
CHANGED
|
@@ -389,6 +389,18 @@
|
|
|
389
389
|
"important_info_contact_post": "Post",
|
|
390
390
|
"important_info_contact_title_other": "How should we contact the licence holder about updates affecting their licence?",
|
|
391
391
|
"important_info_contact_title_you": "How should we contact you about updates affecting your licence?",
|
|
392
|
+
"journey_goal_title": "What do you wish to do?",
|
|
393
|
+
"journey_goal_heading": "What do you wish to do?",
|
|
394
|
+
"journey_goal_error": "Please select what you wish to do",
|
|
395
|
+
"journey_goal_get_new_licence": "Get a new licence",
|
|
396
|
+
"journey_goal_renew_existing_licence": "Renew a 12-month licence",
|
|
397
|
+
"journey_goal_renew_existing_licence_proviso": "For licences that expired in the last 30 days",
|
|
398
|
+
"journey_goal_you_will_need": "You will need",
|
|
399
|
+
"journey_goal_cancel_recurring_payment": "Cancel a recurring card payment",
|
|
400
|
+
"journey_goal_instructions_req_1": "the last 6 characters of your licence number",
|
|
401
|
+
"journey_goal_instructions_req_2": "your date of birth",
|
|
402
|
+
"journey_goal_instructions_req_3": "your postcode",
|
|
403
|
+
"journey_goal_": "",
|
|
392
404
|
"licence_1_day": "1-day",
|
|
393
405
|
"licence_8_day": "8-day",
|
|
394
406
|
"licence_12_month": "12-month",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import resultFunction from '../result-function.js'
|
|
2
|
+
|
|
3
|
+
describe('resultFunction', () => {
|
|
4
|
+
const getMockRequest = journeyGoal => ({
|
|
5
|
+
payload: {
|
|
6
|
+
'journey-goal': journeyGoal
|
|
7
|
+
}
|
|
8
|
+
})
|
|
9
|
+
it.each(['purchase-permission', 'renew-permission', 'cancel-recurring-payment'])(
|
|
10
|
+
'returns journey goal for recognised journey goal - %s',
|
|
11
|
+
async journeyGoal => {
|
|
12
|
+
const mockRequest = getMockRequest(journeyGoal)
|
|
13
|
+
const result = await resultFunction(mockRequest)
|
|
14
|
+
expect(result).toBe(journeyGoal)
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
describe.each(['invalid-goal', 'unknown-journey-goal'])('handles unrecognised journey goal - %s', journeyGoal => {
|
|
19
|
+
it('returns null for unrecognised journey goal', async () => {
|
|
20
|
+
const mockRequest = getMockRequest(journeyGoal)
|
|
21
|
+
const result = await resultFunction(mockRequest)
|
|
22
|
+
expect(result).toBeNull()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('logs an error for unrecognised journey goal', async () => {
|
|
26
|
+
const consoleErrorSpy = jest.spyOn(console, 'error')
|
|
27
|
+
const mockRequest = getMockRequest(journeyGoal)
|
|
28
|
+
await resultFunction(mockRequest)
|
|
29
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Unknown journey goal selected:', journeyGoal)
|
|
30
|
+
consoleErrorSpy.mockRestore()
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import pageRoute from '../../../routes/page-route.js'
|
|
2
|
+
import { JOURNEY_GOAL } from '../../../uri.js'
|
|
3
|
+
import { nextPage } from '../../../routes/next-page.js'
|
|
4
|
+
import { journeyGoalResults } from '../result-function.js'
|
|
5
|
+
import '../route.js'
|
|
6
|
+
|
|
7
|
+
jest.mock('../../../routes/page-route.js')
|
|
8
|
+
jest.mock('../../../uri.js', () => ({
|
|
9
|
+
...jest.requireActual('../../../uri.js'),
|
|
10
|
+
JOURNEY_GOAL: { page: 'journey/goal/page', uri: Symbol('/journey/goal/page') }
|
|
11
|
+
}))
|
|
12
|
+
jest.mock('../../../routes/next-page.js')
|
|
13
|
+
jest.mock('../result-function.js', () => ({
|
|
14
|
+
journeyGoalResults: {
|
|
15
|
+
PURCHASE_PERMISSION: Symbol('purchase-permission'),
|
|
16
|
+
RENEW_PERMISSION: Symbol('renew-permission'),
|
|
17
|
+
CANCEL_RECURRING_PAYMENT: Symbol('cancel-recurring-payment')
|
|
18
|
+
}
|
|
19
|
+
}))
|
|
20
|
+
|
|
21
|
+
const getData = pageRoute.mock.calls[0][4]
|
|
22
|
+
|
|
23
|
+
describe('Journey Goal Page Route', () => {
|
|
24
|
+
it('passes JOURNEY_GOAL.page as view', () => {
|
|
25
|
+
expect(pageRoute).toHaveBeenCalledWith(JOURNEY_GOAL.page, expect.anything(), expect.anything(), expect.anything(), expect.anything())
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('passes JOURNEY_GOAL.uri as path', () => {
|
|
29
|
+
expect(pageRoute).toHaveBeenCalledWith(expect.anything(), JOURNEY_GOAL.uri, expect.anything(), expect.anything(), expect.anything())
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('passes function as validator', () => {
|
|
33
|
+
expect(pageRoute).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.any(Function), expect.anything(), expect.anything())
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('passes nextPage function as completion function', () => {
|
|
37
|
+
expect(pageRoute).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.anything(), nextPage, expect.anything())
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('passes function as getData parameter', () => {
|
|
41
|
+
expect(pageRoute).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.anything(), expect.anything(), expect.any(Function))
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('getData', () => {
|
|
45
|
+
it('returns journey goal data', async () => {
|
|
46
|
+
const data = await getData()
|
|
47
|
+
expect(data).toEqual(expect.objectContaining({ journeyGoals: journeyGoalResults }))
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{% extends "standard-form.njk" %}
|
|
2
|
+
|
|
3
|
+
{% from "radios/macro.njk" import govukRadios %}
|
|
4
|
+
|
|
5
|
+
{% set title = mssgs.journey_goal_title %}
|
|
6
|
+
{% set errorMsg = mssgs.journey_goal_error %}
|
|
7
|
+
|
|
8
|
+
{% set instructions %}
|
|
9
|
+
<p class="govuk-body-m">{{ mssgs.journey_goal_you_will_need }}</p>
|
|
10
|
+
<ul class="govuk-list govuk-list--bullet">
|
|
11
|
+
<li>{{ mssgs.journey_goal_instructions_req_1 }}</li>
|
|
12
|
+
<li>{{ mssgs.journey_goal_instructions_req_2 }}</li>
|
|
13
|
+
<li>{{ mssgs.journey_goal_instructions_req_3 }}</li>
|
|
14
|
+
</ul>
|
|
15
|
+
{% endset %}
|
|
16
|
+
|
|
17
|
+
{% block pageContent %}
|
|
18
|
+
{{ govukRadios({
|
|
19
|
+
idPrefix: 'journey-goal',
|
|
20
|
+
name: "journey-goal",
|
|
21
|
+
items: [
|
|
22
|
+
{
|
|
23
|
+
"id": "selector-buy-licence",
|
|
24
|
+
value: data.journeyGoals.PURCHASE_PERMISSION,
|
|
25
|
+
text: mssgs.journey_goal_get_new_licence,
|
|
26
|
+
checked: payload['journey-goal'] === data.journeyGoals.PURCHASE_PERMISSION
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "selector-renew-licence",
|
|
30
|
+
value: data.journeyGoals.RENEW_PERMISSION,
|
|
31
|
+
text: mssgs.journey_goal_renew_existing_licence,
|
|
32
|
+
checked: payload['journey-goal'] === data.journeyGoals.RENEW_PERMISSION,
|
|
33
|
+
hint: {
|
|
34
|
+
text: mssgs.journey_goal_renew_existing_licence_proviso
|
|
35
|
+
},
|
|
36
|
+
conditional: {
|
|
37
|
+
html: instructions
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "selector-cancel-recurring-payment",
|
|
42
|
+
value: data.journeyGoals.CANCEL_RECURRING_PAYMENT,
|
|
43
|
+
text: mssgs.journey_goal_cancel_recurring_payment,
|
|
44
|
+
checked: payload['journey-goal'] === data.journeyGoals.CANCEL_RECURRING_PAYMENT,
|
|
45
|
+
conditional: {
|
|
46
|
+
html: instructions
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
errorMessage: { text: errorMsg } if error['journey-goal']
|
|
51
|
+
}) }}
|
|
52
|
+
{% endblock %}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const journeyGoalResults = Object.freeze({
|
|
2
|
+
PURCHASE_PERMISSION: 'purchase-permission',
|
|
3
|
+
RENEW_PERMISSION: 'renew-permission',
|
|
4
|
+
CANCEL_RECURRING_PAYMENT: 'cancel-recurring-payment'
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
const journeyGoalResult = async request => {
|
|
8
|
+
switch (request.payload['journey-goal']) {
|
|
9
|
+
case 'purchase-permission':
|
|
10
|
+
return journeyGoalResults.PURCHASE_PERMISSION
|
|
11
|
+
case 'renew-permission':
|
|
12
|
+
return journeyGoalResults.RENEW_PERMISSION
|
|
13
|
+
case 'cancel-recurring-payment':
|
|
14
|
+
return journeyGoalResults.CANCEL_RECURRING_PAYMENT
|
|
15
|
+
default:
|
|
16
|
+
console.error('Unknown journey goal selected:', request.payload['journey-goal'])
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default journeyGoalResult
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import pageRoute from '../../routes/page-route.js'
|
|
2
|
+
import { JOURNEY_GOAL } from '../../uri.js'
|
|
3
|
+
import { nextPage } from '../../routes/next-page.js'
|
|
4
|
+
import { journeyGoalResults } from './result-function.js'
|
|
5
|
+
|
|
6
|
+
const getData = async () => ({
|
|
7
|
+
journeyGoals: journeyGoalResults
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export default pageRoute(JOURNEY_GOAL.page, JOURNEY_GOAL.uri, () => {}, nextPage, getData)
|
|
@@ -36,6 +36,22 @@ Object {
|
|
|
36
36
|
},
|
|
37
37
|
"path": "/oidc/role-required",
|
|
38
38
|
},
|
|
39
|
+
Object {
|
|
40
|
+
"handler": [Function],
|
|
41
|
+
"method": "GET",
|
|
42
|
+
"path": "/buy/journey-goal",
|
|
43
|
+
},
|
|
44
|
+
Object {
|
|
45
|
+
"handler": [Function],
|
|
46
|
+
"method": "POST",
|
|
47
|
+
"options": Object {
|
|
48
|
+
"validate": Object {
|
|
49
|
+
"failAction": [Function],
|
|
50
|
+
"payload": [Function],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
"path": "/buy/journey-goal",
|
|
54
|
+
},
|
|
39
55
|
Object {
|
|
40
56
|
"handler": [Function],
|
|
41
57
|
"method": "GET",
|
|
@@ -188,6 +204,22 @@ Object {
|
|
|
188
204
|
},
|
|
189
205
|
"path": "/oidc/role-required",
|
|
190
206
|
},
|
|
207
|
+
Object {
|
|
208
|
+
"handler": [Function],
|
|
209
|
+
"method": "GET",
|
|
210
|
+
"path": "/buy/journey-goal",
|
|
211
|
+
},
|
|
212
|
+
Object {
|
|
213
|
+
"handler": [Function],
|
|
214
|
+
"method": "POST",
|
|
215
|
+
"options": Object {
|
|
216
|
+
"validate": Object {
|
|
217
|
+
"failAction": [Function],
|
|
218
|
+
"payload": [Function],
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
"path": "/buy/journey-goal",
|
|
222
|
+
},
|
|
191
223
|
],
|
|
192
224
|
}
|
|
193
225
|
`;
|
|
@@ -228,6 +260,22 @@ Object {
|
|
|
228
260
|
},
|
|
229
261
|
"path": "/oidc/role-required",
|
|
230
262
|
},
|
|
263
|
+
Object {
|
|
264
|
+
"handler": [Function],
|
|
265
|
+
"method": "GET",
|
|
266
|
+
"path": "/buy/journey-goal",
|
|
267
|
+
},
|
|
268
|
+
Object {
|
|
269
|
+
"handler": [Function],
|
|
270
|
+
"method": "POST",
|
|
271
|
+
"options": Object {
|
|
272
|
+
"validate": Object {
|
|
273
|
+
"failAction": [Function],
|
|
274
|
+
"payload": [Function],
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
"path": "/buy/journey-goal",
|
|
278
|
+
},
|
|
231
279
|
],
|
|
232
280
|
}
|
|
233
281
|
`;
|
|
@@ -17,27 +17,64 @@ import {
|
|
|
17
17
|
CONTACT,
|
|
18
18
|
NEWSLETTER,
|
|
19
19
|
CHOOSE_PAYMENT,
|
|
20
|
-
TERMS_AND_CONDITIONS
|
|
20
|
+
TERMS_AND_CONDITIONS,
|
|
21
|
+
JOURNEY_GOAL
|
|
21
22
|
} from '../../uri.js'
|
|
22
23
|
import { LICENCE_SUMMARY_SEEN, CONTACT_SUMMARY_SEEN } from '../../constants.js'
|
|
23
24
|
import { isPhysical } from '../../processors/licence-type-display.js'
|
|
24
25
|
jest.mock('../../processors/licence-type-display.js')
|
|
25
26
|
|
|
27
|
+
describe('The journey-goal page', () => {
|
|
28
|
+
it('has no back-link', () => {
|
|
29
|
+
jest.isolateModules(() => {
|
|
30
|
+
process.env.CHANNEL = 'telesales'
|
|
31
|
+
const isolatedJourneyDefinition = require('../journey-definition.js').default
|
|
32
|
+
const isolatedJourneyGoal = isolatedJourneyDefinition.find(n => n.current.page === JOURNEY_GOAL.page)
|
|
33
|
+
expect(isolatedJourneyGoal.backLink({})).not.toBeTruthy()
|
|
34
|
+
delete process.env.CHANNEL
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
26
39
|
describe('The licence-for page', () => {
|
|
27
40
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_FOR.page)
|
|
28
|
-
|
|
41
|
+
|
|
42
|
+
it('has no back-link on initial viewing in websales journey', () => {
|
|
29
43
|
expect(n.backLink({})).not.toBeTruthy()
|
|
30
44
|
})
|
|
45
|
+
|
|
31
46
|
it('has a back-link to the license summary if the summary is seen', () => {
|
|
32
47
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
33
48
|
})
|
|
49
|
+
|
|
50
|
+
it('has a back-link to the journey-goal page in telesales journey', () => {
|
|
51
|
+
jest.isolateModules(() => {
|
|
52
|
+
process.env.CHANNEL = 'telesales'
|
|
53
|
+
const isolatedJourneyDefinition = require('../journey-definition.js').default
|
|
54
|
+
const isolatedJourneyGoal = isolatedJourneyDefinition.find(n => n.current.page === LICENCE_FOR.page)
|
|
55
|
+
expect(isolatedJourneyGoal.backLink({})).toBe(JOURNEY_GOAL.uri)
|
|
56
|
+
delete process.env.CHANNEL
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('has a back-link to the licence summary in telesales journey if the summary is seen', () => {
|
|
61
|
+
jest.isolateModules(() => {
|
|
62
|
+
process.env.CHANNEL = 'telesales'
|
|
63
|
+
const isolatedJourneyDefinition = require('../journey-definition.js').default
|
|
64
|
+
const isolatedJourneyGoal = isolatedJourneyDefinition.find(n => n.current.page === LICENCE_FOR.page)
|
|
65
|
+
expect(isolatedJourneyGoal.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
66
|
+
delete process.env.CHANNEL
|
|
67
|
+
})
|
|
68
|
+
})
|
|
34
69
|
})
|
|
35
70
|
|
|
36
71
|
describe('The date-of-birth page', () => {
|
|
37
72
|
const n = journeyDefinition.find(n => n.current.page === DATE_OF_BIRTH.page)
|
|
73
|
+
|
|
38
74
|
it('has a back-link to the name page on initial viewing', () => {
|
|
39
75
|
expect(n.backLink({})).toBe(NAME.uri)
|
|
40
76
|
})
|
|
77
|
+
|
|
41
78
|
it('has a back-link to the licence summary if the summary is seen', () => {
|
|
42
79
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
43
80
|
})
|
|
@@ -45,9 +82,11 @@ describe('The date-of-birth page', () => {
|
|
|
45
82
|
|
|
46
83
|
describe('The licence-to-start page', () => {
|
|
47
84
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_TO_START.page)
|
|
85
|
+
|
|
48
86
|
it('has a back-link to the disability concessions page on initial viewing', () => {
|
|
49
87
|
expect(n.backLink({})).toBe(DISABILITY_CONCESSION.uri)
|
|
50
88
|
})
|
|
89
|
+
|
|
51
90
|
it('has a back-link to the license summary if the summary is seen', () => {
|
|
52
91
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
53
92
|
})
|
|
@@ -55,9 +94,11 @@ describe('The licence-to-start page', () => {
|
|
|
55
94
|
|
|
56
95
|
describe('The disability-concession page', () => {
|
|
57
96
|
const n = journeyDefinition.find(n => n.current.page === DISABILITY_CONCESSION.page)
|
|
97
|
+
|
|
58
98
|
it('has a back-link to the date-of-birth page on initial viewing', () => {
|
|
59
99
|
expect(n.backLink({})).toBe(DATE_OF_BIRTH.uri)
|
|
60
100
|
})
|
|
101
|
+
|
|
61
102
|
it('has a back-link to the license summary if the summary is seen', () => {
|
|
62
103
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
63
104
|
})
|
|
@@ -65,9 +106,11 @@ describe('The disability-concession page', () => {
|
|
|
65
106
|
|
|
66
107
|
describe('The licence-type page', () => {
|
|
67
108
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_TYPE.page)
|
|
109
|
+
|
|
68
110
|
it('has a back-link to the disability-concession page on initial viewing', () => {
|
|
69
111
|
expect(n.backLink({})).toBe(LICENCE_TO_START.uri)
|
|
70
112
|
})
|
|
113
|
+
|
|
71
114
|
it('has a back-link to the license summary if the summary is seen', () => {
|
|
72
115
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
73
116
|
})
|
|
@@ -75,9 +118,11 @@ describe('The licence-type page', () => {
|
|
|
75
118
|
|
|
76
119
|
describe('The licence-length page', () => {
|
|
77
120
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_LENGTH.page)
|
|
121
|
+
|
|
78
122
|
it('has a back-link to the licence-type page on initial viewing', () => {
|
|
79
123
|
expect(n.backLink({})).toBe(LICENCE_TYPE.uri)
|
|
80
124
|
})
|
|
125
|
+
|
|
81
126
|
it('has a back-link to the license summary if the summary is seen', () => {
|
|
82
127
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
83
128
|
})
|
|
@@ -85,9 +130,11 @@ describe('The licence-length page', () => {
|
|
|
85
130
|
|
|
86
131
|
describe('The licence-start-time page', () => {
|
|
87
132
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_START_TIME.page)
|
|
133
|
+
|
|
88
134
|
it('has a back-link to the licence-length page on initial viewing', () => {
|
|
89
135
|
expect(n.backLink({})).toBe(LICENCE_LENGTH.uri)
|
|
90
136
|
})
|
|
137
|
+
|
|
91
138
|
it('has a back-link to the licence-to-start page if the summary is seen', () => {
|
|
92
139
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_TO_START.uri)
|
|
93
140
|
})
|
|
@@ -95,9 +142,11 @@ describe('The licence-start-time page', () => {
|
|
|
95
142
|
|
|
96
143
|
describe('The name page', () => {
|
|
97
144
|
const n = journeyDefinition.find(n => n.current.page === NAME.page)
|
|
145
|
+
|
|
98
146
|
it('has a back-link to the licence-summary page if the licence-summary is seen', () => {
|
|
99
147
|
expect(n.backLink({ fromSummary: LICENCE_SUMMARY_SEEN })).toBe(LICENCE_SUMMARY.uri)
|
|
100
148
|
})
|
|
149
|
+
|
|
101
150
|
it('has a back-link to the licence-for page if the contact summary has not been seen', () => {
|
|
102
151
|
expect(n.backLink({})).toBe(LICENCE_FOR.uri)
|
|
103
152
|
})
|
|
@@ -105,9 +154,11 @@ describe('The name page', () => {
|
|
|
105
154
|
|
|
106
155
|
describe('The address-lookup page', () => {
|
|
107
156
|
const n = journeyDefinition.find(n => n.current.page === ADDRESS_LOOKUP.page)
|
|
157
|
+
|
|
108
158
|
it('has a back-link to the licence-summary page if the contact summary has not been seen', () => {
|
|
109
159
|
expect(n.backLink({})).toBe(LICENCE_SUMMARY.uri)
|
|
110
160
|
})
|
|
161
|
+
|
|
111
162
|
it('has a back-link to the contact-summary page if the contact-summary is seen', () => {
|
|
112
163
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN })).toBe(CONTACT_SUMMARY.uri)
|
|
113
164
|
})
|
|
@@ -115,9 +166,11 @@ describe('The address-lookup page', () => {
|
|
|
115
166
|
|
|
116
167
|
describe('The address-entry page', () => {
|
|
117
168
|
const n = journeyDefinition.find(n => n.current.page === ADDRESS_ENTRY.page)
|
|
169
|
+
|
|
118
170
|
it('has a back-link to the address-lookup page if the contact summary has not been seen', () => {
|
|
119
171
|
expect(n.backLink({})).toBe(ADDRESS_LOOKUP.uri)
|
|
120
172
|
})
|
|
173
|
+
|
|
121
174
|
it('has a back-link to the contact-summary page if the contact-summary is seen', () => {
|
|
122
175
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN })).toBe(CONTACT_SUMMARY.uri)
|
|
123
176
|
})
|
|
@@ -128,10 +181,12 @@ describe('The licence-fulfilment page', () => {
|
|
|
128
181
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_FULFILMENT.page)
|
|
129
182
|
expect(n.backLink({})).toBe(ADDRESS_LOOKUP.uri)
|
|
130
183
|
})
|
|
184
|
+
|
|
131
185
|
it('has a back-link to the contact-summary page if the contact-summary is seen', () => {
|
|
132
186
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_FULFILMENT.page)
|
|
133
187
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN })).toBe(CONTACT_SUMMARY.uri)
|
|
134
188
|
})
|
|
189
|
+
|
|
135
190
|
it('has a back-link to the licence-summary page if in renewal', () => {
|
|
136
191
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_FULFILMENT.page)
|
|
137
192
|
expect(n.backLink({}, { isRenewal: true })).toBe(LICENCE_SUMMARY.uri)
|
|
@@ -143,14 +198,17 @@ describe('The licence-confirmation page', () => {
|
|
|
143
198
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_CONFIRMATION_METHOD.page)
|
|
144
199
|
expect(n.backLink({})).toBe(LICENCE_FULFILMENT.uri)
|
|
145
200
|
})
|
|
201
|
+
|
|
146
202
|
it('has a back-link to the licence-fulfilment page if the contact-summary has been seen and the last sumbitted page is licence-fulfilment', () => {
|
|
147
203
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_CONFIRMATION_METHOD.page)
|
|
148
204
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN, currentPage: LICENCE_FULFILMENT.page })).toBe(LICENCE_FULFILMENT.uri)
|
|
149
205
|
})
|
|
206
|
+
|
|
150
207
|
it('has a back-link to the licence-fulfilment page if the contact-summary has been seen and the last sumbitted page is licence-confirmation-method', () => {
|
|
151
208
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_CONFIRMATION_METHOD.page)
|
|
152
209
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN, currentPage: LICENCE_CONFIRMATION_METHOD.page })).toBe(LICENCE_FULFILMENT.uri)
|
|
153
210
|
})
|
|
211
|
+
|
|
154
212
|
it('has a back-link to the contact-summary page if the contact-summary is seen', () => {
|
|
155
213
|
const n = journeyDefinition.find(n => n.current.page === LICENCE_CONFIRMATION_METHOD.page)
|
|
156
214
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN })).toBe(CONTACT_SUMMARY.uri)
|
|
@@ -159,18 +217,22 @@ describe('The licence-confirmation page', () => {
|
|
|
159
217
|
|
|
160
218
|
describe('The contact page', () => {
|
|
161
219
|
const n = journeyDefinition.find(n => n.current.page === CONTACT.page)
|
|
220
|
+
|
|
162
221
|
it('has a back-link to the address-lookup page if the contact summary has not been seen and is not a physical licence', () => {
|
|
163
222
|
expect(n.backLink({}, {})).toBe(ADDRESS_LOOKUP.uri)
|
|
164
223
|
})
|
|
224
|
+
|
|
165
225
|
it('has a back-link to the licence confirmation method page if the contact summary has not been seen and is a physical licence', () => {
|
|
166
226
|
isPhysical.mockReturnValueOnce(true)
|
|
167
227
|
expect(n.backLink({}, {})).toBe(LICENCE_CONFIRMATION_METHOD.uri)
|
|
168
228
|
})
|
|
229
|
+
|
|
169
230
|
it('has a back-link to the licence confirmation method page if the contact summary has been seen and the last submitted page is licence confirmation method', () => {
|
|
170
231
|
expect(n.backLink({ currentPage: LICENCE_CONFIRMATION_METHOD.page, fromSummary: CONTACT_SUMMARY_SEEN })).toBe(
|
|
171
232
|
LICENCE_CONFIRMATION_METHOD.uri
|
|
172
233
|
)
|
|
173
234
|
})
|
|
235
|
+
|
|
174
236
|
it('has a back-link to the contact-summary page if the contact-summary is seen', () => {
|
|
175
237
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN })).toBe(CONTACT_SUMMARY.uri)
|
|
176
238
|
})
|
|
@@ -178,9 +240,11 @@ describe('The contact page', () => {
|
|
|
178
240
|
|
|
179
241
|
describe('The newsletter page', () => {
|
|
180
242
|
const n = journeyDefinition.find(n => n.current.page === NEWSLETTER.page)
|
|
243
|
+
|
|
181
244
|
it('has a back-link to the contact page if the contact summary has not been seen', () => {
|
|
182
245
|
expect(n.backLink({})).toBe(CONTACT.uri)
|
|
183
246
|
})
|
|
247
|
+
|
|
184
248
|
it('has a back-link to the contact-summary page if the contact-summary is seen', () => {
|
|
185
249
|
expect(n.backLink({ fromSummary: CONTACT_SUMMARY_SEEN })).toBe(CONTACT_SUMMARY.uri)
|
|
186
250
|
})
|
|
@@ -188,6 +252,7 @@ describe('The newsletter page', () => {
|
|
|
188
252
|
|
|
189
253
|
describe('The choose payment page', () => {
|
|
190
254
|
const n = journeyDefinition.find(n => n.current.page === CHOOSE_PAYMENT.page)
|
|
255
|
+
|
|
191
256
|
it('has a back-link to the terms and conditions page', () => {
|
|
192
257
|
expect(n.backLink).toBe(TERMS_AND_CONDITIONS.uri)
|
|
193
258
|
})
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
CANCEL_RP_CONFIRM,
|
|
36
36
|
CANCEL_RP_COMPLETE,
|
|
37
37
|
CANCEL_RP_AGREEMENT_NOT_FOUND,
|
|
38
|
+
JOURNEY_GOAL,
|
|
38
39
|
CANCEL_RP_ALREADY_CANCELLED,
|
|
39
40
|
CANCEL_RP_LICENCE_NOT_FOUND
|
|
40
41
|
} from '../uri.js'
|
|
@@ -45,8 +46,34 @@ import { licenceToStartResults } from '../pages/licence-details/licence-to-start
|
|
|
45
46
|
import { addressLookupResults } from '../pages/contact/address/lookup/result-function.js'
|
|
46
47
|
import { ageConcessionResults } from '../pages/concessions/date-of-birth/result-function.js'
|
|
47
48
|
import { licenceLengthResults } from '../pages/licence-details/licence-length/result-function.js'
|
|
49
|
+
import { journeyGoalResults } from '../pages/journey-goal/result-function.js'
|
|
48
50
|
import { isPhysical } from '../processors/licence-type-display.js'
|
|
49
51
|
|
|
52
|
+
const getJourneyStart = () => {
|
|
53
|
+
if (process.env.CHANNEL === 'telesales') {
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
current: { page: 'start' },
|
|
57
|
+
next: {
|
|
58
|
+
[CommonResults.OK]: {
|
|
59
|
+
page: JOURNEY_GOAL
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
current: { page: 'start' },
|
|
68
|
+
next: {
|
|
69
|
+
[CommonResults.OK]: {
|
|
70
|
+
page: LICENCE_FOR
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
|
|
50
77
|
/**
|
|
51
78
|
* The structure of each atom is as follows
|
|
52
79
|
* current - the current page
|
|
@@ -54,13 +81,22 @@ import { isPhysical } from '../processors/licence-type-display.js'
|
|
|
54
81
|
* backLink - the location the back link, a uri literal, a function of the current status of a function of the status and transaction
|
|
55
82
|
*/
|
|
56
83
|
export default [
|
|
84
|
+
...getJourneyStart(),
|
|
85
|
+
|
|
57
86
|
{
|
|
58
|
-
current:
|
|
87
|
+
current: JOURNEY_GOAL,
|
|
59
88
|
next: {
|
|
60
|
-
[
|
|
89
|
+
[journeyGoalResults.CANCEL_RECURRING_PAYMENT]: {
|
|
90
|
+
page: CANCEL_RP_IDENTIFY
|
|
91
|
+
},
|
|
92
|
+
[journeyGoalResults.RENEW_PERMISSION]: {
|
|
93
|
+
page: IDENTIFY
|
|
94
|
+
},
|
|
95
|
+
[journeyGoalResults.PURCHASE_PERMISSION]: {
|
|
61
96
|
page: LICENCE_FOR
|
|
62
97
|
}
|
|
63
|
-
}
|
|
98
|
+
},
|
|
99
|
+
backLink: () => null
|
|
64
100
|
},
|
|
65
101
|
|
|
66
102
|
{
|
|
@@ -73,7 +109,15 @@ export default [
|
|
|
73
109
|
page: LICENCE_SUMMARY
|
|
74
110
|
}
|
|
75
111
|
},
|
|
76
|
-
backLink: s =>
|
|
112
|
+
backLink: s => {
|
|
113
|
+
if (s.fromSummary) {
|
|
114
|
+
return LICENCE_SUMMARY.uri
|
|
115
|
+
}
|
|
116
|
+
if (process.env.CHANNEL === 'telesales') {
|
|
117
|
+
return JOURNEY_GOAL.uri
|
|
118
|
+
}
|
|
119
|
+
return null
|
|
120
|
+
}
|
|
77
121
|
},
|
|
78
122
|
|
|
79
123
|
{
|
|
@@ -421,9 +465,9 @@ export default [
|
|
|
421
465
|
[CommonResults.OK]: {
|
|
422
466
|
page: LICENCE_SUMMARY
|
|
423
467
|
}
|
|
424
|
-
}
|
|
468
|
+
},
|
|
469
|
+
...(process.env.CHANNEL === 'telesales' ? { backLink: JOURNEY_GOAL.uri } : {})
|
|
425
470
|
},
|
|
426
|
-
|
|
427
471
|
{
|
|
428
472
|
current: LICENCE_NOT_FOUND,
|
|
429
473
|
backLink: IDENTIFY.uri
|
|
@@ -442,7 +486,8 @@ export default [
|
|
|
442
486
|
[CommonResults.OK]: {
|
|
443
487
|
page: CANCEL_RP_DETAILS
|
|
444
488
|
}
|
|
445
|
-
}
|
|
489
|
+
},
|
|
490
|
+
...(process.env.CHANNEL === 'telesales' ? { backLink: JOURNEY_GOAL.uri } : {})
|
|
446
491
|
},
|
|
447
492
|
{
|
|
448
493
|
current: CANCEL_RP_DETAILS,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OIDC_SIGNIN, OIDC_ACCOUNT_DISABLED, OIDC_ROLE_REQUIRED, CONTROLLER } from '../uri.js'
|
|
2
2
|
import { signIn } from '../handlers/oidc-handler.js'
|
|
3
|
+
import journeyGoal from '../pages/journey-goal/route.js'
|
|
3
4
|
import cancelRPIdentify from '../pages/recurring-payments/cancel/identify/route.js'
|
|
4
5
|
import cancelRPDetails from '../pages/recurring-payments/cancel/details/route.js'
|
|
5
6
|
import cancelRPConfirm from '../pages/recurring-payments/cancel/confirm/route.js'
|
|
@@ -31,7 +32,8 @@ const telesalesRoutes = [
|
|
|
31
32
|
path: OIDC_ROLE_REQUIRED.uri,
|
|
32
33
|
handler: async (request, h) => h.view(OIDC_ROLE_REQUIRED.page, { uri: { buy: CONTROLLER.uri } }),
|
|
33
34
|
options: { auth: false }
|
|
34
|
-
}
|
|
35
|
+
},
|
|
36
|
+
...journeyGoal
|
|
35
37
|
]
|
|
36
38
|
|
|
37
39
|
if (process.env.SHOW_CANCELLATION_JOURNEY === 'true') {
|
package/src/uri.js
CHANGED
|
@@ -77,6 +77,8 @@ export const CANCEL_RP_AGREEMENT_NOT_FOUND = {
|
|
|
77
77
|
export const CANCEL_RP_LICENCE_NOT_FOUND = { uri: '/buy/cancel-recurring-payment/licence-not-found', page: 'licence-not-found' }
|
|
78
78
|
export const CANCEL_RP_ALREADY_CANCELLED = { uri: '/buy/cancel-recurring-payment/already-cancelled', page: 'already-cancelled' }
|
|
79
79
|
|
|
80
|
+
export const JOURNEY_GOAL = { uri: '/buy/journey-goal', page: 'journey-goal' }
|
|
81
|
+
|
|
80
82
|
/**
|
|
81
83
|
* These are informational static pages
|
|
82
84
|
*/
|