@defra-fish/sales-api-service 1.59.0-rc.0 → 1.59.0-rc.1
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 +5 -5
- package/src/schema/__tests__/__snapshots__/recurring-payments.schema.spec.js.snap +212826 -0
- package/src/schema/__tests__/recurring-payments.schema.spec.js +99 -0
- package/src/schema/permission.schema.js +6 -6
- package/src/schema/recurring-payments.schema.js +21 -0
- package/src/server/routes/__tests__/recurring-payments.spec.js +8 -2
- package/src/server/routes/recurring-payments.js +17 -4
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { dueRecurringPaymentsResponseSchema } from '../recurring-payments.schema.js'
|
|
2
|
+
|
|
3
|
+
jest.mock('../validators/validators.js', () => ({
|
|
4
|
+
...jest.requireActual('../validators/validators.js'),
|
|
5
|
+
createEntityIdValidator: () => () => {} // sample data so we don't want it validated for being a real entity id
|
|
6
|
+
}))
|
|
7
|
+
|
|
8
|
+
const getSampleData = () => ({
|
|
9
|
+
id: 'd5549fc6-41c1-ef11-b8e8-7c1e52215dc9',
|
|
10
|
+
name: 'test',
|
|
11
|
+
status: 0,
|
|
12
|
+
nextDueDate: '2025-01-22T00:00:00.000Z',
|
|
13
|
+
cancelledDate: null,
|
|
14
|
+
cancelledReason: null,
|
|
15
|
+
endDate: '2025-12-22T23:59:59.000Z',
|
|
16
|
+
agreementId: 'c756d22b-0003-4e24-a922-009f358852bd',
|
|
17
|
+
activePermission: 'cb549fc6-41c1-ef11-b8e8-7c1e52215dc9',
|
|
18
|
+
contactId: 'bf549fc6-41c1-ef11-b8e8-7c1e52215dc9',
|
|
19
|
+
publicId: 'q/kJYJrYNt/PkVbWChugMRSSxoDEttw1ownaNzDDyEw=',
|
|
20
|
+
expanded: {
|
|
21
|
+
contact: {
|
|
22
|
+
entity: {
|
|
23
|
+
id: 'bf549fc6-41c1-ef11-b8e8-7c1e52215dc9',
|
|
24
|
+
firstName: 'Recurring',
|
|
25
|
+
lastName: 'Test',
|
|
26
|
+
birthDate: '1991-01-01',
|
|
27
|
+
email: 'recurring.test@hotmail.com',
|
|
28
|
+
mobilePhone: null,
|
|
29
|
+
organisation: null,
|
|
30
|
+
premises: '1',
|
|
31
|
+
street: 'Catharine Place',
|
|
32
|
+
locality: null,
|
|
33
|
+
town: 'Bath',
|
|
34
|
+
postcode: 'BA1 2PR'
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
activePermission: {
|
|
38
|
+
entity: {
|
|
39
|
+
id: 'cb549fc6-41c1-ef11-b8e8-7c1e52215dc9',
|
|
40
|
+
referenceNumber: '23221225-2WC3FRT-ADQFJ6',
|
|
41
|
+
issueDate: '2024-12-23T15:22:49.000Z',
|
|
42
|
+
startDate: '2024-12-23T15:52:49.000Z',
|
|
43
|
+
endDate: '2025-12-22T23:59:59.000Z',
|
|
44
|
+
stagingId: 'a544cc77-156c-40e7-9c69-02e70829341d',
|
|
45
|
+
dataSource: {
|
|
46
|
+
id: 910400003,
|
|
47
|
+
label: 'Web Sales',
|
|
48
|
+
description: 'Web Sales'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
describe('getDueRecurringPaymentsSchema', () => {
|
|
56
|
+
it('validates expected object', async () => {
|
|
57
|
+
await expect(() => dueRecurringPaymentsResponseSchema.validateAsync(getSampleData())).not.toThrow()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it.each([
|
|
61
|
+
'id',
|
|
62
|
+
'name',
|
|
63
|
+
'status',
|
|
64
|
+
'nextDueDate',
|
|
65
|
+
'cancelledDate',
|
|
66
|
+
'cancelledReason',
|
|
67
|
+
'endDate',
|
|
68
|
+
'agreementId',
|
|
69
|
+
'activePermission',
|
|
70
|
+
'contactId',
|
|
71
|
+
'publicId'
|
|
72
|
+
])('throws an error if %s is missing', async property => {
|
|
73
|
+
const sampleData = getSampleData()
|
|
74
|
+
delete sampleData[property]
|
|
75
|
+
expect(() => dueRecurringPaymentsResponseSchema.validateAsync(sampleData)).rejects.toThrow()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it.each([
|
|
79
|
+
['id', 'not-a-guid'],
|
|
80
|
+
['name', 99],
|
|
81
|
+
['status', 'not-a-number'],
|
|
82
|
+
['nextDueDate', 'not-a-date'],
|
|
83
|
+
['cancelledDate', 'not-a-date'],
|
|
84
|
+
['cancelledReason', 99],
|
|
85
|
+
['endDate', 'not-a-date'],
|
|
86
|
+
['agreementId', 'not-a-guid'],
|
|
87
|
+
['activePermission', 'not-a-guid'],
|
|
88
|
+
['contactId', 'still-not-a-guid'],
|
|
89
|
+
['publicId', 99]
|
|
90
|
+
])('throws an error if %s is not the correct type', async (property, value) => {
|
|
91
|
+
const sampleData = getSampleData()
|
|
92
|
+
sampleData[property] = value
|
|
93
|
+
expect(() => dueRecurringPaymentsResponseSchema.validateAsync(sampleData)).rejects.toThrow()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('snapshot test schema', async () => {
|
|
97
|
+
expect(dueRecurringPaymentsResponseSchema).toMatchSnapshot()
|
|
98
|
+
})
|
|
99
|
+
})
|
|
@@ -5,25 +5,25 @@ import { optionSetOption } from './option-set.schema.js'
|
|
|
5
5
|
import { createReferenceDataEntityValidator } from './validators/validators.js'
|
|
6
6
|
import { Permit } from '@defra-fish/dynamics-lib'
|
|
7
7
|
import { validation } from '@defra-fish/business-rules-lib'
|
|
8
|
-
import { v4 as uuid } from 'uuid'
|
|
9
8
|
|
|
9
|
+
const DATE_EXAMPLE = '2025-01-01T00:00:00.000Z'
|
|
10
10
|
const issueDateSchema = Joi.string()
|
|
11
11
|
.isoDate()
|
|
12
12
|
.required()
|
|
13
13
|
.allow(null)
|
|
14
14
|
.description('An ISO8601 compatible date string defining when the permission was issued')
|
|
15
|
-
.example(
|
|
15
|
+
.example(DATE_EXAMPLE)
|
|
16
16
|
const startDateSchema = Joi.string()
|
|
17
17
|
.isoDate()
|
|
18
18
|
.required()
|
|
19
19
|
.allow(null)
|
|
20
20
|
.description('An ISO8601 compatible date string defining when the permission commences')
|
|
21
|
-
.example(
|
|
21
|
+
.example(DATE_EXAMPLE)
|
|
22
22
|
const endDateSchema = Joi.string()
|
|
23
23
|
.isoDate()
|
|
24
24
|
.required()
|
|
25
25
|
.description('An ISO8601 compatible date string defining when the permission expires')
|
|
26
|
-
.example(
|
|
26
|
+
.example(DATE_EXAMPLE)
|
|
27
27
|
|
|
28
28
|
export const stagedPermissionSchema = Joi.object({
|
|
29
29
|
permitId: Joi.string()
|
|
@@ -41,12 +41,12 @@ export const stagedPermissionSchema = Joi.object({
|
|
|
41
41
|
}).label('staged-permission')
|
|
42
42
|
|
|
43
43
|
export const finalisedPermissionSchemaContent = {
|
|
44
|
-
id: Joi.string().guid().required().example(
|
|
44
|
+
id: Joi.string().guid().required().example('a17fc331-141b-4fc0-8549-329d6934fadb'),
|
|
45
45
|
referenceNumber: validation.permission.createPermissionNumberValidator(Joi),
|
|
46
46
|
issueDate: issueDateSchema,
|
|
47
47
|
startDate: startDateSchema,
|
|
48
48
|
endDate: endDateSchema,
|
|
49
|
-
stagingId: Joi.string().guid().required().example(
|
|
49
|
+
stagingId: Joi.string().guid().required().example('a17fc331-141b-4fc0-8549-329d6934fadb'),
|
|
50
50
|
dataSource: optionSetOption
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Joi from 'joi'
|
|
2
|
+
import { commonContactSchema } from './contact.schema.js'
|
|
3
|
+
import { finalisedPermissionSchemaContent } from './permission.schema.js'
|
|
4
|
+
|
|
5
|
+
export const dueRecurringPaymentsResponseSchema = Joi.object({
|
|
6
|
+
id: Joi.string().guid().required(),
|
|
7
|
+
name: Joi.string().required(),
|
|
8
|
+
status: Joi.number().required(),
|
|
9
|
+
nextDueDate: Joi.string().isoDate().required(),
|
|
10
|
+
cancelledDate: Joi.string().isoDate().allow(null).required(),
|
|
11
|
+
cancelledReason: Joi.string().allow(null).required(),
|
|
12
|
+
endDate: Joi.string().isoDate().required(),
|
|
13
|
+
agreementId: Joi.string().guid().required(),
|
|
14
|
+
activePermission: Joi.string().guid().required(),
|
|
15
|
+
contactId: Joi.string().guid().required(),
|
|
16
|
+
publicId: Joi.string().required(),
|
|
17
|
+
expanded: Joi.object({
|
|
18
|
+
contact: { entity: commonContactSchema },
|
|
19
|
+
activePermission: { entity: finalisedPermissionSchemaContent }
|
|
20
|
+
})
|
|
21
|
+
})
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import dueRecurringPayments from '../recurring-payments.js'
|
|
2
2
|
import { getRecurringPayments } from '../../../services/recurring-payments.service.js'
|
|
3
3
|
|
|
4
|
+
const [
|
|
5
|
+
{
|
|
6
|
+
options: { handler: drpHandler }
|
|
7
|
+
}
|
|
8
|
+
] = dueRecurringPayments
|
|
9
|
+
|
|
4
10
|
jest.mock('../../../services/recurring-payments.service.js', () => ({
|
|
5
11
|
getRecurringPayments: jest.fn()
|
|
6
12
|
}))
|
|
@@ -19,13 +25,13 @@ describe('recurring payments', () => {
|
|
|
19
25
|
it('handler should return continue response', async () => {
|
|
20
26
|
const request = getMockRequest({})
|
|
21
27
|
const responseToolkit = getMockResponseToolkit()
|
|
22
|
-
expect(await
|
|
28
|
+
expect(await drpHandler(request, responseToolkit)).toEqual(responseToolkit.continue)
|
|
23
29
|
})
|
|
24
30
|
|
|
25
31
|
it('should call getRecurringPayments with date', async () => {
|
|
26
32
|
const date = Symbol('date')
|
|
27
33
|
const request = getMockRequest({ date })
|
|
28
|
-
await
|
|
34
|
+
await drpHandler(request, getMockResponseToolkit())
|
|
29
35
|
expect(getRecurringPayments).toHaveBeenCalledWith(date)
|
|
30
36
|
})
|
|
31
37
|
})
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
+
import { dueRecurringPaymentsResponseSchema } from '../../schema/recurring-payments.schema.js'
|
|
1
2
|
import { getRecurringPayments } from '../../services/recurring-payments.service.js'
|
|
2
3
|
export default [
|
|
3
4
|
{
|
|
4
5
|
method: 'GET',
|
|
5
6
|
path: '/dueRecurringPayments/{date}',
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
options: {
|
|
8
|
+
handler: async (request, h) => {
|
|
9
|
+
const { date } = request.params
|
|
10
|
+
const result = await getRecurringPayments(date)
|
|
11
|
+
return h.response(result)
|
|
12
|
+
},
|
|
13
|
+
description: 'Retrieve recurring payments due for the specified date',
|
|
14
|
+
tags: ['api', 'recurring-payments'],
|
|
15
|
+
plugins: {
|
|
16
|
+
'hapi-swagger': {
|
|
17
|
+
responses: {
|
|
18
|
+
200: { description: 'Recurring payments due', schema: dueRecurringPaymentsResponseSchema }
|
|
19
|
+
},
|
|
20
|
+
order: 1
|
|
21
|
+
}
|
|
22
|
+
}
|
|
10
23
|
}
|
|
11
24
|
}
|
|
12
25
|
]
|