@defra-fish/gafl-webapp-service 1.23.0-rc.9 → 1.23.0
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/__tests__/server.spec.js +86 -1
- package/src/constants.js +1 -0
- package/src/handlers/__tests__/page-handler.spec.js +142 -29
- package/src/handlers/__tests__/{url-handler.spec.js → renewals-friendly-url-handler.spec.js} +19 -23
- package/src/handlers/authentication-handler.js +1 -1
- package/src/handlers/page-handler.js +7 -6
- package/src/handlers/{url-handler.js → renewals-friendly-url-handler.js} +6 -4
- package/src/handlers/result-functions.js +1 -1
- package/src/locales/cy.json +208 -211
- package/src/locales/en.json +9 -6
- package/src/pages/concessions/date-of-birth/date-of-birth.njk +6 -3
- package/src/pages/contact/address/entry/address-entry.njk +1 -1
- package/src/pages/contact/address/lookup/__tests__/route.spec.js +54 -16
- package/src/pages/contact/address/lookup/address-lookup.njk +5 -3
- package/src/pages/contact/address/lookup/route.js +3 -2
- package/src/pages/contact/address/select/address-select.njk +2 -2
- package/src/pages/contact/digital-licence/check-confirmation-contact/check-confirmation-contact.njk +9 -22
- package/src/pages/contact/digital-licence/licence-confirmation-method/licence-confirmation-method.njk +3 -1
- package/src/pages/guidance/accessibility-statement.njk +1 -1
- package/src/pages/guidance/cookies.njk +1 -1
- package/src/pages/guidance/os-terms.njk +1 -1
- package/src/pages/guidance/privacy-policy.njk +1 -1
- package/src/pages/guidance/refund-policy.njk +1 -1
- package/src/pages/layout/layout.njk +15 -0
- package/src/pages/licence-details/licence-length/licence-length.njk +2 -2
- package/src/pages/licence-details/licence-type/licence-type.njk +2 -2
- package/src/pages/macros/licence-type-summary.njk +19 -0
- package/src/pages/macros/pricing-summary.njk +6 -2
- package/src/pages/renewals/identify/route.js +1 -1
- package/src/pages/terms-and-conditions/terms-and-conditions.njk +7 -7
- package/src/processors/__tests__/uri-helper.spec.js +21 -0
- package/src/processors/uri-helper.js +4 -0
- package/src/routes/__tests__/misc-routes-handlers.spec.js +251 -0
- package/src/routes/__tests__/next-page.spec.js +48 -0
- package/src/routes/misc-routes.js +20 -11
- package/src/routes/next-page.js +3 -4
- package/src/server.js +9 -6
- package/src/session-cache/__tests__/session-manager.spec.js +14 -7
- package/src/session-cache/session-manager.js +2 -2
- package/src/uri.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/gafl-webapp-service",
|
|
3
|
-
"version": "1.23.0
|
|
3
|
+
"version": "1.23.0",
|
|
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.23.0
|
|
40
|
-
"@defra-fish/connectors-lib": "1.23.0
|
|
39
|
+
"@defra-fish/business-rules-lib": "1.23.0",
|
|
40
|
+
"@defra-fish/connectors-lib": "1.23.0",
|
|
41
41
|
"@defra/hapi-gapi": "^1.1.0",
|
|
42
42
|
"@hapi/boom": "^9.1.2",
|
|
43
43
|
"@hapi/catbox-redis": "^6.0.2",
|
|
@@ -76,5 +76,5 @@
|
|
|
76
76
|
"gulp-sourcemaps": "^3.0.0",
|
|
77
77
|
"node-sass": "^6.0.1"
|
|
78
78
|
},
|
|
79
|
-
"gitHead": "
|
|
79
|
+
"gitHead": "17bfa0e0f8071495932dd25f05f70f936f42d676"
|
|
80
80
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import { createServer, init, server } from '../server.js'
|
|
1
|
+
import { createServer, init, server, layoutContextAmalgamation } from '../server.js'
|
|
2
2
|
import CatboxMemory from '@hapi/catbox-memory'
|
|
3
|
+
import uris from '../uri.js'
|
|
3
4
|
|
|
4
5
|
jest.mock('@defra-fish/connectors-lib')
|
|
6
|
+
jest.mock('../uri.js', () => ({
|
|
7
|
+
...jest.requireActual('../uri.js'),
|
|
8
|
+
ACCESSIBILITY_STATEMENT: { uri: '/ACCESSIBILITY_STATEMENT' },
|
|
9
|
+
COOKIES: { uri: '/COOKIES' },
|
|
10
|
+
PRIVACY_POLICY: { uri: '/PRIVACY_POLICY' },
|
|
11
|
+
REFUND_POLICY: { uri: '/REFUND_POLICY' },
|
|
12
|
+
NEW_TRANSACTION: { uri: '/NEW_TRANSACTION' }
|
|
13
|
+
}))
|
|
5
14
|
|
|
6
15
|
export const catboxOptions = {
|
|
7
16
|
port: 1234,
|
|
@@ -69,4 +78,80 @@ describe('The server', () => {
|
|
|
69
78
|
}
|
|
70
79
|
})
|
|
71
80
|
})
|
|
81
|
+
|
|
82
|
+
describe('layoutContextAmalgamation', () => {
|
|
83
|
+
it('should add query parameters to the response', () => {
|
|
84
|
+
const request = getSampleRequest()
|
|
85
|
+
layoutContextAmalgamation(request, {})
|
|
86
|
+
expect(request.response.source.context._uri.queryParams).toStrictEqual({ lang: 'cy' })
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it.each([
|
|
90
|
+
['true', true],
|
|
91
|
+
['TRUE', true],
|
|
92
|
+
['false', false],
|
|
93
|
+
['FALSE', false]
|
|
94
|
+
])(
|
|
95
|
+
'if SHOW_WELSH_CONTENT is %s, it should set SHOW_WELSH_CONTENT to %s in the response',
|
|
96
|
+
(inputShowWelshContent, outputShowWelshContent) => {
|
|
97
|
+
process.env.SHOW_WELSH_CONTENT = inputShowWelshContent
|
|
98
|
+
const request = getSampleRequest()
|
|
99
|
+
layoutContextAmalgamation(request, {})
|
|
100
|
+
expect(request.response.source.context.SHOW_WELSH_CONTENT).toBe(outputShowWelshContent)
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
it.each([
|
|
105
|
+
['cookies', 'cookies.url', 'COOKIES'],
|
|
106
|
+
['refunds', 'refunds.url', 'REFUND_POLICY'],
|
|
107
|
+
['accessibility', 'access.ibility.uri', 'ACCESSIBILITY_STATEMENT'],
|
|
108
|
+
['privacy', 'privacy.uri', 'PRIVACY_POLICY'],
|
|
109
|
+
['clear', 'new-transaction.url', 'NEW_TRANSACTION']
|
|
110
|
+
])('should append Welsh language code to _uri elements if the current page contains it', (element, uri, uriConst) => {
|
|
111
|
+
const request = getSampleRequest({
|
|
112
|
+
url: {
|
|
113
|
+
search: '?lang=cy'
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
uris[uriConst] = { uri }
|
|
117
|
+
const regexMatch = new RegExp(`^${uri}\\?lang=cy$`)
|
|
118
|
+
console.log('request?.url?.path?.search', request?.url?.path?.search)
|
|
119
|
+
layoutContextAmalgamation(request, {})
|
|
120
|
+
expect(request.response.source.context._uri[element]).toEqual(expect.stringMatching(regexMatch))
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it.each([
|
|
124
|
+
['cookies', 'biscuits.url', 'COOKIES'],
|
|
125
|
+
['refunds', 'i-want-my-money-back.url', 'REFUND_POLICY'],
|
|
126
|
+
['accessibility', 'easy-to-use.uri', 'ACCESSIBILITY_STATEMENT'],
|
|
127
|
+
['privacy', 'private.uri', 'PRIVACY_POLICY'],
|
|
128
|
+
['clear', 'clear.url', 'NEW_TRANSACTION']
|
|
129
|
+
])("should omit Welsh language code from _uri elements if the current page doesn't contain it", (element, uri, uriConst) => {
|
|
130
|
+
const request = getSampleRequest({
|
|
131
|
+
url: {
|
|
132
|
+
search: ''
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
uris[uriConst] = { uri }
|
|
136
|
+
const regexMatch = new RegExp(`^${uri}$`)
|
|
137
|
+
layoutContextAmalgamation(request, {})
|
|
138
|
+
expect(request.response.source.context._uri[element]).toEqual(expect.stringMatching(regexMatch))
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const getSampleRequest = (overrides = {}) => ({
|
|
142
|
+
auth: {},
|
|
143
|
+
method: 'get',
|
|
144
|
+
response: {
|
|
145
|
+
variety: 'view',
|
|
146
|
+
source: {
|
|
147
|
+
context: {}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
query: { lang: 'cy' },
|
|
151
|
+
url: {
|
|
152
|
+
search: ''
|
|
153
|
+
},
|
|
154
|
+
...overrides
|
|
155
|
+
})
|
|
156
|
+
})
|
|
72
157
|
})
|
package/src/constants.js
CHANGED
|
@@ -14,6 +14,7 @@ export const FEEDBACK_URI_DEFAULT = '#'
|
|
|
14
14
|
export const CHANNEL_DEFAULT = 'websales'
|
|
15
15
|
export const SERVICE_PAGE_DEFAULT = 'https://www.gov.uk/fishing-licences/buy-a-fishing-licence'
|
|
16
16
|
export const RENEWALS_CAMPAIGN_ID = 'renewals'
|
|
17
|
+
export const AEN_INVITATION_ID = 'aen_invitation'
|
|
17
18
|
|
|
18
19
|
export const COMPLETION_STATUS = {
|
|
19
20
|
agreed: 'agreed',
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import db from 'debug'
|
|
2
2
|
import pageHandler from '../page-handler.js'
|
|
3
|
+
import journeyDefinition from '../../routes/journey-definition.js'
|
|
4
|
+
import { addLanguageCodeToUri } from '../../processors/uri-helper.js'
|
|
5
|
+
import GetDataRedirect from '../get-data-redirect.js'
|
|
3
6
|
|
|
4
7
|
jest.mock('debug', () => jest.fn(() => jest.fn()))
|
|
8
|
+
jest.mock('../../routes/journey-definition.js', () => [])
|
|
9
|
+
jest.mock('../../processors/uri-helper.js')
|
|
5
10
|
|
|
6
11
|
describe('The page handler function', () => {
|
|
7
12
|
let fakeDebug
|
|
@@ -9,22 +14,13 @@ describe('The page handler function', () => {
|
|
|
9
14
|
beforeAll(() => {
|
|
10
15
|
fakeDebug = db.mock.results[0].value
|
|
11
16
|
})
|
|
12
|
-
beforeEach(
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.resetAllMocks()
|
|
19
|
+
journeyDefinition.length = 0
|
|
20
|
+
})
|
|
13
21
|
|
|
14
22
|
it('the get method re-throws any exceptions which are not transaction errors ', async () => {
|
|
15
|
-
const request =
|
|
16
|
-
cache: () => ({
|
|
17
|
-
helpers: {
|
|
18
|
-
page: {
|
|
19
|
-
getCurrentPermission: () => ({})
|
|
20
|
-
},
|
|
21
|
-
status: {
|
|
22
|
-
getCurrentPermission: () => ({}),
|
|
23
|
-
setCurrentPermission: () => {}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
}
|
|
23
|
+
const request = getMockRequest()
|
|
28
24
|
|
|
29
25
|
const getData = async () => {
|
|
30
26
|
throw new Error('Random exception')
|
|
@@ -38,21 +34,9 @@ describe('The page handler function', () => {
|
|
|
38
34
|
})
|
|
39
35
|
|
|
40
36
|
it('the error method re-throws any exceptions which are not transaction errors ', async () => {
|
|
41
|
-
const request = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
page: {
|
|
45
|
-
setCurrentPermission: () => {
|
|
46
|
-
throw new Error('Random exception')
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
status: {
|
|
50
|
-
getCurrentPermission: () => ({}),
|
|
51
|
-
setCurrentPermission: () => {}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
}
|
|
37
|
+
const request = getMockRequest(() => {
|
|
38
|
+
throw new Error('Random exception')
|
|
39
|
+
})
|
|
56
40
|
try {
|
|
57
41
|
await pageHandler().error(request, null, { details: [] })
|
|
58
42
|
} catch (err) {
|
|
@@ -84,4 +68,133 @@ describe('The page handler function', () => {
|
|
|
84
68
|
expect(fakeDebug).toHaveBeenCalledWith(expect.stringContaining('Status cache'))
|
|
85
69
|
expect(fakeDebug).toHaveBeenCalledWith(expect.stringContaining('Transaction cache'))
|
|
86
70
|
})
|
|
71
|
+
|
|
72
|
+
it.each([['/previous/page'], ['/last/page']])('get calls addLanguageCodeToUri with request and backLink', async previousPage => {
|
|
73
|
+
const backLink = () => previousPage
|
|
74
|
+
journeyDefinition.push({ current: { page: 'view' }, backLink })
|
|
75
|
+
const { get } = pageHandler(null, 'view', '/next/page')
|
|
76
|
+
const request = getMockRequest(undefined, '/this/page')
|
|
77
|
+
const toolkit = getMockToolkit()
|
|
78
|
+
|
|
79
|
+
await get(request, toolkit)
|
|
80
|
+
|
|
81
|
+
expect(addLanguageCodeToUri).toHaveBeenCalledWith(request, backLink())
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it.each([[() => '/last/page'], ['previous/page']])(
|
|
85
|
+
'pageData.backRef from get uses value generated by addLanguageCodeToUri',
|
|
86
|
+
async backLink => {
|
|
87
|
+
journeyDefinition.push({ current: { page: 'view' }, backLink })
|
|
88
|
+
const { get } = pageHandler(null, 'view', '/next/page')
|
|
89
|
+
const returnValue = Symbol('/previous/page')
|
|
90
|
+
addLanguageCodeToUri.mockReturnValueOnce(returnValue)
|
|
91
|
+
const toolkit = getMockToolkit()
|
|
92
|
+
|
|
93
|
+
await get(getMockRequest(), toolkit)
|
|
94
|
+
|
|
95
|
+
expect(toolkit.view).toHaveBeenCalledWith(
|
|
96
|
+
expect.any(String),
|
|
97
|
+
expect.objectContaining({
|
|
98
|
+
backRef: returnValue
|
|
99
|
+
})
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
it('pageData.backRef is null if backLink is null', async () => {
|
|
105
|
+
const backLink = () => {}
|
|
106
|
+
journeyDefinition.push({ current: { page: 'view' }, backLink })
|
|
107
|
+
const { get } = pageHandler(null, 'view', '/next/page')
|
|
108
|
+
const returnValue = Symbol('/previous/page')
|
|
109
|
+
addLanguageCodeToUri.mockReturnValueOnce(returnValue)
|
|
110
|
+
const toolkit = getMockToolkit()
|
|
111
|
+
|
|
112
|
+
await get(getMockRequest(), toolkit)
|
|
113
|
+
|
|
114
|
+
expect(toolkit.view).toHaveBeenCalledWith(
|
|
115
|
+
expect.any(String),
|
|
116
|
+
expect.objectContaining({
|
|
117
|
+
backRef: null
|
|
118
|
+
})
|
|
119
|
+
)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it.each([['/go/somewhere'], ['/go/somewhere/else']])(
|
|
123
|
+
'GetDataRedirect being thrown will pass url to be decorated to addLanguageCodeToUri',
|
|
124
|
+
async redirectUri => {
|
|
125
|
+
journeyDefinition.push({ current: { page: 'view' }, backLink: '/previous/page' })
|
|
126
|
+
const getData = () => {
|
|
127
|
+
throw new GetDataRedirect(redirectUri)
|
|
128
|
+
}
|
|
129
|
+
const { get } = pageHandler(null, 'view', '/next/page', getData)
|
|
130
|
+
const toolkit = getMockToolkit()
|
|
131
|
+
const request = getMockRequest()
|
|
132
|
+
|
|
133
|
+
await get(request, toolkit)
|
|
134
|
+
|
|
135
|
+
expect(addLanguageCodeToUri).toHaveBeenCalledWith(request, redirectUri)
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
it('GetDataRedirect being thrown will use addLanguageCodeToUri to decorate the redirect target', async () => {
|
|
140
|
+
journeyDefinition.push({ current: { page: 'view' }, backLink: '/previous/page' })
|
|
141
|
+
const getData = () => {
|
|
142
|
+
throw new GetDataRedirect('/go/somewhere/else')
|
|
143
|
+
}
|
|
144
|
+
const { get } = pageHandler(null, 'view', '/next/page', getData)
|
|
145
|
+
const returnValue = Symbol('/previous/page')
|
|
146
|
+
addLanguageCodeToUri.mockReturnValueOnce(returnValue)
|
|
147
|
+
const toolkit = getMockToolkit()
|
|
148
|
+
|
|
149
|
+
await get(getMockRequest(), toolkit)
|
|
150
|
+
|
|
151
|
+
expect(toolkit.redirect).toHaveBeenCalledWith(returnValue)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it('error calls addLanguageCodeToUri with request', async () => {
|
|
155
|
+
const { error } = pageHandler('', 'view')
|
|
156
|
+
const request = getMockRequest()
|
|
157
|
+
await error(request, getMockToolkit(), { details: [] })
|
|
158
|
+
expect(addLanguageCodeToUri).toHaveBeenCalledWith(request)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it.each([['/route/one'], ['/route/sixty-six']])('error redirects to uri decorated by addLanguageCodeToUri', async url => {
|
|
162
|
+
const { error } = pageHandler('', 'view')
|
|
163
|
+
const toolkit = getMockToolkit()
|
|
164
|
+
addLanguageCodeToUri.mockReturnValueOnce(`Redirect to url ${url}`)
|
|
165
|
+
await error(getMockRequest(undefined, url), toolkit, { details: [] })
|
|
166
|
+
expect(toolkit.redirect).toHaveBeenCalledWith(`Redirect to url ${url}`)
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
const getMockRequest = (setCurrentPermission = () => {}, path = '/we/are/here') => ({
|
|
171
|
+
cache: () => ({
|
|
172
|
+
helpers: {
|
|
173
|
+
page: {
|
|
174
|
+
getCurrentPermission: () => ({}),
|
|
175
|
+
setCurrentPermission
|
|
176
|
+
},
|
|
177
|
+
status: {
|
|
178
|
+
getCurrentPermission: () => ({}),
|
|
179
|
+
setCurrentPermission: () => {}
|
|
180
|
+
},
|
|
181
|
+
transaction: {
|
|
182
|
+
getCurrentPermission: () => {}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}),
|
|
186
|
+
i18n: {
|
|
187
|
+
getCatalog: () => {},
|
|
188
|
+
getLocales: () => [],
|
|
189
|
+
getLocale: () => ''
|
|
190
|
+
},
|
|
191
|
+
path,
|
|
192
|
+
url: {
|
|
193
|
+
search: ''
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
const getMockToolkit = () => ({
|
|
198
|
+
redirect: jest.fn(() => ({ takeover: () => {} })),
|
|
199
|
+
view: jest.fn()
|
|
87
200
|
})
|
package/src/handlers/__tests__/{url-handler.spec.js → renewals-friendly-url-handler.spec.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UTM, QUERYSTRING_LICENCE_KEY } from '../../constants'
|
|
2
|
-
import urlHandler from '../url-handler'
|
|
3
|
-
import {
|
|
2
|
+
import urlHandler from '../renewals-friendly-url-handler'
|
|
3
|
+
import { IDENTIFY } from '../../uri'
|
|
4
4
|
|
|
5
5
|
jest.mock('../../constants', () => ({
|
|
6
6
|
UTM: {
|
|
@@ -9,7 +9,10 @@ jest.mock('../../constants', () => ({
|
|
|
9
9
|
CONTENT: 'utmcontent',
|
|
10
10
|
SOURCE: 'utmsource',
|
|
11
11
|
TERM: 'utmterm'
|
|
12
|
-
}
|
|
12
|
+
},
|
|
13
|
+
RENEWALS_CAMPAIGN_ID: 'renewals',
|
|
14
|
+
AEN_INVITATION_ID: 'aen_invitation',
|
|
15
|
+
QUERYSTRING_LICENCE_KEY: 'reference'
|
|
13
16
|
}))
|
|
14
17
|
|
|
15
18
|
jest.mock('../../uri', () => ({
|
|
@@ -23,46 +26,39 @@ describe('The url handler', () => {
|
|
|
23
26
|
})
|
|
24
27
|
|
|
25
28
|
it('returns identify if no licence key', async () => {
|
|
26
|
-
const
|
|
29
|
+
const params = {
|
|
27
30
|
[UTM.CAMPAIGN]: 'renewals',
|
|
28
31
|
[QUERYSTRING_LICENCE_KEY]: null
|
|
29
32
|
}
|
|
30
33
|
const responseToolkit = generateResponseToolkitMock()
|
|
31
|
-
await urlHandler(generateRequestMock(
|
|
34
|
+
await urlHandler(generateRequestMock(params), responseToolkit)
|
|
32
35
|
expect(responseToolkit.redirect).toHaveBeenCalledWith(IDENTIFY.uri)
|
|
33
36
|
})
|
|
34
37
|
|
|
35
|
-
it.each([
|
|
36
|
-
|
|
37
|
-
['AH56F6'],
|
|
38
|
-
['GH330P']
|
|
39
|
-
])('6 digit reference number exists and returns ATTRIBUTION', async licenceKey => {
|
|
40
|
-
const query = {
|
|
41
|
-
[UTM.CAMPAIGN]: 'renewals',
|
|
38
|
+
it.each([['B2F11U'], ['AH56F6'], ['GH330P']])('6 digit reference number exists and returns ATTRIBUTION', async licenceKey => {
|
|
39
|
+
const params = {
|
|
42
40
|
[QUERYSTRING_LICENCE_KEY]: licenceKey
|
|
43
41
|
}
|
|
44
42
|
const responseToolkit = generateResponseToolkitMock()
|
|
45
|
-
await urlHandler(generateRequestMock(
|
|
46
|
-
const regExMatch = new RegExp(
|
|
43
|
+
await urlHandler(generateRequestMock(params), responseToolkit)
|
|
44
|
+
const regExMatch = new RegExp(`^/attribution-url\\?utmcampaign\\=renewals&utmsource\\=aen_invitation&reference\\=${licenceKey}$`)
|
|
47
45
|
expect(responseToolkit.redirect).toHaveBeenCalledWith(expect.stringMatching(regExMatch))
|
|
48
46
|
})
|
|
49
47
|
|
|
50
|
-
it.each([
|
|
51
|
-
|
|
52
|
-
['AH56'],
|
|
53
|
-
['GH330PPTD']
|
|
54
|
-
])('reference number is not 6 digits and returns back to IDENTIFY', async licenceKey => {
|
|
55
|
-
const query = {
|
|
48
|
+
it.each([['B2F11UH5D'], ['AH56'], ['GH330PPTD']])('reference number is not 6 digits and returns back to IDENTIFY', async licenceKey => {
|
|
49
|
+
const params = {
|
|
56
50
|
[UTM.CAMPAIGN]: 'renewals',
|
|
51
|
+
[UTM.SOURCE]: 'aen_invitation',
|
|
57
52
|
[QUERYSTRING_LICENCE_KEY]: licenceKey
|
|
58
53
|
}
|
|
59
54
|
const responseToolkit = generateResponseToolkitMock()
|
|
60
|
-
await urlHandler(generateRequestMock(
|
|
55
|
+
await urlHandler(generateRequestMock(params), responseToolkit)
|
|
61
56
|
expect(responseToolkit.redirect).toHaveBeenCalledWith(IDENTIFY.uri)
|
|
62
57
|
})
|
|
63
58
|
|
|
64
|
-
const generateRequestMock = (query, status = {}) => ({
|
|
65
|
-
|
|
59
|
+
const generateRequestMock = (params, query, status = {}) => ({
|
|
60
|
+
params,
|
|
61
|
+
query: { _ga: null },
|
|
66
62
|
cache: jest.fn(() => ({
|
|
67
63
|
helpers: {
|
|
68
64
|
status: {
|
|
@@ -20,7 +20,7 @@ export default async (request, h) => {
|
|
|
20
20
|
const dateOfBirth = await validation.contact
|
|
21
21
|
.createBirthDateValidator(Joi)
|
|
22
22
|
.validateAsync(`${payload['date-of-birth-year']}-${payload['date-of-birth-month']}-${payload['date-of-birth-day']}`)
|
|
23
|
-
const postcode = await validation.contact.
|
|
23
|
+
const postcode = await validation.contact.createOverseasPostcodeValidator(Joi).validateAsync(payload.postcode)
|
|
24
24
|
|
|
25
25
|
const permission = await request.cache().helpers.status.getCurrentPermission()
|
|
26
26
|
const referenceNumber = payload.referenceNumber || permission.referenceNumber
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import db from 'debug'
|
|
2
|
-
|
|
3
2
|
import { CacheError } from '../session-cache/cache-manager.js'
|
|
4
3
|
import { PAGE_STATE } from '../constants.js'
|
|
5
4
|
import { CONTROLLER } from '../uri.js'
|
|
6
5
|
import GetDataRedirect from './get-data-redirect.js'
|
|
7
6
|
import journeyDefinition from '../routes/journey-definition.js'
|
|
7
|
+
import { addLanguageCodeToUri } from '../processors/uri-helper.js'
|
|
8
8
|
|
|
9
9
|
const debug = db('webapp:page-handler')
|
|
10
10
|
|
|
@@ -24,18 +24,18 @@ export const errorShimm = e => e.details.reduce((a, c) => ({ ...a, [c.path[0]]:
|
|
|
24
24
|
*/
|
|
25
25
|
const getBackReference = async (request, view) => {
|
|
26
26
|
const current = journeyDefinition.find(p => p.current.page === view)
|
|
27
|
-
|
|
28
27
|
if (!current || !current.backLink) {
|
|
29
28
|
return null
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
if (typeof current.backLink === 'function') {
|
|
33
|
-
|
|
32
|
+
const backLink = current.backLink(
|
|
34
33
|
await request.cache().helpers.status.getCurrentPermission(),
|
|
35
34
|
await request.cache().helpers.transaction.getCurrentPermission()
|
|
36
35
|
)
|
|
36
|
+
return backLink ? addLanguageCodeToUri(request, backLink) : null
|
|
37
37
|
} else {
|
|
38
|
-
return current.backLink
|
|
38
|
+
return addLanguageCodeToUri(request, current.backLink)
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -90,7 +90,7 @@ export default (path, view, completion, getData) => ({
|
|
|
90
90
|
} catch (err) {
|
|
91
91
|
// If GetDataRedirect is thrown the getData function is requesting a redirect
|
|
92
92
|
if (err instanceof GetDataRedirect) {
|
|
93
|
-
return h.redirect(err.redirectUrl)
|
|
93
|
+
return h.redirect(addLanguageCodeToUri(request, err.redirectUrl))
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
throw err
|
|
@@ -137,7 +137,8 @@ export default (path, view, completion, getData) => ({
|
|
|
137
137
|
try {
|
|
138
138
|
await request.cache().helpers.page.setCurrentPermission(view, { payload: request.payload, error: errorShimm(err) })
|
|
139
139
|
await request.cache().helpers.status.setCurrentPermission({ [view]: PAGE_STATE.error, currentPage: view })
|
|
140
|
-
|
|
140
|
+
|
|
141
|
+
return h.redirect(addLanguageCodeToUri(request)).takeover()
|
|
141
142
|
} catch (err2) {
|
|
142
143
|
// Need a catch here if the user has posted an invalid response with no cookie
|
|
143
144
|
if (err2 instanceof CacheError) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QUERYSTRING_LICENCE_KEY } from '../constants.js'
|
|
1
|
+
import { QUERYSTRING_LICENCE_KEY, UTM, RENEWALS_CAMPAIGN_ID, AEN_INVITATION_ID } from '../constants.js'
|
|
2
2
|
import { initialiseAnalyticsSessionData } from '../processors/analytics.js'
|
|
3
3
|
import { IDENTIFY, ATTRIBUTION } from '../uri.js'
|
|
4
4
|
|
|
@@ -10,11 +10,13 @@ import { IDENTIFY, ATTRIBUTION } from '../uri.js'
|
|
|
10
10
|
*/
|
|
11
11
|
export default async (request, h) => {
|
|
12
12
|
await initialiseAnalyticsSessionData(request)
|
|
13
|
-
if (request.
|
|
14
|
-
const refNumber = request.
|
|
13
|
+
if (request.params[QUERYSTRING_LICENCE_KEY]) {
|
|
14
|
+
const refNumber = request.params[QUERYSTRING_LICENCE_KEY]
|
|
15
15
|
const sixDigit = /^[A-Za-z0-9]{6}$/.test(refNumber)
|
|
16
16
|
if (sixDigit) {
|
|
17
|
-
return h.redirect(
|
|
17
|
+
return h.redirect(
|
|
18
|
+
`${ATTRIBUTION.uri}?${UTM.CAMPAIGN}=${RENEWALS_CAMPAIGN_ID}&${UTM.SOURCE}=${AEN_INVITATION_ID}&${QUERYSTRING_LICENCE_KEY}=${refNumber}`
|
|
19
|
+
)
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
return h.redirect(IDENTIFY.uri)
|
|
@@ -44,7 +44,7 @@ export default {
|
|
|
44
44
|
[DISABILITY_CONCESSION.page]: disabilityConcession,
|
|
45
45
|
[LICENCE_LENGTH.page]: licenceLength,
|
|
46
46
|
[LICENCE_TYPE.page]: licenceType,
|
|
47
|
-
[LICENCE_FOR]: licenceFor,
|
|
47
|
+
[LICENCE_FOR.page]: licenceFor,
|
|
48
48
|
[LICENCE_START_TIME.page]: licenceStartTime,
|
|
49
49
|
[ADDRESS_LOOKUP.page]: addressLookup,
|
|
50
50
|
[ADDRESS_ENTRY.page]: addressEntry,
|