@defra-fish/sales-api-service 1.58.0 → 1.59.0-rc.0

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.58.0",
3
+ "version": "1.59.0-rc.0",
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.58.0",
39
- "@defra-fish/connectors-lib": "1.58.0",
40
- "@defra-fish/dynamics-lib": "1.58.0",
38
+ "@defra-fish/business-rules-lib": "1.59.0-rc.0",
39
+ "@defra-fish/connectors-lib": "1.59.0-rc.0",
40
+ "@defra-fish/dynamics-lib": "1.59.0-rc.0",
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": "4d2c2ef1bf3016fa38140a1bd78bf26ba5adb68d"
55
+ "gitHead": "01bc1d91c4f25234b008dafe06b0525760f9c752"
56
56
  }
@@ -5,11 +5,10 @@ import { permitSchema } from './permit.schema.js'
5
5
  import { contactResponseSchema } from './contact.schema.js'
6
6
  import { finalisedPermissionSchemaContent } from './permission.schema.js'
7
7
 
8
+ const REFERENCE_LENGTH = 6
9
+
8
10
  export const authenticateRenewalRequestParamsSchema = Joi.object({
9
- referenceNumber: Joi.string()
10
- .min(6)
11
- .required()
12
- .description('The permission reference number (supports partial)')
11
+ referenceNumber: Joi.string().min(REFERENCE_LENGTH).required().description('The permission reference number (supports partial)')
13
12
  }).label('authenticate-renewal-request-params')
14
13
 
15
14
  export const authenticateRenewalRequestQuerySchema = Joi.object({
@@ -1,4 +1,4 @@
1
- import { permissionForLicensee, executeQuery } from '@defra-fish/dynamics-lib'
1
+ import { contactForLicenseeNoReference, executeQuery } from '@defra-fish/dynamics-lib'
2
2
  import db from 'debug'
3
3
  jest.mock('@defra-fish/dynamics-lib')
4
4
  jest.mock('debug')
@@ -10,7 +10,7 @@ describe('executeWithErrorLog', () => {
10
10
  executeQuery.mockImplementation(() => {
11
11
  throw new Error()
12
12
  })
13
- permissionForLicensee.mockReturnValueOnce({ filter: 'query filter test' })
13
+ contactForLicenseeNoReference.mockReturnValueOnce({ filter: 'query filter test' })
14
14
  const authenticate = require('../authenticate.js').default
15
15
  const [
16
16
  {
@@ -1,5 +1,5 @@
1
1
  import initialiseServer from '../../server.js'
2
- import { executeQuery, permissionForLicensee } from '@defra-fish/dynamics-lib'
2
+ import { contactForLicenseeNoReference, executeQuery, permissionForContacts } from '@defra-fish/dynamics-lib'
3
3
  import {
4
4
  MOCK_EXISTING_PERMISSION_ENTITY,
5
5
  MOCK_EXISTING_CONTACT_ENTITY,
@@ -10,8 +10,9 @@ import {
10
10
 
11
11
  jest.mock('@defra-fish/dynamics-lib', () => ({
12
12
  ...jest.requireActual('@defra-fish/dynamics-lib'),
13
- permissionForLicensee: jest.fn(),
14
- executeQuery: jest.fn()
13
+ contactForLicenseeNoReference: jest.fn(),
14
+ executeQuery: jest.fn(),
15
+ permissionForContacts: jest.fn()
15
16
  }))
16
17
 
17
18
  let server = null
@@ -27,6 +28,12 @@ describe('authenticate handler', () => {
27
28
 
28
29
  describe('authenticateRenewal', () => {
29
30
  it('authenticates a renewal request', async () => {
31
+ executeQuery.mockResolvedValueOnce([
32
+ {
33
+ entity: MOCK_EXISTING_CONTACT_ENTITY,
34
+ expanded: {}
35
+ }
36
+ ])
30
37
  executeQuery.mockResolvedValueOnce([
31
38
  {
32
39
  entity: MOCK_EXISTING_PERMISSION_ENTITY,
@@ -42,7 +49,6 @@ describe('authenticate handler', () => {
42
49
  method: 'GET',
43
50
  url: '/authenticate/renewal/CD379B?licenseeBirthDate=2000-01-01&licenseePostcode=AB12 3CD'
44
51
  })
45
- expect(permissionForLicensee).toHaveBeenCalledWith('CD379B', '2000-01-01', 'AB12 3CD')
46
52
  expect(result.statusCode).toBe(200)
47
53
  expect(JSON.parse(result.payload)).toMatchObject({
48
54
  permission: expect.objectContaining({
@@ -61,6 +67,12 @@ describe('authenticate handler', () => {
61
67
 
62
68
  describe('if no concessions are returned', () => {
63
69
  beforeEach(() => {
70
+ executeQuery.mockResolvedValueOnce([
71
+ {
72
+ entity: MOCK_EXISTING_CONTACT_ENTITY,
73
+ expanded: {}
74
+ }
75
+ ])
64
76
  executeQuery.mockResolvedValueOnce([
65
77
  {
66
78
  entity: MOCK_EXISTING_PERMISSION_ENTITY,
@@ -73,12 +85,20 @@ describe('authenticate handler', () => {
73
85
  ])
74
86
  })
75
87
 
76
- it('should call permissionForLicensee with the licence number, dob and postcode for a renewal request, ', async () => {
88
+ it('should call contactForLicenseeNoReference with dob and postcode for a renewal request', async () => {
89
+ await server.inject({
90
+ method: 'GET',
91
+ url: '/authenticate/renewal/CD379B?licenseeBirthDate=2000-01-01&licenseePostcode=AB12 3CD'
92
+ })
93
+ expect(contactForLicenseeNoReference).toHaveBeenCalledWith('2000-01-01', 'AB12 3CD')
94
+ })
95
+
96
+ it('should call permissionForContacts with contact ids from contactForLicenseeNoReference', async () => {
77
97
  await server.inject({
78
98
  method: 'GET',
79
99
  url: '/authenticate/renewal/CD379B?licenseeBirthDate=2000-01-01&licenseePostcode=AB12 3CD'
80
100
  })
81
- expect(permissionForLicensee).toHaveBeenCalledWith('CD379B', '2000-01-01', 'AB12 3CD')
101
+ expect(permissionForContacts).toHaveBeenCalledWith([MOCK_EXISTING_CONTACT_ENTITY.id])
82
102
  })
83
103
 
84
104
  it('returns 200 from a renewal request', async () => {
@@ -105,7 +125,13 @@ describe('authenticate handler', () => {
105
125
  })
106
126
 
107
127
  it('throws 500 errors if more than one result was found for the query', async () => {
108
- executeQuery.mockResolvedValueOnce([{}, {}])
128
+ executeQuery.mockResolvedValueOnce([
129
+ {
130
+ entity: MOCK_EXISTING_CONTACT_ENTITY,
131
+ expanded: {}
132
+ }
133
+ ])
134
+ executeQuery.mockResolvedValueOnce([{ entity: { referenceNumber: 'CD379B' } }, { entity: { referenceNumber: 'CD379B' } }])
109
135
  const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn())
110
136
  const result = await server.inject({
111
137
  method: 'GET',
@@ -121,6 +147,26 @@ describe('authenticate handler', () => {
121
147
  })
122
148
 
123
149
  it('throws 401 errors if the renewal could not be authenticated', async () => {
150
+ executeQuery.mockResolvedValueOnce([
151
+ {
152
+ entity: MOCK_EXISTING_CONTACT_ENTITY,
153
+ expanded: {}
154
+ }
155
+ ])
156
+ executeQuery.mockResolvedValueOnce([])
157
+ const result = await server.inject({
158
+ method: 'GET',
159
+ url: '/authenticate/renewal/CD379B?licenseeBirthDate=2000-01-01&licenseePostcode=AB12 3CD'
160
+ })
161
+ expect(result.statusCode).toBe(401)
162
+ expect(JSON.parse(result.payload)).toMatchObject({
163
+ error: 'Unauthorized',
164
+ message: 'The licensee could not be authenticated',
165
+ statusCode: 401
166
+ })
167
+ })
168
+
169
+ it('throws 401 errors if no contact to be authenticated', async () => {
124
170
  executeQuery.mockResolvedValueOnce([])
125
171
  const result = await server.inject({
126
172
  method: 'GET',
@@ -5,8 +5,9 @@ import {
5
5
  authenticateRenewalResponseSchema
6
6
  } from '../../schema/authenticate.schema.js'
7
7
  import db from 'debug'
8
- import { permissionForLicensee, concessionsByIds, executeQuery } from '@defra-fish/dynamics-lib'
8
+ import { permissionForContacts, concessionsByIds, executeQuery, contactForLicenseeNoReference } from '@defra-fish/dynamics-lib'
9
9
  const debug = db('sales:renewal-authentication')
10
+ const failAuthenticate = 'The licensee could not be authenticated'
10
11
 
11
12
  const executeWithErrorLog = async query => {
12
13
  try {
@@ -24,33 +25,37 @@ export default [
24
25
  options: {
25
26
  handler: async (request, h) => {
26
27
  const { licenseeBirthDate, licenseePostcode } = request.query
27
- const results = await executeWithErrorLog(
28
- permissionForLicensee(request.params.referenceNumber, licenseeBirthDate, licenseePostcode)
29
- )
30
-
31
- if (results.length === 1) {
32
- let concessionProofs = []
33
- if (results[0].expanded.concessionProofs.length > 0) {
34
- const ids = results[0].expanded.concessionProofs.map(f => f.entity.id)
35
- concessionProofs = await executeWithErrorLog(concessionsByIds(ids))
28
+ const contacts = await executeWithErrorLog(contactForLicenseeNoReference(licenseeBirthDate, licenseePostcode))
29
+ if (contacts.length > 0) {
30
+ const contactIds = contacts.map(contact => contact.entity.id)
31
+ const permissions = await executeWithErrorLog(permissionForContacts(contactIds))
32
+ const results = permissions.filter(p => p.entity.referenceNumber.endsWith(request.params.referenceNumber))
33
+ if (results.length === 1) {
34
+ let concessionProofs = []
35
+ if (results[0].expanded.concessionProofs.length > 0) {
36
+ const ids = results[0].expanded.concessionProofs.map(f => f.entity.id)
37
+ concessionProofs = await executeWithErrorLog(concessionsByIds(ids))
38
+ }
39
+ return h
40
+ .response({
41
+ permission: {
42
+ ...results[0].entity.toJSON(),
43
+ licensee: results[0].expanded.licensee.entity.toJSON(),
44
+ concessions: concessionProofs.map(c => ({
45
+ id: c.expanded.concession.entity.id,
46
+ proof: c.entity.toJSON()
47
+ })),
48
+ permit: results[0].expanded.permit.entity.toJSON()
49
+ }
50
+ })
51
+ .code(200)
52
+ } else if (results.length === 0) {
53
+ throw Boom.unauthorized(failAuthenticate)
54
+ } else {
55
+ throw new Error('Unable to authenticate, non-unique results for query')
36
56
  }
37
- return h
38
- .response({
39
- permission: {
40
- ...results[0].entity.toJSON(),
41
- licensee: results[0].expanded.licensee.entity.toJSON(),
42
- concessions: concessionProofs.map(c => ({
43
- id: c.expanded.concession.entity.id,
44
- proof: c.entity.toJSON()
45
- })),
46
- permit: results[0].expanded.permit.entity.toJSON()
47
- }
48
- })
49
- .code(200)
50
- } else if (results.length === 0) {
51
- throw Boom.unauthorized('The licensee could not be authenticated')
52
57
  } else {
53
- throw new Error('Unable to authenticate, non-unique results for query')
58
+ throw Boom.unauthorized(failAuthenticate)
54
59
  }
55
60
  },
56
61
  description: 'Authenticate a licensee by checking the licence number corresponds with the provided contact details',
@@ -66,7 +71,7 @@ export default [
66
71
  'hapi-swagger': {
67
72
  responses: {
68
73
  200: { description: 'The licensee was successfully authenticated', schema: authenticateRenewalResponseSchema },
69
- 401: { description: 'The licensee could not be authenticated' }
74
+ 401: { description: failAuthenticate }
70
75
  },
71
76
  order: 1
72
77
  }