@defra-fish/gafl-webapp-service 1.55.0-rc.6 → 1.55.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra-fish/gafl-webapp-service",
3
- "version": "1.55.0-rc.6",
3
+ "version": "1.55.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.55.0-rc.6",
40
- "@defra-fish/connectors-lib": "1.55.0-rc.6",
39
+ "@defra-fish/business-rules-lib": "1.55.0",
40
+ "@defra-fish/connectors-lib": "1.55.0",
41
41
  "@defra/hapi-gapi": "^2.0.0",
42
42
  "@hapi/boom": "^9.1.2",
43
43
  "@hapi/catbox-redis": "^6.0.2",
@@ -80,5 +80,5 @@
80
80
  "./gafl-jest-matchers.js"
81
81
  ]
82
82
  },
83
- "gitHead": "2c55000bca5980f5de132040edd1b7d1166e5d95"
83
+ "gitHead": "3405322b81a2016ba22e530de8d096a49be0bea4"
84
84
  }
@@ -1,8 +1,8 @@
1
1
  import { salesApi } from '@defra-fish/connectors-lib'
2
2
  import { COMPLETION_STATUS, RECURRING_PAYMENT } from '../../constants.js'
3
3
  import agreedHandler from '../agreed-handler.js'
4
- import { preparePayment, prepareRecurringPaymentAgreement } from '../../processors/payment.js'
5
- import { sendPayment, sendRecurringPayment, getPaymentStatus } from '../../services/payment/govuk-pay-service.js'
4
+ import { prepareRecurringPayment } from '../../processors/payment.js'
5
+ import { sendRecurringPayment } from '../../services/payment/govuk-pay-service.js'
6
6
  import { prepareApiTransactionPayload } from '../../processors/api-transaction.js'
7
7
  import { v4 as uuidv4 } from 'uuid'
8
8
  import db from 'debug'
@@ -10,13 +10,7 @@ import db from 'debug'
10
10
  jest.mock('@defra-fish/connectors-lib')
11
11
  jest.mock('../../processors/payment.js')
12
12
  jest.mock('../../services/payment/govuk-pay-service.js', () => ({
13
- sendPayment: jest.fn(() => ({
14
- payment_id: 'payment-id-1',
15
- _links: {
16
- next_url: { href: 'next-url' },
17
- self: { href: 'self-url' }
18
- }
19
- })),
13
+ sendPayment: jest.fn(),
20
14
  getPaymentStatus: jest.fn(),
21
15
  sendRecurringPayment: jest.fn(() => ({ agreementId: 'agr-eem-ent-id1' }))
22
16
  }))
@@ -38,12 +32,12 @@ describe('The agreed handler', () => {
38
32
  })
39
33
  beforeEach(jest.clearAllMocks)
40
34
 
41
- const getMockRequest = ({ overrides = {}, transactionSet = () => {} } = {}) => ({
35
+ const getMockRequest = (overrides = {}) => ({
42
36
  cache: () => ({
43
37
  helpers: {
44
38
  transaction: {
45
39
  get: async () => ({ cost: 0 }),
46
- set: transactionSet
40
+ set: async () => {}
47
41
  },
48
42
  status: {
49
43
  get: async () => ({
@@ -60,7 +54,6 @@ describe('The agreed handler', () => {
60
54
  })
61
55
 
62
56
  const getRequestToolkit = () => ({
63
- redirect: jest.fn(),
64
57
  redirectWithLanguageCode: jest.fn()
65
58
  })
66
59
 
@@ -68,20 +61,18 @@ describe('The agreed handler', () => {
68
61
  it('sends the request and transaction to prepare the recurring payment', async () => {
69
62
  const transaction = { cost: 0 }
70
63
  const mockRequest = getMockRequest({
71
- overrides: {
72
- transaction: {
73
- get: async () => transaction,
74
- set: () => {}
75
- }
64
+ transaction: {
65
+ get: async () => transaction,
66
+ set: () => {}
76
67
  }
77
68
  })
78
69
  await agreedHandler(mockRequest, getRequestToolkit())
79
- expect(prepareRecurringPaymentAgreement).toHaveBeenCalledWith(mockRequest, transaction)
70
+ expect(prepareRecurringPayment).toHaveBeenCalledWith(mockRequest, transaction)
80
71
  })
81
72
 
82
73
  it('adds a v4 guid to the transaction as an id', async () => {
83
74
  let transactionPayload = null
84
- prepareRecurringPaymentAgreement.mockImplementationOnce((_p1, tp) => {
75
+ prepareRecurringPayment.mockImplementationOnce((_p1, tp) => {
85
76
  transactionPayload = { ...tp }
86
77
  })
87
78
  const v4guid = Symbol('v4guid')
@@ -99,73 +90,46 @@ describe('The agreed handler', () => {
99
90
  expect(transactionPayload.id).toBe(v4guid)
100
91
  })
101
92
 
102
- it('sends a recurring payment agreement creation request to Gov.UK Pay', async () => {
103
- const preparedPayment = Symbol('preparedPayment')
104
- prepareRecurringPaymentAgreement.mockResolvedValueOnce(preparedPayment)
105
- await agreedHandler(getMockRequest(), getRequestToolkit())
106
- expect(sendRecurringPayment).toHaveBeenCalledWith(preparedPayment)
107
- })
108
-
109
- describe('when there is a cost and recurringAgreement status is set to true', () => {
110
- beforeEach(() => {
111
- salesApi.createTransaction.mockResolvedValueOnce({
112
- id: 'transaction-id-1',
113
- cost: 100
114
- })
115
- })
116
-
117
- it('calls preparePayment', async () => {
118
- const transaction = { id: Symbol('transaction') }
119
- const request = getMockRequest({
120
- overrides: {
121
- transaction: {
122
- get: async () => transaction,
123
- set: () => {}
124
- }
125
- }
126
- })
127
- const toolkit = getRequestToolkit()
128
-
129
- await agreedHandler(request, toolkit)
130
- expect(preparePayment).toHaveBeenCalledWith(request, transaction)
131
- })
132
-
133
- it('calls sendPayment with recurring as true', async () => {
134
- const preparedPayment = Symbol('preparedPayment')
135
- preparePayment.mockReturnValueOnce(preparedPayment)
136
-
137
- await agreedHandler(getMockRequest(), getRequestToolkit())
138
- expect(sendPayment).toHaveBeenCalledWith(preparedPayment, true)
93
+ it("doesn't overwrite transaction id if one is already set", async () => {
94
+ const setTransaction = jest.fn()
95
+ const transactionId = 'abc-123-def-456'
96
+ uuidv4.mockReturnValue('def-789-ghi-012')
97
+ salesApi.finaliseTransaction.mockReturnValueOnce({
98
+ permissions: []
139
99
  })
140
-
141
- it('calls getPaymentStatus with recurring as true', async () => {
142
- const id = Symbol('paymentId')
143
- const transaction = { id: '123', payment: { payment_id: id } }
144
- const request = getMockRequest({
145
- overrides: {
146
- transaction: {
147
- get: async () => transaction,
148
- set: () => {}
149
- },
100
+ const mockRequest = {
101
+ cache: () => ({
102
+ helpers: {
150
103
  status: {
151
104
  get: async () => ({
152
105
  [COMPLETION_STATUS.agreed]: true,
153
- [COMPLETION_STATUS.posted]: false,
154
- [COMPLETION_STATUS.finalised]: true,
155
- [RECURRING_PAYMENT]: true,
156
- [COMPLETION_STATUS.paymentCreated]: true
106
+ [COMPLETION_STATUS.posted]: true,
107
+ [COMPLETION_STATUS.finalised]: false,
108
+ [RECURRING_PAYMENT]: false
157
109
  }),
158
110
  set: () => {}
111
+ },
112
+ transaction: {
113
+ get: async () => ({ cost: 0, id: transactionId }),
114
+ set: setTransaction
159
115
  }
160
116
  }
161
117
  })
162
- const toolkit = getRequestToolkit()
118
+ }
163
119
 
164
- getPaymentStatus.mockReturnValueOnce({ state: { finished: true, status: 'success' } })
120
+ await agreedHandler(mockRequest, getRequestToolkit())
165
121
 
166
- await agreedHandler(request, toolkit)
167
- expect(getPaymentStatus).toHaveBeenCalledWith(id, true)
168
- })
122
+ expect(salesApi.finaliseTransaction).toHaveBeenCalledWith(
123
+ transactionId,
124
+ undefined // prepareApiFinalisationPayload has no mocked return value
125
+ )
126
+ })
127
+
128
+ it('sends a recurring payment creation request to Gov.UK Pay', async () => {
129
+ const preparedPayment = Symbol('preparedPayment')
130
+ prepareRecurringPayment.mockResolvedValueOnce(preparedPayment)
131
+ await agreedHandler(getMockRequest(), getRequestToolkit())
132
+ expect(sendRecurringPayment).toHaveBeenCalledWith(preparedPayment)
169
133
  })
170
134
 
171
135
  // this doesn't really belong here, but until the other agreed handler tests are refactored to
@@ -176,7 +140,7 @@ describe('The agreed handler', () => {
176
140
 
177
141
  await agreedHandler(getMockRequest(), getRequestToolkit())
178
142
 
179
- expect(prepareApiTransactionPayload).toHaveBeenCalledWith(expect.any(Object), v4guid, undefined)
143
+ expect(prepareApiTransactionPayload).toHaveBeenCalledWith(expect.any(Object), v4guid)
180
144
  })
181
145
 
182
146
  it.each(['zxy-098-wvu-765', '467482f1-099d-403d-b6b3-8db7e70d19e3'])(
@@ -194,23 +158,5 @@ describe('The agreed handler', () => {
194
158
  expect(debugMock).toHaveBeenCalledWith(`Created agreement with id ${agreement_id}`)
195
159
  }
196
160
  )
197
-
198
- it.each(['zxy-098-wvu-765', '467482f1-099d-403d-b6b3-8db7e70d19e3'])(
199
- "assigns agreement id '%s' to the transaction when recurring payment agreement created",
200
- async agreementId => {
201
- const mockTransactionCacheSet = jest.fn()
202
- sendRecurringPayment.mockResolvedValueOnce({
203
- agreement_id: agreementId
204
- })
205
-
206
- await agreedHandler(getMockRequest({ transactionSet: mockTransactionCacheSet }), getRequestToolkit())
207
-
208
- expect(mockTransactionCacheSet).toHaveBeenCalledWith(
209
- expect.objectContaining({
210
- agreementId
211
- })
212
- )
213
- }
214
- )
215
161
  })
216
162
  })
@@ -14,7 +14,7 @@ import db from 'debug'
14
14
  import { salesApi } from '@defra-fish/connectors-lib'
15
15
  import { prepareApiTransactionPayload, prepareApiFinalisationPayload } from '../processors/api-transaction.js'
16
16
  import { sendPayment, getPaymentStatus, sendRecurringPayment } from '../services/payment/govuk-pay-service.js'
17
- import { preparePayment, prepareRecurringPaymentAgreement } from '../processors/payment.js'
17
+ import { preparePayment, prepareRecurringPayment } from '../processors/payment.js'
18
18
  import { COMPLETION_STATUS, RECURRING_PAYMENT } from '../constants.js'
19
19
  import { ORDER_COMPLETE, PAYMENT_CANCELLED, PAYMENT_FAILED } from '../uri.js'
20
20
  import { PAYMENT_JOURNAL_STATUS_CODES, GOVUK_PAY_ERROR_STATUS_CODES } from '@defra-fish/business-rules-lib'
@@ -29,7 +29,7 @@ const debug = db('webapp:agreed-handler')
29
29
  * @returns {Promise<*>}
30
30
  */
31
31
  const sendToSalesApi = async (request, transaction, status) => {
32
- const apiTransactionPayload = await prepareApiTransactionPayload(request, transaction.id, transaction.agreementId)
32
+ const apiTransactionPayload = await prepareApiTransactionPayload(request, transaction.id)
33
33
  let response
34
34
  try {
35
35
  response = await salesApi.createTransaction(apiTransactionPayload)
@@ -63,7 +63,7 @@ const createRecurringPayment = async (request, transaction, status) => {
63
63
  /*
64
64
  * Prepare the payment payload
65
65
  */
66
- const preparedPayment = await prepareRecurringPaymentAgreement(request, transaction)
66
+ const preparedPayment = await prepareRecurringPayment(request, transaction)
67
67
 
68
68
  /*
69
69
  * Send the prepared payment to the GOV.UK pay API using the connector
@@ -72,11 +72,7 @@ const createRecurringPayment = async (request, transaction, status) => {
72
72
 
73
73
  debug(`Created agreement with id ${paymentResponse.agreement_id}`)
74
74
  status[COMPLETION_STATUS.recurringAgreement] = true
75
-
76
- transaction.agreementId = paymentResponse.agreement_id
77
-
78
75
  await request.cache().helpers.status.set(status)
79
- await request.cache().helpers.transaction.set(transaction)
80
76
  }
81
77
 
82
78
  /**
@@ -92,8 +88,6 @@ const createRecurringPayment = async (request, transaction, status) => {
92
88
  * @returns {Promise<void>}
93
89
  */
94
90
  const createPayment = async (request, transaction, status) => {
95
- const recurring = status && status[COMPLETION_STATUS.recurringAgreement] === true
96
-
97
91
  /*
98
92
  * Prepare the payment payload
99
93
  */
@@ -102,7 +96,7 @@ const createPayment = async (request, transaction, status) => {
102
96
  /*
103
97
  * Send the prepared payment to the GOV.UK pay API using the connector
104
98
  */
105
- const paymentResponse = await sendPayment(preparedPayment, recurring)
99
+ const paymentResponse = await sendPayment(preparedPayment)
106
100
 
107
101
  /*
108
102
  * Used by the payment mop up job, create the payment journal entry which is removed when the user completes the journey
@@ -149,12 +143,10 @@ const createPayment = async (request, transaction, status) => {
149
143
  * @returns {Promise<void>}
150
144
  */
151
145
  const processPayment = async (request, transaction, status) => {
152
- const recurring = status && status[COMPLETION_STATUS.recurringAgreement] === true
153
-
154
146
  /*
155
147
  * Get the payment status
156
148
  */
157
- const { state } = await getPaymentStatus(transaction.payment.payment_id, recurring)
149
+ const { state } = await getPaymentStatus(transaction.payment.payment_id)
158
150
 
159
151
  if (!state.finished) {
160
152
  throw Boom.forbidden('Attempt to access the agreed handler during payment journey')
@@ -466,11 +466,11 @@
466
466
  "licence_type_payment_edge_case": "Mae’n rhaid i chi gwblhau eich taliad cyn 11:30pm ar 31 Mawrth 2024 i dalu’r pris a ddangosir",
467
467
  "licence_type_radio_salmon_hint": "Mae'n cynnwys brithyllod a physgod bras (hyd at 3 gwialen)",
468
468
  "licence_type_radio_salmon": "Eogiaid a brithyllod y môr",
469
- "licence_type_radio_salmon_payment_summary": "Eogiaid a brithyllod y môr",
469
+ "licence_type_radio_salmon_payment_summary": "eogiaid a brithyllod y môr",
470
470
  "licence_type_radio_trout_three_rod": "Brithyllod a physgod bras (hyd at 3 gwialen)",
471
- "licence_type_radio_trout_three_rod_payment_summary": "Brithyllod a physgod bras (hyd at 3 gwialen)",
471
+ "licence_type_radio_trout_three_rod_payment_summary": "brithyllod a physgod bras (hyd at 3 gwialen)",
472
472
  "licence_type_radio_trout_two_rod": "Brithyllod a physgod bras (hyd at 2 wialen)",
473
- "licence_type_radio_trout_two_rod_payment_summary": "Brithyllod a physgod bras (hyd at 2 wialen)",
473
+ "licence_type_radio_trout_two_rod_payment_summary": "brithyllod a physgod bras (hyd at 2 wialen)",
474
474
  "licence_type_rules": "rheolau pysgota â gwialen (yn agor ar dudalen newydd)",
475
475
  "licence_type_salmon_acr_note_1": "Yn ôl y gyfraith, mae'n rhaid i chi roi gwybod am ",
476
476
  "licence_type_salmon_acr_note_2": " ffurflen daliadau (yn agor ar dudalen newydd)",
@@ -466,11 +466,11 @@
466
466
  "licence_type_payment_edge_case": "You must complete payment before 11:30pm on 31 March 2024 to get the price shown",
467
467
  "licence_type_radio_salmon_hint": "Includes trout and coarse (up to 3 rods)",
468
468
  "licence_type_radio_salmon": "Salmon and sea trout",
469
- "licence_type_radio_salmon_payment_summary": "Salmon and sea trout",
469
+ "licence_type_radio_salmon_payment_summary": "salmon and sea trout",
470
470
  "licence_type_radio_trout_three_rod": "Trout and coarse (up to 3 rods)",
471
- "licence_type_radio_trout_three_rod_payment_summary": "Trout and coarse (up to 3 rods)",
471
+ "licence_type_radio_trout_three_rod_payment_summary": "trout and coarse (up to 3 rods)",
472
472
  "licence_type_radio_trout_two_rod": "Trout and coarse (up to 2 rods)",
473
- "licence_type_radio_trout_two_rod_payment_summary": "Trout and coarse (up to 2 rods)",
473
+ "licence_type_radio_trout_two_rod_payment_summary": "trout and coarse (up to 2 rods)",
474
474
  "licence_type_rules": "rod fishing rules (opens in new tab)",
475
475
  "licence_type_salmon_acr_note_1": "Licence holders must by law ",
476
476
  "licence_type_salmon_acr_note_2": " report a catch return (opens in new tab)",
@@ -246,127 +246,6 @@ Array [
246
246
  ]
247
247
  `;
248
248
 
249
- exports[`licence-summary > route licence summary rows creates licence summary name rows for 1 year new three rod licence 1`] = `
250
- Array [
251
- Object {
252
- "actions": Object {
253
- "items": Array [
254
- Object {
255
- "attributes": Object {
256
- "id": "change-name",
257
- },
258
- "href": "/buy/name",
259
- "text": "contact_summary_change",
260
- "visuallyHiddenText": "licence_summary_name",
261
- },
262
- ],
263
- },
264
- "key": Object {
265
- "text": "licence_summary_name",
266
- },
267
- "value": Object {
268
- "html": "Brenin Pysgotwr",
269
- },
270
- },
271
- Object {
272
- "actions": Object {
273
- "items": Array [
274
- Object {
275
- "attributes": Object {
276
- "id": "change-birth-date",
277
- },
278
- "href": "/buy/date-of-birth",
279
- "text": "contact_summary_change",
280
- "visuallyHiddenText": "licence_summary_dob",
281
- },
282
- ],
283
- },
284
- "key": Object {
285
- "text": "licence_summary_dob",
286
- },
287
- "value": Object {
288
- "html": "1st January 1946",
289
- },
290
- },
291
- Object {
292
- "actions": Object {
293
- "items": Array [
294
- Object {
295
- "attributes": Object {
296
- "id": "change-licence-type",
297
- },
298
- "href": "/buy/licence-type",
299
- "text": "contact_summary_change",
300
- "visuallyHiddenText": "licence_summary_type",
301
- },
302
- ],
303
- },
304
- "key": Object {
305
- "text": "licence_summary_type",
306
- },
307
- "value": Object {
308
- "html": "Special Canal Licence, Shopping Trollies and Old Wellies",
309
- },
310
- },
311
- Object {
312
- "key": Object {
313
- "text": "licence_summary_length",
314
- },
315
- "value": Object {
316
- "html": "licence_type_12m",
317
- },
318
- },
319
- Object {
320
- "actions": Object {
321
- "items": Array [
322
- Object {
323
- "attributes": Object {
324
- "id": "change-licence-to-start",
325
- },
326
- "href": "/buy/start-kind",
327
- "text": "contact_summary_change",
328
- "visuallyHiddenText": "licence_summary_start_date",
329
- },
330
- ],
331
- },
332
- "key": Object {
333
- "text": "licence_summary_start_date",
334
- },
335
- "value": Object {
336
- "html": "30licence_summary_minutes_after_payment",
337
- },
338
- },
339
- Object {
340
- "actions": Object {
341
- "items": Array [
342
- Object {
343
- "attributes": Object {
344
- "id": "change-benefit-check",
345
- },
346
- "href": "/buy/disability-concession",
347
- "text": "contact_summary_change",
348
- "visuallyHiddenText": "licence_summary_ni_num",
349
- },
350
- ],
351
- },
352
- "key": Object {
353
- "text": "licence_summary_ni_num",
354
- },
355
- "value": Object {
356
- "html": "AB 12 34 56 A",
357
- },
358
- },
359
- Object {
360
- "key": Object {
361
- "text": "damage",
362
- },
363
- "value": Object {
364
- "html": "#6",
365
- },
366
- },
367
- ]
368
- `;
369
-
370
249
  exports[`licence-summary > route licence summary rows creates licence summary name rows for 1 year renewal 1`] = `
371
250
  Array [
372
251
  Object {
@@ -116,7 +116,7 @@ const getMockPermission = (licenseeOverrides = {}) => ({
116
116
  licenceToStart: 'after-payment',
117
117
  licenceStartDate: '2022-11-10',
118
118
  licenceType: 'Trout and coarse',
119
- numberOfRods: '2',
119
+ numberOfRods: '3',
120
120
  permit: { cost: 6 }
121
121
  })
122
122
 
@@ -372,17 +372,16 @@ describe('licence-summary > route', () => {
372
372
 
373
373
  describe('licence summary rows', () => {
374
374
  it.each`
375
- desc | currentPermission
376
- ${'1 year renewal'} | ${getMockPermission()}
377
- ${'1 year new licence'} | ${getMockNewPermission()}
378
- ${'1 year senior renewal'} | ${getMockSeniorPermission()}
379
- ${'8 day licence'} | ${{ ...getMockNewPermission(), licenceLength: '8D' }}
380
- ${'1 day licence'} | ${{ ...getMockNewPermission(), licenceLength: '1D' }}
381
- ${'Junior licence'} | ${getMockJuniorPermission()}
382
- ${'Blue badge concession'} | ${getMockBlueBadgePermission()}
383
- ${'Continuing permission'} | ${getMockContinuingPermission()}
384
- ${'Another date permission'} | ${{ ...getMockPermission(), licenceToStart: 'another-date' }}
385
- ${'1 year new three rod licence '} | ${{ ...getMockNewPermission(), numberOfRods: '3' }}
375
+ desc | currentPermission
376
+ ${'1 year renewal'} | ${getMockPermission()}
377
+ ${'1 year new licence'} | ${getMockNewPermission()}
378
+ ${'1 year senior renewal'} | ${getMockSeniorPermission()}
379
+ ${'8 day licence'} | ${{ ...getMockNewPermission(), licenceLength: '8D' }}
380
+ ${'1 day licence'} | ${{ ...getMockNewPermission(), licenceLength: '1D' }}
381
+ ${'Junior licence'} | ${getMockJuniorPermission()}
382
+ ${'Blue badge concession'} | ${getMockBlueBadgePermission()}
383
+ ${'Continuing permission'} | ${getMockContinuingPermission()}
384
+ ${'Another date permission'} | ${{ ...getMockPermission(), licenceToStart: 'another-date' }}
386
385
  `('creates licence summary name rows for $desc', async ({ currentPermission }) => {
387
386
  const mockRequest = getMockRequest({ currentPermission })
388
387
  const data = await getData(mockRequest)
@@ -113,13 +113,12 @@ class RowGenerator {
113
113
  }
114
114
 
115
115
  generateLicenceLengthRow () {
116
- const args = ['licence_summary_length', this.labels[`licence_type_${this.permission.licenceLength.toLowerCase()}`]]
117
-
118
- if (this.permission.numberOfRods !== '3') {
119
- args.push(LICENCE_LENGTH.uri, 'change-licence-length')
120
- }
121
-
122
- return this.generateStandardRow(...args)
116
+ return this.generateStandardRow(
117
+ 'licence_summary_length',
118
+ this.labels[`licence_type_${this.permission.licenceLength.toLowerCase()}`],
119
+ LICENCE_LENGTH.uri,
120
+ 'change-licence-length'
121
+ )
123
122
  }
124
123
  }
125
124
 
@@ -63,7 +63,7 @@ describe('prepareApiTransactionPayload', () => {
63
63
  })
64
64
  })
65
65
 
66
- it('adds transactionId to payload', async () => {
66
+ it('adds transaction id to payload', async () => {
67
67
  const transactionId = Symbol('transactionId')
68
68
 
69
69
  const payload = await prepareApiTransactionPayload(getMockRequest(), transactionId)
@@ -71,14 +71,6 @@ describe('prepareApiTransactionPayload', () => {
71
71
  expect(payload.transactionId).toBe(transactionId)
72
72
  })
73
73
 
74
- it('adds agreementId to payload', async () => {
75
- const agreementId = Symbol('agreementId')
76
-
77
- const payload = await prepareApiTransactionPayload(getMockRequest(), 'transaction_id', agreementId)
78
-
79
- expect(payload.agreementId).toBe(agreementId)
80
- })
81
-
82
74
  const getMockRequest = (overrides = {}, state = {}) => ({
83
75
  cache: () => ({
84
76
  helpers: {
@@ -1,4 +1,4 @@
1
- import { preparePayment, prepareRecurringPaymentAgreement } from '../payment.js'
1
+ import { preparePayment, prepareRecurringPayment } from '../payment.js'
2
2
  import { licenceTypeAndLengthDisplay } from '../licence-type-display.js'
3
3
  import { addLanguageCodeToUri } from '../uri-helper.js'
4
4
  import { AGREED } from '../../uri.js'
@@ -20,16 +20,9 @@ const createRequest = (opts = {}, catalog = {}) => ({
20
20
  server: { info: { protocol: opts.protocol || '' } }
21
21
  })
22
22
 
23
- const createTransaction = ({
24
- isLicenceForYou = true,
25
- additionalPermissions = [],
26
- cost = 12,
27
- licenseeOverrides = {},
28
- agreementId
29
- } = {}) => ({
23
+ const createTransaction = ({ isLicenceForYou = true, additionalPermissions = [], cost = 12, licenseeOverrides = {} } = {}) => ({
30
24
  id: 'transaction-id',
31
25
  cost,
32
- agreementId,
33
26
  permissions: [
34
27
  {
35
28
  id: 'permission-id',
@@ -56,7 +49,7 @@ describe('preparePayment', () => {
56
49
  it.each(['http', 'https'])('uses SSL when "x-forwarded-proto" header is present, proto "%s"', proto => {
57
50
  addLanguageCodeToUri.mockReturnValue(proto + '://localhost:1234/buy/agreed')
58
51
  const request = createRequest({ headers: { 'x-forwarded-proto': proto } })
59
- const result = preparePayment(request, createTransaction(), false)
52
+ const result = preparePayment(request, createTransaction())
60
53
 
61
54
  expect(result.return_url).toBe(`${proto}://localhost:1234/buy/agreed`)
62
55
  })
@@ -218,30 +211,12 @@ describe('preparePayment', () => {
218
211
  expect(result.email).toBe(undefined)
219
212
  })
220
213
  })
221
-
222
- describe('if agreementId is not present', () => {
223
- it('does not include set_up_agreement', () => {
224
- const result = preparePayment(createRequest(), createTransaction())
225
- expect(result.set_up_agreement).toBe(undefined)
226
- })
227
- })
228
-
229
- describe('if agreementId is present', () => {
230
- it('set_up_agreement is set to agreementId', () => {
231
- const agreementId = 'foo'
232
- const recurringPaymentTransaction = createTransaction({ agreementId })
233
-
234
- const result = preparePayment(createRequest(), recurringPaymentTransaction)
235
-
236
- expect(result.set_up_agreement).toBe(agreementId)
237
- })
238
- })
239
214
  })
240
215
 
241
- describe('prepareRecurringPaymentAgreement', () => {
216
+ describe('prepareRecurringPayment', () => {
242
217
  it('reference equals transaction.id', async () => {
243
218
  const transaction = createTransaction()
244
- const result = await prepareRecurringPaymentAgreement(createRequest(), transaction)
219
+ const result = await prepareRecurringPayment(createRequest(), transaction)
245
220
  expect(result.reference).toBe(transaction.id)
246
221
  })
247
222
 
@@ -252,7 +227,7 @@ describe('prepareRecurringPaymentAgreement', () => {
252
227
  const request = createRequest({}, mockCatalog)
253
228
  const transaction = createTransaction()
254
229
 
255
- const result = await prepareRecurringPaymentAgreement(request, transaction)
230
+ const result = await prepareRecurringPayment(request, transaction)
256
231
  expect(result.description).toBe(mockCatalog.recurring_payment_description)
257
232
  })
258
233
 
@@ -260,7 +235,7 @@ describe('prepareRecurringPaymentAgreement', () => {
260
235
  const transaction = createTransaction()
261
236
  const request = createRequest()
262
237
 
263
- const result = await prepareRecurringPaymentAgreement(request, transaction)
264
- expect(debug).toHaveBeenCalledWith('Creating prepared recurring payment agreement %o', result)
238
+ const result = await prepareRecurringPayment(request, transaction)
239
+ expect(debug).toHaveBeenCalledWith('Creating prepared recurring payment %o', result)
265
240
  })
266
241
  })
@@ -7,7 +7,7 @@ import { countries } from './refdata-helper.js'
7
7
  import { salesApi } from '@defra-fish/connectors-lib'
8
8
  import { licenceToStart } from '../pages/licence-details/licence-to-start/update-transaction.js'
9
9
 
10
- export const prepareApiTransactionPayload = async (request, transactionId, agreementId) => {
10
+ export const prepareApiTransactionPayload = async (request, transactionId) => {
11
11
  const transactionCache = await request.cache().helpers.transaction.get()
12
12
  const concessions = await salesApi.concessions.getAll()
13
13
  const countryList = await countries.getAll()
@@ -63,8 +63,7 @@ export const prepareApiTransactionPayload = async (request, transactionId, agree
63
63
  request.state && request.state[process.env.OIDC_SESSION_COOKIE_NAME]
64
64
  ? request.state[process.env.OIDC_SESSION_COOKIE_NAME].oid
65
65
  : undefined,
66
- transactionId,
67
- agreementId
66
+ transactionId
68
67
  }
69
68
  }
70
69
 
@@ -50,21 +50,17 @@ export const preparePayment = (request, transaction) => {
50
50
  }
51
51
  }
52
52
 
53
- if (transaction.agreementId) {
54
- result.set_up_agreement = transaction.agreementId
55
- }
56
-
57
53
  debug('Creating prepared payment %o', result)
58
54
  return result
59
55
  }
60
56
 
61
- export const prepareRecurringPaymentAgreement = async (request, transaction) => {
57
+ export const prepareRecurringPayment = async (request, transaction) => {
62
58
  debug('Preparing recurring payment %s', JSON.stringify(transaction, undefined, '\t'))
63
- // The recurring card payment agreement for your rod fishing licence
59
+ // The recurring card payment for your rod fishing licence
64
60
  const result = {
65
61
  reference: transaction.id,
66
62
  description: request.i18n.getCatalog().recurring_payment_description
67
63
  }
68
- debug('Creating prepared recurring payment agreement %o', result)
64
+ debug('Creating prepared recurring payment %o', result)
69
65
  return result
70
66
  }
@@ -2,7 +2,7 @@ import mockTransaction from './data/mock-transaction.js'
2
2
  import { preparePayment } from '../../../processors/payment.js'
3
3
  import { AGREED } from '../../../uri.js'
4
4
  import { addLanguageCodeToUri } from '../../../processors/uri-helper.js'
5
- import { sendPayment, sendRecurringPayment, getPaymentStatus } from '../govuk-pay-service.js'
5
+ import { sendRecurringPayment } from '../govuk-pay-service.js'
6
6
  import { govUkPayApi } from '@defra-fish/connectors-lib'
7
7
  import db from 'debug'
8
8
  const { value: debug } = db.mock.results[db.mock.calls.findIndex(c => c[0] === 'webapp:govuk-pay-service')]
@@ -158,142 +158,6 @@ describe('The govuk-pay-service', () => {
158
158
  console.log(preparedPayment)
159
159
  })
160
160
 
161
- describe('sendPayment', () => {
162
- const preparedPayment = {
163
- id: '1234',
164
- user_identifier: 'test-user'
165
- }
166
-
167
- beforeEach(() => {
168
- jest.clearAllMocks()
169
- })
170
-
171
- it.each([
172
- [true, true],
173
- [false, false],
174
- [false, undefined]
175
- ])('should call the govUkPayApi with recurring as %s if the argument is %s', async (expected, value) => {
176
- const mockResponse = {
177
- ok: true,
178
- json: jest.fn().mockResolvedValue({ success: true, paymentId: 'abc123' })
179
- }
180
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
181
- const unique = Symbol('payload')
182
- const payload = { unique }
183
- await sendPayment(payload, value)
184
- expect(govUkPayApi.createPayment).toHaveBeenCalledWith(payload, expected)
185
- })
186
-
187
- it('should send provided payload data to Gov.UK Pay', async () => {
188
- const mockResponse = {
189
- ok: true,
190
- json: jest.fn().mockResolvedValue({ success: true, paymentId: 'abc123' })
191
- }
192
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
193
- const unique = Symbol('payload')
194
- const payload = {
195
- reference: 'd81f1a2b-6508-468f-8342-b6770f60f7cd',
196
- description: 'Fishing permission',
197
- user_identifier: '1218c1c5-38e4-4bf3-81ea-9cbce3994d30',
198
- unique
199
- }
200
- await sendPayment(payload)
201
- expect(govUkPayApi.createPayment).toHaveBeenCalledWith(payload, false)
202
- })
203
-
204
- it('should return response body when payment creation is successful', async () => {
205
- const mockResponse = {
206
- ok: true,
207
- json: jest.fn().mockResolvedValue({ success: true, paymentId: 'abc123' })
208
- }
209
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
210
-
211
- const result = await sendPayment(preparedPayment)
212
-
213
- expect(result).toEqual({ success: true, paymentId: 'abc123' })
214
- })
215
-
216
- it('should log debug message when response.ok is true', async () => {
217
- const mockResponse = {
218
- ok: true,
219
- json: jest.fn().mockResolvedValue({ success: true, paymentId: 'abc123' })
220
- }
221
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
222
-
223
- await sendPayment(preparedPayment)
224
-
225
- expect(debug).toHaveBeenCalledWith('Successful payment creation response: %o', { success: true, paymentId: 'abc123' })
226
- })
227
-
228
- it('should log error message when response.ok is false', async () => {
229
- const mockResponse = {
230
- ok: false,
231
- status: 500,
232
- json: jest.fn().mockResolvedValue({ message: 'Server error' })
233
- }
234
- const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
235
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
236
-
237
- try {
238
- await sendPayment(preparedPayment)
239
- } catch (error) {
240
- expect(consoleErrorSpy).toHaveBeenCalledWith('Failure creating payment in the GOV.UK API service', {
241
- transactionId: preparedPayment.id,
242
- method: 'POST',
243
- payload: preparedPayment,
244
- status: mockResponse.status,
245
- response: { message: 'Server error' }
246
- })
247
- }
248
- })
249
-
250
- it('should throw error when API call fails with network issue', async () => {
251
- const mockError = new Error('Network error')
252
- const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
253
- govUkPayApi.createPayment.mockRejectedValue(mockError)
254
-
255
- try {
256
- await sendPayment(preparedPayment)
257
- } catch (error) {
258
- expect(consoleErrorSpy).toHaveBeenCalledWith(
259
- `Error creating payment in the GOV.UK API service - tid: ${preparedPayment.id}`,
260
- mockError
261
- )
262
- }
263
- })
264
-
265
- it('should throw error for when rate limit is breached', async () => {
266
- const mockResponse = {
267
- ok: false,
268
- status: 429,
269
- json: jest.fn().mockResolvedValue({ message: 'Rate limit exceeded' })
270
- }
271
- const consoleErrorSpy = jest.spyOn(console, 'info').mockImplementation(jest.fn())
272
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
273
-
274
- try {
275
- await sendPayment(preparedPayment)
276
- } catch (error) {
277
- expect(consoleErrorSpy).toHaveBeenCalledWith(`GOV.UK Pay API rate limit breach - tid: ${preparedPayment.id}`)
278
- }
279
- })
280
-
281
- it('should throw error for unexpected response status', async () => {
282
- const mockResponse = {
283
- ok: false,
284
- status: 500,
285
- json: jest.fn().mockResolvedValue({ message: 'Server error' })
286
- }
287
- govUkPayApi.createPayment.mockResolvedValue(mockResponse)
288
-
289
- try {
290
- await sendPayment(preparedPayment)
291
- } catch (error) {
292
- expect(error.message).toBe('Unexpected response from GOV.UK pay API')
293
- }
294
- })
295
- })
296
-
297
161
  describe('sendRecurringPayment', () => {
298
162
  const preparedPayment = {
299
163
  id: '1234',
@@ -413,120 +277,4 @@ describe('The govuk-pay-service', () => {
413
277
  }
414
278
  })
415
279
  })
416
-
417
- describe('getPaymentStatus', () => {
418
- const paymentId = '1234'
419
-
420
- beforeEach(() => {
421
- jest.clearAllMocks()
422
- })
423
-
424
- it.each([
425
- [true, true],
426
- [false, false],
427
- [false, undefined]
428
- ])('should call the govUkPayApi with recurring as %s if the argument is %s', async (expected, value) => {
429
- const mockResponse = { ok: true, status: 200, json: () => {} }
430
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
431
- await getPaymentStatus(paymentId, value)
432
- expect(govUkPayApi.fetchPaymentStatus).toHaveBeenCalledWith(paymentId, expected)
433
- })
434
-
435
- it('should send provided paymentId to Gov.UK Pay', async () => {
436
- const mockResponse = { ok: true, status: 200, json: () => {} }
437
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
438
- await getPaymentStatus(paymentId)
439
- expect(govUkPayApi.fetchPaymentStatus).toHaveBeenCalledWith(paymentId, false)
440
- })
441
-
442
- it('should return response body when payment status check is successful', async () => {
443
- const resBody = Symbol('body')
444
- const mockResponse = { ok: true, status: 200, json: jest.fn().mockResolvedValue(resBody) }
445
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
446
-
447
- const result = await getPaymentStatus(paymentId)
448
-
449
- expect(result).toEqual(resBody)
450
- })
451
-
452
- it('should log debug message when response.ok is true', async () => {
453
- const resBody = Symbol('body')
454
- const mockResponse = { ok: true, status: 200, json: jest.fn().mockResolvedValue(resBody) }
455
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
456
-
457
- await getPaymentStatus(paymentId)
458
-
459
- expect(debug).toHaveBeenCalledWith('Payment status response: %o', resBody)
460
- })
461
-
462
- it('should log error message when response.ok is false', async () => {
463
- const mockResponse = {
464
- ok: false,
465
- status: 500,
466
- json: jest.fn().mockResolvedValue({ message: 'Server error' })
467
- }
468
- const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
469
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
470
-
471
- try {
472
- await getPaymentStatus(paymentId)
473
- } catch (error) {
474
- expect(consoleErrorSpy).toHaveBeenCalledWith(
475
- `Error retrieving the payment status from the GOV.UK API service - tid: ${paymentId}`,
476
- {
477
- method: 'GET',
478
- paymentId: paymentId,
479
- status: mockResponse.status,
480
- response: { message: 'Server error' }
481
- }
482
- )
483
- }
484
- })
485
-
486
- it('should throw error when API call fails with network issue', async () => {
487
- const mockError = new Error('Network error')
488
- const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
489
- govUkPayApi.fetchPaymentStatus.mockRejectedValue(mockError)
490
-
491
- try {
492
- await getPaymentStatus(paymentId)
493
- } catch (error) {
494
- expect(consoleErrorSpy).toHaveBeenCalledWith(
495
- `Error retrieving the payment status from the GOV.UK API service - paymentId: ${paymentId}`,
496
- mockError
497
- )
498
- }
499
- })
500
-
501
- it('should throw error for when rate limit is breached', async () => {
502
- const mockResponse = {
503
- ok: false,
504
- status: 429,
505
- json: jest.fn().mockResolvedValue({ message: 'Rate limit exceeded' })
506
- }
507
- const consoleErrorSpy = jest.spyOn(console, 'info').mockImplementation(jest.fn())
508
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
509
-
510
- try {
511
- await getPaymentStatus(paymentId)
512
- } catch (error) {
513
- expect(consoleErrorSpy).toHaveBeenCalledWith(`GOV.UK Pay API rate limit breach - paymentId: ${paymentId}`)
514
- }
515
- })
516
-
517
- it('should throw error for unexpected response status', async () => {
518
- const mockResponse = {
519
- ok: false,
520
- status: 500,
521
- json: jest.fn().mockResolvedValue({ message: 'Server error' })
522
- }
523
- govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockResponse)
524
-
525
- try {
526
- await getPaymentStatus(paymentId)
527
- } catch (error) {
528
- expect(error.message).toBe('Unexpected response from GOV.UK pay API')
529
- }
530
- })
531
- })
532
280
  })
@@ -46,10 +46,10 @@ const getTransactionErrorMessage = async (transactionId, payload, response) => (
46
46
  * @param preparedPayment - the prepared payload for the payment. See in processors/payment.js
47
47
  * @returns {Promise<*>}
48
48
  */
49
- export const sendPayment = async (preparedPayment, recurring = false) => {
49
+ export const sendPayment = async preparedPayment => {
50
50
  let response
51
51
  try {
52
- response = await govUkPayApi.createPayment(preparedPayment, recurring)
52
+ response = await govUkPayApi.createPayment(preparedPayment)
53
53
  } catch (err) {
54
54
  /*
55
55
  * Potentially errors caught here (unreachable, timeouts) may be retried - set origin on the error to indicate
@@ -78,11 +78,11 @@ export const sendPayment = async (preparedPayment, recurring = false) => {
78
78
  * @param paymentId - the paymentId
79
79
  * @returns {Promise<any>}
80
80
  */
81
- export const getPaymentStatus = async (paymentId, recurring = false) => {
81
+ export const getPaymentStatus = async paymentId => {
82
82
  debug(`Get payment status for paymentId: ${paymentId}`)
83
83
  let response
84
84
  try {
85
- response = await govUkPayApi.fetchPaymentStatus(paymentId, recurring)
85
+ response = await govUkPayApi.fetchPaymentStatus(paymentId)
86
86
  } catch (err) {
87
87
  /*
88
88
  * Errors caught here (unreachable, timeouts) may be retried - set origin on the error to indicate