@defra-fish/recurring-payments-job 1.60.0-rc.3 → 1.60.0-rc.4
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.60.0-rc.
|
|
3
|
+
"version": "1.60.0-rc.4",
|
|
4
4
|
"description": "Rod Licensing Recurring Payments Job",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@defra-fish/business-rules-lib": "1.60.0-rc.
|
|
40
|
-
"@defra-fish/connectors-lib": "1.60.0-rc.
|
|
39
|
+
"@defra-fish/business-rules-lib": "1.60.0-rc.4",
|
|
40
|
+
"@defra-fish/connectors-lib": "1.60.0-rc.4",
|
|
41
41
|
"commander": "^7.2.0",
|
|
42
42
|
"moment-timezone": "^0.5.34"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "0c5c50b668c126c636f7a7a018dc5706e2d74eaf"
|
|
45
45
|
}
|
|
@@ -10,8 +10,10 @@ jest.mock('@defra-fish/connectors-lib', () => ({
|
|
|
10
10
|
licensee: { countryCode: 'GB-ENG' }
|
|
11
11
|
})),
|
|
12
12
|
createTransaction: jest.fn(() => ({
|
|
13
|
+
id: 'test-transaction-id',
|
|
13
14
|
cost: 30
|
|
14
|
-
}))
|
|
15
|
+
})),
|
|
16
|
+
processRPResult: jest.fn()
|
|
15
17
|
}
|
|
16
18
|
}))
|
|
17
19
|
|
|
@@ -21,6 +23,19 @@ jest.mock('../services/govuk-pay-service.js', () => ({
|
|
|
21
23
|
}))
|
|
22
24
|
|
|
23
25
|
const PAYMENT_STATUS_DELAY = 60000
|
|
26
|
+
const getPaymentStatusSuccess = () => ({ state: { status: 'success' } })
|
|
27
|
+
const getMockPaymentRequestResponse = () => [
|
|
28
|
+
{
|
|
29
|
+
entity: { agreementId: 'agreement-1' },
|
|
30
|
+
expanded: {
|
|
31
|
+
activePermission: {
|
|
32
|
+
entity: {
|
|
33
|
+
referenceNumber: 'ref-1'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
24
39
|
|
|
25
40
|
describe('recurring-payments-processor', () => {
|
|
26
41
|
beforeEach(() => {
|
|
@@ -65,9 +80,9 @@ describe('recurring-payments-processor', () => {
|
|
|
65
80
|
it('prepares the data for found recurring payments', async () => {
|
|
66
81
|
const referenceNumber = Symbol('reference')
|
|
67
82
|
salesApi.getDueRecurringPayments.mockReturnValueOnce([getMockDueRecurringPayment(referenceNumber)])
|
|
68
|
-
const mockPaymentResponse = { payment_id: 'test-payment-id' }
|
|
83
|
+
const mockPaymentResponse = { payment_id: 'test-payment-id', created_date: '2025-01-01T00:00:00.000Z' }
|
|
69
84
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
70
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
85
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
71
86
|
|
|
72
87
|
await processRecurringPayments()
|
|
73
88
|
|
|
@@ -119,7 +134,7 @@ describe('recurring-payments-processor', () => {
|
|
|
119
134
|
|
|
120
135
|
const mockPaymentResponse = { payment_id: 'test-payment-id', agreementId: 'test-agreement-id' }
|
|
121
136
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
122
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
137
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
123
138
|
|
|
124
139
|
await processRecurringPayments()
|
|
125
140
|
|
|
@@ -144,7 +159,7 @@ describe('recurring-payments-processor', () => {
|
|
|
144
159
|
|
|
145
160
|
const mockPaymentResponse = { payment_id: 'test-payment-id' }
|
|
146
161
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
147
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
162
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
148
163
|
|
|
149
164
|
await processRecurringPayments()
|
|
150
165
|
|
|
@@ -174,7 +189,7 @@ describe('recurring-payments-processor', () => {
|
|
|
174
189
|
|
|
175
190
|
const mockPaymentResponse = { payment_id: 'test-payment-id' }
|
|
176
191
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
177
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
192
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
178
193
|
|
|
179
194
|
await processRecurringPayments()
|
|
180
195
|
|
|
@@ -195,7 +210,7 @@ describe('recurring-payments-processor', () => {
|
|
|
195
210
|
|
|
196
211
|
const mockPaymentResponse = { payment_id: 'test-payment-id' }
|
|
197
212
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
198
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
213
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
199
214
|
|
|
200
215
|
await processRecurringPayments()
|
|
201
216
|
|
|
@@ -233,7 +248,7 @@ describe('recurring-payments-processor', () => {
|
|
|
233
248
|
|
|
234
249
|
const mockPaymentResponse = { payment_id: 'test-payment-id', agreementId }
|
|
235
250
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
236
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
251
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
237
252
|
|
|
238
253
|
const expectedData = {
|
|
239
254
|
amount: 5000,
|
|
@@ -261,16 +276,15 @@ describe('recurring-payments-processor', () => {
|
|
|
261
276
|
}
|
|
262
277
|
}
|
|
263
278
|
]
|
|
264
|
-
salesApi.getDueRecurringPayments.
|
|
265
|
-
salesApi.createTransaction.
|
|
279
|
+
salesApi.getDueRecurringPayments.mockResolvedValueOnce(mockResponse)
|
|
280
|
+
salesApi.createTransaction.mockResolvedValueOnce({
|
|
266
281
|
id: 'payment-id-1'
|
|
267
282
|
})
|
|
268
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
283
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
269
284
|
const mockPaymentResponse = { payment_id: 'test-payment-id', agreementId: 'agreement-1' }
|
|
270
285
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
271
286
|
|
|
272
287
|
await processRecurringPayments()
|
|
273
|
-
jest.useFakeTimers(60000)
|
|
274
288
|
|
|
275
289
|
expect(getPaymentStatus).toHaveBeenCalledWith('test-payment-id')
|
|
276
290
|
})
|
|
@@ -290,20 +304,17 @@ describe('recurring-payments-processor', () => {
|
|
|
290
304
|
}
|
|
291
305
|
}
|
|
292
306
|
]
|
|
293
|
-
salesApi.getDueRecurringPayments.
|
|
294
|
-
salesApi.createTransaction.
|
|
307
|
+
salesApi.getDueRecurringPayments.mockResolvedValueOnce(mockResponse)
|
|
308
|
+
salesApi.createTransaction.mockResolvedValueOnce({
|
|
295
309
|
id: mockPaymentId
|
|
296
310
|
})
|
|
297
311
|
const mockPaymentResponse = { payment_id: mockPaymentId, agreementId: 'agreement-1' }
|
|
298
312
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
299
|
-
|
|
300
|
-
getPaymentStatus.mockResolvedValueOnce(mockPaymentStatus)
|
|
301
|
-
const mockStatus = JSON.stringify(mockPaymentStatus.state.status)
|
|
313
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
302
314
|
|
|
303
315
|
await processRecurringPayments()
|
|
304
|
-
jest.advanceTimersByTime(60000)
|
|
305
316
|
|
|
306
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(`Payment status for ${mockPaymentId}:
|
|
317
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(`Payment status for ${mockPaymentId}: success`)
|
|
307
318
|
})
|
|
308
319
|
|
|
309
320
|
it('should call setTimeout with correct delay when there are recurring payments', async () => {
|
|
@@ -311,7 +322,7 @@ describe('recurring-payments-processor', () => {
|
|
|
311
322
|
salesApi.getDueRecurringPayments.mockResolvedValueOnce([getMockDueRecurringPayment(referenceNumber)])
|
|
312
323
|
const mockPaymentResponse = { payment_id: 'test-payment-id' }
|
|
313
324
|
sendPayment.mockResolvedValueOnce(mockPaymentResponse)
|
|
314
|
-
getPaymentStatus.mockResolvedValueOnce(
|
|
325
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
315
326
|
|
|
316
327
|
const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(cb => cb())
|
|
317
328
|
|
|
@@ -330,6 +341,32 @@ describe('recurring-payments-processor', () => {
|
|
|
330
341
|
expect(setTimeoutSpy).not.toHaveBeenCalled()
|
|
331
342
|
})
|
|
332
343
|
|
|
344
|
+
it('calls processRPResult with transaction id, payment id and created date when payment is successful', async () => {
|
|
345
|
+
const mockTransactionId = 'test-transaction-id'
|
|
346
|
+
const mockPaymentId = 'test-payment-id'
|
|
347
|
+
const mockPaymentCreatedDate = '2025-01-01T00:00:00.000Z'
|
|
348
|
+
salesApi.getDueRecurringPayments.mockResolvedValueOnce(getMockPaymentRequestResponse())
|
|
349
|
+
salesApi.createTransaction.mockResolvedValueOnce({ id: mockTransactionId, cost: 30 })
|
|
350
|
+
sendPayment.mockResolvedValueOnce({ payment_id: mockPaymentId, agreementId: 'agreement-1', created_date: mockPaymentCreatedDate })
|
|
351
|
+
getPaymentStatus.mockResolvedValueOnce(getPaymentStatusSuccess())
|
|
352
|
+
|
|
353
|
+
await processRecurringPayments()
|
|
354
|
+
|
|
355
|
+
expect(salesApi.processRPResult).toHaveBeenCalledWith(mockTransactionId, mockPaymentId, mockPaymentCreatedDate)
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
it("doesn't call processRPResult if payment status is not successful", async () => {
|
|
359
|
+
const mockPaymentId = 'test-payment-id'
|
|
360
|
+
salesApi.getDueRecurringPayments.mockResolvedValueOnce(getMockPaymentRequestResponse())
|
|
361
|
+
salesApi.createTransaction.mockResolvedValueOnce({ id: mockPaymentId, cost: 30 })
|
|
362
|
+
sendPayment.mockResolvedValueOnce({ payment_id: mockPaymentId, agreementId: 'agreement-1' })
|
|
363
|
+
getPaymentStatus.mockResolvedValueOnce({ state: { status: 'Pending' } })
|
|
364
|
+
|
|
365
|
+
await processRecurringPayments()
|
|
366
|
+
|
|
367
|
+
expect(salesApi.processRPResult).not.toHaveBeenCalledWith()
|
|
368
|
+
})
|
|
369
|
+
|
|
333
370
|
describe.each([2, 3, 10])('if there are %d recurring payments', count => {
|
|
334
371
|
it('prepares the data for each one', async () => {
|
|
335
372
|
const references = []
|
|
@@ -344,7 +381,7 @@ describe('recurring-payments-processor', () => {
|
|
|
344
381
|
salesApi.getDueRecurringPayments.mockReturnValueOnce(mockGetDueRecurringPayments)
|
|
345
382
|
const mockPaymentResponse = { payment_id: 'test-payment-id' }
|
|
346
383
|
sendPayment.mockResolvedValue(mockPaymentResponse)
|
|
347
|
-
const mockPaymentStatus =
|
|
384
|
+
const mockPaymentStatus = getPaymentStatusSuccess()
|
|
348
385
|
getPaymentStatus.mockResolvedValue(mockPaymentStatus)
|
|
349
386
|
|
|
350
387
|
const expectedData = []
|
|
@@ -5,6 +5,7 @@ import { getPaymentStatus, sendPayment } from './services/govuk-pay-service.js'
|
|
|
5
5
|
|
|
6
6
|
const PAYMENT_STATUS_DELAY = 60000
|
|
7
7
|
const payments = []
|
|
8
|
+
const PAYMENT_STATUS_SUCCESS = 'success'
|
|
8
9
|
|
|
9
10
|
export const processRecurringPayments = async () => {
|
|
10
11
|
if (process.env.RUN_RECURRING_PAYMENTS?.toLowerCase() === 'true') {
|
|
@@ -48,7 +49,9 @@ const takeRecurringPayment = async (agreementId, transaction) => {
|
|
|
48
49
|
const payment = await sendPayment(preparedPayment)
|
|
49
50
|
payments.push({
|
|
50
51
|
agreementId,
|
|
51
|
-
paymentId: payment.payment_id
|
|
52
|
+
paymentId: payment.payment_id,
|
|
53
|
+
created_date: payment.created_date,
|
|
54
|
+
transaction
|
|
52
55
|
})
|
|
53
56
|
}
|
|
54
57
|
|
|
@@ -101,10 +104,13 @@ const processRecurringPaymentStatus = async record => {
|
|
|
101
104
|
const {
|
|
102
105
|
state: { status }
|
|
103
106
|
} = await getPaymentStatus(paymentId)
|
|
104
|
-
console.log(`Payment status for ${paymentId}: ${
|
|
107
|
+
console.log(`Payment status for ${paymentId}: ${status}`)
|
|
108
|
+
if (status === PAYMENT_STATUS_SUCCESS) {
|
|
109
|
+
const payment = payments.find(p => p.paymentId === paymentId)
|
|
110
|
+
await salesApi.processRPResult(payment.transaction.id, paymentId, payment.created_date)
|
|
111
|
+
}
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
const getPaymentId = agreementId => {
|
|
108
|
-
|
|
109
|
-
return payment.paymentId
|
|
115
|
+
return payments.find(p => p.agreementId === agreementId).paymentId
|
|
110
116
|
}
|