account-lookup-service 17.8.1 → 17.9.0-snapshot.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "account-lookup-service",
3
3
  "description": "Account Lookup Service is used to validate Party and Participant lookups.",
4
- "version": "17.8.1",
4
+ "version": "17.9.0-snapshot.1",
5
5
  "license": "Apache-2.0",
6
6
  "author": "ModusBox",
7
7
  "contributors": [
package/src/lib/util.js CHANGED
@@ -97,8 +97,8 @@ const rethrowDatabaseError = (error) => {
97
97
  }
98
98
 
99
99
  const countFspiopError = (error, options) => {
100
- options.loggerOverride = logger
101
- rethrow.countFspiopError(error, options)
100
+ options.loggerOverride = options?.log || logger
101
+ return rethrow.countFspiopError(error, options)
102
102
  }
103
103
 
104
104
  /**
@@ -29,18 +29,25 @@
29
29
  const Mustache = require('mustache')
30
30
  const request = require('@mojaloop/central-services-shared').Util.Request
31
31
  const Enums = require('@mojaloop/central-services-shared').Enum
32
- const Logger = require('@mojaloop/central-services-logger')
33
32
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
34
33
  const Metrics = require('@mojaloop/central-services-metrics')
35
34
 
36
35
  const Config = require('../../lib/config')
37
- const oracleEndpointCached = require('../oracle/oracleEndpointCached')
36
+ const { logger } = require('../../lib')
37
+ const { countFspiopError } = require('../../lib/util')
38
38
  const { hubNameRegex } = require('../../lib/util').hubNameConfig
39
+ const oracleEndpointCached = require('../oracle/oracleEndpointCached')
40
+
41
+ const { Headers, RestMethods, ReturnCodes } = Enums.Http
42
+
43
+ const sendHttpRequest = ({ method, ...restArgs }) => request.sendRequest({
44
+ ...restArgs,
45
+ method: method.toUpperCase(),
46
+ hubNameRegex
47
+ })
39
48
 
40
49
  /**
41
- * @function oracleRequest
42
- *
43
- * @description This sends a request to the oracles that are registered to the ALS
50
+ * Sends a request to the oracles that are registered to the ALS
44
51
  *
45
52
  * @param {object} headers - incoming http request headers
46
53
  * @param {string} method - incoming http request method
@@ -49,130 +56,131 @@ const { hubNameRegex } = require('../../lib/util').hubNameConfig
49
56
  * @param {object} payload - payload of the request being sent out
50
57
  * @param {object} assertPendingAcquire - flag to check DB pool pending acquire limit
51
58
  *
52
- * @returns {object} returns the response from the oracle
59
+ * @returns {object} - response from the oracle
53
60
  */
54
- exports.oracleRequest = async (headers, method, params = {}, query = {}, payload = undefined, cache, assertPendingAcquire) => {
61
+ const oracleRequest = async (headers, method, params = {}, query = {}, payload = undefined, cache, assertPendingAcquire) => {
62
+ const operation = oracleRequest.name
63
+ const log = logger.child({ component: operation, params })
64
+ let step = 'start'
65
+
55
66
  try {
56
- let url
57
- const partyIdType = params.Type
58
- const partyIdentifier = params.ID
59
- const currency = (payload && payload.currency) ? payload.currency : (query && query.currency) ? query.currency : undefined
60
- const partySubIdOrType = (params && params.SubId) ? params.SubId : (query && query.partySubIdOrType) ? query.partySubIdOrType : undefined
61
- const isGetRequest = method.toUpperCase() === Enums.Http.RestMethods.GET
62
- const isDeleteRequest = method.toUpperCase() === Enums.Http.RestMethods.DELETE
63
-
64
- if (currency && partySubIdOrType && isGetRequest) {
65
- url = await _getOracleEndpointByTypeCurrencyAndSubId(partyIdType, partyIdentifier, currency, partySubIdOrType, assertPendingAcquire)
66
- } else if (currency && isGetRequest) {
67
- url = await _getOracleEndpointByTypeAndCurrency(partyIdType, partyIdentifier, currency, assertPendingAcquire)
68
- } else if (partySubIdOrType && isGetRequest) {
69
- url = await _getOracleEndpointByTypeAndSubId(partyIdType, partyIdentifier, partySubIdOrType, assertPendingAcquire)
70
- } else {
71
- url = await _getOracleEndpointByType(partyIdType, partyIdentifier, assertPendingAcquire)
72
- if (partySubIdOrType) {
73
- payload = { ...payload, partySubIdOrType }
74
- }
67
+ const source = headers[Headers.FSPIOP.SOURCE]
68
+ const destination = headers[Headers.FSPIOP.DESTINATION] || Config.HUB_NAME
69
+ const partySubIdOrType = params?.SubId || query?.partySubIdOrType
70
+ log.info('oracleRequest start...', { method, source, destination })
71
+
72
+ step = 'determineOracleEndpoint'
73
+ const url = await determineOracleEndpoint({
74
+ method, params, query, payload, assertPendingAcquire
75
+ })
76
+
77
+ if (method.toUpperCase() === RestMethods.GET) {
78
+ step = 'sendOracleGetRequest'
79
+ return await sendOracleGetRequest({
80
+ url, source, destination, headers, method, params, cache
81
+ })
75
82
  }
76
- Logger.isDebugEnabled && Logger.debug(`Oracle endpoints: ${url}`)
77
- const histTimerEnd = Metrics.getHistogram(
78
- 'egress_oracleRequest',
79
- 'Egress: oracleRequest',
80
- ['success', 'hit']
81
- ).startTimer()
82
- try {
83
- if (isGetRequest) {
84
- let cachedOracleFspResponse
85
- cachedOracleFspResponse = cache && cache.get(cache.createKey(`oracleSendRequest_${url}`))
86
- if (!cachedOracleFspResponse) {
87
- cachedOracleFspResponse = await request.sendRequest({
88
- url,
89
- headers,
90
- source: headers[Enums.Http.Headers.FSPIOP.SOURCE],
91
- destination: headers[Enums.Http.Headers.FSPIOP.DESTINATION] || Config.HUB_NAME,
92
- method: method.toUpperCase(),
93
- payload,
94
- hubNameRegex
95
- })
96
- // Trying to cache the whole response object will fail because it contains circular references
97
- // so we'll just cache the data property of the response.
98
- cachedOracleFspResponse = {
99
- data: cachedOracleFspResponse.data
100
- }
101
- cache && cache.set(
102
- cache.createKey(`oracleSendRequest_${url}`),
103
- cachedOracleFspResponse
104
- )
105
- histTimerEnd({ success: true, hit: false })
106
- } else {
107
- cachedOracleFspResponse = cachedOracleFspResponse.item
108
- histTimerEnd({ success: true, hit: true })
109
- Logger.isDebugEnabled && Logger.debug(`${new Date().toISOString()}, [oracleRequest]: cache hit for fsp for partyId lookup`)
110
- }
111
83
 
112
- return cachedOracleFspResponse
113
- }
84
+ if (partySubIdOrType && payload) payload.partySubIdOrType = partySubIdOrType
114
85
 
115
- if (isDeleteRequest && Config.DELETE_PARTICIPANT_VALIDATION_ENABLED) {
116
- // If the request is a DELETE request, we need to ensure that the participant belongs to the requesting FSP
117
- const getOracleResponse = await request.sendRequest({
118
- url,
119
- headers,
120
- source: headers[Enums.Http.Headers.FSPIOP.SOURCE],
121
- destination: headers[Enums.Http.Headers.FSPIOP.DESTINATION] || Config.HUB_NAME,
122
- method: Enums.Http.RestMethods.GET,
123
- payload,
124
- hubNameRegex
125
- })
126
-
127
- if (getOracleResponse.status === Enums.Http.ReturnCodes.OK.CODE) {
128
- const participant = getOracleResponse.data
129
- if (participant?.partyList?.length > 0) {
130
- const party = participant.partyList[0]
131
- if (party.fspId === headers[Enums.Http.Headers.FSPIOP.SOURCE]) {
132
- return await request.sendRequest({
133
- url,
134
- headers,
135
- source: headers[Enums.Http.Headers.FSPIOP.SOURCE],
136
- destination: headers[Enums.Http.Headers.FSPIOP.DESTINATION] || Config.HUB_NAME,
137
- method: method.toUpperCase(),
138
- payload,
139
- hubNameRegex
140
- })
141
- } else {
142
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DELETE_PARTY_INFO_ERROR, `The party ${partyIdType}:${partyIdentifier} does not belong to the requesting FSP`)
143
- }
144
- }
145
- }
86
+ if (method.toUpperCase() === RestMethods.DELETE && Config.DELETE_PARTICIPANT_VALIDATION_ENABLED) {
87
+ step = 'validatePartyDeletion'
88
+ await validatePartyDeletion({ url, source, destination, headers, params })
89
+ }
146
90
 
147
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND)
148
- }
91
+ step = 'sendHttpRequest'
92
+ return await sendHttpRequest({
93
+ url,
94
+ headers,
95
+ source,
96
+ destination,
97
+ method,
98
+ payload
99
+ })
100
+ } catch (err) {
101
+ log.error('error in oracleRequest: ', err)
102
+ throw countFspiopError(err, { operation, step, log })
103
+ }
104
+ }
105
+
106
+ const determineOracleEndpoint = async ({
107
+ method, params, query, payload, assertPendingAcquire
108
+ }) => {
109
+ const partyIdType = params.Type
110
+ const partyIdentifier = params.ID
111
+ const partySubIdOrType = params?.SubId || query?.partySubIdOrType
112
+ const currency = payload?.currency || query?.currency
113
+ const isGetRequest = method.toUpperCase() === RestMethods.GET
114
+ let url
149
115
 
150
- return await request.sendRequest({
116
+ if (currency && partySubIdOrType && isGetRequest) {
117
+ url = await _getOracleEndpointByTypeCurrencyAndSubId(partyIdType, partyIdentifier, currency, partySubIdOrType, assertPendingAcquire)
118
+ } else if (currency && isGetRequest) {
119
+ url = await _getOracleEndpointByTypeAndCurrency(partyIdType, partyIdentifier, currency, assertPendingAcquire)
120
+ } else if (partySubIdOrType && isGetRequest) {
121
+ url = await _getOracleEndpointByTypeAndSubId(partyIdType, partyIdentifier, partySubIdOrType, assertPendingAcquire)
122
+ } else {
123
+ url = await _getOracleEndpointByType(partyIdType, partyIdentifier, assertPendingAcquire)
124
+ }
125
+
126
+ logger.verbose(`Oracle endpoint: ${url}`, { currency, params, partySubIdOrType, url })
127
+ return url
128
+ }
129
+
130
+ const sendOracleGetRequest = async ({
131
+ url, source, destination, headers, method, params, cache
132
+ }) => {
133
+ const histTimerEnd = Metrics.getHistogram(
134
+ 'egress_oracleRequest',
135
+ 'Egress: oracleRequest',
136
+ ['success', 'hit']
137
+ ).startTimer()
138
+ const log = logger.child({ component: 'sendOracleGetRequest', params })
139
+
140
+ try {
141
+ let cachedOracleFspResponse
142
+ cachedOracleFspResponse = cache && cache.get(cache.createKey(`oracleSendRequest_${url}`))
143
+
144
+ if (!cachedOracleFspResponse) {
145
+ cachedOracleFspResponse = await sendHttpRequest({
151
146
  url,
152
147
  headers,
153
- source: headers[Enums.Http.Headers.FSPIOP.SOURCE],
154
- destination: headers[Enums.Http.Headers.FSPIOP.DESTINATION] || Config.HUB_NAME,
155
- method: method.toUpperCase(),
156
- payload,
157
- hubNameRegex
148
+ source,
149
+ destination,
150
+ method
158
151
  })
159
- } catch (err) {
160
- histTimerEnd({ success: false, hit: false })
161
- throw err
152
+ // Trying to cache the whole response object will fail because it contains circular references
153
+ // so we'll just cache the data property of the response.
154
+ cachedOracleFspResponse = {
155
+ data: cachedOracleFspResponse.data
156
+ }
157
+ cache && cache.set(
158
+ cache.createKey(`oracleSendRequest_${url}`),
159
+ cachedOracleFspResponse
160
+ )
161
+ histTimerEnd({ success: true, hit: false })
162
+ } else {
163
+ cachedOracleFspResponse = cachedOracleFspResponse.item
164
+ histTimerEnd({ success: true, hit: true })
165
+ logger.debug('[oracleRequest]: cache hit for fsp for partyId lookup')
162
166
  }
167
+
168
+ return cachedOracleFspResponse
163
169
  } catch (err) {
164
- const extensions = [{
165
- key: 'system',
166
- value: '["@hapi/catbox-memory","http"]'
167
- }]
168
- Logger.isErrorEnabled && Logger.error(`error in oracleRequest: ${err?.stack}`)
170
+ log.warn('error in sendOracleGetRequest: ', err)
171
+ histTimerEnd({ success: false, hit: false })
172
+
169
173
  // If the error was a 400 from the Oracle, we'll modify the error to generate a response to the
170
174
  // initiator of the request.
171
175
  if (
172
176
  err.name === 'FSPIOPError' &&
173
177
  err.apiErrorCode.code === ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_COMMUNICATION_ERROR.code
174
178
  ) {
175
- if (err.extensions.some(ext => (ext.key === 'status' && ext.value === Enums.Http.ReturnCodes.BADREQUEST.CODE))) {
179
+ const extensions = [{
180
+ key: 'system',
181
+ value: '["@hapi/catbox-memory","http"]'
182
+ }]
183
+ if (err.extensions.some(ext => (ext.key === 'status' && ext.value === ReturnCodes.BADREQUEST.CODE))) {
176
184
  throw ErrorHandler.Factory.createFSPIOPError(
177
185
  ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND,
178
186
  undefined,
@@ -180,10 +188,11 @@ exports.oracleRequest = async (headers, method, params = {}, query = {}, payload
180
188
  undefined,
181
189
  extensions
182
190
  )
183
- // Added error 404 to cover a special case of the Mowali implementation
184
- // which uses mojaloop/als-oracle-pathfinder and currently returns 404
185
- // and in which case the Mowali implementation expects back `DESTINATION_FSP_ERROR`.
186
- } else if (err.extensions.some(ext => (ext.key === 'status' && ext.value === Enums.Http.ReturnCodes.NOTFOUND.CODE))) {
191
+ }
192
+ // Added error 404 to cover a special case of the Mowali implementation
193
+ // which uses mojaloop/als-oracle-pathfinder and currently returns 404
194
+ // and in which case the Mowali implementation expects back `DESTINATION_FSP_ERROR`.
195
+ if (err.extensions.some(ext => (ext.key === 'status' && ext.value === ReturnCodes.NOTFOUND.CODE))) {
187
196
  throw ErrorHandler.Factory.createFSPIOPError(
188
197
  ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR,
189
198
  undefined,
@@ -193,13 +202,43 @@ exports.oracleRequest = async (headers, method, params = {}, query = {}, payload
193
202
  )
194
203
  }
195
204
  }
196
- throw ErrorHandler.Factory.reformatFSPIOPError(
197
- err,
198
- undefined,
199
- undefined,
200
- extensions
201
- )
205
+
206
+ throw err
207
+ }
208
+ }
209
+
210
+ const validatePartyDeletion = async ({ url, source, destination, headers, params }) => {
211
+ const log = logger.child({ component: 'validatePartyDeletion', params })
212
+ // If the request is a DELETE request, we need to ensure that the participant belongs to the requesting FSP
213
+ const getParticipantResponse = await sendHttpRequest({
214
+ url,
215
+ headers,
216
+ source,
217
+ destination,
218
+ method: RestMethods.GET
219
+ })
220
+
221
+ if (getParticipantResponse.status !== ReturnCodes.OK.CODE) {
222
+ const errMessage = `Invalid getOracleResponse status code: ${getParticipantResponse.status}`
223
+ log.warn(errMessage)
224
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND, errMessage)
225
+ // todo: clarify if we need to throw PARTY_NOT_FOUND
226
+ }
227
+
228
+ const participant = getParticipantResponse.data
229
+ if (!Array.isArray(participant?.partyList) || participant.partyList.length === 0) {
230
+ const errMessage = 'No participant found for the party'
231
+ log.warn(errMessage)
232
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DELETE_PARTY_INFO_ERROR, errMessage)
233
+ }
234
+
235
+ const party = participant.partyList[0] // todo: clarify why we check only the first party?
236
+ if (party.fspId !== source) {
237
+ const errMessage = `The party ${params.Type}:${params.ID} does not belong to the requesting FSP`
238
+ log.warn(errMessage)
239
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DELETE_PARTY_INFO_ERROR, errMessage)
202
240
  }
241
+ return true
203
242
  }
204
243
 
205
244
  /**
@@ -233,8 +272,10 @@ const _getOracleEndpointByTypeAndCurrency = async (partyIdType, partyIdentifier,
233
272
  )
234
273
  }
235
274
  } else {
236
- Logger.isErrorEnabled && Logger.error(`Oracle type:${partyIdType} and currency:${currency} not found`)
237
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, `Oracle type:${partyIdType} and currency:${currency} not found`).toApiErrorObject(Config.ERROR_HANDLING)
275
+ const errMessage = `Oracle type:${partyIdType} and currency:${currency} not found`
276
+ logger.warn(errMessage)
277
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, errMessage)
278
+ .toApiErrorObject(Config.ERROR_HANDLING)
238
279
  }
239
280
  return url
240
281
  }
@@ -269,8 +310,9 @@ const _getOracleEndpointByType = async (partyIdType, partyIdentifier, assertPend
269
310
  )
270
311
  }
271
312
  } else {
272
- Logger.isErrorEnabled && Logger.error(`Oracle type:${partyIdType} not found`)
273
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, `Oracle type: ${partyIdType} not found`)
313
+ const errMessage = `Oracle type:${partyIdType} not found`
314
+ logger.warn(errMessage)
315
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, errMessage)
274
316
  }
275
317
  return url
276
318
  }
@@ -306,8 +348,10 @@ const _getOracleEndpointByTypeAndSubId = async (partyIdType, partyIdentifier, pa
306
348
  )
307
349
  }
308
350
  } else {
309
- Logger.isErrorEnabled && Logger.error(`Oracle type: ${partyIdType} and subId: ${partySubIdOrType} not found`)
310
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, `Oracle type: ${partyIdType} and subId: ${partySubIdOrType} not found`).toApiErrorObject(Config.ERROR_HANDLING)
351
+ const errMessage = `Oracle type: ${partyIdType} and subId: ${partySubIdOrType} not found`
352
+ logger.warn(errMessage)
353
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, errMessage)
354
+ .toApiErrorObject(Config.ERROR_HANDLING)
311
355
  }
312
356
  return url
313
357
  }
@@ -344,16 +388,16 @@ const _getOracleEndpointByTypeCurrencyAndSubId = async (partyIdType, partyIdenti
344
388
  )
345
389
  }
346
390
  } else {
347
- Logger.isErrorEnabled && Logger.error(`Oracle type: ${partyIdType}, currency: ${currency}, and subId: ${partySubIdOrType} not found`)
348
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, `Oracle type:${partyIdType}, currency:${currency} and subId: ${partySubIdOrType} not found`).toApiErrorObject(Config.ERROR_HANDLING)
391
+ const errMessage = `Oracle type: ${partyIdType}, currency: ${currency} and subId: ${partySubIdOrType} not found`
392
+ logger.warn(errMessage)
393
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, errMessage)
394
+ .toApiErrorObject(Config.ERROR_HANDLING)
349
395
  }
350
396
  return url
351
397
  }
352
398
 
353
399
  /**
354
- * @function oracleBatchRequest
355
- *
356
- * @description This sends a request to the oracles that are registered to the ALS
400
+ * Sends a request to the oracles that are registered to the ALS
357
401
  *
358
402
  * @param {object} headers - incoming http request headers
359
403
  * @param {object} method - incoming http request method
@@ -361,9 +405,9 @@ const _getOracleEndpointByTypeCurrencyAndSubId = async (partyIdType, partyIdenti
361
405
  * @param {string} type - oracle type
362
406
  * @param {object} payload - the payload to send in the request
363
407
  *
364
- * @returns {object} returns the response from the oracle
408
+ * @returns {object} - response from the oracle
365
409
  */
366
- exports.oracleBatchRequest = async (headers, method, requestPayload, type, payload) => {
410
+ const oracleBatchRequest = async (headers, method, requestPayload, type, payload) => {
367
411
  try {
368
412
  let oracleEndpointModel
369
413
  let url
@@ -383,22 +427,26 @@ exports.oracleBatchRequest = async (headers, method, requestPayload, type, paylo
383
427
  } else {
384
428
  url = oracleEndpointModel[0].value + Enums.EndPoints.FspEndpointTemplates.ORACLE_PARTICIPANTS_BATCH
385
429
  }
386
- Logger.isDebugEnabled && Logger.debug(`Oracle endpoints: ${url}`)
387
- return await request.sendRequest({
430
+ logger.debug(`Oracle endpoints: ${url}`)
431
+ return await sendHttpRequest({
388
432
  url,
389
433
  headers,
390
- source: headers[Enums.Http.Headers.FSPIOP.SOURCE],
391
- destination: headers[Enums.Http.Headers.FSPIOP.DESTINATION] || Config.HUB_NAME,
434
+ source: headers[Headers.FSPIOP.SOURCE],
435
+ destination: headers[Headers.FSPIOP.DESTINATION] || Config.HUB_NAME,
392
436
  method,
393
- payload,
394
- hubNameRegex
437
+ payload
395
438
  })
396
439
  } else {
397
- Logger.isErrorEnabled && Logger.error(`Oracle type:${type} not found`)
440
+ logger.error(`Oracle type:${type} not found`)
398
441
  throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, `Oracle type:${type} not found`)
399
442
  }
400
443
  } catch (err) {
401
- Logger.isErrorEnabled && Logger.error(err)
444
+ logger.error('error in oracleBatchRequest: ', err)
402
445
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
403
446
  }
404
447
  }
448
+
449
+ module.exports = {
450
+ oracleRequest,
451
+ oracleBatchRequest
452
+ }
@@ -30,14 +30,15 @@
30
30
  const Sinon = require('sinon')
31
31
  const Enums = require('@mojaloop/central-services-shared').Enum
32
32
  const request = require('@mojaloop/central-services-shared').Util.Request
33
+ const errorHandling = require('@mojaloop/central-services-error-handling')
33
34
 
34
- const OracleFacade = require('../../../../src/models/oracle/facade')
35
- const oracleEndpointCached = require('../../../../src/models/oracle/oracleEndpointCached')
36
- const Logger = require('@mojaloop/central-services-logger')
35
+ const OracleFacade = require('#src/models/oracle/facade')
36
+ const oracleEndpointCached = require('#src/models/oracle/oracleEndpointCached')
37
+ const fixtures = require('#test/fixtures/index')
38
+
39
+ const { createFSPIOPError } = errorHandling.Factory
40
+ const { FSPIOPErrorCodes } = errorHandling.Enums
37
41
 
38
- Logger.isDebugEnabled = jest.fn(() => true)
39
- Logger.isErrorEnabled = jest.fn(() => true)
40
- Logger.isInfoEnabled = jest.fn(() => true)
41
42
  let sandbox
42
43
 
43
44
  describe('Oracle Facade', () => {
@@ -443,6 +444,21 @@ describe('Oracle Facade', () => {
443
444
  // Assert
444
445
  await expect(action()).rejects.toThrowError(/(Oracle type:.*not found)/)
445
446
  })
447
+
448
+ it('should return proper error on adding existing party [CSI-1352]', async () => {
449
+ expect.hasAssertions()
450
+ const ERROR = FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR
451
+ request.sendRequest = sandbox.stub().rejects(createFSPIOPError(ERROR))
452
+ sandbox.stub(oracleEndpointCached, 'getOracleEndpointByType').resolves([{}])
453
+ const method = Enums.Http.RestMethods.POST
454
+ const headers = fixtures.partiesCallHeadersDto()
455
+ const params = fixtures.partiesParamsDto()
456
+
457
+ await OracleFacade.oracleRequest(headers, method, params)
458
+ .catch(err => {
459
+ expect(err.apiErrorCode.code).toBe(ERROR.code)
460
+ })
461
+ })
446
462
  })
447
463
 
448
464
  describe('oracleBatchRequest', () => {