@mojaloop/sdk-scheme-adapter 11.18.8
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/.env.example +140 -0
- package/.eslintignore +2 -0
- package/.eslintrc.json +30 -0
- package/.nvmrc +1 -0
- package/.versionrc +15 -0
- package/CHANGELOG.md +118 -0
- package/InboundServer/api.yaml +3594 -0
- package/InboundServer/api_template.yaml +69 -0
- package/InboundServer/handlers.js +940 -0
- package/InboundServer/index.js +205 -0
- package/InboundServer/middlewares.js +426 -0
- package/OAuthTestServer/index.js +66 -0
- package/OAuthTestServer/model.js +70 -0
- package/OutboundServer/api.yaml +2732 -0
- package/OutboundServer/api_interfaces/index.d.ts +117 -0
- package/OutboundServer/api_interfaces/openapi.d.ts +1475 -0
- package/OutboundServer/api_template/components/parameters/bulkQuoteId.yaml +9 -0
- package/OutboundServer/api_template/components/parameters/bulkTransferId.yaml +9 -0
- package/OutboundServer/api_template/components/parameters/requestToPayTransactionId.yaml +9 -0
- package/OutboundServer/api_template/components/parameters/transferId.yaml +9 -0
- package/OutboundServer/api_template/components/responses/accountsCreationCompleted.yaml +5 -0
- package/OutboundServer/api_template/components/responses/accountsCreationError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/accountsCreationTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/responses/authorizationPostSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/authorizationsServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/responses/partiesByIdError404.yaml +9 -0
- package/OutboundServer/api_template/components/responses/partiesByIdSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/quotesPostSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/quotesServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/requestToPaySuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/requestToPayTransferBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/requestToPayTransferSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/simpleTransfersPostSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/simpleTransfersServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/accountCreationStatus.yaml +18 -0
- package/OutboundServer/api_template/components/schemas/accountsCreationState.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/accountsRequest.yaml +20 -0
- package/OutboundServer/api_template/components/schemas/accountsResponse.yaml +15 -0
- package/OutboundServer/api_template/components/schemas/async2SyncCurrentState.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/authorizationsPostRequest.yaml +15 -0
- package/OutboundServer/api_template/components/schemas/authorizationsPostResponse.yaml +19 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteErrorResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteRequest.yaml +26 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteResponse.yaml +21 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteStatus.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteStatusResponse.yaml +17 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferErrorResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferRequest.yaml +26 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferResponse.yaml +16 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferStatus.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferStatusResponse.yaml +17 -0
- package/OutboundServer/api_template/components/schemas/errorAccountsResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/errorAuthorizationsResponse.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/errorQuotesResponse.yaml +9 -0
- package/OutboundServer/api_template/components/schemas/errorResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/errorSimpleTransfersResponse.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/errorTransferResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/extensionListEmptiable.yaml +6 -0
- package/OutboundServer/api_template/components/schemas/individualQuote.yaml +32 -0
- package/OutboundServer/api_template/components/schemas/individualQuoteResult.yaml +28 -0
- package/OutboundServer/api_template/components/schemas/individualTransfer.yaml +32 -0
- package/OutboundServer/api_template/components/schemas/individualTransferFulfilment.yaml +13 -0
- package/OutboundServer/api_template/components/schemas/individualTransferResult.yaml +41 -0
- package/OutboundServer/api_template/components/schemas/mojaloopError.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/mojaloopTransactionRequestState.yaml +2 -0
- package/OutboundServer/api_template/components/schemas/partiesByIdResponse.yaml +13 -0
- package/OutboundServer/api_template/components/schemas/quote.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/quoteError.yaml +16 -0
- package/OutboundServer/api_template/components/schemas/quotesPostRequest.yaml +13 -0
- package/OutboundServer/api_template/components/schemas/quotesPostResponse.yaml +48 -0
- package/OutboundServer/api_template/components/schemas/requestToPayRequest.yaml +39 -0
- package/OutboundServer/api_template/components/schemas/requestToPayResponse.yaml +41 -0
- package/OutboundServer/api_template/components/schemas/requestToPayTransferRequest.yaml +42 -0
- package/OutboundServer/api_template/components/schemas/requestToPayTransferResponse.yaml +58 -0
- package/OutboundServer/api_template/components/schemas/simpleTransferServerError.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/simpleTransfersPostRequest.yaml +12 -0
- package/OutboundServer/api_template/components/schemas/simpleTransfersPostResponse.yaml +11 -0
- package/OutboundServer/api_template/components/schemas/transactionType.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/transferContinuationAcceptOTP.yaml +9 -0
- package/OutboundServer/api_template/components/schemas/transferContinuationAcceptParty.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/transferContinuationAcceptQuote.yaml +9 -0
- package/OutboundServer/api_template/components/schemas/transferError.yaml +16 -0
- package/OutboundServer/api_template/components/schemas/transferFulfilment.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/transferParty.yaml +40 -0
- package/OutboundServer/api_template/components/schemas/transferRequest.yaml +37 -0
- package/OutboundServer/api_template/components/schemas/transferResponse.yaml +58 -0
- package/OutboundServer/api_template/components/schemas/transferStatus.yaml +6 -0
- package/OutboundServer/api_template/components/schemas/transferStatusResponse.yaml +13 -0
- package/OutboundServer/api_template/health.yaml +12 -0
- package/OutboundServer/api_template/openapi.yaml +55 -0
- package/OutboundServer/api_template/paths/accounts.yaml +26 -0
- package/OutboundServer/api_template/paths/authorizations.yaml +19 -0
- package/OutboundServer/api_template/paths/bulkQuotes.yaml +23 -0
- package/OutboundServer/api_template/paths/bulkQuotes_bulkQuoteId.yaml +24 -0
- package/OutboundServer/api_template/paths/bulkTransfers.yaml +23 -0
- package/OutboundServer/api_template/paths/bulkTransfers_bulkTransferId.yaml +24 -0
- package/OutboundServer/api_template/paths/parties_Type_ID.yaml +20 -0
- package/OutboundServer/api_template/paths/parties_Type_ID_SubId.yaml +22 -0
- package/OutboundServer/api_template/paths/quotes.yaml +20 -0
- package/OutboundServer/api_template/paths/requestToPay.yaml +22 -0
- package/OutboundServer/api_template/paths/requestToPayTransfer.yaml +57 -0
- package/OutboundServer/api_template/paths/requestToPayTransfer_requestToPayTransactionId.yaml +34 -0
- package/OutboundServer/api_template/paths/simpleTransfers.yaml +19 -0
- package/OutboundServer/api_template/paths/transfers.yaml +55 -0
- package/OutboundServer/api_template/paths/transfers_transferId.yaml +58 -0
- package/OutboundServer/handlers.js +622 -0
- package/OutboundServer/index.js +137 -0
- package/OutboundServer/middlewares.js +67 -0
- package/TestServer/api.yaml +62 -0
- package/TestServer/handlers.js +63 -0
- package/TestServer/index.js +215 -0
- package/audit-resolve.json +65 -0
- package/babel.config.js +3 -0
- package/config.js +158 -0
- package/index.d.ts +1 -0
- package/index.js +149 -0
- package/jest.config.js +15 -0
- package/lib/api/index.js +12 -0
- package/lib/cache.js +352 -0
- package/lib/check.js +25 -0
- package/lib/model/AccountsModel.js +396 -0
- package/lib/model/Async2SyncModel.js +283 -0
- package/lib/model/AuthorizationsModel.js +86 -0
- package/lib/model/InboundTransfersModel.js +730 -0
- package/lib/model/OutboundBulkQuotesModel.js +485 -0
- package/lib/model/OutboundBulkTransfersModel.js +479 -0
- package/lib/model/OutboundRequestToPayModel.js +517 -0
- package/lib/model/OutboundRequestToPayTransferModel.js +893 -0
- package/lib/model/OutboundTransfersModel.js +823 -0
- package/lib/model/PartiesModel.js +70 -0
- package/lib/model/ProxyModel/MatchRules/Expression.js +48 -0
- package/lib/model/ProxyModel/MatchRules/Headers.js +65 -0
- package/lib/model/ProxyModel/MatchRules/MatchRule.js +27 -0
- package/lib/model/ProxyModel/MatchRules/Path.js +36 -0
- package/lib/model/ProxyModel/MatchRules/Query.js +65 -0
- package/lib/model/ProxyModel/MatchRules/index.js +19 -0
- package/lib/model/ProxyModel/Route.js +82 -0
- package/lib/model/ProxyModel/configSchema.json +118 -0
- package/lib/model/ProxyModel/index.js +138 -0
- package/lib/model/QuotesModel.js +94 -0
- package/lib/model/TransfersModel.js +81 -0
- package/lib/model/common/BackendError.js +26 -0
- package/lib/model/common/PersistentStateMachine.js +93 -0
- package/lib/model/common/index.js +18 -0
- package/lib/model/index.js +43 -0
- package/lib/model/lib/deferredJob.js +113 -0
- package/lib/model/lib/index.js +9 -0
- package/lib/model/lib/requests/backendRequests.js +227 -0
- package/lib/model/lib/requests/common.js +76 -0
- package/lib/model/lib/requests/index.js +19 -0
- package/lib/model/lib/shared.js +468 -0
- package/lib/randomphrase/index.js +21 -0
- package/lib/randomphrase/words.json +3397 -0
- package/lib/router.js +28 -0
- package/lib/validate.js +205 -0
- package/package.json +102 -0
- package/test/__mocks__/@mojaloop/sdk-standard-components.js +152 -0
- package/test/__mocks__/javascript-state-machine.js +21 -0
- package/test/__mocks__/redis.js +49 -0
- package/test/__mocks__/uuidv4.js +16 -0
- package/test/config/integration.env +136 -0
- package/test/integration/lib/Outbound/authorizations.test.js +58 -0
- package/test/integration/lib/Outbound/data/authorizationsPostRequest.json +43 -0
- package/test/integration/lib/Outbound/data/quotesPostRequest.json +52 -0
- package/test/integration/lib/Outbound/data/transfersPostRequest.json +24 -0
- package/test/integration/lib/Outbound/parties.test.js +28 -0
- package/test/integration/lib/Outbound/quotes.test.js +58 -0
- package/test/integration/lib/Outbound/simpleTransfers.test.js +67 -0
- package/test/integration/lib/cache.test.js +80 -0
- package/test/integration/testEnv.js +7 -0
- package/test/unit/InboundServer.test.js +443 -0
- package/test/unit/TestServer.test.js +394 -0
- package/test/unit/api/accounts/accounts.test.js +128 -0
- package/test/unit/api/accounts/data/postAccountsBody.json +7 -0
- package/test/unit/api/accounts/data/postAccountsErrorMojaloopResponse.json +25 -0
- package/test/unit/api/accounts/data/postAccountsErrorTimeoutResponse.json +19 -0
- package/test/unit/api/accounts/data/postAccountsSuccessResponse.json +17 -0
- package/test/unit/api/accounts/data/postAccountsSuccessResponseWithError1.json +21 -0
- package/test/unit/api/accounts/data/postAccountsSuccessResponseWithError2.json +21 -0
- package/test/unit/api/accounts/utils.js +65 -0
- package/test/unit/api/proxy/data/proxyConfig.yaml +82 -0
- package/test/unit/api/proxy/data/requestBody.json +22 -0
- package/test/unit/api/proxy/data/requestHeaders.json +5 -0
- package/test/unit/api/proxy/data/requestQuery.json +6 -0
- package/test/unit/api/proxy/data/responseBody.json +21 -0
- package/test/unit/api/proxy/data/responseHeaders.json +5 -0
- package/test/unit/api/proxy/proxy.test.js +220 -0
- package/test/unit/api/proxy/utils.js +79 -0
- package/test/unit/api/transfers/data/getTransfersCommittedResponse.json +21 -0
- package/test/unit/api/transfers/data/getTransfersErrorNotFound.json +17 -0
- package/test/unit/api/transfers/data/postQuotesBody.json +52 -0
- package/test/unit/api/transfers/data/postTransfersBadBody.json +17 -0
- package/test/unit/api/transfers/data/postTransfersBody.json +24 -0
- package/test/unit/api/transfers/data/postTransfersErrorMojaloopResponse.json +53 -0
- package/test/unit/api/transfers/data/postTransfersErrorTimeoutResponse.json +47 -0
- package/test/unit/api/transfers/data/postTransfersSimpleBody.json +26 -0
- package/test/unit/api/transfers/data/postTransfersSuccessResponse.json +101 -0
- package/test/unit/api/transfers/data/putPartiesBody.json +20 -0
- package/test/unit/api/transfers/data/putQuotesBody.json +37 -0
- package/test/unit/api/transfers/data/putTransfersBody.json +17 -0
- package/test/unit/api/transfers/transfers.test.js +191 -0
- package/test/unit/api/transfers/utils.js +183 -0
- package/test/unit/api/utils.js +75 -0
- package/test/unit/config.test.js +119 -0
- package/test/unit/data/commonHttpHeaders.json +6 -0
- package/test/unit/data/defaultConfig.json +58 -0
- package/test/unit/data/postQuotesBody.json +52 -0
- package/test/unit/data/putParticipantsBody.json +12 -0
- package/test/unit/data/putPartiesBody.json +20 -0
- package/test/unit/data/testFile.json +29 -0
- package/test/unit/data/testFile.yaml +14 -0
- package/test/unit/inboundApi/data/mockArguments.json +117 -0
- package/test/unit/inboundApi/data/mockTransactionRequest.json +42 -0
- package/test/unit/inboundApi/handlers.test.js +799 -0
- package/test/unit/index.test.js +55 -0
- package/test/unit/lib/cache.test.js +146 -0
- package/test/unit/lib/model/AccountsModel.test.js +121 -0
- package/test/unit/lib/model/AuthorizationsModel.test.js +460 -0
- package/test/unit/lib/model/InboundTransfersModel.test.js +628 -0
- package/test/unit/lib/model/OutboundBulkQuotesModel.test.js +249 -0
- package/test/unit/lib/model/OutboundBulkTransfersModel.test.js +244 -0
- package/test/unit/lib/model/OutboundRequestToPayModel.test.js +166 -0
- package/test/unit/lib/model/OutboundRequestToPayTransferModel.test.js +245 -0
- package/test/unit/lib/model/OutboundTransfersModel.test.js +836 -0
- package/test/unit/lib/model/PartiesModel.test.js +468 -0
- package/test/unit/lib/model/QuotesModel.test.js +470 -0
- package/test/unit/lib/model/TransfersModel.test.js +474 -0
- package/test/unit/lib/model/common/PersistentStateMachine.test.js +179 -0
- package/test/unit/lib/model/data/authorizationsResponse.json +13 -0
- package/test/unit/lib/model/data/bulkQuoteRequest.json +27 -0
- package/test/unit/lib/model/data/bulkQuoteResponse.json +35 -0
- package/test/unit/lib/model/data/bulkTransferFulfil.json +13 -0
- package/test/unit/lib/model/data/bulkTransferRequest.json +29 -0
- package/test/unit/lib/model/data/defaultConfig.json +47 -0
- package/test/unit/lib/model/data/getBulkTransfersBackendResponse.json +42 -0
- package/test/unit/lib/model/data/getBulkTransfersMojaloopResponse.json +22 -0
- package/test/unit/lib/model/data/getTransfersBackendResponse.json +34 -0
- package/test/unit/lib/model/data/getTransfersMojaloopResponse.json +17 -0
- package/test/unit/lib/model/data/mockArguments.json +131 -0
- package/test/unit/lib/model/data/mockTxnRequestsArguments.json +63 -0
- package/test/unit/lib/model/data/notificationToPayee.json +10 -0
- package/test/unit/lib/model/data/payeeParty.json +16 -0
- package/test/unit/lib/model/data/putAuthorizationsResponse.json +10 -0
- package/test/unit/lib/model/data/putQuotesResponse.json +33 -0
- package/test/unit/lib/model/data/putTransfersResponse.json +5 -0
- package/test/unit/lib/model/data/quoteResponse.json +31 -0
- package/test/unit/lib/model/data/requestToPayRequest.json +20 -0
- package/test/unit/lib/model/data/requestToPayTransferRequest.json +27 -0
- package/test/unit/lib/model/data/transactionRequestResponse.json +18 -0
- package/test/unit/lib/model/data/transferFulfil.json +8 -0
- package/test/unit/lib/model/data/transferRequest.json +26 -0
- package/test/unit/lib/model/mockedLibRequests.js +74 -0
- package/test/unit/mockLogger.js +39 -0
- package/test/unit/outboundApi/data/bulkQuoteRequest.json +28 -0
- package/test/unit/outboundApi/data/bulkTransferRequest.json +28 -0
- package/test/unit/outboundApi/data/mockBulkQuoteError.json +45 -0
- package/test/unit/outboundApi/data/mockBulkTransferError.json +48 -0
- package/test/unit/outboundApi/data/mockError.json +41 -0
- package/test/unit/outboundApi/data/mockGetPartiesError.json +4 -0
- package/test/unit/outboundApi/data/mockRequestToPayError.json +32 -0
- package/test/unit/outboundApi/data/mockRequestToPayTransferError.json +39 -0
- package/test/unit/outboundApi/data/requestToPay.json +21 -0
- package/test/unit/outboundApi/data/requestToPayTransferRequest.json +20 -0
- package/test/unit/outboundApi/data/transferRequest.json +21 -0
- package/test/unit/outboundApi/handlers.test.js +986 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**************************************************************************
|
|
2
|
+
* (C) Copyright ModusBox Inc. 2020 - All rights reserved. *
|
|
3
|
+
* *
|
|
4
|
+
* This file is made available under the terms of the license agreement *
|
|
5
|
+
* specified in the corresponding source code repository. *
|
|
6
|
+
* *
|
|
7
|
+
* ORIGINAL AUTHOR: *
|
|
8
|
+
* Steven Oderayi - steven.oderayi@modusbox.com *
|
|
9
|
+
**************************************************************************/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
// we use a mock standard components lib to intercept and mock certain funcs
|
|
14
|
+
jest.mock('@mojaloop/sdk-standard-components');
|
|
15
|
+
jest.mock('redis');
|
|
16
|
+
|
|
17
|
+
const Cache = require('../../../../lib/cache');
|
|
18
|
+
const Model = require('../../../../lib/model').OutboundBulkQuotesModel;
|
|
19
|
+
|
|
20
|
+
const { MojaloopRequests, Logger } = require('@mojaloop/sdk-standard-components');
|
|
21
|
+
const StateMachine = require('javascript-state-machine');
|
|
22
|
+
|
|
23
|
+
const defaultConfig = require('./data/defaultConfig');
|
|
24
|
+
const bulkQuoteRequest = require('./data/bulkQuoteRequest');
|
|
25
|
+
const bulkQuoteResponseTemplate = require('./data/bulkQuoteResponse');
|
|
26
|
+
|
|
27
|
+
// util function to simulate a quote response subscription message on a cache client
|
|
28
|
+
const emitBulkQuoteResponseCacheMessage = (cache, bulkQuoteId, bulkQuoteResponse) => {
|
|
29
|
+
cache.publish(`bulkQuote_${bulkQuoteId}`, JSON.stringify(bulkQuoteResponse));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
describe('OutboundBulkQuotesModel', () => {
|
|
33
|
+
let bulkQuoteResponse;
|
|
34
|
+
let config;
|
|
35
|
+
let logger;
|
|
36
|
+
let cache;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @param {Object} opts
|
|
41
|
+
* @param {Number} opts.expirySeconds
|
|
42
|
+
* @param {Object} opts.delays
|
|
43
|
+
* @param {Number} delays.requestBulkQuotes
|
|
44
|
+
* @param {Object} opts.rejects
|
|
45
|
+
* @param {boolean} rejects.bulkQuoteResponse
|
|
46
|
+
*/
|
|
47
|
+
async function testBulkQuoteWithDelay({expirySeconds, delays, rejects}) {
|
|
48
|
+
const config = JSON.parse(JSON.stringify(defaultConfig));
|
|
49
|
+
config.expirySeconds = expirySeconds;
|
|
50
|
+
config.rejectExpiredQuoteResponses = rejects.bulkQuoteResponse;
|
|
51
|
+
|
|
52
|
+
// simulate a delayed callback with the bulk quote response
|
|
53
|
+
MojaloopRequests.__postBulkQuotes = jest.fn((postBulkQuotesBody) => {
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
emitBulkQuoteResponseCacheMessage(cache, postBulkQuotesBody.bulkQuoteId, bulkQuoteResponse);
|
|
56
|
+
}, delays.requestBulkQuotes ? delays.requestBulkQuotes * 1000 : 0);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const model = new Model({
|
|
60
|
+
...config,
|
|
61
|
+
cache,
|
|
62
|
+
logger,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkQuoteRequest)));
|
|
66
|
+
|
|
67
|
+
let expectError;
|
|
68
|
+
|
|
69
|
+
if (rejects.bulkQuoteResponse && delays.requestBulkQuotes && expirySeconds < delays.requestBulkQuotes) {
|
|
70
|
+
expectError = 'Bulk quote response missed expiry deadline';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (expectError) {
|
|
74
|
+
await expect(model.run()).rejects.toThrowError(expectError);
|
|
75
|
+
} else {
|
|
76
|
+
const result = await model.run();
|
|
77
|
+
await expect(result.currentState).toBe('COMPLETED');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
beforeAll(async () => {
|
|
82
|
+
logger = new Logger.Logger({ context: { app: 'outbound-model-unit-tests-cache' }, stringify: () => '' });
|
|
83
|
+
bulkQuoteResponse = JSON.parse(JSON.stringify(bulkQuoteResponseTemplate));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
beforeEach(async () => {
|
|
87
|
+
config = JSON.parse(JSON.stringify(defaultConfig));
|
|
88
|
+
|
|
89
|
+
MojaloopRequests.__postBulkQuotes = jest.fn(() => Promise.resolve());
|
|
90
|
+
MojaloopRequests.__putBulkQuotes = jest.fn(() => Promise.resolve());
|
|
91
|
+
MojaloopRequests.__putBulkQuotesError = jest.fn(() => Promise.resolve());
|
|
92
|
+
|
|
93
|
+
cache = new Cache({
|
|
94
|
+
host: 'dummycachehost',
|
|
95
|
+
port: 1234,
|
|
96
|
+
logger,
|
|
97
|
+
});
|
|
98
|
+
await cache.connect();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
afterEach(async () => {
|
|
102
|
+
await cache.disconnect();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('initializes to starting state', async () => {
|
|
106
|
+
const model = new Model({
|
|
107
|
+
cache,
|
|
108
|
+
logger,
|
|
109
|
+
...config,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkQuoteRequest)));
|
|
113
|
+
expect(StateMachine.__instance.state).toBe('start');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('test get bulk quote', async () => {
|
|
117
|
+
MojaloopRequests.__getBulkQuotes = jest.fn((bulkQuoteId) => {
|
|
118
|
+
emitBulkQuoteResponseCacheMessage(cache, bulkQuoteId, bulkQuoteResponse);
|
|
119
|
+
return Promise.resolve();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const model = new Model({
|
|
123
|
+
cache,
|
|
124
|
+
logger,
|
|
125
|
+
...config,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const BULK_QUOTE_ID = 'bq-id000011';
|
|
129
|
+
|
|
130
|
+
await model.initialize(JSON.parse(JSON.stringify({
|
|
131
|
+
currentState: 'getBulkQuote',
|
|
132
|
+
bulkQuoteId: BULK_QUOTE_ID,
|
|
133
|
+
})));
|
|
134
|
+
|
|
135
|
+
expect(StateMachine.__instance.state).toBe('getBulkQuote');
|
|
136
|
+
|
|
137
|
+
// start the model running
|
|
138
|
+
const result = await model.run();
|
|
139
|
+
|
|
140
|
+
expect(MojaloopRequests.__getBulkQuotes).toHaveBeenCalledTimes(1);
|
|
141
|
+
|
|
142
|
+
// check we stopped at succeeded state
|
|
143
|
+
expect(result.currentState).toBe('COMPLETED');
|
|
144
|
+
expect(StateMachine.__instance.state).toBe('succeeded');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('sends bulk quotes request with correct payload', async () => {
|
|
148
|
+
MojaloopRequests.__postBulkQuotes = jest.fn((postBulkQuotesBody) => {
|
|
149
|
+
// ensure that the `MojaloopRequests.postBulkQuotes` method has been called with correct arguments
|
|
150
|
+
// including extension list
|
|
151
|
+
const extensionList = postBulkQuotesBody.extensionList.extension;
|
|
152
|
+
expect(extensionList).toBeTruthy();
|
|
153
|
+
expect(extensionList.length).toBe(2);
|
|
154
|
+
expect(extensionList[0]).toEqual({ key: 'qkey1', value: 'qvalue1' });
|
|
155
|
+
expect(extensionList[1]).toEqual({ key: 'qkey2', value: 'qvalue2' });
|
|
156
|
+
|
|
157
|
+
// simulate a callback with the bulk quote response
|
|
158
|
+
emitBulkQuoteResponseCacheMessage(cache, postBulkQuotesBody.bulkQuoteId, bulkQuoteResponse);
|
|
159
|
+
return Promise.resolve();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const model = new Model({
|
|
163
|
+
cache,
|
|
164
|
+
logger,
|
|
165
|
+
...config,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkQuoteRequest)));
|
|
169
|
+
|
|
170
|
+
expect(StateMachine.__instance.state).toBe('start');
|
|
171
|
+
|
|
172
|
+
// start the model running
|
|
173
|
+
const result = await model.run();
|
|
174
|
+
|
|
175
|
+
expect(MojaloopRequests.__postBulkQuotes).toHaveBeenCalledTimes(1);
|
|
176
|
+
|
|
177
|
+
// check we stopped at 'succeeded' state
|
|
178
|
+
expect(result.currentState).toBe('COMPLETED');
|
|
179
|
+
expect(StateMachine.__instance.state).toBe('succeeded');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('pass quote response `expiration` deadline', () =>
|
|
183
|
+
testBulkQuoteWithDelay({
|
|
184
|
+
expirySeconds: 2,
|
|
185
|
+
delays: {
|
|
186
|
+
requestBulkQuotes: 1,
|
|
187
|
+
},
|
|
188
|
+
rejects: {
|
|
189
|
+
bulkQuoteResponse: true,
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
test('fail on quote response `expiration` deadline', () =>
|
|
195
|
+
testBulkQuoteWithDelay({
|
|
196
|
+
expirySeconds: 1,
|
|
197
|
+
delays: {
|
|
198
|
+
requestBulkQuotes: 2,
|
|
199
|
+
},
|
|
200
|
+
rejects: {
|
|
201
|
+
bulkQuoteResponse: true,
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
test('Throws with mojaloop error in response body when quote request error callback occurs', async () => {
|
|
207
|
+
const expectError = {
|
|
208
|
+
type: 'bulkQuoteResponseError',
|
|
209
|
+
data: {
|
|
210
|
+
errorInformation: {
|
|
211
|
+
errorCode: '3205',
|
|
212
|
+
errorDescription: 'Bulk quote ID not found'
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
MojaloopRequests.__postBulkQuotes = jest.fn((postBulkQuotesBody) => {
|
|
218
|
+
// simulate a callback with the bulk quote response
|
|
219
|
+
cache.publish(`bulkQuote_${postBulkQuotesBody.bulkQuoteId}`, JSON.stringify(expectError));
|
|
220
|
+
return Promise.resolve();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const model = new Model({
|
|
224
|
+
cache,
|
|
225
|
+
logger,
|
|
226
|
+
...config,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkQuoteRequest)));
|
|
230
|
+
|
|
231
|
+
expect(StateMachine.__instance.state).toBe('start');
|
|
232
|
+
|
|
233
|
+
const errMsg = 'Got an error response requesting bulk quote: { errorInformation:\n { errorCode: \'3205\', errorDescription: \'Bulk quote ID not found\' } }';
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
await model.run();
|
|
237
|
+
}
|
|
238
|
+
catch(err) {
|
|
239
|
+
expect(err.message.replace(/[ \n]/g,'')).toEqual(errMsg.replace(/[ \n]/g,''));
|
|
240
|
+
expect(err.bulkQuoteState).toBeTruthy();
|
|
241
|
+
expect(err.bulkQuoteState.lastError).toBeTruthy();
|
|
242
|
+
expect(err.bulkQuoteState.lastError.mojaloopError).toEqual(expectError.data);
|
|
243
|
+
expect(err.bulkQuoteState.lastError.bulkQuoteState).toBe(undefined);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
throw new Error('Outbound bulk quotes model should have thrown');
|
|
248
|
+
});
|
|
249
|
+
});
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**************************************************************************
|
|
2
|
+
* (C) Copyright ModusBox Inc. 2020 - All rights reserved. *
|
|
3
|
+
* *
|
|
4
|
+
* This file is made available under the terms of the license agreement *
|
|
5
|
+
* specified in the corresponding source code repository. *
|
|
6
|
+
* *
|
|
7
|
+
* ORIGINAL AUTHOR: *
|
|
8
|
+
* Steven Oderayi - steven.oderayi@modusbox.com *
|
|
9
|
+
**************************************************************************/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
// we use a mock standard components lib to intercept and mock certain funcs
|
|
14
|
+
jest.mock('@mojaloop/sdk-standard-components');
|
|
15
|
+
jest.mock('redis');
|
|
16
|
+
|
|
17
|
+
const Cache = require('../../../../lib/cache');
|
|
18
|
+
const Model = require('../../../../lib/model').OutboundBulkTransfersModel;
|
|
19
|
+
|
|
20
|
+
const { MojaloopRequests, Logger } = require('@mojaloop/sdk-standard-components');
|
|
21
|
+
const StateMachine = require('javascript-state-machine');
|
|
22
|
+
|
|
23
|
+
const defaultConfig = require('./data/defaultConfig');
|
|
24
|
+
const bulkTransferRequest = require('./data/bulkTransferRequest');
|
|
25
|
+
const bulkTransferFulfil = require('./data/bulkTransferFulfil');
|
|
26
|
+
|
|
27
|
+
// util function to simulate a bulk transfer fulfilment subscription message on a cache client
|
|
28
|
+
const emitBulkTransferFulfilCacheMessage = (cache, bulkTransferId, fulfils) => cache.publish(`bulkTransfer_${bulkTransferId}`, JSON.stringify(fulfils));
|
|
29
|
+
|
|
30
|
+
describe('outboundBulkTransferModel', () => {
|
|
31
|
+
let config;
|
|
32
|
+
let logger;
|
|
33
|
+
let cache;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param {Object} opts
|
|
38
|
+
* @param {Number} opts.expirySeconds
|
|
39
|
+
* @param {Object} opts.delays
|
|
40
|
+
* @param {Number} delays.prepareTransfer
|
|
41
|
+
* @param {Object} opts.rejects
|
|
42
|
+
* @param {boolean} rejects.transferFulfils
|
|
43
|
+
*/
|
|
44
|
+
async function testBulkTransferWithDelay({expirySeconds, delays, rejects}) {
|
|
45
|
+
const config = JSON.parse(JSON.stringify(defaultConfig));
|
|
46
|
+
config.expirySeconds = expirySeconds;
|
|
47
|
+
config.rejectExpiredTransferFulfils = rejects.transferFulfils;
|
|
48
|
+
|
|
49
|
+
// simulate a delayed callback with the bulk transfer fulfilments
|
|
50
|
+
MojaloopRequests.__postBulkTransfers = jest.fn((postBulkTransfersBody) => {
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
emitBulkTransferFulfilCacheMessage(cache, postBulkTransfersBody.bulkTransferId, bulkTransferFulfil);
|
|
53
|
+
}, delays.prepareTransfer ? delays.prepareTransfer * 1000 : 0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const model = new Model({
|
|
57
|
+
...config,
|
|
58
|
+
cache,
|
|
59
|
+
logger,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkTransferRequest)));
|
|
63
|
+
|
|
64
|
+
let expectError;
|
|
65
|
+
|
|
66
|
+
if (rejects.transferFulfils && delays.prepareTransfer && expirySeconds < delays.prepareTransfer) {
|
|
67
|
+
expectError = 'Bulk transfer fulfils missed expiry deadline';
|
|
68
|
+
}
|
|
69
|
+
if (expectError) {
|
|
70
|
+
await expect(model.run()).rejects.toThrowError(expectError);
|
|
71
|
+
} else {
|
|
72
|
+
const result = await model.run();
|
|
73
|
+
await expect(result.currentState).toBe('COMPLETED');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
beforeAll(async () => {
|
|
78
|
+
logger = new Logger.Logger({ context: { app: 'outbound-model-unit-tests-cache' }, stringify: () => '' });
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
beforeEach(async () => {
|
|
82
|
+
config = JSON.parse(JSON.stringify(defaultConfig));
|
|
83
|
+
MojaloopRequests.__postBulkTransfers = jest.fn(() => Promise.resolve());
|
|
84
|
+
|
|
85
|
+
cache = new Cache({
|
|
86
|
+
host: 'dummycachehost',
|
|
87
|
+
port: 1234,
|
|
88
|
+
logger,
|
|
89
|
+
});
|
|
90
|
+
await cache.connect();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
afterEach(async () => {
|
|
94
|
+
await cache.disconnect();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('initializes to starting state', async () => {
|
|
98
|
+
const model = new Model({
|
|
99
|
+
cache,
|
|
100
|
+
logger,
|
|
101
|
+
...config,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkTransferRequest)));
|
|
105
|
+
expect(StateMachine.__instance.state).toBe('start');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
test('executes bulk transfer', async () => {
|
|
110
|
+
MojaloopRequests.__postBulkTransfers = jest.fn((postBulkTransfersBody) => {
|
|
111
|
+
//ensure that the `MojaloopRequests.postBulkTransfers` method has been called with the correct arguments
|
|
112
|
+
// set as the destination FSPID
|
|
113
|
+
const extensionList = postBulkTransfersBody.extensionList.extension;
|
|
114
|
+
expect(extensionList).toBeTruthy();
|
|
115
|
+
expect(extensionList.length).toBe(2);
|
|
116
|
+
expect(extensionList[0]).toEqual({ key: 'tkey1', value: 'tvalue1' });
|
|
117
|
+
expect(extensionList[1]).toEqual({ key: 'tkey2', value: 'tvalue2' });
|
|
118
|
+
|
|
119
|
+
// simulate a callback with the transfer fulfilment
|
|
120
|
+
emitBulkTransferFulfilCacheMessage(cache, postBulkTransfersBody.bulkTransferId, bulkTransferFulfil);
|
|
121
|
+
return Promise.resolve();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const model = new Model({
|
|
125
|
+
cache,
|
|
126
|
+
logger,
|
|
127
|
+
...config,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkTransferRequest)));
|
|
131
|
+
|
|
132
|
+
expect(StateMachine.__instance.state).toBe('start');
|
|
133
|
+
|
|
134
|
+
// start the model running
|
|
135
|
+
const result = await model.run();
|
|
136
|
+
|
|
137
|
+
expect(MojaloopRequests.__postBulkTransfers).toHaveBeenCalledTimes(1);
|
|
138
|
+
|
|
139
|
+
// check we stopped at succeeded state
|
|
140
|
+
expect(result.currentState).toBe('COMPLETED');
|
|
141
|
+
expect(StateMachine.__instance.state).toBe('succeeded');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('test get bulk transfer', async () => {
|
|
145
|
+
MojaloopRequests.__getBulkTransfers = jest.fn((bulkTransferId) => {
|
|
146
|
+
emitBulkTransferFulfilCacheMessage(cache, bulkTransferId, bulkTransferFulfil);
|
|
147
|
+
return Promise.resolve();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const model = new Model({
|
|
151
|
+
cache,
|
|
152
|
+
logger,
|
|
153
|
+
...config,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const BULK_TRANSFER_ID = 'btx-id000011';
|
|
157
|
+
|
|
158
|
+
await model.initialize(JSON.parse(JSON.stringify({
|
|
159
|
+
...bulkTransferRequest,
|
|
160
|
+
currentState: 'getBulkTransfer',
|
|
161
|
+
bulkTransferId: BULK_TRANSFER_ID,
|
|
162
|
+
})));
|
|
163
|
+
|
|
164
|
+
expect(StateMachine.__instance.state).toBe('getBulkTransfer');
|
|
165
|
+
|
|
166
|
+
// start the model running
|
|
167
|
+
const result = await model.run();
|
|
168
|
+
|
|
169
|
+
expect(MojaloopRequests.__getBulkTransfers).toHaveBeenCalledTimes(1);
|
|
170
|
+
|
|
171
|
+
// check we stopped at succeeded state
|
|
172
|
+
expect(result.currentState).toBe('COMPLETED');
|
|
173
|
+
expect(StateMachine.__instance.state).toBe('succeeded');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('pass transfer fulfills `expiration` deadline', () =>
|
|
177
|
+
testBulkTransferWithDelay({
|
|
178
|
+
expirySeconds: 2,
|
|
179
|
+
delays: {
|
|
180
|
+
prepareTransfer: 1,
|
|
181
|
+
},
|
|
182
|
+
rejects: {
|
|
183
|
+
transferFulfils: true,
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
test('fail on transfer fulfills `expiration` deadline', () =>
|
|
189
|
+
testBulkTransferWithDelay({
|
|
190
|
+
expirySeconds: 1,
|
|
191
|
+
delays: {
|
|
192
|
+
prepareTransfer: 2,
|
|
193
|
+
},
|
|
194
|
+
rejects: {
|
|
195
|
+
transferFulfils: true,
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
test('Throws with mojaloop error in response body when transfer request error callback occurs', async () => {
|
|
202
|
+
const expectError = {
|
|
203
|
+
type: 'bulkTransferError',
|
|
204
|
+
data: {
|
|
205
|
+
errorInformation: {
|
|
206
|
+
errorCode: '4001',
|
|
207
|
+
errorDescription: 'Payer FSP insufficient liquidity'
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
MojaloopRequests.__postBulkTransfers = jest.fn((postBulkTransfersBody) => {
|
|
213
|
+
// simulate an error callback with the transfer fulfilments
|
|
214
|
+
cache.publish(`bulkTransfer_${postBulkTransfersBody.bulkTransferId}`, JSON.stringify(expectError));
|
|
215
|
+
return Promise.resolve();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const model = new Model({
|
|
219
|
+
cache,
|
|
220
|
+
logger,
|
|
221
|
+
...config,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
await model.initialize(JSON.parse(JSON.stringify(bulkTransferRequest)));
|
|
225
|
+
|
|
226
|
+
expect(StateMachine.__instance.state).toBe('start');
|
|
227
|
+
|
|
228
|
+
const errMsg = 'Got an error response preparing bulk transfer: { errorInformation:\n { errorCode: \'4001\',\n errorDescription: \'Payer FSP insufficient liquidity\' } }';
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
await model.run();
|
|
232
|
+
}
|
|
233
|
+
catch(err) {
|
|
234
|
+
expect(err.message.replace(/[ \n]/g,'')).toEqual(errMsg.replace(/[ \n]/g,''));
|
|
235
|
+
expect(err.bulkTransferState).toBeTruthy();
|
|
236
|
+
expect(err.bulkTransferState.lastError).toBeTruthy();
|
|
237
|
+
expect(err.bulkTransferState.lastError.mojaloopError).toEqual(expectError.data);
|
|
238
|
+
expect(err.bulkTransferState.lastError.bulkTransferState).toBe(undefined);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
throw new Error('Outbound model should have thrown');
|
|
243
|
+
});
|
|
244
|
+
});
|