@defra-fish/sales-api-service 1.63.0-rc.4 → 1.63.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/sales-api-service",
3
- "version": "1.63.0-rc.4",
3
+ "version": "1.63.0-rc.6",
4
4
  "description": "Rod Licensing Sales API",
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,9 +35,9 @@
35
35
  "test": "echo \"Error: run tests from root\" && exit 1"
36
36
  },
37
37
  "dependencies": {
38
- "@defra-fish/business-rules-lib": "1.63.0-rc.4",
39
- "@defra-fish/connectors-lib": "1.63.0-rc.4",
40
- "@defra-fish/dynamics-lib": "1.63.0-rc.4",
38
+ "@defra-fish/business-rules-lib": "1.63.0-rc.6",
39
+ "@defra-fish/connectors-lib": "1.63.0-rc.6",
40
+ "@defra-fish/dynamics-lib": "1.63.0-rc.6",
41
41
  "@hapi/boom": "^9.1.2",
42
42
  "@hapi/hapi": "^20.1.3",
43
43
  "@hapi/inert": "^6.0.3",
@@ -52,5 +52,5 @@
52
52
  "moment-timezone": "^0.5.34",
53
53
  "uuid": "^8.3.2"
54
54
  },
55
- "gitHead": "19c5ac3cf85aa9f3dc5e7ebc0f14cfe88936125c"
55
+ "gitHead": "bb4bf03e0fdf3e8c04b00a1bf10b844475796434"
56
56
  }
@@ -1,4 +1,9 @@
1
- import { createTransactionSchema, createTransactionResponseSchema, finaliseTransactionResponseSchema } from '../transaction.schema.js'
1
+ import {
2
+ createTransactionSchema,
3
+ createTransactionResponseSchema,
4
+ finaliseTransactionResponseSchema,
5
+ retrieveStagedTransactionParamsSchema
6
+ } from '../transaction.schema.js'
2
7
  import { mockTransactionPayload, mockStagedTransactionRecord, mockFinalisedTransactionRecord } from '../../__mocks__/test-data.js'
3
8
 
4
9
  jest.mock('../validators/validators.js', () => ({
@@ -110,12 +115,9 @@ describe('createTransactionSchema', () => {
110
115
  await expect(createTransactionSchema.validateAsync(mockPayload)).resolves.not.toThrow()
111
116
  })
112
117
 
113
- it.each([
114
- ['agreement id', { id: 'fdc73d20-a0bf-4da6-9a49-2f0a24bd3509' }],
115
- ['id', { agreementId: 'jhy7u8ii87uyhjui87u89ui8ie' }]
116
- ])('fails validation if %s is omitted from recurring payment detail', async (_d, recurringPayment) => {
118
+ it('fails validation if agreement id is omitted from recurring payment detail', async () => {
117
119
  const mockPayload = mockTransactionPayload()
118
- mockPayload.recurringPayment = recurringPayment
120
+ mockPayload.recurringPayment = { id: 'fdc73d20-a0bf-4da6-9a49-2f0a24bd3509' }
119
121
  await expect(() => createTransactionSchema.validateAsync(mockPayload)).rejects.toThrow()
120
122
  })
121
123
 
@@ -153,3 +155,32 @@ describe('finaliseTransactionResponseSchema', () => {
153
155
  expect(result).toBeInstanceOf(Object)
154
156
  })
155
157
  })
158
+
159
+ describe('retrieveStagedTransactionParamsSchema', () => {
160
+ it.each([
161
+ ['36fb757c-6377-49c5-ab6e-32eb9782fcf0'],
162
+ ['c290b78d-3bbc-4445-b4dd-b36f6ee044a2'],
163
+ ['2323a890-b36f-47b1-ab9f-d60e292ac4ae'],
164
+ ['9c6b79be-28be-4916-aa5c-08520aa1e804']
165
+ ])('validates successfully when a uuid v4 transactionId is %s', async transactionId => {
166
+ const sampleData = { id: transactionId }
167
+ await expect(retrieveStagedTransactionParamsSchema.validateAsync(sampleData)).resolves.not.toThrow()
168
+ })
169
+
170
+ it.each([
171
+ ['uuid1 string', '5a429f62-871b-11ef-b864-0242ac120002'],
172
+ ['uuid2 string', '000003e8-871b-21ef-8000-325096b39f47'],
173
+ ['uuid3 string', 'a3bb189e-8bf9-3888-9912-ace4e6543002'],
174
+ ['uuid5 string', 'a6edc906-2f9f-5fb2-a373-efac406f0ef2'],
175
+ ['uuid6 string', 'a3bb189e-8bf9-3888-9912-ace4e6543002'],
176
+ ['uuid7 string', '01927705-ffac-77b5-89af-c97451b1bbe2'],
177
+ ['numeric', 4567]
178
+ ])('fails validation when provided with a %s for transactionId', async (_d, transactionId) => {
179
+ const sampleData = { id: transactionId }
180
+ await expect(() => retrieveStagedTransactionParamsSchema.validateAsync(sampleData)).rejects.toThrow()
181
+ })
182
+
183
+ it('throws an error if id missing', async () => {
184
+ await expect(() => retrieveStagedTransactionParamsSchema.validateAsync({}).rejects.toThrow())
185
+ })
186
+ })
@@ -38,7 +38,7 @@ const createTransactionRequestSchemaContent = {
38
38
  transactionId: Joi.string().guid({ version: 'uuidv4' }).optional(),
39
39
  recurringPayment: Joi.object({
40
40
  agreementId: Joi.string().alphanum().length(AGREEMENT_ID_LENGTH).required(),
41
- id: Joi.string().guid().required()
41
+ id: Joi.string().guid()
42
42
  }).optional()
43
43
  }
44
44
 
@@ -156,3 +156,7 @@ export const finaliseTransactionResponseSchema = Joi.object({
156
156
  .required()
157
157
  .label('finalise-transaction-status')
158
158
  }).label('finalise-transaction-response')
159
+
160
+ export const retrieveStagedTransactionParamsSchema = Joi.object({
161
+ id: Joi.string().guid({ version: 'uuidv4' }).required()
162
+ })
@@ -1,6 +1,10 @@
1
1
  import initialiseServer from '../../server.js'
2
2
  import { mockTransactionPayload, mockStagedTransactionRecord } from '../../../__mocks__/test-data.js'
3
3
  import { v4 as uuidv4 } from 'uuid'
4
+ import { retrieveStagedTransactionParamsSchema } from '../../../schema/transaction.schema.js'
5
+ import { retrieveStagedTransaction } from '../../../services/transactions/retrieve-transaction.js'
6
+ import transactions from '../transactions.js'
7
+
4
8
  jest.mock('../../../services/transactions/transactions.service.js', () => ({
5
9
  createTransaction: jest.fn(async () => mockStagedTransactionRecord()),
6
10
  createTransactions: jest.fn(async payloads => Array(payloads.length).fill(mockStagedTransactionRecord())),
@@ -9,6 +13,10 @@ jest.mock('../../../services/transactions/transactions.service.js', () => ({
9
13
  processDlq: jest.fn(async () => {})
10
14
  }))
11
15
 
16
+ jest.mock('../../../services/transactions/retrieve-transaction.js', () => ({
17
+ retrieveStagedTransaction: jest.fn()
18
+ }))
19
+
12
20
  jest.mock('../../../schema/validators/validators.js', () => ({
13
21
  ...jest.requireActual('../../../schema/validators/validators.js'),
14
22
  createOptionSetValidator: () => async () => undefined,
@@ -18,6 +26,20 @@ jest.mock('../../../schema/validators/validators.js', () => ({
18
26
  createPermitConcessionValidator: () => async () => undefined
19
27
  }))
20
28
 
29
+ jest.mock('@defra-fish/connectors-lib', () => {
30
+ const awsMock = {
31
+ docClient: {
32
+ get: jest.fn(() => ({ Item: { id: 'abc123' } }))
33
+ }
34
+ }
35
+ return {
36
+ AWS: jest.fn(() => awsMock),
37
+ airbrake: {
38
+ initialise: jest.fn()
39
+ }
40
+ }
41
+ })
42
+
21
43
  let server = null
22
44
 
23
45
  describe('transaction handler', () => {
@@ -214,4 +236,30 @@ describe('transaction handler', () => {
214
236
  expect(result).toBeUnprocessableEntityErrorResponse()
215
237
  })
216
238
  })
239
+
240
+ describe('retrieveStagedTransaction', () => {
241
+ const getMockRequest = ({ id = 'abc123' }) => ({ params: { id } })
242
+ const getMockResponseToolkit = () => ({ response: jest.fn() })
243
+ const retrieveHandler = transactions[transactions.length - 1].options.handler
244
+
245
+ it('handler should return continue response', async () => {
246
+ const request = getMockRequest({})
247
+ const responseToolkit = getMockResponseToolkit()
248
+ expect(await retrieveHandler(request, responseToolkit)).toEqual(responseToolkit.continue)
249
+ })
250
+
251
+ it('should call retrieveStagedTransaction with id', async () => {
252
+ const id = 'transaction-id'
253
+ const request = getMockRequest({ id })
254
+ await retrieveHandler(request, getMockResponseToolkit())
255
+ expect(retrieveStagedTransaction).toHaveBeenCalledWith(id)
256
+ })
257
+
258
+ it('should validate with cancelRecurringPaymentRequestParamsSchema', async () => {
259
+ const id = 'transaction-id'
260
+ const request = getMockRequest({ id })
261
+ await retrieveHandler(request, getMockResponseToolkit())
262
+ expect(transactions[5].options.validate.params).toBe(retrieveStagedTransactionParamsSchema)
263
+ })
264
+ })
217
265
  })
@@ -7,6 +7,7 @@ import {
7
7
  processQueue,
8
8
  processDlq
9
9
  } from '../../services/transactions/transactions.service.js'
10
+ import { retrieveStagedTransaction } from '../../services/transactions/retrieve-transaction.js'
10
11
  import {
11
12
  createTransactionSchema,
12
13
  createTransactionResponseSchema,
@@ -14,6 +15,7 @@ import {
14
15
  createTransactionBatchResponseSchema,
15
16
  finaliseTransactionRequestSchema,
16
17
  finaliseTransactionResponseSchema,
18
+ retrieveStagedTransactionParamsSchema,
17
19
  BATCH_CREATE_MAX_COUNT
18
20
  } from '../../schema/transaction.schema.js'
19
21
  import db from 'debug'
@@ -174,5 +176,29 @@ export default [
174
176
  }
175
177
  }
176
178
  }
179
+ },
180
+ {
181
+ method: 'GET',
182
+ path: '/retrieveStagedTransaction/{id}',
183
+ options: {
184
+ handler: async (request, h) => {
185
+ const { id } = request.params
186
+ const result = await retrieveStagedTransaction(id)
187
+ return h.response(result)
188
+ },
189
+ description: 'Retrieve a staged transaction',
190
+ tags: ['api', 'transactions'],
191
+ validate: {
192
+ params: retrieveStagedTransactionParamsSchema
193
+ },
194
+ plugins: {
195
+ 'hapi-swagger': {
196
+ responses: {
197
+ 200: { description: 'Staged transaction retreived' }
198
+ },
199
+ order: 5
200
+ }
201
+ }
202
+ }
177
203
  }
178
204
  ]
@@ -392,7 +392,9 @@ describe('recurring payments service', () => {
392
392
  ...permission
393
393
  }
394
394
  ],
395
- agreementId,
395
+ recurringPayment: {
396
+ agreementId
397
+ },
396
398
  payment: {
397
399
  amount: 35.8,
398
400
  source: 'Gov Pay',
@@ -37,8 +37,8 @@ const getNextDueDate = (startDate, issueDate, endDate) => {
37
37
  }
38
38
 
39
39
  export const generateRecurringPaymentRecord = async (transactionRecord, permission) => {
40
- if (transactionRecord.agreementId) {
41
- const agreementResponse = await getRecurringPaymentAgreement(transactionRecord.agreementId)
40
+ if (transactionRecord.recurringPayment.agreementId) {
41
+ const agreementResponse = await getRecurringPaymentAgreement(transactionRecord.recurringPayment.agreementId)
42
42
  const lastDigitsCardNumbers = agreementResponse.payment_instrument?.card_details?.last_digits_card_number
43
43
  const [{ startDate, issueDate, endDate }] = transactionRecord.permissions
44
44
  return {
@@ -49,7 +49,7 @@ export const generateRecurringPaymentRecord = async (transactionRecord, permissi
49
49
  cancelledDate: null,
50
50
  cancelledReason: null,
51
51
  endDate,
52
- agreementId: transactionRecord.agreementId,
52
+ agreementId: transactionRecord.recurringPayment.agreementId,
53
53
  status: 1,
54
54
  last_digits_card_number: lastDigitsCardNumbers
55
55
  }