account-lookup-service 17.7.0-snapshot.4 → 17.7.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.
@@ -32,82 +32,64 @@ const BasePartiesService = require('./BasePartiesService')
32
32
  const { RestMethods } = BasePartiesService.enums()
33
33
 
34
34
  class PutPartiesService extends BasePartiesService {
35
- async handleRequest () {
36
- const { destination, source, proxy } = this.state
37
- this.log.info('handleRequest start', { destination, source, proxy })
38
-
39
- await this.validateSourceParticipant()
40
- if (proxy) {
41
- await this.checkProxySuccessResponse()
42
- }
43
- await this.identifyDestinationForSuccessCallback()
44
- await this.sendSuccessCallback()
45
- }
46
-
47
- async validateSourceParticipant () {
48
- const { source, proxy, proxyEnabled } = this.state
49
- const log = this.log.child({ source, proxy, method: 'validateSourceParticipant' })
50
- this.stepInProgress('validateSourceParticipant-1')
51
-
52
- const schemeParticipant = await super.validateParticipant(source)
53
- if (!schemeParticipant) {
54
- if (!proxyEnabled || !proxy) {
55
- throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.sourceFspNotFound, log)
35
+ // async handleRequest () {
36
+ // // todo: add impl.
37
+ // }
38
+
39
+ async validateSourceParticipant ({ source, proxy }) {
40
+ this.deps.stepState.inProgress('validateSourceParticipant-1')
41
+ const requesterParticipant = await super.validateParticipant(source)
42
+
43
+ if (!requesterParticipant) {
44
+ if (!this.proxyEnabled || !proxy) {
45
+ const errMessage = ERROR_MESSAGES.sourceFspNotFound
46
+ this.log.warn(`${errMessage} and no proxy`, { source })
47
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, errMessage)
56
48
  }
57
-
58
49
  const isCached = await this.deps.proxyCache.addDfspIdToProxyMapping(source, proxy)
59
50
  if (!isCached) {
60
- throw super.createFspiopIdNotFoundError('failed to addDfspIdToProxyMapping', log)
51
+ const errMessage = 'failed to addDfspIdToProxyMapping'
52
+ this.log.warn(errMessage, { source, proxy })
53
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, errMessage)
61
54
  }
62
55
 
63
- log.info('addDfspIdToProxyMapping is done', { source, proxy })
56
+ this.log.info('addDfspIdToProxyMapping is done', { source, proxy })
64
57
  }
65
58
  }
66
59
 
67
- async checkProxySuccessResponse () {
68
- if (this.state.proxyEnabled) {
69
- this.stepInProgress('checkProxySuccessResponse')
70
- const { headers, params } = this.inputs
71
- const { destination, source } = this.state
60
+ async checkProxySuccessResponse ({ destination, source, headers, params }) {
61
+ if (this.proxyEnabled) {
62
+ this.deps.stepState.inProgress('checkProxySuccessResponse-2')
72
63
  const alsReq = this.deps.partiesUtils.alsRequestDto(destination, params)
73
64
 
74
65
  const isExists = await this.deps.proxyCache.receivedSuccessResponse(alsReq)
75
- if (!isExists) {
76
- this.log.verbose('NOT inter-scheme receivedSuccessResponse case')
77
- await this.removeProxyGetPartiesTimeoutCache(alsReq)
78
- return
79
- }
80
-
81
- const schemeParticipant = await super.validateParticipant(destination)
82
- if (schemeParticipant) {
66
+ if (isExists) {
83
67
  await this.#updateOracleWithParticipantMapping({ source, headers, params })
68
+ return
84
69
  }
70
+ this.log.warn('destination is NOT in scheme, and no cached sendToProxiesList', { destination, alsReq })
71
+ // todo: think, if we need to throw an error here
85
72
  }
86
73
  }
87
74
 
88
- async identifyDestinationForSuccessCallback () {
89
- const { destination } = this.state
90
- this.stepInProgress('identifyDestinationForSuccessCallback')
75
+ async identifyDestinationForSuccessCallback (destination) {
76
+ this.deps.stepState.inProgress('validateDestinationParticipant-4')
91
77
  const destinationParticipant = await super.validateParticipant(destination)
92
78
  if (destinationParticipant) {
93
- this.state.requester = destinationParticipant.name
94
- return
79
+ return destinationParticipant.name
95
80
  }
96
81
 
97
- const proxyName = this.state.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
82
+ const proxyName = this.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
98
83
  if (!proxyName) {
99
84
  const errMessage = ERROR_MESSAGES.partyDestinationFspNotFound
100
85
  this.log.warn(`${errMessage} and no proxy`, { destination })
101
86
  throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, errMessage)
102
87
  }
103
-
104
- this.state.requester = proxyName
88
+ return proxyName
105
89
  }
106
90
 
107
- async sendSuccessCallback () {
108
- const { headers, params, dataUri } = this.inputs
109
- const sendTo = this.state.requester
110
- this.stepInProgress('sendSuccessCallback')
91
+ async sendSuccessCallback ({ sendTo, headers, params, dataUri }) {
92
+ this.deps.stepState.inProgress('#sendSuccessCallback-6')
111
93
  const payload = PutPartiesService.decodeDataUriPayload(dataUri)
112
94
  const callbackEndpointType = this.deps.partiesUtils.putPartyCbType(params.SubId)
113
95
  const options = this.deps.partiesUtils.partiesRequestOptionsDto(params)
@@ -115,11 +97,11 @@ class PutPartiesService extends BasePartiesService {
115
97
  await this.deps.participant.sendRequest(
116
98
  headers, sendTo, callbackEndpointType, RestMethods.PUT, payload, options
117
99
  )
118
- this.log.verbose('sendSuccessCallback is sent', { sendTo, payload })
100
+ this.log.verbose('sendSuccessCallback is done', { sendTo, payload })
119
101
  }
120
102
 
121
103
  async #updateOracleWithParticipantMapping ({ source, headers, params }) {
122
- this.stepInProgress('#updateOracleWithParticipantMapping-3')
104
+ this.deps.stepState.inProgress('#updateOracleWithParticipantMapping-3')
123
105
  const mappingPayload = {
124
106
  fspId: source
125
107
  }
@@ -52,10 +52,6 @@ const timeoutInterschemePartiesLookups = async ({ proxyCache, batchSize }) => {
52
52
  return proxyCache.processExpiredAlsKeys(sendTimeoutCallback, batchSize)
53
53
  }
54
54
 
55
- const timeoutProxyGetPartiesLookups = async ({ proxyCache, batchSize }) => {
56
- return proxyCache.processExpiredProxyGetPartiesKeys(sendTimeoutCallback, batchSize)
57
- }
58
-
59
55
  const sendTimeoutCallback = async (cacheKey) => {
60
56
  const histTimerEnd = Metrics.getHistogram(
61
57
  'eg_timeoutInterschemePartiesLookups',
@@ -63,7 +59,7 @@ const sendTimeoutCallback = async (cacheKey) => {
63
59
  ['success']
64
60
  ).startTimer()
65
61
  let step
66
- const [destination, partyType, partyId] = parseCacheKey(cacheKey)
62
+ const [, destination, partyType, partyId] = cacheKey.split(':')
67
63
  const { errorInformation, params, headers, endpointType, span } = await timeoutCallbackDto({ destination, partyId, partyType })
68
64
  logger.debug('sendTimeoutCallback details:', { destination, partyType, partyId, cacheKey })
69
65
 
@@ -107,13 +103,7 @@ const finishSpan = async (span, err) => {
107
103
  }
108
104
  }
109
105
 
110
- const parseCacheKey = (cacheKey) => {
111
- const [destination, partyType, partyId] = cacheKey.split(':').slice(-3)
112
- return [destination, partyType, partyId]
113
- }
114
-
115
106
  module.exports = {
116
107
  timeoutInterschemePartiesLookups,
117
- timeoutProxyGetPartiesLookups,
118
108
  sendTimeoutCallback // Exposed for testing
119
109
  }
@@ -41,13 +41,13 @@ let isRunning
41
41
 
42
42
  const timeout = async (options) => {
43
43
  if (isRunning) return
44
+
44
45
  const { logger } = options
45
46
 
46
47
  try {
47
48
  isRunning = true
49
+ logger.debug('Timeout handler triggered')
48
50
  await TimeoutService.timeoutInterschemePartiesLookups(options)
49
- await TimeoutService.timeoutProxyGetPartiesLookups(options)
50
- logger.verbose('ALS timeout handler is done')
51
51
  } catch (err) {
52
52
  logger.error('error in timeout: ', err)
53
53
  } finally {
package/src/lib/util.js CHANGED
@@ -29,11 +29,10 @@ const util = require('node:util')
29
29
  const Path = require('node:path')
30
30
  const EventSdk = require('@mojaloop/event-sdk')
31
31
  const Enum = require('@mojaloop/central-services-shared').Enum
32
- const { HeaderValidation } = require('@mojaloop/central-services-shared').Util
32
+ const { HeaderValidation, Hapi } = require('@mojaloop/central-services-shared').Util
33
33
  const rethrow = require('@mojaloop/central-services-shared').Util.rethrow.with('ALS')
34
34
 
35
35
  const Config = require('../lib/config')
36
- const { API_TYPES } = require('../constants')
37
36
  const { logger } = require('./index')
38
37
 
39
38
  const getSpanTags = ({ headers }, transactionType, transactionAction) => {
@@ -70,7 +69,7 @@ const pathForInterface = ({ isAdmin, isMockInterface }) => {
70
69
  if (isMockInterface) {
71
70
  apiFile = 'api_swagger.json'
72
71
  } else {
73
- apiFile = Config.API_TYPE === API_TYPES.iso20022
72
+ apiFile = Config.API_TYPE === Hapi.API_TYPES.iso20022
74
73
  ? 'api-swagger-iso20022-parties.yaml'
75
74
  : 'api-swagger.yaml'
76
75
  }
@@ -101,14 +100,7 @@ const countFspiopError = (error, options) => {
101
100
  rethrow.countFspiopError(error, options)
102
101
  }
103
102
 
104
- /**
105
- * An immutable object representing the step state
106
- * @typedef {Object} StepState
107
- * @property {string} step - The current step value (read-only getter property)
108
- * @property {(string) => void} inProgress - Method to update the current step
109
- */
110
-
111
- /** @returns {StepState} */
103
+ // todo: think better name
112
104
  const initStepState = (initStep = 'start') => {
113
105
  let step = initStep
114
106
  return Object.freeze({
@@ -1,30 +1,3 @@
1
- /*****
2
- License
3
- --------------
4
- Copyright © 2020-2025 Mojaloop Foundation
5
- The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
-
7
- http://www.apache.org/licenses/LICENSE-2.0
8
-
9
- Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
-
11
- Contributors
12
- --------------
13
- This is the official list of the Mojaloop project contributors for this file.
14
- Names of the original copyright holders (individuals or organizations)
15
- should be listed with a '*' in the first column. People who have
16
- contributed from an organization can be listed under the organization
17
- that actually holds the copyright for their contributions (see the
18
- Mojaloop Foundation for an example). Those individuals should have
19
- their names indented and be marked with a '-'. Email address can be added
20
- optionally within square brackets <email>.
21
-
22
- * Mojaloop Foundation
23
- * Eugen Klymniuk <eugen.klymniuk@infitx.com>
24
-
25
- --------------
26
- ******/
27
-
28
1
  const { randomUUID } = require('node:crypto')
29
2
  const { Enum } = require('@mojaloop/central-services-shared')
30
3
  const isoFixtures = require('./iso')
@@ -47,16 +20,6 @@ const headersDto = ({
47
20
  'content-type': contentType || accept
48
21
  })
49
22
 
50
- const partiesParamsDto = ({
51
- Type = 'MSISDN',
52
- ID = String(Date.now()),
53
- SubId
54
- } = {}) => ({
55
- Type,
56
- ID,
57
- ...(SubId && { SubId })
58
- })
59
-
60
23
  const protocolVersionsDto = () => ({
61
24
  CONTENT: {
62
25
  DEFAULT: '2.1',
@@ -179,7 +142,6 @@ const mockHapiRequestDto = ({ // https://hapi.dev/api/?v=21.3.3#request-properti
179
142
  module.exports = {
180
143
  ...isoFixtures,
181
144
  partiesCallHeadersDto,
182
- partiesParamsDto,
183
145
  participantsCallHeadersDto,
184
146
  oracleRequestResponseDto,
185
147
  putPartiesSuccessResponseDto,
@@ -56,7 +56,7 @@ const fixtures = require('../../../fixtures')
56
56
  const { type: proxyCacheType, proxyConfig: proxyCacheConfig } = Config.PROXY_CACHE_CONFIG
57
57
 
58
58
  const { encodePayload } = Util.StreamingProtocol
59
- const { RestMethods, Headers } = Enum.Http
59
+ const { RestMethods } = Enum.Http
60
60
 
61
61
  Logger.isDebugEnabled = jest.fn(() => true)
62
62
  Logger.isErrorEnabled = jest.fn(() => true)
@@ -192,26 +192,24 @@ describe('Parties Tests', () => {
192
192
  expect(cached).toBe(proxy)
193
193
  })
194
194
 
195
- it('should cleanup oracle and trigger discovery flow, if destination is not in scheme and no dfsp-to-proxy mapping', async () => {
196
- Config.PROXY_CACHE_CONFIG.enabled = true
195
+ it('should send error callback if destination is not in the scheme, and not in proxyCache', async () => {
197
196
  participant.validateParticipant = sandbox.stub()
198
197
  .onFirstCall().resolves({}) // source
199
198
  .onSecondCall().resolves(null) // destination
200
199
  participant.sendRequest = sandbox.stub().resolves()
201
200
  participant.sendErrorToParticipant = sandbox.stub().resolves()
202
201
  sandbox.stub(oracle, 'oracleRequest')
203
- const proxy = 'some-proxy'
204
- Util.proxies.getAllProxiesNames = sandbox.stub().resolves([proxy])
205
202
  const headers = fixtures.partiesCallHeadersDto()
206
203
 
207
204
  await partiesDomain.getPartiesByTypeAndID(headers, Helper.getByTypeIdRequest.params, Helper.getByTypeIdRequest.method, Helper.getByTypeIdRequest.query, Helper.mockSpan(), null, proxyCache)
208
205
 
209
- expect(oracle.oracleRequest.lastCall.args[1]).toBe(RestMethods.DELETE)
210
- expect(participant.sendErrorToParticipant.callCount).toBe(0)
211
- expect(participant.sendRequest.callCount).toBe(1)
212
- // eslint-disable-next-line no-unused-vars
213
- const [_, sendTo] = participant.sendRequest.lastCall.args
214
- expect(sendTo).toBe(proxy)
206
+ expect(participant.sendRequest.callCount).toBe(0)
207
+ expect(oracle.oracleRequest.callCount).toBe(0)
208
+ expect(participant.sendErrorToParticipant.callCount).toBe(1)
209
+
210
+ const { errorInformation } = participant.sendErrorToParticipant.getCall(0).args[2]
211
+ expect(errorInformation.errorCode).toBe('3200')
212
+ expect(errorInformation.errorDescription).toContain(ERROR_MESSAGES.partyDestinationFspNotFound)
215
213
  })
216
214
 
217
215
  it('should send request to proxy, if destination is not in the scheme, but has proxyMapping', async () => {
@@ -472,7 +470,7 @@ describe('Parties Tests', () => {
472
470
  expect(firstCallArgs[2]).toBe(expectedCallbackEnpointType)
473
471
  })
474
472
 
475
- it('should send errorCallback if oracle returns external dfsp, and source is external', async () => {
473
+ it('should send request to proxy if oracle returns dfsp NOT from the scheme', async () => {
476
474
  Config.PROXY_CACHE_CONFIG.enabled = true
477
475
  const proxyName = `proxy-${Date.now()}`
478
476
  const fspId = `dfspNotFromScheme-${Date.now()}`
@@ -481,7 +479,7 @@ describe('Parties Tests', () => {
481
479
  })
482
480
  sandbox.stub(oracle, 'oracleRequest').resolves(oracleResponse)
483
481
  participant.validateParticipant = sandbox.stub()
484
- .onFirstCall().resolves(null) // source
482
+ .onFirstCall().resolves({}) // source
485
483
  .onSecondCall().resolves(null) // oracle dfsp
486
484
  participant.sendRequest = sandbox.stub().resolves()
487
485
  participant.sendErrorToParticipant = sandbox.stub().resolves()
@@ -489,20 +487,15 @@ describe('Parties Tests', () => {
489
487
  const isAdded = await proxyCache.addDfspIdToProxyMapping(fspId, proxyName)
490
488
  expect(isAdded).toBe(true)
491
489
 
492
- const source = `fromDfsp-${Date.now()}`
493
- const headers = fixtures.partiesCallHeadersDto({ destination: '', source, proxy: 'proxy' })
490
+ const headers = fixtures.partiesCallHeadersDto({ destination: '' })
494
491
  const { params, method, query } = Helper.getByTypeIdRequest
495
492
 
496
493
  await partiesDomain.getPartiesByTypeAndID(headers, params, method, query, null, null, proxyCache)
497
494
 
498
- expect(participant.sendRequest.callCount).toBe(0)
499
- expect(participant.sendErrorToParticipant.callCount).toBe(1)
500
- // eslint-disable-next-line no-unused-vars
501
- const [sentTo, _, payload, sentHeaders] = participant.sendErrorToParticipant.lastCall.args
502
- expect(sentTo).toBe(source)
503
- expect(payload.errorInformation.errorCode).toBe('3200')
504
- expect(sentHeaders[Headers.FSPIOP.SOURCE]).toBe(Config.HUB_NAME)
505
- expect(sentHeaders[Headers.FSPIOP.DESTINATION]).toBe(headers[Headers.FSPIOP.SOURCE])
495
+ expect(participant.sendErrorToParticipant.callCount).toBe(0)
496
+ expect(participant.sendRequest.callCount).toBe(1)
497
+ const calledProxy = participant.sendRequest.getCall(0).args[1]
498
+ expect(calledProxy).toBe(proxyName)
506
499
  })
507
500
 
508
501
  it('handles error when `oracleRequest` returns no result', async () => {
@@ -561,14 +554,13 @@ describe('Parties Tests', () => {
561
554
  participant.sendRequest = sandbox.stub().rejects(new Error('Some network issue'))
562
555
  participant.sendErrorToParticipant = sandbox.stub().resolves()
563
556
  const headers = fixtures.partiesCallHeadersDto({ destination: '' })
564
- const params = fixtures.partiesParamsDto()
565
557
 
566
- await partiesDomain.getPartiesByTypeAndID(headers, params, Helper.getByTypeIdRequest.method, Helper.getByTypeIdRequest.query, Helper.mockSpan(), null, proxyCache)
558
+ await partiesDomain.getPartiesByTypeAndID(headers, Helper.getByTypeIdRequest.params, Helper.getByTypeIdRequest.method, Helper.getByTypeIdRequest.query, Helper.mockSpan(), null, proxyCache)
567
559
 
568
560
  expect(participant.sendRequest.callCount).toBe(proxyNames.length)
569
561
  expect(participant.sendErrorToParticipant.callCount).toBe(1)
570
562
 
571
- const { errorInformation } = participant.sendErrorToParticipant.lastCall.args[2]
563
+ const { errorInformation } = participant.sendErrorToParticipant.getCall(0).args[2]
572
564
  expect(errorInformation.errorCode).toBe('3200')
573
565
  expect(errorInformation.errorDescription).toContain(ERROR_MESSAGES.proxyConnectionError)
574
566
  })
@@ -0,0 +1,60 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+
9
+ Contributors
10
+ --------------
11
+ This is the official list of the Mojaloop project contributors for this file.
12
+ Names of the original copyright holders (individuals or organizations)
13
+ should be listed with a '*' in the first column. People who have
14
+ contributed from an organization can be listed under the organization
15
+ that actually holds the copyright for their contributions (see the
16
+ Mojaloop Foundation organization for an example). Those individuals should have
17
+ their names indented and be marked with a '-'. Email address can be added
18
+ optionally within square brackets <email>.
19
+ * Mojaloop Foundation
20
+ - Name Surname <name.surname@mojaloop.io>
21
+
22
+ * Eugen Klymniuk <eugen.klymniuk@infitx.com>
23
+ --------------
24
+ **********/
25
+
26
+ const mockSendRequest = jest.fn()
27
+
28
+ jest.mock('@mojaloop/central-services-shared', () => ({
29
+ ...jest.requireActual('@mojaloop/central-services-shared'),
30
+ Util: {
31
+ ...jest.requireActual('@mojaloop/central-services-shared').Util,
32
+ Endpoints: { getEndpoint: jest.fn() },
33
+ Request: { sendRequest: mockSendRequest }
34
+ }
35
+ }))
36
+
37
+ const { API_TYPES } = require('@mojaloop/central-services-shared').Util.Hapi
38
+ const { logger } = require('../../../../src/lib')
39
+ const partiesUtils = require('../../../../src/domain/parties/partiesUtils')
40
+ const config = require('../../../../src/lib/config')
41
+ const fixtures = require('../../../fixtures')
42
+
43
+ describe('parties utils Tests -->', () => {
44
+ test('should send error party callback in ISO format', async () => {
45
+ const isoConfig = { ...config, API_TYPE: API_TYPES.iso20022 }
46
+ const err = new Error('test error')
47
+ const source = 'dfsp1'
48
+ const headers = fixtures.partiesCallHeadersDto({ source })
49
+ const params = { ID: '1234', Type: 'MSISDN' }
50
+
51
+ const handleError = partiesUtils.createErrorHandlerOnSendingCallback(isoConfig, logger)
52
+ await handleError(err, headers, params, source)
53
+
54
+ expect(mockSendRequest).toHaveBeenCalledTimes(1)
55
+ const { payload } = mockSendRequest.mock.calls[0][0]
56
+ expect(payload.Rpt.Rsn.Cd).toBe('2001')
57
+ expect(payload.Rpt.OrgnlId).toBe(`${params.Type}/${params.ID}`)
58
+ expect(payload.Assgnmt.Assgnr.Agt.FinInstnId.Othr.Id).toBe(source)
59
+ })
60
+ })
@@ -64,16 +64,16 @@ describe('Timeout Domain', () => {
64
64
 
65
65
  describe('sendTimeoutCallback', () => {
66
66
  it('should send error to participant', async () => {
67
- const SOURCE_ID = 'sourceId'
68
- jest.spyOn(Participant, 'validateParticipant').mockResolvedValue({ fspId: SOURCE_ID })
67
+ jest.spyOn(Participant, 'validateParticipant').mockResolvedValue({ fspId: 'sourceId' })
69
68
 
70
- const cacheKey = `als:${SOURCE_ID}:2:3` // ':expiresAt' part is removed inside proxyCache.processExpiryKey()
69
+ const cacheKey = 'als:sourceId:2:3:expiresAt'
70
+ const [, destination] = cacheKey.split(':')
71
71
 
72
72
  await TimeoutDomain.sendTimeoutCallback(cacheKey)
73
73
 
74
- expect(Participant.validateParticipant).toHaveBeenCalledWith(SOURCE_ID)
74
+ expect(Participant.validateParticipant).toHaveBeenCalledWith('sourceId')
75
75
  expect(Participant.sendErrorToParticipant).toHaveBeenCalledWith(
76
- SOURCE_ID,
76
+ destination,
77
77
  'FSPIOP_CALLBACK_URL_PARTIES_PUT_ERROR',
78
78
  { errorInformation: { errorCode: '3300', errorDescription: 'Generic expired error' } },
79
79
  expect.any(Object), expect.any(Object), undefined, expect.any(Object)
@@ -1,10 +1,11 @@
1
- const { AlsApiClient, ProxyApiClient } = require('./apiClients')
2
- const mockDeps = require('./mockDeps')
3
1
  const onboarding = require('./onboarding')
2
+ const {
3
+ AlsApiClient,
4
+ ProxyApiClient
5
+ } = require('./apiClients')
4
6
 
5
7
  module.exports = {
8
+ onboarding,
6
9
  AlsApiClient,
7
- ProxyApiClient,
8
- mockDeps,
9
- onboarding
10
+ ProxyApiClient
10
11
  }
@@ -1,51 +0,0 @@
1
- /*****
2
- License
3
- --------------
4
- Copyright © 2020-2025 Mojaloop Foundation
5
- The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
-
9
- Contributors
10
- --------------
11
- This is the official list of the Mojaloop project contributors for this file.
12
- Names of the original copyright holders (individuals or organizations)
13
- should be listed with a '*' in the first column. People who have
14
- contributed from an organization can be listed under the organization
15
- that actually holds the copyright for their contributions (see the
16
- Mojaloop Foundation organization for an example). Those individuals should have
17
- their names indented and be marked with a '-'. Email address can be added
18
- optionally within square brackets <email>.
19
- * Mojaloop Foundation
20
- - Name Surname <name.surname@mojaloop.io>
21
-
22
- * Eugen Klymniuk <eugen.klymniuk@infitx.com>
23
- --------------
24
- **********/
25
-
26
- const ErrorHandler = require('@mojaloop/central-services-error-handling')
27
- const partiesUtils = require('#src/domain/parties/partiesUtils')
28
- const config = require('#src/lib/config')
29
- const { API_TYPES } = require('#src/constants')
30
- const fixtures = require('#test/fixtures/index')
31
-
32
- describe('partiesUtils Tests -->', () => {
33
- describe('makePutPartiesErrorPayload Tests', () => {
34
- const error = ErrorHandler.Factory.reformatFSPIOPError(new Error('Test Error'))
35
- const ERR_CODE = '2001'
36
- const headers = fixtures.partiesCallHeadersDto()
37
- const params = fixtures.partiesParamsDto()
38
-
39
- test('should make putParties error payload in FSPIOP format', async () => {
40
- const fspiopConfig = { ...config, API_TYPE: API_TYPES.fspiop }
41
- const payload = await partiesUtils.makePutPartiesErrorPayload(fspiopConfig, error, headers, params)
42
- expect(payload.errorInformation.errorCode).toBe(ERR_CODE)
43
- })
44
-
45
- test('should make putParties error payload in ISO20022 format', async () => {
46
- const fspiopConfig = { ...config, API_TYPE: API_TYPES.iso20022 }
47
- const payload = await partiesUtils.makePutPartiesErrorPayload(fspiopConfig, error, headers, params)
48
- expect(payload.Rpt.Rsn.Cd).toBe(ERR_CODE)
49
- })
50
- })
51
- })
@@ -1,71 +0,0 @@
1
- /*****
2
- License
3
- --------------
4
- Copyright © 2020-2025 Mojaloop Foundation
5
- The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
-
7
- http://www.apache.org/licenses/LICENSE-2.0
8
-
9
- Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
-
11
- Contributors
12
- --------------
13
- This is the official list of the Mojaloop project contributors for this file.
14
- Names of the original copyright holders (individuals or organizations)
15
- should be listed with a '*' in the first column. People who have
16
- contributed from an organization can be listed under the organization
17
- that actually holds the copyright for their contributions (see the
18
- Mojaloop Foundation for an example). Those individuals should have
19
- their names indented and be marked with a '-'. Email address can be added
20
- optionally within square brackets <email>.
21
-
22
- * Mojaloop Foundation
23
- * Eugen Klymniuk <eugen.klymniuk@infitx.com>
24
-
25
- --------------
26
- ******/
27
-
28
- const { createMockDeps, participantMock } = require('./deps')
29
- // should be first require to mock external deps
30
- const BasePartiesService = require('#src/domain/parties/services/BasePartiesService')
31
- const config = require('#src/lib/config')
32
- const { API_TYPES } = require('#src/constants')
33
- const fixtures = require('#test/fixtures/index')
34
-
35
- describe('BasePartiesService Tests -->', () => {
36
- beforeEach(() => {
37
- jest.clearAllMocks()
38
- })
39
-
40
- test('should send error party callback in ISO20022 format', async () => {
41
- const deps = {
42
- ...createMockDeps(),
43
- config: { ...config, API_TYPE: API_TYPES.iso20022 }
44
- }
45
- const source = 'sourceFsp'
46
- const headers = fixtures.partiesCallHeadersDto({ source })
47
- const params = fixtures.partiesParamsDto()
48
- const service = new BasePartiesService(deps, { headers, params })
49
-
50
- await service.handleError(new Error('test error'))
51
- expect(participantMock.sendErrorToParticipant.mock.calls.length).toBe(1)
52
- // eslint-disable-next-line no-unused-vars
53
- const [sentTo, _, payload] = participantMock.sendErrorToParticipant.mock.lastCall
54
- expect(sentTo).toBe(source)
55
- expect(payload.Rpt.Rsn.Cd).toBe('2001')
56
- expect(payload.Rpt.OrgnlId).toBe(`${params.Type}/${params.ID}`)
57
- expect(payload.Assgnmt.Assgnr.Agt.FinInstnId.Othr.Id).toBe(source)
58
- })
59
-
60
- test('should remove proxy getParties timeout cache key', async () => {
61
- const deps = createMockDeps()
62
- const proxy = 'proxyAB'
63
- const headers = fixtures.partiesCallHeadersDto({ proxy })
64
- const params = fixtures.partiesParamsDto()
65
- const alsReq = {}
66
- const service = new BasePartiesService(deps, { headers, params })
67
-
68
- await service.removeProxyGetPartiesTimeoutCache(alsReq)
69
- expect(deps.proxyCache.removeProxyGetPartiesTimeout).toHaveBeenCalledWith(alsReq, proxy)
70
- })
71
- })