@defra-fish/recurring-payments-job 1.64.0-rc.5 → 1.64.0-rc.6
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/recurring-payments-job",
|
|
3
|
-
"version": "1.64.0-rc.
|
|
3
|
+
"version": "1.64.0-rc.6",
|
|
4
4
|
"description": "Rod Licensing Recurring Payments Job",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@defra-fish/business-rules-lib": "1.64.0-rc.
|
|
40
|
-
"@defra-fish/connectors-lib": "1.64.0-rc.
|
|
39
|
+
"@defra-fish/business-rules-lib": "1.64.0-rc.6",
|
|
40
|
+
"@defra-fish/connectors-lib": "1.64.0-rc.6",
|
|
41
41
|
"commander": "7.2.0",
|
|
42
42
|
"debug": "4.3.3",
|
|
43
43
|
"moment-timezone": "0.5.34"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "4ca80d63c58c37122b6fc8903840681202983468"
|
|
46
46
|
}
|
|
@@ -70,6 +70,7 @@ const getMockDueRecurringPayment = ({ agreementId = 'test-agreement-id', id = 'a
|
|
|
70
70
|
expanded: { activePermission: { entity: { referenceNumber } } }
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
+
// eslint-disable-next-line camelcase
|
|
73
74
|
const getMockSendPaymentResponse = ({ payment_id = 'pay-1', agreementId = 'agr-1', created_date = '2025-01-01T00:00:00.000Z' } = {}) => ({
|
|
74
75
|
payment_id,
|
|
75
76
|
agreementId,
|
|
@@ -215,7 +216,8 @@ describe('recurring-payments-processor', () => {
|
|
|
215
216
|
})
|
|
216
217
|
|
|
217
218
|
describe('When payment request throws an error...', () => {
|
|
218
|
-
it('
|
|
219
|
+
it('console.error is called with error message', async () => {
|
|
220
|
+
jest.spyOn(console, 'error')
|
|
219
221
|
salesApi.getDueRecurringPayments.mockReturnValueOnce(getMockPaymentRequestResponse())
|
|
220
222
|
const oopsie = new Error('payment gate down')
|
|
221
223
|
sendPayment.mockRejectedValueOnce(oopsie)
|
|
@@ -224,7 +226,7 @@ describe('recurring-payments-processor', () => {
|
|
|
224
226
|
await execute()
|
|
225
227
|
} catch {}
|
|
226
228
|
|
|
227
|
-
expect(
|
|
229
|
+
expect(console.error).toHaveBeenCalledWith(expect.any(String), oopsie)
|
|
228
230
|
})
|
|
229
231
|
|
|
230
232
|
it('prepares and sends all payment requests, even if some fail', async () => {
|
|
@@ -283,6 +285,7 @@ describe('recurring-payments-processor', () => {
|
|
|
283
285
|
})
|
|
284
286
|
|
|
285
287
|
it('logs an error for every failure', async () => {
|
|
288
|
+
jest.spyOn(console, 'error')
|
|
286
289
|
const errors = [new Error('error 1'), new Error('error 2'), new Error('error 3')]
|
|
287
290
|
salesApi.getDueRecurringPayments.mockReturnValueOnce([
|
|
288
291
|
getMockDueRecurringPayment({ referenceNumber: 'fee', agreementId: 'a1' }),
|
|
@@ -299,7 +302,7 @@ describe('recurring-payments-processor', () => {
|
|
|
299
302
|
|
|
300
303
|
await execute()
|
|
301
304
|
|
|
302
|
-
expect(
|
|
305
|
+
expect(console.error).toHaveBeenCalledWith(expect.any(String), ...errors)
|
|
303
306
|
})
|
|
304
307
|
})
|
|
305
308
|
|
|
@@ -583,6 +586,7 @@ describe('recurring-payments-processor', () => {
|
|
|
583
586
|
})
|
|
584
587
|
|
|
585
588
|
it('logs an error if createTransaction fails', async () => {
|
|
589
|
+
jest.spyOn(console, 'error')
|
|
586
590
|
salesApi.getDueRecurringPayments.mockReturnValueOnce([getMockDueRecurringPayment()])
|
|
587
591
|
const error = new Error('Wuh-oh!')
|
|
588
592
|
salesApi.createTransaction.mockImplementationOnce(() => {
|
|
@@ -591,7 +595,7 @@ describe('recurring-payments-processor', () => {
|
|
|
591
595
|
|
|
592
596
|
await execute()
|
|
593
597
|
|
|
594
|
-
expect(
|
|
598
|
+
expect(console.error).toHaveBeenCalledWith(expect.any(String), error)
|
|
595
599
|
})
|
|
596
600
|
|
|
597
601
|
// --- //
|
|
@@ -735,6 +739,7 @@ describe('recurring-payments-processor', () => {
|
|
|
735
739
|
[512, 'Payment status API error for test-payment-id, error 512'],
|
|
736
740
|
[599, 'Payment status API error for test-payment-id, error 599']
|
|
737
741
|
])('logs the correct message when getPaymentStatus rejects with HTTP %i', async (statusCode, expectedMessage) => {
|
|
742
|
+
jest.spyOn(console, 'error')
|
|
738
743
|
const mockPaymentId = 'test-payment-id'
|
|
739
744
|
const mockResponse = [
|
|
740
745
|
{ entity: { agreementId: 'agreement-1' }, expanded: { activePermission: { entity: { referenceNumber: 'ref-1' } } } }
|
|
@@ -752,10 +757,11 @@ describe('recurring-payments-processor', () => {
|
|
|
752
757
|
|
|
753
758
|
await execute()
|
|
754
759
|
|
|
755
|
-
expect(
|
|
760
|
+
expect(console.error).toHaveBeenCalledWith(expectedMessage)
|
|
756
761
|
})
|
|
757
762
|
|
|
758
763
|
it('logs the generic unexpected-error message and still rejects', async () => {
|
|
764
|
+
jest.spyOn(console, 'error')
|
|
759
765
|
const mockPaymentId = 'test-payment-id'
|
|
760
766
|
salesApi.getDueRecurringPayments.mockResolvedValueOnce(getMockPaymentRequestResponse())
|
|
761
767
|
salesApi.createTransaction.mockResolvedValueOnce({ id: mockPaymentId })
|
|
@@ -770,7 +776,7 @@ describe('recurring-payments-processor', () => {
|
|
|
770
776
|
|
|
771
777
|
await execute()
|
|
772
778
|
|
|
773
|
-
expect(
|
|
779
|
+
expect(console.error).toHaveBeenCalledWith(`Unexpected error fetching payment status for ${mockPaymentId}.`)
|
|
774
780
|
})
|
|
775
781
|
|
|
776
782
|
it('should call setTimeout with correct delay when there are recurring payments', async () => {
|
|
@@ -70,7 +70,7 @@ const requestPayments = async dueRCPayments => {
|
|
|
70
70
|
const payments = paymentRequestResults.filter(prr => prr.status === 'fulfilled').map(p => p.value)
|
|
71
71
|
const failures = paymentRequestResults.filter(prr => prr.status === 'rejected').map(f => f.reason)
|
|
72
72
|
if (failures.length) {
|
|
73
|
-
|
|
73
|
+
console.error('Error requesting payments:', ...failures)
|
|
74
74
|
}
|
|
75
75
|
return payments
|
|
76
76
|
}
|
|
@@ -178,11 +178,11 @@ const processRecurringPaymentStatus = async payment => {
|
|
|
178
178
|
const status = error.response?.status
|
|
179
179
|
|
|
180
180
|
if (isClientError(status)) {
|
|
181
|
-
|
|
181
|
+
console.error(`Failed to fetch status for payment ${payment.paymentId}, error ${status}`)
|
|
182
182
|
} else if (isServerError(status)) {
|
|
183
|
-
|
|
183
|
+
console.error(`Payment status API error for ${payment.paymentId}, error ${status}`)
|
|
184
184
|
} else {
|
|
185
|
-
|
|
185
|
+
console.error(`Unexpected error fetching payment status for ${payment.paymentId}.`)
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -57,19 +57,6 @@ describe('govuk-pay-service', () => {
|
|
|
57
57
|
}
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
-
it('should log error message when the GOV.UK Pay API raises an error', async () => {
|
|
61
|
-
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
62
|
-
govUkPayApi.createPayment.mockImplementationOnce(() => {
|
|
63
|
-
throw new Error()
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
await sendPayment(preparedPayment)
|
|
68
|
-
} catch (error) {
|
|
69
|
-
expect(consoleSpy).toHaveBeenCalledWith('Error creating payment', preparedPayment.id)
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
|
|
73
60
|
it('should throw an error when response is not ok', async () => {
|
|
74
61
|
const mockFetchResponse = {
|
|
75
62
|
ok: false,
|
|
@@ -92,43 +79,6 @@ describe('govuk-pay-service', () => {
|
|
|
92
79
|
})
|
|
93
80
|
).rejects.toThrow('Unexpected response from GOV.UK Pay API')
|
|
94
81
|
})
|
|
95
|
-
|
|
96
|
-
it('should log details when response is not ok', async () => {
|
|
97
|
-
const status = 400
|
|
98
|
-
const serviceResponseBody = {
|
|
99
|
-
code: 'P0102',
|
|
100
|
-
field: 'agreement_id',
|
|
101
|
-
description: 'Invalid attribute value: agreement_id. Agreement does not exist'
|
|
102
|
-
}
|
|
103
|
-
const transactionId = 'a50f0d51-295f-42b3-98f8-97c0641ede5a'
|
|
104
|
-
const preparedPayment = {
|
|
105
|
-
amount: 100,
|
|
106
|
-
description: 'The recurring card payment for your rod fishing licence',
|
|
107
|
-
id: transactionId,
|
|
108
|
-
authorisation_mode: 'agreement',
|
|
109
|
-
agreement_id: 'does_not_exist'
|
|
110
|
-
}
|
|
111
|
-
govUkPayApi.createPayment.mockResolvedValueOnce({
|
|
112
|
-
ok: false,
|
|
113
|
-
status,
|
|
114
|
-
json: jest.fn().mockResolvedValue(serviceResponseBody)
|
|
115
|
-
})
|
|
116
|
-
jest.spyOn(console, 'error')
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
await sendPayment(preparedPayment)
|
|
120
|
-
} catch {}
|
|
121
|
-
|
|
122
|
-
expect(console.error).toHaveBeenCalledWith(
|
|
123
|
-
expect.objectContaining({
|
|
124
|
-
method: 'POST',
|
|
125
|
-
status,
|
|
126
|
-
response: serviceResponseBody,
|
|
127
|
-
transactionId,
|
|
128
|
-
payload: preparedPayment
|
|
129
|
-
})
|
|
130
|
-
)
|
|
131
|
-
})
|
|
132
82
|
})
|
|
133
83
|
|
|
134
84
|
describe('getPaymentStatus', () => {
|
|
@@ -3,24 +3,15 @@ import db from 'debug'
|
|
|
3
3
|
const debug = db('recurring-payments:gov.uk-pay-service')
|
|
4
4
|
|
|
5
5
|
export const sendPayment = async preparedPayment => {
|
|
6
|
-
const createPayment =
|
|
7
|
-
try {
|
|
8
|
-
return await govUkPayApi.createPayment(preparedPayment, true)
|
|
9
|
-
} catch (e) {
|
|
10
|
-
console.error('Error creating payment', preparedPayment.id)
|
|
11
|
-
throw e
|
|
12
|
-
}
|
|
13
|
-
}
|
|
6
|
+
const createPayment = () => govUkPayApi.createPayment(preparedPayment, true)
|
|
14
7
|
const response = await createPayment()
|
|
15
8
|
if (!response.ok) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
})
|
|
23
|
-
throw new Error('Unexpected response from GOV.UK Pay API')
|
|
9
|
+
throw new Error(`Unexpected response from GOV.UK Pay API.
|
|
10
|
+
Status: ${response.status},
|
|
11
|
+
Response: ${JSON.stringify(await response.json())}
|
|
12
|
+
Transaction ID: ${preparedPayment.id}
|
|
13
|
+
Payload: ${JSON.stringify(preparedPayment)}
|
|
14
|
+
`)
|
|
24
15
|
}
|
|
25
16
|
return response.json()
|
|
26
17
|
}
|