account-lookup-service 15.6.0-iso.2 → 15.6.0-iso.20

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.
Files changed (43) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/.ncurc.yaml +1 -2
  3. package/audit-ci.jsonc +3 -1
  4. package/jest.config.js +2 -0
  5. package/package.json +14 -16
  6. package/src/constants.js +2 -1
  7. package/src/domain/participants/participants.js +173 -130
  8. package/src/domain/parties/getPartiesByTypeAndID.js +15 -14
  9. package/src/domain/parties/parties.js +13 -12
  10. package/src/domain/parties/utils.js +13 -6
  11. package/src/domain/timeout/dto.js +4 -10
  12. package/src/handlers/index.js +4 -4
  13. package/src/handlers/monitoring/index.js +1 -1
  14. package/src/interface/api-swagger-iso20022-parties.yaml +7 -6
  15. package/src/interface/api-swagger.yaml +7 -6
  16. package/src/interface/fspiop-rest-v2.0-ISO20022_parties.yaml +2043 -1583
  17. package/src/lib/config.js +1 -1
  18. package/src/lib/index.js +1 -2
  19. package/src/models/participantEndpoint/facade.js +21 -19
  20. package/src/plugins.js +20 -9
  21. package/src/server.js +3 -19
  22. package/test/fixtures/index.js +30 -6
  23. package/test/fixtures/iso.js +1 -1
  24. package/test/unit/api/health.test.js +3 -0
  25. package/test/unit/api/participants/participants.test.js +5 -7
  26. package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +0 -3
  27. package/test/unit/api/participants/{Type}/{ID}.test.js +0 -3
  28. package/test/unit/api/participants.test.js +36 -3
  29. package/test/unit/domain/participants/participants.test.js +76 -48
  30. package/test/unit/domain/parties/parties.test.js +3 -3
  31. package/test/unit/domain/parties/utils.test.js +60 -0
  32. package/test/unit/domain/timeout/dto.test.js +1 -2
  33. package/test/unit/lib/TransformFacades.test.js +2 -1
  34. package/test/unit/lib/config.test.js +7 -0
  35. package/test/unit/models/participantEndpoint/facade.test.js +25 -8
  36. package/test/unit/plugins.test.js +4 -2
  37. package/test/util/apiClients/BasicApiClient.js +2 -2
  38. package/src/handlers/monitoring/plugins/metrics.js +0 -48
  39. package/src/lib/requestLogger.js +0 -54
  40. package/src/metrics/handler.js +0 -33
  41. package/src/metrics/plugin.js +0 -52
  42. package/src/metrics/routes.js +0 -43
  43. package/test/unit/lib/requestLogger.test.js +0 -115
@@ -38,12 +38,13 @@ const ErrorHandler = require('@mojaloop/central-services-error-handling')
38
38
  const participantsDomain = require('../../../../src/domain/participants/participants')
39
39
  const participant = require('../../../../src/models/participantEndpoint/facade')
40
40
  const oracle = require('../../../../src/models/oracle/facade')
41
- const Helper = require('../../../util/helper')
42
41
  const Config = require('../../../../src/lib/config')
42
+ const { logger } = require('../../../../src/lib')
43
+ const { ERROR_MESSAGES } = require('../../../../src/constants')
44
+ const Helper = require('../../../util/helper')
45
+ const fixtures = require('../../../fixtures')
43
46
 
44
- Logger.isDebugEnabled = jest.fn(() => true)
45
- Logger.isErrorEnabled = jest.fn(() => true)
46
- Logger.isInfoEnabled = jest.fn(() => true)
47
+ const { Headers } = Enums.Http
47
48
 
48
49
  describe('participant Tests', () => {
49
50
  describe('getParticipantsByTypeAndID', () => {
@@ -185,7 +186,7 @@ describe('participant Tests', () => {
185
186
  expect.hasAssertions()
186
187
  // Arrange
187
188
  participant.validateParticipant = sandbox.stub().resolves(null)
188
- const logErrorStub = sandbox.stub(Logger, 'error')
189
+ const logStub = sandbox.stub(logger.constructor.prototype, 'warn')
189
190
 
190
191
  participant.sendRequest = sandbox.stub()
191
192
  const args = [
@@ -199,8 +200,8 @@ describe('participant Tests', () => {
199
200
  await participantsDomain.getParticipantsByTypeAndID(...args)
200
201
 
201
202
  // Assert
202
- const firstCallArgs = logErrorStub.getCall(0).args
203
- expect(firstCallArgs[0]).toBe('Requester FSP not found')
203
+ const firstCallArgs = logStub.getCall(0).args
204
+ expect(firstCallArgs[0]).toBe(ERROR_MESSAGES.sourceFspNotFound)
204
205
  })
205
206
 
206
207
  it('fails when `oracleRequest` response is empty', async () => {
@@ -485,9 +486,8 @@ describe('participant Tests', () => {
485
486
  it('handles the case where `validateParticipant` returns null', async () => {
486
487
  expect.hasAssertions()
487
488
  // Arrange
489
+ const logStub = sandbox.stub(logger.constructor.prototype, 'error')
488
490
  participant.validateParticipant = sandbox.stub().resolves(null)
489
- sandbox.stub(Logger)
490
- Logger.error = sandbox.stub()
491
491
  participant.sendErrorToParticipant = sandbox.stub()
492
492
  const headers = {
493
493
  accept: 'application/vnd.interoperability.participants+json;version=1',
@@ -510,8 +510,7 @@ describe('participant Tests', () => {
510
510
  await participantsDomain.putParticipantsByTypeAndID(headers, params, method, payload)
511
511
 
512
512
  // Assert
513
- const loggerFirstCallArgs = Logger.error.getCall(0).args
514
- expect(loggerFirstCallArgs[0]).toBe('Requester FSP not found')
513
+ expect(logStub.getCall(0).args[1].message).toBe(ERROR_MESSAGES.sourceFspNotFound)
515
514
  })
516
515
 
517
516
  it('handles case where type is not in `PartyAccountTypes`', async () => {
@@ -739,9 +738,6 @@ describe('participant Tests', () => {
739
738
  it('handles PUT /error when SubId supplied but validateParticipant throws error', async () => {
740
739
  expect.hasAssertions()
741
740
  // Arrange
742
- sandbox.stub(Logger)
743
- Logger.info = sandbox.stub()
744
- Logger.error = sandbox.stub()
745
741
  participant.validateParticipant = sandbox.stub().throws(new Error('Validation failed'))
746
742
  oracle.oracleRequest = sandbox.stub().resolves(null)
747
743
  participant.sendErrorToParticipant = sandbox.stub()
@@ -771,15 +767,11 @@ describe('participant Tests', () => {
771
767
  expect(participant.sendErrorToParticipant.callCount).toBe(1)
772
768
  const firstCallArgs = participant.sendErrorToParticipant.getCall(0).args
773
769
  expect(firstCallArgs[1]).toBe(expectedCallbackEndpointType)
774
- expect(Logger.error.callCount).toBe(1)
775
770
  })
776
771
 
777
772
  it('handles PUT /error when `sendErrorToParticipant` throws error', async () => {
778
773
  expect.hasAssertions()
779
774
  // Arrange
780
- sandbox.stub(Logger)
781
- Logger.info = sandbox.stub()
782
- Logger.error = sandbox.stub()
783
775
  participant.validateParticipant = sandbox.stub().resolves({})
784
776
  participant.sendErrorToParticipant = sandbox.stub().throws(new Error('sendErrorToParticipant failed'))
785
777
  const expectedCallbackEndpointType = Enums.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR
@@ -809,15 +801,11 @@ describe('participant Tests', () => {
809
801
  const secondCallArgs = participant.sendErrorToParticipant.getCall(1).args
810
802
  expect(firstCallArgs[1]).toBe(expectedCallbackEndpointType)
811
803
  expect(secondCallArgs[0]).toBe(Config.HUB_NAME)
812
- expect(Logger.error.callCount).toBe(2)
813
804
  })
814
805
 
815
806
  it('handles PUT /error when SubId is supplied and `sendErrorToParticipant` throws error', async () => {
816
807
  expect.hasAssertions()
817
808
  // Arrange
818
- sandbox.stub(Logger)
819
- Logger.info = sandbox.stub()
820
- Logger.error = sandbox.stub()
821
809
  participant.validateParticipant = sandbox.stub().resolves({})
822
810
  participant.sendErrorToParticipant = sandbox.stub().throws(new Error('sendErrorToParticipant failed'))
823
811
  const expectedCallbackEndpointType = Enums.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT_ERROR
@@ -848,7 +836,6 @@ describe('participant Tests', () => {
848
836
  const secondCallArgs = participant.sendErrorToParticipant.getCall(1).args
849
837
  expect(firstCallArgs[1]).toBe(expectedCallbackEndpointType)
850
838
  expect(secondCallArgs[0]).toBe(Config.HUB_NAME)
851
- expect(Logger.error.callCount).toBe(2)
852
839
  })
853
840
  })
854
841
 
@@ -1048,9 +1035,8 @@ describe('participant Tests', () => {
1048
1035
  it('handles the case where `validateParticipant` returns null', async () => {
1049
1036
  expect.hasAssertions()
1050
1037
  // Arrange
1038
+ const logStub = sandbox.stub(logger.constructor.prototype, 'error')
1051
1039
  participant.validateParticipant = sandbox.stub().resolves(null)
1052
- sandbox.stub(Logger)
1053
- Logger.error = sandbox.stub()
1054
1040
  participant.sendErrorToParticipant = sandbox.stub()
1055
1041
  const headers = {
1056
1042
  accept: 'application/vnd.interoperability.participants+json;version=1',
@@ -1072,8 +1058,7 @@ describe('participant Tests', () => {
1072
1058
  await participantsDomain.postParticipants(headers, 'get', params, payload)
1073
1059
 
1074
1060
  // Assert
1075
- const loggerFirstCallArgs = Logger.error.getCall(0).args
1076
- expect(loggerFirstCallArgs[0]).toBe('Requester FSP not found')
1061
+ expect(logStub.getCall(0).args[0]).toBe(ERROR_MESSAGES.sourceFspNotFound)
1077
1062
  })
1078
1063
 
1079
1064
  it('handles case where type is not in `PartyAccountTypes`', async () => {
@@ -1202,7 +1187,7 @@ describe('participant Tests', () => {
1202
1187
 
1203
1188
  const headers = {
1204
1189
  accept: 'application/vnd.interoperability.participants+json;version=1',
1205
- 'fspiop-destination': Config.HUB_NAME,
1190
+ // 'fspiop-destination': Config.HUB_NAME,
1206
1191
  'content-type': 'application/vnd.interoperability.participants+json;version=1.1',
1207
1192
  date: '2019-05-24 08:52:19',
1208
1193
  'fspiop-source': 'fsp1'
@@ -1318,15 +1303,23 @@ describe('participant Tests', () => {
1318
1303
  const expected = {
1319
1304
  currency: 'USD',
1320
1305
  partyList: [
1321
- ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND, undefined, undefined, undefined, [{
1322
- key: Enums.Accounts.PartyAccountTypes.MSISDN,
1323
- value: undefined
1324
- }]).toApiErrorObject(Config.ERROR_HANDLING),
1325
- ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, undefined, undefined, undefined, [{
1326
- key: 'NOT_A_VALID_PARTY_ID',
1327
- value: undefined
1328
- }]).toApiErrorObject(Config.ERROR_HANDLING),
1329
- { partyId: { currency: undefined } }
1306
+ {
1307
+ ...ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND, undefined, undefined, undefined, [{
1308
+ key: Enums.Accounts.PartyAccountTypes.MSISDN,
1309
+ value: undefined
1310
+ }]).toApiErrorObject(Config.ERROR_HANDLING),
1311
+ partyId: payload.partyList[1]
1312
+ },
1313
+ {
1314
+ ...ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, undefined, undefined, undefined, [{
1315
+ key: 'NOT_A_VALID_PARTY_ID',
1316
+ value: undefined
1317
+ }]).toApiErrorObject(Config.ERROR_HANDLING),
1318
+ partyId: payload.partyList[2]
1319
+ },
1320
+ {
1321
+ partyId: { currency: undefined }
1322
+ }
1330
1323
  ]
1331
1324
  }
1332
1325
 
@@ -1342,10 +1335,10 @@ describe('participant Tests', () => {
1342
1335
  it('handles error when `validateParticipant` fails and `sendErrorToParticipant` throws', async () => {
1343
1336
  expect.hasAssertions()
1344
1337
  // Arrange
1345
- sandbox.stub(Logger)
1346
- Logger.error = sandbox.stub()
1338
+ const logStub = sandbox.stub(logger.constructor.prototype, 'error')
1347
1339
  participant.validateParticipant = sandbox.stub().resolves(null)
1348
- participant.sendErrorToParticipant = sandbox.stub().throws(new Error('unknown error'))
1340
+ const cbError = new Error('unknown error')
1341
+ participant.sendErrorToParticipant = sandbox.stub().throws(cbError)
1349
1342
 
1350
1343
  const headers = {
1351
1344
  accept: 'application/vnd.interoperability.participants+json;version=1',
@@ -1368,10 +1361,8 @@ describe('participant Tests', () => {
1368
1361
  await participantsDomain.postParticipantsBatch(headers, 'get', payload, Helper.mockSpan())
1369
1362
 
1370
1363
  // Assert
1371
- const firstCallArgs = Logger.error.getCall(0).args
1372
- const thirdCallArgs = Logger.error.getCall(2).args
1373
- expect(firstCallArgs[0]).toBe('Requester FSP not found')
1374
- expect(thirdCallArgs[0].message).toBe('unknown error')
1364
+ expect(logStub.getCall(0).firstArg).toBe(ERROR_MESSAGES.sourceFspNotFound)
1365
+ expect(logStub.getCall(2).lastArg).toEqual(cbError)
1375
1366
  })
1376
1367
 
1377
1368
  it('handles error when `oracleBatchRequest` returns no result', async () => {
@@ -1447,6 +1438,44 @@ describe('participant Tests', () => {
1447
1438
  expect(firstCallArgs[4].partyList[1].errorInformation).toBeDefined()
1448
1439
  expect(firstCallArgs[4].partyList[2].errorInformation).toBeDefined()
1449
1440
  })
1441
+
1442
+ it('should not call oracle if source-header and fspId in payload are different, and no destination [CSI-938]', async () => {
1443
+ const headers = fixtures.participantsCallHeadersDto({ destination: '' })
1444
+ const payload = {
1445
+ requestId: '0e21b07e-3117-46ca-ae22-6ee370895697',
1446
+ currency: 'MWK',
1447
+ partyList: [
1448
+ {
1449
+ fspId: 'test-mwk-dfsp',
1450
+ partyIdType: 'MSISDN',
1451
+ partyIdentifier: '16665551002'
1452
+ }
1453
+ ]
1454
+ }
1455
+ expect(headers.source).not.toBe(payload.partyList[0].fspId)
1456
+ expect(headers.destination).toBeUndefined()
1457
+
1458
+ participant.validateParticipant = sandbox.stub().resolves({})
1459
+ participant.sendRequest = sandbox.stub()
1460
+ participant.sendErrorToParticipant = sandbox.stub().resolves({})
1461
+ oracle.oracleBatchRequest = sandbox.stub().resolves({})
1462
+
1463
+ await participantsDomain.postParticipantsBatch(headers, 'put', payload, Helper.mockSpan())
1464
+
1465
+ expect(oracle.oracleBatchRequest.callCount).toBe(0)
1466
+ expect(participant.sendErrorToParticipant.callCount).toBe(0)
1467
+ expect(participant.sendRequest.callCount).toBe(1)
1468
+
1469
+ const { args } = participant.sendRequest.getCall(0)
1470
+ expect(args[0][Headers.FSPIOP.DESTINATION]).toBe(headers[Headers.FSPIOP.SOURCE])
1471
+ expect(args[0][Headers.FSPIOP.SOURCE]).toBe(Config.HUB_NAME)
1472
+ expect(args[1]).toBe(headers[Headers.FSPIOP.SOURCE])
1473
+
1474
+ const { partyList } = args[4]
1475
+ expect(partyList.length).toBe(1)
1476
+ expect(partyList[0].errorInformation).toBeDefined()
1477
+ expect(partyList[0].partyId).toBe(payload.partyList[0])
1478
+ })
1450
1479
  })
1451
1480
 
1452
1481
  describe('deleteParticipants', () => {
@@ -1602,9 +1631,8 @@ describe('participant Tests', () => {
1602
1631
  it('handles the case where `validateParticipant` returns null', async () => {
1603
1632
  expect.hasAssertions()
1604
1633
  // Arrange
1634
+ const logStub = sandbox.stub(logger.constructor.prototype, 'error')
1605
1635
  participant.validateParticipant = sandbox.stub().resolves(null)
1606
- sandbox.stub(Logger)
1607
- Logger.error = sandbox.stub()
1608
1636
  participant.sendErrorToParticipant = sandbox.stub()
1609
1637
  const headers = {
1610
1638
  accept: 'application/vnd.interoperability.participants+json;version=1',
@@ -1625,8 +1653,8 @@ describe('participant Tests', () => {
1625
1653
  await participantsDomain.deleteParticipants(headers, params, method, query)
1626
1654
 
1627
1655
  // Assert
1628
- const loggerFirstCallArgs = Logger.error.getCall(0).args
1629
- expect(loggerFirstCallArgs[0]).toBe('Requester FSP not found')
1656
+ expect(logStub.getCall(0).firstArg).toBe(ERROR_MESSAGES.sourceFspNotFound)
1657
+ // expect(logStub.getCall()]).toBe(ERROR_MESSAGES.sourceFspNotFound)
1630
1658
  })
1631
1659
 
1632
1660
  it('handles case where type is not in `PartyAccountTypes`', async () => {
@@ -613,7 +613,7 @@ describe('Parties Tests', () => {
613
613
  it('handles error when `participant.validateParticipant()` returns no participant', async () => {
614
614
  expect.hasAssertions()
615
615
  // Arrange
616
- const loggerStub = sandbox.stub(logger, 'error')
616
+ const loggerStub = sandbox.stub(logger.constructor.prototype, 'error')
617
617
  participant.sendErrorToParticipant = sandbox.stub().resolves()
618
618
 
619
619
  const payload = JSON.stringify({ testPayload: true })
@@ -874,7 +874,7 @@ describe('Parties Tests', () => {
874
874
  it('handles error when `validateParticipant()` fails', async () => {
875
875
  expect.hasAssertions()
876
876
  // Arrange)
877
- const loggerStub = sandbox.stub(logger.mlLogger, 'error')
877
+ const loggerStub = sandbox.stub(logger.constructor.prototype, 'error')
878
878
  participant.validateParticipant = sandbox.stub().throws(new Error('Validation fails'))
879
879
  participant.sendErrorToParticipant = sandbox.stub().resolves({})
880
880
  const payload = JSON.stringify({ errorPayload: true })
@@ -894,7 +894,7 @@ describe('Parties Tests', () => {
894
894
  expect.hasAssertions()
895
895
  // Arrange
896
896
 
897
- const loggerStub = sandbox.stub(logger.mlLogger, 'error')
897
+ const loggerStub = sandbox.stub(logger.constructor.prototype, 'error')
898
898
  participant.validateParticipant = sandbox.stub().throws(new Error('Validation fails'))
899
899
  participant.sendErrorToParticipant = sandbox.stub().resolves({})
900
900
  const payload = JSON.stringify({ errorPayload: true })
@@ -0,0 +1,60 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2017 Bill & Melinda Gates Foundation
5
+ The Mojaloop files are made available by the Bill & Melinda Gates 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
+ Gates 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
+ * Gates Foundation
20
+ - Name Surname <name.surname@gatesfoundation.com>
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 utils = require('../../../../src/domain/parties/utils')
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 = utils.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
+ })
@@ -9,8 +9,7 @@ describe('timeoutCallbackDto Tests -->', () => {
9
9
  config.API_TYPE = realApiType
10
10
  })
11
11
 
12
- // todo: unskip after fixing transformLib SubId issue for parties.putError
13
- test.skip('should produce ISO payload', async () => {
12
+ test('should produce ISO payload', async () => {
14
13
  config.API_TYPE = API_TYPES.iso20022
15
14
  const destination = 'D1'
16
15
  const partyId = 'P1'
@@ -5,10 +5,11 @@ describe('TransformFacades Tests -->', () => {
5
5
  test('should transform PUT /parties error callback payload to ISO format', async () => {
6
6
  const body = errorCallbackResponseDto()
7
7
  const headers = partiesCallHeadersDto()
8
+ TransformFacades.FSPIOP.configure({ isTestingMode: true })
8
9
  const isoPayload = await TransformFacades.FSPIOP.parties.putError({
9
10
  body,
10
11
  headers,
11
- params: { IdPath: '123456789' }
12
+ params: { Type: 'MSISDN', ID: '123456789' }
12
13
  })
13
14
  expect(isoPayload.body).toBeTruthy()
14
15
  expect(isoPayload.body.Assgnmt).toBeTruthy()
@@ -105,4 +105,11 @@ describe('Config tests', () => {
105
105
  expect(isSuccess).toBe(false)
106
106
  expect(error.message).toBe('File doesn\'t exist')
107
107
  })
108
+
109
+ it('should have FSPIOP_SOURCE_TO_SIGN config defined', () => {
110
+ process.env.ALS_ENDPOINT_SECURITY__JWS__JWS_SIGN = 'false' // to avoid error in config getFileContent()
111
+ const config = require(configImport)
112
+ expect(config.FSPIOP_SOURCE_TO_SIGN).toBeDefined()
113
+ expect(config.FSPIOP_SOURCE_TO_SIGN).toBe(config.HUB_NAME)
114
+ })
108
115
  })
@@ -58,6 +58,18 @@ jest.mock('@mojaloop/central-services-shared', () => ({
58
58
  const Logger = require('@mojaloop/central-services-logger')
59
59
  const fixtures = require('../../../fixtures')
60
60
 
61
+ const mockConfigDto = ({
62
+ apiType = 'fspiop', // todo: use API_TYPES
63
+ jwsSign = false
64
+ } = {}) => ({
65
+ API_TYPE: apiType,
66
+ JWS_SIGN: jwsSign,
67
+ FSPIOP_SOURCE_TO_SIGN: mockHubName,
68
+ JWS_SIGNING_KEY_PATH: 'secrets/jwsSigningKey.key',
69
+ JWS_SIGNING_KEY: 'somekey',
70
+ PROTOCOL_VERSIONS: fixtures.protocolVersionsDto()
71
+ })
72
+
61
73
  Logger.isDebugEnabled = jest.fn(() => true)
62
74
  Logger.isErrorEnabled = jest.fn(() => true)
63
75
  Logger.isInfoEnabled = jest.fn(() => true)
@@ -190,14 +202,6 @@ describe('participantEndpoint Facade', () => {
190
202
  })
191
203
 
192
204
  describe('sendErrorToParticipant', () => {
193
- const mockConfigDto = ({ jwsSign = false } = {}) => ({
194
- JWS_SIGN: jwsSign,
195
- FSPIOP_SOURCE_TO_SIGN: mockHubName,
196
- JWS_SIGNING_KEY_PATH: 'secrets/jwsSigningKey.key',
197
- JWS_SIGNING_KEY: 'somekey',
198
- PROTOCOL_VERSIONS: fixtures.protocolVersionsDto()
199
- })
200
-
201
205
  it('throws an error when the request fails', async () => {
202
206
  // Arrange
203
207
  jest.mock('../../../../src/lib/config', () => mockConfigDto())
@@ -291,5 +295,18 @@ describe('participantEndpoint Facade', () => {
291
295
  })
292
296
  spy.mockRestore()
293
297
  })
298
+
299
+ it('should send error response with apiType from config [ISO20022]', async () => {
300
+ const apiType = 'iso20022'
301
+ jest.mock('../../../../src/lib/config', () => mockConfigDto({ apiType }))
302
+ mockGetEndpoint.mockImplementation(() => 'http://example.com/12345')
303
+
304
+ const { sendErrorToParticipant } = require(`${src}/models/participantEndpoint/facade`)
305
+ await sendErrorToParticipant('participantName', 'URL', fixtures.errorCallbackResponseDto(), {})
306
+
307
+ expect(mockSendRequest).toHaveBeenCalledTimes(1)
308
+ const args = mockSendRequest.mock.calls[0][0]
309
+ expect(args.apiType).toBe(apiType)
310
+ })
294
311
  })
295
312
  })
@@ -50,6 +50,7 @@ describe('Plugin Tests', () => {
50
50
  // Arrange
51
51
  const server = {
52
52
  register: sandbox.spy(),
53
+ ext: sandbox.spy(),
53
54
  info: {
54
55
  port: '8000'
55
56
  }
@@ -63,7 +64,7 @@ describe('Plugin Tests', () => {
63
64
  await registerPlugins(server, api)
64
65
 
65
66
  // Assert
66
- expect(server.register.callCount).toBe(10)
67
+ expect(server.register.callCount).toBe(11)
67
68
  const firstCallArgs = server.register.getCall(1).args
68
69
  expect(firstCallArgs[0].options.document.info.title.includes('Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version)')).toBe(true)
69
70
  })
@@ -72,6 +73,7 @@ describe('Plugin Tests', () => {
72
73
  // Arrange
73
74
  const server = {
74
75
  register: sandbox.spy(),
76
+ ext: sandbox.spy(),
75
77
  info: {
76
78
  port: '8000'
77
79
  }
@@ -84,6 +86,6 @@ describe('Plugin Tests', () => {
84
86
  await registerPlugins(server, api)
85
87
 
86
88
  // Assert
87
- expect(server.register.callCount).toBe(9)
89
+ expect(server.register.callCount).toBe(10)
88
90
  })
89
91
  })
@@ -1,12 +1,12 @@
1
1
  const axiosLib = require('axios')
2
- const { loggerFactory } = require('../../../src/lib')
2
+ const lib = require('../../../src/lib')
3
3
  const fixtures = require('../../fixtures')
4
4
 
5
5
  class BasicApiClient {
6
6
  constructor ({
7
7
  baseURL,
8
8
  axios = axiosLib.create({ baseURL }),
9
- logger = loggerFactory(this.constructor.name)
9
+ logger = lib.logger.child(this.constructor.name)
10
10
  } = {}) {
11
11
  this.baseURL = baseURL
12
12
  this.axios = axios
@@ -1,48 +0,0 @@
1
- /*****
2
- LICENSE
3
-
4
- Copyright © 2020 Mojaloop Foundation
5
-
6
- The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
7
- (the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
8
-
9
- You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
10
-
11
- 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,
12
- either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0).
13
-
14
- * Infitx
15
- - Steven Oderayi <steven.oderayi@infitx.com>
16
- --------------
17
- ******/
18
-
19
- 'use strict'
20
-
21
- const HTTPENUM = require('@mojaloop/central-services-shared').Enum.Http
22
- const Metrics = require('@mojaloop/central-services-metrics')
23
-
24
- const handler = {
25
- get: async (_request, reply) => {
26
- return reply.response(await Metrics.getMetricsForPrometheus()).code(HTTPENUM.ReturnCodes.OK.CODE)
27
- }
28
- }
29
-
30
- const routes = [
31
- {
32
- method: 'GET',
33
- path: '/metrics',
34
- handler: handler.get
35
- }
36
- ]
37
-
38
- const plugin = {
39
- name: 'Metrics',
40
- register (server) {
41
- server.route(routes)
42
- }
43
- }
44
-
45
- module.exports = {
46
- plugin,
47
- handler
48
- }
@@ -1,54 +0,0 @@
1
- /*****
2
- License
3
- --------------
4
- Copyright © 2017 Bill & Melinda Gates Foundation
5
- The Mojaloop files are made available by the Bill & Melinda Gates 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
- Contributors
9
- --------------
10
- This is the official list of the Mojaloop project contributors for this file.
11
- Names of the original copyright holders (individuals or organizations)
12
- should be listed with a '*' in the first column. People who have
13
- contributed from an organization can be listed under the organization
14
- that actually holds the copyright for their contributions (see the
15
- Gates Foundation organization for an example). Those individuals should have
16
- their names indented and be marked with a '-'. Email address can be added
17
- optionally within square brackets <email>.
18
- * Gates Foundation
19
-
20
- * Rajiv Mothilal <rajiv.mothilal@modusbox.com>
21
-
22
- --------------
23
- ******/
24
-
25
- 'use strict'
26
-
27
- const { logger, asyncStorage } = require('./index')
28
-
29
- const logRequest = function (request) {
30
- const { path, method, headers, payload, query } = request
31
- const requestId = request.info.id = `${request.info.id}__${headers.traceid}`
32
- asyncStorage.enterWith({ requestId })
33
-
34
- logger.isInfoEnabled && logger.info(`[==> req] ${method.toUpperCase()} ${path}`, { headers, payload, query })
35
- }
36
-
37
- const logResponse = function (request) {
38
- if (logger.isInfoEnabled) {
39
- const { path, method, headers, payload, query, response } = request
40
- const { received } = request.info
41
-
42
- const statusCode = response instanceof Error
43
- ? response.output?.statusCode
44
- : response.statusCode
45
- const respTimeSec = ((Date.now() - received) / 1000).toFixed(3)
46
-
47
- logger.info(`[<== ${statusCode}][${respTimeSec} s] ${method.toUpperCase()} ${path}`, { headers, payload, query })
48
- }
49
- }
50
-
51
- module.exports = {
52
- logRequest,
53
- logResponse
54
- }
@@ -1,33 +0,0 @@
1
- /*****
2
- License
3
- --------------
4
- Copyright © 2017 Bill & Melinda Gates Foundation
5
- The Mojaloop files are made available by the Bill & Melinda Gates 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
- Contributors
9
- --------------
10
- This is the official list of the Mojaloop project contributors for this file.
11
- Names of the original copyright holders (individuals or organizations)
12
- should be listed with a '*' in the first column. People who have
13
- contributed from an organization can be listed under the organization
14
- that actually holds the copyright for their contributions (see the
15
- Gates Foundation organization for an example). Those individuals should have
16
- their names indented and be marked with a '-'. Email address can be added
17
- optionally within square brackets <email>.
18
- * Gates Foundation
19
- - Name Surname <name.surname@gatesfoundation.com>
20
-
21
- - Pedro Barreto <pedrob@crosslaketech.com>
22
- - Rajiv Mothilal <rajivmothilal@gmail.com>
23
- - Shashikant Hirugade <shashikant.hirugade@modusbox.com>
24
- --------------
25
- ******/
26
-
27
- 'use strict'
28
-
29
- const Metrics = require('@mojaloop/central-services-metrics')
30
-
31
- exports.metrics = async function (request, h) {
32
- return h.response(await Metrics.getMetricsForPrometheus()).code(200)
33
- }