@defra-fish/recurring-payments-job 1.63.0-rc.6 → 1.63.0-rc.8

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.63.0-rc.6",
3
+ "version": "1.63.0-rc.8",
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.63.0-rc.6",
40
- "@defra-fish/connectors-lib": "1.63.0-rc.6",
39
+ "@defra-fish/business-rules-lib": "1.63.0-rc.8",
40
+ "@defra-fish/connectors-lib": "1.63.0-rc.8",
41
41
  "commander": "^7.2.0",
42
42
  "debug": "^4.3.3",
43
43
  "moment-timezone": "^0.5.34"
44
44
  },
45
- "gitHead": "bb4bf03e0fdf3e8c04b00a1bf10b844475796434"
45
+ "gitHead": "4376fb63f6e1867708241521e43c4bce5791e08a"
46
46
  }
@@ -16,9 +16,11 @@ describe('govuk-pay-service', () => {
16
16
 
17
17
  it('sendPayment should return response from createPayment in json format', async () => {
18
18
  const mockPreparedPayment = { id: 'test-payment-id' }
19
- const mockResponse = { status: 'success', paymentId: 'abc123' }
19
+ const mockResponse = { state: { status: 'created' }, payment_id: 'abcde12345' }
20
20
 
21
21
  const mockFetchResponse = {
22
+ status: 200,
23
+ ok: true,
22
24
  json: jest.fn().mockResolvedValue(mockResponse)
23
25
  }
24
26
  govUkPayApi.createPayment.mockResolvedValue(mockFetchResponse)
@@ -67,6 +69,66 @@ describe('govuk-pay-service', () => {
67
69
  expect(consoleSpy).toHaveBeenCalledWith('Error creating payment', preparedPayment.id)
68
70
  }
69
71
  })
72
+
73
+ it('should throw an error when response is not ok', async () => {
74
+ const mockFetchResponse = {
75
+ ok: false,
76
+ status: 400,
77
+ json: jest.fn().mockResolvedValue({
78
+ code: 'P0102',
79
+ field: 'agreement_id',
80
+ description: 'Invalid attribute value: agreement_id. Agreement does not exist'
81
+ })
82
+ }
83
+ govUkPayApi.createPayment.mockResolvedValueOnce(mockFetchResponse)
84
+
85
+ await expect(
86
+ sendPayment({
87
+ amount: 100,
88
+ description: 'The recurring card payment for your rod fishing licence',
89
+ id: 'a50f0d51-295f-42b3-98f8-97c0641ede5a',
90
+ authorisation_mode: 'agreement',
91
+ agreement_id: 'does_not_exist'
92
+ })
93
+ ).rejects.toThrow('Unexpected response from GOV.UK Pay API')
94
+ })
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
+ })
70
132
  })
71
133
 
72
134
  describe('getPaymentStatus', () => {
@@ -81,7 +143,7 @@ describe('govuk-pay-service', () => {
81
143
  })
82
144
 
83
145
  it('should return the payment status on successful response', async () => {
84
- const mockPaymentStatus = { code: 'P1234', description: 'Success' }
146
+ const mockPaymentStatus = { amount: 37.5, state: { status: 'success', finished: 'true' } }
85
147
  govUkPayApi.fetchPaymentStatus.mockResolvedValue({
86
148
  ok: true,
87
149
  json: jest.fn().mockResolvedValue(mockPaymentStatus)
@@ -96,25 +158,47 @@ describe('govuk-pay-service', () => {
96
158
  })
97
159
 
98
160
  it('should throw an error when response is not ok', async () => {
99
- const mockErrorDetails = { error: 'Payment not found' }
100
161
  const mockFetchResponse = {
101
162
  ok: false,
102
- json: jest.fn().mockResolvedValue(mockErrorDetails)
163
+ status: 404,
164
+ json: jest.fn().mockResolvedValue({
165
+ code: 'P0200',
166
+ field: 'payment_id',
167
+ description: 'No payment matched the payment id you provided'
168
+ })
103
169
  }
104
170
  govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockFetchResponse)
105
171
 
106
- await expect(getPaymentStatus('invalid-payment-id')).rejects.toThrow('Payment not found')
172
+ await expect(getPaymentStatus('invalid-payment-id')).rejects.toThrow('Unexpected response from GOV.UK Pay API')
107
173
  })
108
174
 
109
- it('should throw an error when response is not ok but errorDetails has no value', async () => {
110
- const mockErrorDetails = {}
175
+ it('should log details when response is not ok', async () => {
176
+ const serviceResponseBody = {
177
+ code: 'P0200',
178
+ field: 'payment_id',
179
+ description: 'No payment matched the payment id you provided'
180
+ }
111
181
  const mockFetchResponse = {
112
182
  ok: false,
113
- json: jest.fn().mockResolvedValue(mockErrorDetails)
183
+ status: 404,
184
+ json: jest.fn().mockResolvedValue(serviceResponseBody)
114
185
  }
115
186
  govUkPayApi.fetchPaymentStatus.mockResolvedValue(mockFetchResponse)
187
+ jest.spyOn(console, 'error')
188
+ const paymentId = 'invalid-payment-id'
116
189
 
117
- await expect(getPaymentStatus('invalid-payment-id')).rejects.toThrow('Error fetching payment status')
190
+ try {
191
+ await getPaymentStatus(paymentId)
192
+ } catch {}
193
+
194
+ expect(console.error).toHaveBeenCalledWith(
195
+ expect.objectContaining({
196
+ method: 'GET',
197
+ status: mockFetchResponse.status,
198
+ response: serviceResponseBody,
199
+ paymentId
200
+ })
201
+ )
118
202
  })
119
203
 
120
204
  it('should throw an error when fetchPaymentStatus fails', async () => {
@@ -3,13 +3,26 @@ 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
- try {
7
- const response = await govUkPayApi.createPayment(preparedPayment, true)
8
- return await response.json()
9
- } catch (e) {
10
- console.error('Error creating payment', preparedPayment.id)
11
- throw e
6
+ const createPayment = async () => {
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
+ }
14
+ const response = await createPayment()
15
+ if (!response.ok) {
16
+ console.error({
17
+ method: 'POST',
18
+ status: response.status,
19
+ response: await response.json(),
20
+ transactionId: preparedPayment.id,
21
+ payload: preparedPayment
22
+ })
23
+ throw new Error('Unexpected response from GOV.UK Pay API')
12
24
  }
25
+ return response.json()
13
26
  }
14
27
 
15
28
  export const getPaymentStatus = async paymentId => {
@@ -17,21 +30,28 @@ export const getPaymentStatus = async paymentId => {
17
30
  throw new Error('Invalid payment ID')
18
31
  }
19
32
 
20
- try {
21
- const response = await govUkPayApi.fetchPaymentStatus(paymentId, true)
22
-
23
- if (!response.ok) {
24
- const errorDetails = await response.json()
25
- console.log(errorDetails)
26
- throw new Error(errorDetails.error || 'Error fetching payment status')
33
+ const fetchPaymentStatus = async () => {
34
+ try {
35
+ return await govUkPayApi.fetchPaymentStatus(paymentId, true)
36
+ } catch (e) {
37
+ console.error('Error fetching payment status', paymentId)
38
+ throw e
27
39
  }
40
+ }
41
+
42
+ const response = await fetchPaymentStatus()
28
43
 
29
- const paymentStatus = await response.json()
30
- return paymentStatus
31
- } catch (error) {
32
- console.error('Error in getPaymentStatus:', error)
33
- throw error
44
+ if (!response.ok) {
45
+ console.error({
46
+ method: 'GET',
47
+ status: response.status,
48
+ response: await response.json(),
49
+ paymentId
50
+ })
51
+ throw new Error('Unexpected response from GOV.UK Pay API')
34
52
  }
53
+
54
+ return response.json()
35
55
  }
36
56
 
37
57
  export const isGovPayUp = async () => {