@defra-fish/connectors-lib 1.75.0-rc.2 → 1.75.0-rc.3
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 +2 -2
- package/src/__tests__/govuk-pay-api.spec.js +162 -4
- package/src/govuk-pay-api.js +23 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/connectors-lib",
|
|
3
|
-
"version": "1.75.0-rc.
|
|
3
|
+
"version": "1.75.0-rc.3",
|
|
4
4
|
"description": "Shared connectors",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"node-fetch": "2.7.0",
|
|
48
48
|
"redlock": "4.2.0"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "0f6912bc7a73c58e2d3494529adc62ce8d65e9e5"
|
|
51
51
|
}
|
|
@@ -47,7 +47,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
47
47
|
fetch.mockImplementationOnce(() => {
|
|
48
48
|
throw new Error('')
|
|
49
49
|
})
|
|
50
|
-
expect(govUkPayApi.createPayment({ cost: 0 })).rejects.toEqual(Error(''))
|
|
50
|
+
await expect(govUkPayApi.createPayment({ cost: 0 })).rejects.toEqual(Error(''))
|
|
51
51
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment', {
|
|
52
52
|
body: JSON.stringify({ cost: 0 }),
|
|
53
53
|
headers: headers(),
|
|
@@ -67,6 +67,20 @@ describe('govuk-pay-api-connector', () => {
|
|
|
67
67
|
timeout: 10000
|
|
68
68
|
})
|
|
69
69
|
})
|
|
70
|
+
|
|
71
|
+
it('rethrows the same error when fetch rejects', async () => {
|
|
72
|
+
const error = new Error('creating payment failed')
|
|
73
|
+
fetch.mockRejectedValueOnce(error)
|
|
74
|
+
await expect(govUkPayApi.createPayment('abc-123')).rejects.toBe(error)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('logs an error when fetch rejects', async () => {
|
|
78
|
+
const error = new Error('creating payment failed')
|
|
79
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
80
|
+
fetch.mockRejectedValueOnce(error)
|
|
81
|
+
await govUkPayApi.createPayment('abc-123').catch(() => {})
|
|
82
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error creating payment in the GOV.UK API service - payment: "abc-123"', error)
|
|
83
|
+
})
|
|
70
84
|
})
|
|
71
85
|
|
|
72
86
|
describe('fetchPaymentStatus', () => {
|
|
@@ -99,6 +113,23 @@ describe('govuk-pay-api-connector', () => {
|
|
|
99
113
|
timeout: 10000
|
|
100
114
|
})
|
|
101
115
|
})
|
|
116
|
+
|
|
117
|
+
it('rethrows the same error when fetch rejects', async () => {
|
|
118
|
+
const error = new Error('fetching payment status failed')
|
|
119
|
+
fetch.mockRejectedValueOnce(error)
|
|
120
|
+
await expect(govUkPayApi.fetchPaymentStatus('abc-123')).rejects.toBe(error)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('logs an error when fetch rejects', async () => {
|
|
124
|
+
const error = new Error('fetching payment status failed')
|
|
125
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
126
|
+
fetch.mockRejectedValueOnce(error)
|
|
127
|
+
await govUkPayApi.fetchPaymentStatus('abc-123').catch(() => {})
|
|
128
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
129
|
+
'Error retrieving the payment status from the GOV.UK API service - paymentId: abc-123',
|
|
130
|
+
error
|
|
131
|
+
)
|
|
132
|
+
})
|
|
102
133
|
})
|
|
103
134
|
|
|
104
135
|
describe('fetchPaymentEvents', () => {
|
|
@@ -126,6 +157,23 @@ describe('govuk-pay-api-connector', () => {
|
|
|
126
157
|
timeout: 10000
|
|
127
158
|
})
|
|
128
159
|
})
|
|
160
|
+
|
|
161
|
+
it('rethrows the same error when fetch rejects', async () => {
|
|
162
|
+
const error = new Error('fetching payments failed')
|
|
163
|
+
fetch.mockRejectedValueOnce(error)
|
|
164
|
+
await expect(govUkPayApi.fetchPaymentEvents('abc-123')).rejects.toBe(error)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('logs an error when fetch rejects', async () => {
|
|
168
|
+
const error = new Error('fetching payments failed')
|
|
169
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
170
|
+
fetch.mockRejectedValueOnce(error)
|
|
171
|
+
await govUkPayApi.fetchPaymentEvents('abc-123').catch(() => {})
|
|
172
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
173
|
+
'Error retrieving the payment events from the GOV.UK API service - paymentId: abc-123',
|
|
174
|
+
error
|
|
175
|
+
)
|
|
176
|
+
})
|
|
129
177
|
})
|
|
130
178
|
|
|
131
179
|
describe('createRecurringPaymentAgreement', () => {
|
|
@@ -145,7 +193,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
145
193
|
fetch.mockImplementationOnce(() => {
|
|
146
194
|
throw new Error('')
|
|
147
195
|
})
|
|
148
|
-
expect(govUkPayApi.createRecurringPaymentAgreement({ reference: '123' })).rejects.toEqual(Error(''))
|
|
196
|
+
await expect(govUkPayApi.createRecurringPaymentAgreement({ reference: '123' })).rejects.toEqual(Error(''))
|
|
149
197
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/agreement', {
|
|
150
198
|
body: JSON.stringify({ reference: '123' }),
|
|
151
199
|
headers: recurringHeaders(),
|
|
@@ -282,7 +330,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
282
330
|
|
|
283
331
|
it('logs errors', async () => {
|
|
284
332
|
const error = new Error('Fail')
|
|
285
|
-
const consoleErrorSpy = jest.spyOn(console, 'error')
|
|
333
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
286
334
|
fetch.mockImplementationOnce(() => {
|
|
287
335
|
throw error
|
|
288
336
|
})
|
|
@@ -291,11 +339,26 @@ describe('govuk-pay-api-connector', () => {
|
|
|
291
339
|
} catch {}
|
|
292
340
|
expect(consoleErrorSpy).toHaveBeenCalledWith('Error retrieving GovPay health status', error)
|
|
293
341
|
})
|
|
342
|
+
|
|
343
|
+
it('rethrows the same error when fetch rejects', async () => {
|
|
344
|
+
const error = new Error('fetching GovPay health status failed')
|
|
345
|
+
fetch.mockRejectedValueOnce(error)
|
|
346
|
+
await expect(govUkPayApi.isGovPayUp()).rejects.toBe(error)
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
it('logs an error when fetch rejects', async () => {
|
|
350
|
+
const error = new Error('fetching GovPay health status failed')
|
|
351
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
352
|
+
fetch.mockRejectedValueOnce(error)
|
|
353
|
+
await govUkPayApi.isGovPayUp().catch(() => {})
|
|
354
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error retrieving GovPay health status', error)
|
|
355
|
+
})
|
|
294
356
|
})
|
|
295
357
|
|
|
296
358
|
describe('getRecurringPaymentAgreementInformation', () => {
|
|
297
359
|
it('retrieves recurring payment agreement information', async () => {
|
|
298
|
-
|
|
360
|
+
const mockResponse = { ok: true, status: 200, json: () => {} }
|
|
361
|
+
fetch.mockResolvedValueOnce(mockResponse)
|
|
299
362
|
await expect(govUkPayApi.getRecurringPaymentAgreementInformation(123)).resolves.toEqual(
|
|
300
363
|
expect.objectContaining({ ok: true, status: 200 })
|
|
301
364
|
)
|
|
@@ -310,5 +373,100 @@ describe('govuk-pay-api-connector', () => {
|
|
|
310
373
|
await expect(govUkPayApi.getRecurringPaymentAgreementInformation(123)).rejects.toEqual(Error('test event error'))
|
|
311
374
|
expect(consoleErrorSpy).toHaveBeenCalled()
|
|
312
375
|
})
|
|
376
|
+
|
|
377
|
+
it('rethrows the same error when fetch rejects', async () => {
|
|
378
|
+
const error = new Error('fetching agreement failed')
|
|
379
|
+
fetch.mockRejectedValueOnce(error)
|
|
380
|
+
await expect(govUkPayApi.getRecurringPaymentAgreementInformation('abc-123')).rejects.toBe(error)
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
it('logs an error when fetch rejects', async () => {
|
|
384
|
+
const error = new Error('fetching agreement failed')
|
|
385
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
386
|
+
fetch.mockRejectedValueOnce(error)
|
|
387
|
+
await govUkPayApi.getRecurringPaymentAgreementInformation('abc-123').catch(() => {})
|
|
388
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
389
|
+
'Error fetching recurring payment agreement information in the GOV.UK API service - agreementId: abc-123',
|
|
390
|
+
error
|
|
391
|
+
)
|
|
392
|
+
})
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
describe.each(['abc-123', 'def-456', 'ghi-789'])('cancelRecurringPaymentAgreement with agreement id %s', agreementId => {
|
|
396
|
+
it('calls the cancel endpoint for the provided agreement id', async () => {
|
|
397
|
+
const mockResponse = { ok: true, status: 204 }
|
|
398
|
+
fetch.mockReturnValueOnce(mockResponse)
|
|
399
|
+
await govUkPayApi.cancelRecurringPaymentAgreement(agreementId)
|
|
400
|
+
expect(fetch).toHaveBeenCalledWith(`http://0.0.0.0/agreement/${agreementId}/cancel`, expect.any(Object))
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
it('sends recurring API headers', async () => {
|
|
404
|
+
const mockResponse = { ok: true, status: 204 }
|
|
405
|
+
fetch.mockResolvedValueOnce(mockResponse)
|
|
406
|
+
await govUkPayApi.cancelRecurringPaymentAgreement(agreementId)
|
|
407
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
408
|
+
expect.any(String),
|
|
409
|
+
expect.objectContaining({
|
|
410
|
+
headers: recurringHeaders()
|
|
411
|
+
})
|
|
412
|
+
)
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
it('uses POST method', async () => {
|
|
416
|
+
const mockResponse = { ok: true, status: 204 }
|
|
417
|
+
fetch.mockResolvedValueOnce(mockResponse)
|
|
418
|
+
await govUkPayApi.cancelRecurringPaymentAgreement(agreementId)
|
|
419
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
420
|
+
expect.any(String),
|
|
421
|
+
expect.objectContaining({
|
|
422
|
+
method: 'post'
|
|
423
|
+
})
|
|
424
|
+
)
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
it('uses the configured request timeout', async () => {
|
|
428
|
+
const mockResponse = { ok: true, status: 204 }
|
|
429
|
+
fetch.mockResolvedValueOnce(mockResponse)
|
|
430
|
+
await govUkPayApi.cancelRecurringPaymentAgreement(agreementId)
|
|
431
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
432
|
+
expect.any(String),
|
|
433
|
+
expect.objectContaining({
|
|
434
|
+
timeout: 10000
|
|
435
|
+
})
|
|
436
|
+
)
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
it('returns the fetch response when GOV.UK Pay request succeeds', async () => {
|
|
440
|
+
const mockResponse = { ok: true, status: 204 }
|
|
441
|
+
fetch.mockResolvedValueOnce(mockResponse)
|
|
442
|
+
const result = await govUkPayApi.cancelRecurringPaymentAgreement(agreementId)
|
|
443
|
+
expect(result).toEqual({ ok: true, status: 204 })
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
it('returns non-ok responses for caller-side handling', async () => {
|
|
447
|
+
const mockResponse = { ok: false, status: 400, statusText: 'Bad Request' }
|
|
448
|
+
fetch.mockResolvedValueOnce(mockResponse)
|
|
449
|
+
const result = await govUkPayApi.cancelRecurringPaymentAgreement(agreementId)
|
|
450
|
+
expect(result).toEqual(mockResponse)
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
it('rethrows the same error when fetch rejects', async () => {
|
|
454
|
+
const error = new Error('cancel agreement failed')
|
|
455
|
+
fetch.mockRejectedValueOnce(error)
|
|
456
|
+
|
|
457
|
+
await expect(govUkPayApi.cancelRecurringPaymentAgreement(agreementId)).rejects.toBe(error)
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
it('logs an error when fetch rejects', async () => {
|
|
461
|
+
const error = new Error('cancel agreement failed')
|
|
462
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
463
|
+
fetch.mockRejectedValueOnce(error)
|
|
464
|
+
|
|
465
|
+
await govUkPayApi.cancelRecurringPaymentAgreement(agreementId).catch(() => {})
|
|
466
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
467
|
+
`Error cancelling recurring payment agreement in the GOV.UK API service - agreementId: ${agreementId}`,
|
|
468
|
+
error
|
|
469
|
+
)
|
|
470
|
+
})
|
|
313
471
|
})
|
|
314
472
|
})
|
package/src/govuk-pay-api.js
CHANGED
|
@@ -17,7 +17,7 @@ const headers = recurring => ({
|
|
|
17
17
|
*/
|
|
18
18
|
export const createRecurringPaymentAgreement = async preparedPayment => {
|
|
19
19
|
try {
|
|
20
|
-
return fetch(process.env.GOV_PAY_RCP_API_URL, {
|
|
20
|
+
return await fetch(process.env.GOV_PAY_RCP_API_URL, {
|
|
21
21
|
headers: headers(true),
|
|
22
22
|
method: 'post',
|
|
23
23
|
body: JSON.stringify(preparedPayment),
|
|
@@ -64,7 +64,7 @@ export const queueRecurringPaymentStatusCheck = (paymentId, batcher) => {
|
|
|
64
64
|
*/
|
|
65
65
|
export const createPayment = async (preparedPayment, recurring = false) => {
|
|
66
66
|
try {
|
|
67
|
-
return fetch(process.env.GOV_PAY_API_URL, {
|
|
67
|
+
return await fetch(process.env.GOV_PAY_API_URL, {
|
|
68
68
|
headers: headers(recurring),
|
|
69
69
|
method: 'post',
|
|
70
70
|
body: JSON.stringify(preparedPayment),
|
|
@@ -83,7 +83,7 @@ export const createPayment = async (preparedPayment, recurring = false) => {
|
|
|
83
83
|
*/
|
|
84
84
|
export const fetchPaymentStatus = async (paymentId, recurring = false) => {
|
|
85
85
|
try {
|
|
86
|
-
return fetch(`${process.env.GOV_PAY_API_URL}/${paymentId}`, {
|
|
86
|
+
return await fetch(`${process.env.GOV_PAY_API_URL}/${paymentId}`, {
|
|
87
87
|
headers: headers(recurring),
|
|
88
88
|
method: 'get',
|
|
89
89
|
timeout: process.env.GOV_PAY_REQUEST_TIMEOUT_MS || GOV_PAY_REQUEST_TIMEOUT_MS_DEFAULT
|
|
@@ -101,7 +101,7 @@ export const fetchPaymentStatus = async (paymentId, recurring = false) => {
|
|
|
101
101
|
*/
|
|
102
102
|
export const fetchPaymentEvents = async (paymentId, recurring = false) => {
|
|
103
103
|
try {
|
|
104
|
-
return fetch(`${process.env.GOV_PAY_API_URL}/${paymentId}/events`, {
|
|
104
|
+
return await fetch(`${process.env.GOV_PAY_API_URL}/${paymentId}/events`, {
|
|
105
105
|
headers: headers(recurring),
|
|
106
106
|
method: 'get',
|
|
107
107
|
timeout: process.env.GOV_PAY_REQUEST_TIMEOUT_MS || GOV_PAY_REQUEST_TIMEOUT_MS_DEFAULT
|
|
@@ -128,7 +128,7 @@ export const isGovPayUp = async () => {
|
|
|
128
128
|
*/
|
|
129
129
|
export const getRecurringPaymentAgreementInformation = async agreementId => {
|
|
130
130
|
try {
|
|
131
|
-
return fetch(`${process.env.GOV_PAY_RCP_API_URL}/${agreementId}`, {
|
|
131
|
+
return await fetch(`${process.env.GOV_PAY_RCP_API_URL}/${agreementId}`, {
|
|
132
132
|
headers: headers(true),
|
|
133
133
|
method: 'get',
|
|
134
134
|
timeout: process.env.GOV_PAY_REQUEST_TIMEOUT_MS || GOV_PAY_REQUEST_TIMEOUT_MS_DEFAULT
|
|
@@ -138,3 +138,21 @@ export const getRecurringPaymentAgreementInformation = async agreementId => {
|
|
|
138
138
|
throw err
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Cancel a recurring payment agreement in GOV.UK Pay
|
|
144
|
+
* @param agreementId - the agreement to cancel
|
|
145
|
+
* @returns {Promise<*>}
|
|
146
|
+
*/
|
|
147
|
+
export const cancelRecurringPaymentAgreement = async agreementId => {
|
|
148
|
+
try {
|
|
149
|
+
return await fetch(`${process.env.GOV_PAY_RCP_API_URL}/${agreementId}/cancel`, {
|
|
150
|
+
headers: headers(true),
|
|
151
|
+
method: 'post',
|
|
152
|
+
timeout: process.env.GOV_PAY_REQUEST_TIMEOUT_MS || GOV_PAY_REQUEST_TIMEOUT_MS_DEFAULT
|
|
153
|
+
})
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error(`Error cancelling recurring payment agreement in the GOV.UK API service - agreementId: ${agreementId}`, err)
|
|
156
|
+
throw err
|
|
157
|
+
}
|
|
158
|
+
}
|