@defra-fish/connectors-lib 1.62.0-rc.1 → 1.62.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -20,7 +20,8 @@ Provides connectivity to the resources/infrastructure used in the rod licensing
|
|
|
20
20
|
| GOV_PAY_APIKEY | GOV pay access identifier | yes | | | |
|
|
21
21
|
| GOV_PAY_RECURRING_APIKEY | GOV pay access identifier for recurring payments | yes | | | |
|
|
22
22
|
| GOV_PAY_REQUEST_TIMEOUT_MS | Timeout in milliseconds for API requests | no | 10000 | | |
|
|
23
|
-
| GOV_PAY_RCP_API_URL | The GOV.UK Pay API url for agreements | yes | |
|
|
23
|
+
| GOV_PAY_RCP_API_URL | The GOV.UK Pay API url for agreements | yes | | | |
|
|
24
|
+
| GOV_PAY_HEALTH_CHECK_URL | The Gov.UK Pay health check url | yes | | | |
|
|
24
25
|
|
|
25
26
|
# Prerequisites
|
|
26
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/connectors-lib",
|
|
3
|
-
"version": "1.62.0-rc.
|
|
3
|
+
"version": "1.62.0-rc.10",
|
|
4
4
|
"description": "Shared connectors",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"node-fetch": "^2.7.0",
|
|
47
47
|
"redlock": "^4.2.0"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "7be5ffd5ab38a7b7690cb2b7f7c711c5d8473860"
|
|
50
50
|
}
|
|
@@ -24,7 +24,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
24
24
|
|
|
25
25
|
describe('createPayment', () => {
|
|
26
26
|
it('creates new payments', async () => {
|
|
27
|
-
fetch.
|
|
27
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200 })
|
|
28
28
|
await expect(govUkPayApi.createPayment({ cost: 0 })).resolves.toEqual({ ok: true, status: 200 })
|
|
29
29
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment', {
|
|
30
30
|
body: JSON.stringify({ cost: 0 }),
|
|
@@ -36,7 +36,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
36
36
|
|
|
37
37
|
it('logs and throws errors', async () => {
|
|
38
38
|
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
39
|
-
fetch.
|
|
39
|
+
fetch.mockImplementationOnce(() => {
|
|
40
40
|
throw new Error('')
|
|
41
41
|
})
|
|
42
42
|
expect(govUkPayApi.createPayment({ cost: 0 })).rejects.toEqual(Error(''))
|
|
@@ -50,7 +50,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
it('uses the correct API key if recurring arg is set to true', async () => {
|
|
53
|
-
fetch.
|
|
53
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200 })
|
|
54
54
|
await expect(govUkPayApi.createPayment({ cost: 0 }, true)).resolves.toEqual({ ok: true, status: 200 })
|
|
55
55
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment', {
|
|
56
56
|
body: JSON.stringify({ cost: 0 }),
|
|
@@ -63,7 +63,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
63
63
|
|
|
64
64
|
describe('fetchPaymentStatus', () => {
|
|
65
65
|
it('retrieves payment status', async () => {
|
|
66
|
-
fetch.
|
|
66
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200, json: () => {} })
|
|
67
67
|
await expect(govUkPayApi.fetchPaymentStatus(123)).resolves.toEqual(expect.objectContaining({ ok: true, status: 200 }))
|
|
68
68
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment/123', {
|
|
69
69
|
headers,
|
|
@@ -74,7 +74,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
74
74
|
|
|
75
75
|
it('logs and throws errors', async () => {
|
|
76
76
|
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
77
|
-
fetch.
|
|
77
|
+
fetch.mockImplementationOnce(() => {
|
|
78
78
|
throw new Error('')
|
|
79
79
|
})
|
|
80
80
|
await expect(govUkPayApi.fetchPaymentStatus(123)).rejects.toEqual(Error(''))
|
|
@@ -83,7 +83,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
83
83
|
})
|
|
84
84
|
|
|
85
85
|
it('uses the correct API key if recurring arg is set to true', async () => {
|
|
86
|
-
fetch.
|
|
86
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200, json: () => {} })
|
|
87
87
|
await expect(govUkPayApi.fetchPaymentStatus(123, true)).resolves.toEqual(expect.objectContaining({ ok: true, status: 200 }))
|
|
88
88
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment/123', {
|
|
89
89
|
headers: recurringHeaders,
|
|
@@ -95,14 +95,14 @@ describe('govuk-pay-api-connector', () => {
|
|
|
95
95
|
|
|
96
96
|
describe('fetchPaymentEvents', () => {
|
|
97
97
|
it('retrieves payment events', async () => {
|
|
98
|
-
fetch.
|
|
98
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200, json: () => {} })
|
|
99
99
|
await expect(govUkPayApi.fetchPaymentEvents(123)).resolves.toEqual(expect.objectContaining({ ok: true, status: 200 }))
|
|
100
100
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment/123/events', { headers, method: 'get', timeout: 10000 })
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
it('logs and throws errors', async () => {
|
|
104
104
|
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
105
|
-
fetch.
|
|
105
|
+
fetch.mockImplementationOnce(() => {
|
|
106
106
|
throw new Error('test event error')
|
|
107
107
|
})
|
|
108
108
|
await expect(govUkPayApi.fetchPaymentEvents(123)).rejects.toEqual(Error('test event error'))
|
|
@@ -110,7 +110,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
110
110
|
})
|
|
111
111
|
|
|
112
112
|
it('uses the correct API key if recurring arg is set to true', async () => {
|
|
113
|
-
fetch.
|
|
113
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200, json: () => {} })
|
|
114
114
|
await expect(govUkPayApi.fetchPaymentEvents(123, true)).resolves.toEqual(expect.objectContaining({ ok: true, status: 200 }))
|
|
115
115
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/payment/123/events', {
|
|
116
116
|
headers: recurringHeaders,
|
|
@@ -122,7 +122,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
122
122
|
|
|
123
123
|
describe('createRecurringPaymentAgreement', () => {
|
|
124
124
|
it('creates new payments', async () => {
|
|
125
|
-
fetch.
|
|
125
|
+
fetch.mockReturnValueOnce({ ok: true, status: 200 })
|
|
126
126
|
await expect(govUkPayApi.createRecurringPaymentAgreement({ cost: 0 })).resolves.toEqual({ ok: true, status: 200 })
|
|
127
127
|
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/agreement', {
|
|
128
128
|
body: JSON.stringify({ cost: 0 }),
|
|
@@ -134,7 +134,7 @@ describe('govuk-pay-api-connector', () => {
|
|
|
134
134
|
|
|
135
135
|
it('logs and throws errors', async () => {
|
|
136
136
|
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
137
|
-
fetch.
|
|
137
|
+
fetch.mockImplementationOnce(() => {
|
|
138
138
|
throw new Error('')
|
|
139
139
|
})
|
|
140
140
|
expect(govUkPayApi.createRecurringPaymentAgreement({ reference: '123' })).rejects.toEqual(Error(''))
|
|
@@ -147,4 +147,60 @@ describe('govuk-pay-api-connector', () => {
|
|
|
147
147
|
expect(consoleErrorSpy).toHaveBeenCalled()
|
|
148
148
|
})
|
|
149
149
|
})
|
|
150
|
+
|
|
151
|
+
describe('isGovPayUp', () => {
|
|
152
|
+
it.each(['http://gov.uk.pay/health/check/url', 'https://gov-uk-pay?health-check-url'])(
|
|
153
|
+
'calls healthy endpoint %s',
|
|
154
|
+
async healthCheckURL => {
|
|
155
|
+
process.env.GOV_PAY_HEALTH_CHECK_URL = healthCheckURL
|
|
156
|
+
await govUkPayApi.isGovPayUp()
|
|
157
|
+
expect(fetch).toHaveBeenCalledWith(healthCheckURL)
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
it('returns the fetch response', async () => {
|
|
162
|
+
const response = Symbol('response')
|
|
163
|
+
fetch.mockReturnValueOnce(response)
|
|
164
|
+
expect(await govUkPayApi.isGovPayUp()).toBe(response)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('throws errors that are thrown by fetch', async () => {
|
|
168
|
+
const error = new Error('Fail')
|
|
169
|
+
fetch.mockImplementationOnce(() => {
|
|
170
|
+
throw error
|
|
171
|
+
})
|
|
172
|
+
await expect(govUkPayApi.isGovPayUp()).rejects.toBe(error)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('logs errors', async () => {
|
|
176
|
+
const error = new Error('Fail')
|
|
177
|
+
const consoleErrorSpy = jest.spyOn(console, 'error')
|
|
178
|
+
fetch.mockImplementationOnce(() => {
|
|
179
|
+
throw error
|
|
180
|
+
})
|
|
181
|
+
try {
|
|
182
|
+
await govUkPayApi.isGovPayUp()
|
|
183
|
+
} catch {}
|
|
184
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error retrieving GovPay health status', error)
|
|
185
|
+
})
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
describe('getRecurringPaymentAgreementInformation', () => {
|
|
189
|
+
it('retrieves recurring payment agreement information', async () => {
|
|
190
|
+
fetch.mockReturnValue({ ok: true, status: 200, json: () => {} })
|
|
191
|
+
await expect(govUkPayApi.getRecurringPaymentAgreementInformation(123)).resolves.toEqual(
|
|
192
|
+
expect.objectContaining({ ok: true, status: 200 })
|
|
193
|
+
)
|
|
194
|
+
expect(fetch).toHaveBeenCalledWith('http://0.0.0.0/agreement/123', { headers: recurringHeaders, method: 'get', timeout: 10000 })
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('logs and throws errors', async () => {
|
|
198
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
|
|
199
|
+
fetch.mockImplementation(() => {
|
|
200
|
+
throw new Error('test event error')
|
|
201
|
+
})
|
|
202
|
+
await expect(govUkPayApi.getRecurringPaymentAgreementInformation(123)).rejects.toEqual(Error('test event error'))
|
|
203
|
+
expect(consoleErrorSpy).toHaveBeenCalled()
|
|
204
|
+
})
|
|
205
|
+
})
|
|
150
206
|
})
|
|
@@ -706,4 +706,44 @@ describe('sales-api-connector', () => {
|
|
|
706
706
|
})
|
|
707
707
|
})
|
|
708
708
|
})
|
|
709
|
+
|
|
710
|
+
describe('cancelRecurringPayment', () => {
|
|
711
|
+
describe.each([['id'], ['abc-123']])("Cancelling recurring payment id '%s'", id => {
|
|
712
|
+
beforeEach(() => {
|
|
713
|
+
fetch.mockReturnValue({
|
|
714
|
+
ok: true,
|
|
715
|
+
status: 200,
|
|
716
|
+
statusText: 'OK',
|
|
717
|
+
text: async () => JSON.stringify({ id })
|
|
718
|
+
})
|
|
719
|
+
})
|
|
720
|
+
|
|
721
|
+
it('calls the endpoint with the correct parameters', async () => {
|
|
722
|
+
await salesApi.cancelRecurringPayment(id)
|
|
723
|
+
|
|
724
|
+
expect(fetch).toHaveBeenCalledWith(`http://0.0.0.0:4000/cancelRecurringPayment/${id}`, {
|
|
725
|
+
method: 'get',
|
|
726
|
+
headers: expect.any(Object),
|
|
727
|
+
timeout: 20000
|
|
728
|
+
})
|
|
729
|
+
})
|
|
730
|
+
|
|
731
|
+
it('returns the expected response data', async () => {
|
|
732
|
+
const processedResult = await salesApi.cancelRecurringPayment(id)
|
|
733
|
+
|
|
734
|
+
expect(processedResult).toEqual({ id })
|
|
735
|
+
})
|
|
736
|
+
})
|
|
737
|
+
|
|
738
|
+
it('throws an error on non-2xx response', async () => {
|
|
739
|
+
fetch.mockReturnValue({
|
|
740
|
+
ok: false,
|
|
741
|
+
status: 500,
|
|
742
|
+
statusText: 'Internal Server Error',
|
|
743
|
+
text: async () => 'Server Error'
|
|
744
|
+
})
|
|
745
|
+
|
|
746
|
+
await expect(salesApi.cancelRecurringPayment('id')).rejects.toThrow('Internal Server Error')
|
|
747
|
+
})
|
|
748
|
+
})
|
|
709
749
|
})
|
package/src/govuk-pay-api.js
CHANGED
|
@@ -86,3 +86,30 @@ export const fetchPaymentEvents = async (paymentId, recurring = false) => {
|
|
|
86
86
|
throw err
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
|
|
90
|
+
export const isGovPayUp = async () => {
|
|
91
|
+
try {
|
|
92
|
+
return await fetch(process.env.GOV_PAY_HEALTH_CHECK_URL)
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.error('Error retrieving GovPay health status', err)
|
|
95
|
+
throw err
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Gets payment information linked too a payment
|
|
101
|
+
* @param agreementId - agreementId set up when creating recurring payment
|
|
102
|
+
* @returns {Promise<*>}
|
|
103
|
+
*/
|
|
104
|
+
export const getRecurringPaymentAgreementInformation = async agreementId => {
|
|
105
|
+
try {
|
|
106
|
+
return fetch(`${process.env.GOV_PAY_RCP_API_URL}/${agreementId}`, {
|
|
107
|
+
headers: headers(true),
|
|
108
|
+
method: 'get',
|
|
109
|
+
timeout: process.env.GOV_PAY_REQUEST_TIMEOUT_MS || GOV_PAY_REQUEST_TIMEOUT_MS_DEFAULT
|
|
110
|
+
})
|
|
111
|
+
} catch (err) {
|
|
112
|
+
console.error(`Error fetching recurring payment agreement information in the GOV.UK API service - agreementId: ${agreementId}`, err)
|
|
113
|
+
throw err
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -308,3 +308,14 @@ export const preparePermissionDataForRenewal = async referenceNumber =>
|
|
|
308
308
|
export const processRPResult = async (transactionId, paymentId, createdDate) => {
|
|
309
309
|
return exec2xxOrThrow(call(new URL(`/processRPResult/${transactionId}/${paymentId}/${createdDate}`, urlBase), 'get'))
|
|
310
310
|
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Cancel a RecurringPayment
|
|
314
|
+
*
|
|
315
|
+
* @param id
|
|
316
|
+
* @returns {Promise<*>}
|
|
317
|
+
* @throws on a non-2xx response
|
|
318
|
+
*/
|
|
319
|
+
export const cancelRecurringPayment = async id => {
|
|
320
|
+
return exec2xxOrThrow(call(new URL(`/cancelRecurringPayment/${id}`, urlBase), 'get'))
|
|
321
|
+
}
|