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.
- package/.circleci/config.yml +1 -1
- package/.ncurc.yaml +1 -2
- package/audit-ci.jsonc +3 -1
- package/jest.config.js +2 -0
- package/package.json +14 -16
- package/src/constants.js +2 -1
- package/src/domain/participants/participants.js +173 -130
- package/src/domain/parties/getPartiesByTypeAndID.js +15 -14
- package/src/domain/parties/parties.js +13 -12
- package/src/domain/parties/utils.js +13 -6
- package/src/domain/timeout/dto.js +4 -10
- package/src/handlers/index.js +4 -4
- package/src/handlers/monitoring/index.js +1 -1
- package/src/interface/api-swagger-iso20022-parties.yaml +7 -6
- package/src/interface/api-swagger.yaml +7 -6
- package/src/interface/fspiop-rest-v2.0-ISO20022_parties.yaml +2043 -1583
- package/src/lib/config.js +1 -1
- package/src/lib/index.js +1 -2
- package/src/models/participantEndpoint/facade.js +21 -19
- package/src/plugins.js +20 -9
- package/src/server.js +3 -19
- package/test/fixtures/index.js +30 -6
- package/test/fixtures/iso.js +1 -1
- package/test/unit/api/health.test.js +3 -0
- package/test/unit/api/participants/participants.test.js +5 -7
- package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +0 -3
- package/test/unit/api/participants/{Type}/{ID}.test.js +0 -3
- package/test/unit/api/participants.test.js +36 -3
- package/test/unit/domain/participants/participants.test.js +76 -48
- package/test/unit/domain/parties/parties.test.js +3 -3
- package/test/unit/domain/parties/utils.test.js +60 -0
- package/test/unit/domain/timeout/dto.test.js +1 -2
- package/test/unit/lib/TransformFacades.test.js +2 -1
- package/test/unit/lib/config.test.js +7 -0
- package/test/unit/models/participantEndpoint/facade.test.js +25 -8
- package/test/unit/plugins.test.js +4 -2
- package/test/util/apiClients/BasicApiClient.js +2 -2
- package/src/handlers/monitoring/plugins/metrics.js +0 -48
- package/src/lib/requestLogger.js +0 -54
- package/src/metrics/handler.js +0 -33
- package/src/metrics/plugin.js +0 -52
- package/src/metrics/routes.js +0 -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
|
-
|
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
|
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 =
|
203
|
-
expect(firstCallArgs[0]).toBe(
|
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
|
-
|
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
|
-
|
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
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
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(
|
1346
|
-
Logger.error = sandbox.stub()
|
1338
|
+
const logStub = sandbox.stub(logger.constructor.prototype, 'error')
|
1347
1339
|
participant.validateParticipant = sandbox.stub().resolves(null)
|
1348
|
-
|
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
|
-
|
1372
|
-
|
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
|
-
|
1629
|
-
expect(
|
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.
|
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.
|
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
|
-
|
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: {
|
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(
|
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(
|
89
|
+
expect(server.register.callCount).toBe(10)
|
88
90
|
})
|
89
91
|
})
|
@@ -1,12 +1,12 @@
|
|
1
1
|
const axiosLib = require('axios')
|
2
|
-
const
|
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 =
|
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
|
-
}
|
package/src/lib/requestLogger.js
DELETED
@@ -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
|
-
}
|
package/src/metrics/handler.js
DELETED
@@ -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
|
-
}
|