@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.
Files changed (277) hide show
  1. package/.env.example +140 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc.json +30 -0
  4. package/.nvmrc +1 -0
  5. package/.versionrc +15 -0
  6. package/CHANGELOG.md +118 -0
  7. package/InboundServer/api.yaml +3594 -0
  8. package/InboundServer/api_template.yaml +69 -0
  9. package/InboundServer/handlers.js +940 -0
  10. package/InboundServer/index.js +205 -0
  11. package/InboundServer/middlewares.js +426 -0
  12. package/OAuthTestServer/index.js +66 -0
  13. package/OAuthTestServer/model.js +70 -0
  14. package/OutboundServer/api.yaml +2732 -0
  15. package/OutboundServer/api_interfaces/index.d.ts +117 -0
  16. package/OutboundServer/api_interfaces/openapi.d.ts +1475 -0
  17. package/OutboundServer/api_template/components/parameters/bulkQuoteId.yaml +9 -0
  18. package/OutboundServer/api_template/components/parameters/bulkTransferId.yaml +9 -0
  19. package/OutboundServer/api_template/components/parameters/requestToPayTransactionId.yaml +9 -0
  20. package/OutboundServer/api_template/components/parameters/transferId.yaml +9 -0
  21. package/OutboundServer/api_template/components/responses/accountsCreationCompleted.yaml +5 -0
  22. package/OutboundServer/api_template/components/responses/accountsCreationError.yaml +5 -0
  23. package/OutboundServer/api_template/components/responses/accountsCreationTimeout.yaml +5 -0
  24. package/OutboundServer/api_template/components/responses/authorizationPostSuccess.yaml +5 -0
  25. package/OutboundServer/api_template/components/responses/authorizationsServerError.yaml +5 -0
  26. package/OutboundServer/api_template/components/responses/bulkQuoteBadRequest.yaml +5 -0
  27. package/OutboundServer/api_template/components/responses/bulkQuoteServerError.yaml +5 -0
  28. package/OutboundServer/api_template/components/responses/bulkQuoteSuccess.yaml +5 -0
  29. package/OutboundServer/api_template/components/responses/bulkQuoteTimeout.yaml +5 -0
  30. package/OutboundServer/api_template/components/responses/bulkTransferBadRequest.yaml +5 -0
  31. package/OutboundServer/api_template/components/responses/bulkTransferServerError.yaml +5 -0
  32. package/OutboundServer/api_template/components/responses/bulkTransferSuccess.yaml +5 -0
  33. package/OutboundServer/api_template/components/responses/bulkTransferTimeout.yaml +5 -0
  34. package/OutboundServer/api_template/components/responses/partiesByIdError404.yaml +9 -0
  35. package/OutboundServer/api_template/components/responses/partiesByIdSuccess.yaml +5 -0
  36. package/OutboundServer/api_template/components/responses/quotesPostSuccess.yaml +5 -0
  37. package/OutboundServer/api_template/components/responses/quotesServerError.yaml +5 -0
  38. package/OutboundServer/api_template/components/responses/requestToPaySuccess.yaml +5 -0
  39. package/OutboundServer/api_template/components/responses/requestToPayTransferBadRequest.yaml +5 -0
  40. package/OutboundServer/api_template/components/responses/requestToPayTransferSuccess.yaml +5 -0
  41. package/OutboundServer/api_template/components/responses/simpleTransfersPostSuccess.yaml +5 -0
  42. package/OutboundServer/api_template/components/responses/simpleTransfersServerError.yaml +5 -0
  43. package/OutboundServer/api_template/components/responses/transferBadRequest.yaml +5 -0
  44. package/OutboundServer/api_template/components/responses/transferServerError.yaml +5 -0
  45. package/OutboundServer/api_template/components/responses/transferSuccess.yaml +5 -0
  46. package/OutboundServer/api_template/components/responses/transferTimeout.yaml +5 -0
  47. package/OutboundServer/api_template/components/schemas/accountCreationStatus.yaml +18 -0
  48. package/OutboundServer/api_template/components/schemas/accountsCreationState.yaml +4 -0
  49. package/OutboundServer/api_template/components/schemas/accountsRequest.yaml +20 -0
  50. package/OutboundServer/api_template/components/schemas/accountsResponse.yaml +15 -0
  51. package/OutboundServer/api_template/components/schemas/async2SyncCurrentState.yaml +5 -0
  52. package/OutboundServer/api_template/components/schemas/authorizationsPostRequest.yaml +15 -0
  53. package/OutboundServer/api_template/components/schemas/authorizationsPostResponse.yaml +19 -0
  54. package/OutboundServer/api_template/components/schemas/bulkQuoteErrorResponse.yaml +8 -0
  55. package/OutboundServer/api_template/components/schemas/bulkQuoteRequest.yaml +26 -0
  56. package/OutboundServer/api_template/components/schemas/bulkQuoteResponse.yaml +21 -0
  57. package/OutboundServer/api_template/components/schemas/bulkQuoteStatus.yaml +4 -0
  58. package/OutboundServer/api_template/components/schemas/bulkQuoteStatusResponse.yaml +17 -0
  59. package/OutboundServer/api_template/components/schemas/bulkTransferErrorResponse.yaml +8 -0
  60. package/OutboundServer/api_template/components/schemas/bulkTransferRequest.yaml +26 -0
  61. package/OutboundServer/api_template/components/schemas/bulkTransferResponse.yaml +16 -0
  62. package/OutboundServer/api_template/components/schemas/bulkTransferStatus.yaml +4 -0
  63. package/OutboundServer/api_template/components/schemas/bulkTransferStatusResponse.yaml +17 -0
  64. package/OutboundServer/api_template/components/schemas/errorAccountsResponse.yaml +8 -0
  65. package/OutboundServer/api_template/components/schemas/errorAuthorizationsResponse.yaml +3 -0
  66. package/OutboundServer/api_template/components/schemas/errorQuotesResponse.yaml +9 -0
  67. package/OutboundServer/api_template/components/schemas/errorResponse.yaml +8 -0
  68. package/OutboundServer/api_template/components/schemas/errorSimpleTransfersResponse.yaml +3 -0
  69. package/OutboundServer/api_template/components/schemas/errorTransferResponse.yaml +8 -0
  70. package/OutboundServer/api_template/components/schemas/extensionListEmptiable.yaml +6 -0
  71. package/OutboundServer/api_template/components/schemas/individualQuote.yaml +32 -0
  72. package/OutboundServer/api_template/components/schemas/individualQuoteResult.yaml +28 -0
  73. package/OutboundServer/api_template/components/schemas/individualTransfer.yaml +32 -0
  74. package/OutboundServer/api_template/components/schemas/individualTransferFulfilment.yaml +13 -0
  75. package/OutboundServer/api_template/components/schemas/individualTransferResult.yaml +41 -0
  76. package/OutboundServer/api_template/components/schemas/mojaloopError.yaml +5 -0
  77. package/OutboundServer/api_template/components/schemas/mojaloopTransactionRequestState.yaml +2 -0
  78. package/OutboundServer/api_template/components/schemas/partiesByIdResponse.yaml +13 -0
  79. package/OutboundServer/api_template/components/schemas/quote.yaml +3 -0
  80. package/OutboundServer/api_template/components/schemas/quoteError.yaml +16 -0
  81. package/OutboundServer/api_template/components/schemas/quotesPostRequest.yaml +13 -0
  82. package/OutboundServer/api_template/components/schemas/quotesPostResponse.yaml +48 -0
  83. package/OutboundServer/api_template/components/schemas/requestToPayRequest.yaml +39 -0
  84. package/OutboundServer/api_template/components/schemas/requestToPayResponse.yaml +41 -0
  85. package/OutboundServer/api_template/components/schemas/requestToPayTransferRequest.yaml +42 -0
  86. package/OutboundServer/api_template/components/schemas/requestToPayTransferResponse.yaml +58 -0
  87. package/OutboundServer/api_template/components/schemas/simpleTransferServerError.yaml +5 -0
  88. package/OutboundServer/api_template/components/schemas/simpleTransfersPostRequest.yaml +12 -0
  89. package/OutboundServer/api_template/components/schemas/simpleTransfersPostResponse.yaml +11 -0
  90. package/OutboundServer/api_template/components/schemas/transactionType.yaml +4 -0
  91. package/OutboundServer/api_template/components/schemas/transferContinuationAcceptOTP.yaml +9 -0
  92. package/OutboundServer/api_template/components/schemas/transferContinuationAcceptParty.yaml +8 -0
  93. package/OutboundServer/api_template/components/schemas/transferContinuationAcceptQuote.yaml +9 -0
  94. package/OutboundServer/api_template/components/schemas/transferError.yaml +16 -0
  95. package/OutboundServer/api_template/components/schemas/transferFulfilment.yaml +3 -0
  96. package/OutboundServer/api_template/components/schemas/transferParty.yaml +40 -0
  97. package/OutboundServer/api_template/components/schemas/transferRequest.yaml +37 -0
  98. package/OutboundServer/api_template/components/schemas/transferResponse.yaml +58 -0
  99. package/OutboundServer/api_template/components/schemas/transferStatus.yaml +6 -0
  100. package/OutboundServer/api_template/components/schemas/transferStatusResponse.yaml +13 -0
  101. package/OutboundServer/api_template/health.yaml +12 -0
  102. package/OutboundServer/api_template/openapi.yaml +55 -0
  103. package/OutboundServer/api_template/paths/accounts.yaml +26 -0
  104. package/OutboundServer/api_template/paths/authorizations.yaml +19 -0
  105. package/OutboundServer/api_template/paths/bulkQuotes.yaml +23 -0
  106. package/OutboundServer/api_template/paths/bulkQuotes_bulkQuoteId.yaml +24 -0
  107. package/OutboundServer/api_template/paths/bulkTransfers.yaml +23 -0
  108. package/OutboundServer/api_template/paths/bulkTransfers_bulkTransferId.yaml +24 -0
  109. package/OutboundServer/api_template/paths/parties_Type_ID.yaml +20 -0
  110. package/OutboundServer/api_template/paths/parties_Type_ID_SubId.yaml +22 -0
  111. package/OutboundServer/api_template/paths/quotes.yaml +20 -0
  112. package/OutboundServer/api_template/paths/requestToPay.yaml +22 -0
  113. package/OutboundServer/api_template/paths/requestToPayTransfer.yaml +57 -0
  114. package/OutboundServer/api_template/paths/requestToPayTransfer_requestToPayTransactionId.yaml +34 -0
  115. package/OutboundServer/api_template/paths/simpleTransfers.yaml +19 -0
  116. package/OutboundServer/api_template/paths/transfers.yaml +55 -0
  117. package/OutboundServer/api_template/paths/transfers_transferId.yaml +58 -0
  118. package/OutboundServer/handlers.js +622 -0
  119. package/OutboundServer/index.js +137 -0
  120. package/OutboundServer/middlewares.js +67 -0
  121. package/TestServer/api.yaml +62 -0
  122. package/TestServer/handlers.js +63 -0
  123. package/TestServer/index.js +215 -0
  124. package/audit-resolve.json +65 -0
  125. package/babel.config.js +3 -0
  126. package/config.js +158 -0
  127. package/index.d.ts +1 -0
  128. package/index.js +149 -0
  129. package/jest.config.js +15 -0
  130. package/lib/api/index.js +12 -0
  131. package/lib/cache.js +352 -0
  132. package/lib/check.js +25 -0
  133. package/lib/model/AccountsModel.js +396 -0
  134. package/lib/model/Async2SyncModel.js +283 -0
  135. package/lib/model/AuthorizationsModel.js +86 -0
  136. package/lib/model/InboundTransfersModel.js +730 -0
  137. package/lib/model/OutboundBulkQuotesModel.js +485 -0
  138. package/lib/model/OutboundBulkTransfersModel.js +479 -0
  139. package/lib/model/OutboundRequestToPayModel.js +517 -0
  140. package/lib/model/OutboundRequestToPayTransferModel.js +893 -0
  141. package/lib/model/OutboundTransfersModel.js +823 -0
  142. package/lib/model/PartiesModel.js +70 -0
  143. package/lib/model/ProxyModel/MatchRules/Expression.js +48 -0
  144. package/lib/model/ProxyModel/MatchRules/Headers.js +65 -0
  145. package/lib/model/ProxyModel/MatchRules/MatchRule.js +27 -0
  146. package/lib/model/ProxyModel/MatchRules/Path.js +36 -0
  147. package/lib/model/ProxyModel/MatchRules/Query.js +65 -0
  148. package/lib/model/ProxyModel/MatchRules/index.js +19 -0
  149. package/lib/model/ProxyModel/Route.js +82 -0
  150. package/lib/model/ProxyModel/configSchema.json +118 -0
  151. package/lib/model/ProxyModel/index.js +138 -0
  152. package/lib/model/QuotesModel.js +94 -0
  153. package/lib/model/TransfersModel.js +81 -0
  154. package/lib/model/common/BackendError.js +26 -0
  155. package/lib/model/common/PersistentStateMachine.js +93 -0
  156. package/lib/model/common/index.js +18 -0
  157. package/lib/model/index.js +43 -0
  158. package/lib/model/lib/deferredJob.js +113 -0
  159. package/lib/model/lib/index.js +9 -0
  160. package/lib/model/lib/requests/backendRequests.js +227 -0
  161. package/lib/model/lib/requests/common.js +76 -0
  162. package/lib/model/lib/requests/index.js +19 -0
  163. package/lib/model/lib/shared.js +468 -0
  164. package/lib/randomphrase/index.js +21 -0
  165. package/lib/randomphrase/words.json +3397 -0
  166. package/lib/router.js +28 -0
  167. package/lib/validate.js +205 -0
  168. package/package.json +102 -0
  169. package/test/__mocks__/@mojaloop/sdk-standard-components.js +152 -0
  170. package/test/__mocks__/javascript-state-machine.js +21 -0
  171. package/test/__mocks__/redis.js +49 -0
  172. package/test/__mocks__/uuidv4.js +16 -0
  173. package/test/config/integration.env +136 -0
  174. package/test/integration/lib/Outbound/authorizations.test.js +58 -0
  175. package/test/integration/lib/Outbound/data/authorizationsPostRequest.json +43 -0
  176. package/test/integration/lib/Outbound/data/quotesPostRequest.json +52 -0
  177. package/test/integration/lib/Outbound/data/transfersPostRequest.json +24 -0
  178. package/test/integration/lib/Outbound/parties.test.js +28 -0
  179. package/test/integration/lib/Outbound/quotes.test.js +58 -0
  180. package/test/integration/lib/Outbound/simpleTransfers.test.js +67 -0
  181. package/test/integration/lib/cache.test.js +80 -0
  182. package/test/integration/testEnv.js +7 -0
  183. package/test/unit/InboundServer.test.js +443 -0
  184. package/test/unit/TestServer.test.js +394 -0
  185. package/test/unit/api/accounts/accounts.test.js +128 -0
  186. package/test/unit/api/accounts/data/postAccountsBody.json +7 -0
  187. package/test/unit/api/accounts/data/postAccountsErrorMojaloopResponse.json +25 -0
  188. package/test/unit/api/accounts/data/postAccountsErrorTimeoutResponse.json +19 -0
  189. package/test/unit/api/accounts/data/postAccountsSuccessResponse.json +17 -0
  190. package/test/unit/api/accounts/data/postAccountsSuccessResponseWithError1.json +21 -0
  191. package/test/unit/api/accounts/data/postAccountsSuccessResponseWithError2.json +21 -0
  192. package/test/unit/api/accounts/utils.js +65 -0
  193. package/test/unit/api/proxy/data/proxyConfig.yaml +82 -0
  194. package/test/unit/api/proxy/data/requestBody.json +22 -0
  195. package/test/unit/api/proxy/data/requestHeaders.json +5 -0
  196. package/test/unit/api/proxy/data/requestQuery.json +6 -0
  197. package/test/unit/api/proxy/data/responseBody.json +21 -0
  198. package/test/unit/api/proxy/data/responseHeaders.json +5 -0
  199. package/test/unit/api/proxy/proxy.test.js +220 -0
  200. package/test/unit/api/proxy/utils.js +79 -0
  201. package/test/unit/api/transfers/data/getTransfersCommittedResponse.json +21 -0
  202. package/test/unit/api/transfers/data/getTransfersErrorNotFound.json +17 -0
  203. package/test/unit/api/transfers/data/postQuotesBody.json +52 -0
  204. package/test/unit/api/transfers/data/postTransfersBadBody.json +17 -0
  205. package/test/unit/api/transfers/data/postTransfersBody.json +24 -0
  206. package/test/unit/api/transfers/data/postTransfersErrorMojaloopResponse.json +53 -0
  207. package/test/unit/api/transfers/data/postTransfersErrorTimeoutResponse.json +47 -0
  208. package/test/unit/api/transfers/data/postTransfersSimpleBody.json +26 -0
  209. package/test/unit/api/transfers/data/postTransfersSuccessResponse.json +101 -0
  210. package/test/unit/api/transfers/data/putPartiesBody.json +20 -0
  211. package/test/unit/api/transfers/data/putQuotesBody.json +37 -0
  212. package/test/unit/api/transfers/data/putTransfersBody.json +17 -0
  213. package/test/unit/api/transfers/transfers.test.js +191 -0
  214. package/test/unit/api/transfers/utils.js +183 -0
  215. package/test/unit/api/utils.js +75 -0
  216. package/test/unit/config.test.js +119 -0
  217. package/test/unit/data/commonHttpHeaders.json +6 -0
  218. package/test/unit/data/defaultConfig.json +58 -0
  219. package/test/unit/data/postQuotesBody.json +52 -0
  220. package/test/unit/data/putParticipantsBody.json +12 -0
  221. package/test/unit/data/putPartiesBody.json +20 -0
  222. package/test/unit/data/testFile.json +29 -0
  223. package/test/unit/data/testFile.yaml +14 -0
  224. package/test/unit/inboundApi/data/mockArguments.json +117 -0
  225. package/test/unit/inboundApi/data/mockTransactionRequest.json +42 -0
  226. package/test/unit/inboundApi/handlers.test.js +799 -0
  227. package/test/unit/index.test.js +55 -0
  228. package/test/unit/lib/cache.test.js +146 -0
  229. package/test/unit/lib/model/AccountsModel.test.js +121 -0
  230. package/test/unit/lib/model/AuthorizationsModel.test.js +460 -0
  231. package/test/unit/lib/model/InboundTransfersModel.test.js +628 -0
  232. package/test/unit/lib/model/OutboundBulkQuotesModel.test.js +249 -0
  233. package/test/unit/lib/model/OutboundBulkTransfersModel.test.js +244 -0
  234. package/test/unit/lib/model/OutboundRequestToPayModel.test.js +166 -0
  235. package/test/unit/lib/model/OutboundRequestToPayTransferModel.test.js +245 -0
  236. package/test/unit/lib/model/OutboundTransfersModel.test.js +836 -0
  237. package/test/unit/lib/model/PartiesModel.test.js +468 -0
  238. package/test/unit/lib/model/QuotesModel.test.js +470 -0
  239. package/test/unit/lib/model/TransfersModel.test.js +474 -0
  240. package/test/unit/lib/model/common/PersistentStateMachine.test.js +179 -0
  241. package/test/unit/lib/model/data/authorizationsResponse.json +13 -0
  242. package/test/unit/lib/model/data/bulkQuoteRequest.json +27 -0
  243. package/test/unit/lib/model/data/bulkQuoteResponse.json +35 -0
  244. package/test/unit/lib/model/data/bulkTransferFulfil.json +13 -0
  245. package/test/unit/lib/model/data/bulkTransferRequest.json +29 -0
  246. package/test/unit/lib/model/data/defaultConfig.json +47 -0
  247. package/test/unit/lib/model/data/getBulkTransfersBackendResponse.json +42 -0
  248. package/test/unit/lib/model/data/getBulkTransfersMojaloopResponse.json +22 -0
  249. package/test/unit/lib/model/data/getTransfersBackendResponse.json +34 -0
  250. package/test/unit/lib/model/data/getTransfersMojaloopResponse.json +17 -0
  251. package/test/unit/lib/model/data/mockArguments.json +131 -0
  252. package/test/unit/lib/model/data/mockTxnRequestsArguments.json +63 -0
  253. package/test/unit/lib/model/data/notificationToPayee.json +10 -0
  254. package/test/unit/lib/model/data/payeeParty.json +16 -0
  255. package/test/unit/lib/model/data/putAuthorizationsResponse.json +10 -0
  256. package/test/unit/lib/model/data/putQuotesResponse.json +33 -0
  257. package/test/unit/lib/model/data/putTransfersResponse.json +5 -0
  258. package/test/unit/lib/model/data/quoteResponse.json +31 -0
  259. package/test/unit/lib/model/data/requestToPayRequest.json +20 -0
  260. package/test/unit/lib/model/data/requestToPayTransferRequest.json +27 -0
  261. package/test/unit/lib/model/data/transactionRequestResponse.json +18 -0
  262. package/test/unit/lib/model/data/transferFulfil.json +8 -0
  263. package/test/unit/lib/model/data/transferRequest.json +26 -0
  264. package/test/unit/lib/model/mockedLibRequests.js +74 -0
  265. package/test/unit/mockLogger.js +39 -0
  266. package/test/unit/outboundApi/data/bulkQuoteRequest.json +28 -0
  267. package/test/unit/outboundApi/data/bulkTransferRequest.json +28 -0
  268. package/test/unit/outboundApi/data/mockBulkQuoteError.json +45 -0
  269. package/test/unit/outboundApi/data/mockBulkTransferError.json +48 -0
  270. package/test/unit/outboundApi/data/mockError.json +41 -0
  271. package/test/unit/outboundApi/data/mockGetPartiesError.json +4 -0
  272. package/test/unit/outboundApi/data/mockRequestToPayError.json +32 -0
  273. package/test/unit/outboundApi/data/mockRequestToPayTransferError.json +39 -0
  274. package/test/unit/outboundApi/data/requestToPay.json +21 -0
  275. package/test/unit/outboundApi/data/requestToPayTransferRequest.json +20 -0
  276. package/test/unit/outboundApi/data/transferRequest.json +21 -0
  277. package/test/unit/outboundApi/handlers.test.js +986 -0
@@ -0,0 +1,394 @@
1
+ /**************************************************************************
2
+ * (C) Copyright ModusBox Inc. 2019 - 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
+ * James Bush - james.bush@modusbox.com *
9
+ **************************************************************************/
10
+
11
+ 'use strict';
12
+
13
+ const supertest = require('supertest');
14
+
15
+ const defaultConfig = require('./data/defaultConfig');
16
+ const putPartiesBody = require('./data/putPartiesBody');
17
+ const postQuotesBody = require('./data/postQuotesBody');
18
+ const putParticipantsBody = require('./data/putParticipantsBody');
19
+ const commonHttpHeaders = require('./data/commonHttpHeaders');
20
+ const WebSocket = require('ws');
21
+ const { Logger } = require('@mojaloop/sdk-standard-components');
22
+
23
+ jest.mock('../../lib/cache');
24
+ jest.mock('@mojaloop/sdk-standard-components');
25
+ jest.mock('../../lib/model/lib/requests', () => require('./lib/model/mockedLibRequests'));
26
+
27
+ const Cache = require('../../lib/cache');
28
+ const InboundServer = require('../../InboundServer');
29
+ const TestServer = require('../../TestServer');
30
+
31
+ const createWsClient = async (port, path) => {
32
+ const result = new WebSocket(`ws://127.0.0.1:${port}${path}`);
33
+ await new Promise((resolve, reject) => {
34
+ result.on('open', resolve);
35
+ result.on('error', reject);
36
+ });
37
+ return result;
38
+ };
39
+
40
+ describe('Test Server', () => {
41
+ let testServer, inboundServer, inboundReq, testReq, serverConfig, wsClients, testServerPort,
42
+ logger, cache;
43
+
44
+ beforeEach(async () => {
45
+ Cache.mockClear();
46
+
47
+ logger = new Logger.Logger({ stringify: () => '' });
48
+
49
+ serverConfig = {
50
+ ...JSON.parse(JSON.stringify(defaultConfig)),
51
+ enableTestFeatures: true,
52
+ };
53
+ cache = new Cache({ ...serverConfig.cacheConfig, logger: logger.push({ component: 'cache' }), enableTestFeatures: true });
54
+
55
+ testServer = new TestServer({ logger, cache });
56
+ await testServer.start();
57
+ testServerPort = testServer._server.address().port;
58
+
59
+ expect(testServer._server.listening).toBe(true);
60
+ testReq = supertest.agent(testServer._server);
61
+
62
+ inboundServer = new InboundServer(serverConfig, logger, cache);
63
+ await inboundServer.start();
64
+ inboundReq = supertest(inboundServer._server);
65
+
66
+ wsClients = {
67
+ root: await createWsClient(testServerPort, '/'),
68
+ callbacks: await createWsClient(testServerPort, '/callbacks'),
69
+ requests: await createWsClient(testServerPort, '/requests'),
70
+ };
71
+
72
+ expect(Object.values(wsClients).every((cli) => cli.readyState === WebSocket.OPEN)).toBe(true);
73
+ expect(testServer._wsapi._wsClients.size).toBeGreaterThan(0);
74
+
75
+ expect(Cache).toHaveBeenCalledTimes(1);
76
+ });
77
+
78
+ afterEach(async () => {
79
+ await Promise.all(Object.values(wsClients).map((cli) => {
80
+ cli.close();
81
+ return new Promise((resolve) => cli.on('close', resolve));
82
+ }));
83
+ await testServer.stop();
84
+ await inboundServer.stop();
85
+ });
86
+
87
+ // TODO: check this happens correctly with top-level server if possible?
88
+ test('Inbound server and Test server construct cache with same parameters when provided same config', async () => {
89
+ expect(Cache).toHaveBeenCalledTimes(1);
90
+ const testArgs = { ...Cache.mock.calls[0][0], logger: expect.anything() };
91
+ expect(Cache).toHaveBeenNthCalledWith(1, testArgs);
92
+ });
93
+
94
+ test('Health check', async () => {
95
+ const result = await testReq.get('/');
96
+ expect(result.ok).toBeTruthy();
97
+ expect(result.statusCode).toEqual(204);
98
+ });
99
+
100
+ test('PUT /parties cache get and set use same value', async () => {
101
+ const MSISDN = '123456789';
102
+
103
+ await inboundReq
104
+ .put(`/parties/MSISDN/${MSISDN}`)
105
+ .send(putPartiesBody)
106
+ .set(commonHttpHeaders)
107
+ .set('content-type', 'application/vnd.interoperability.parties+json;version=1.0')
108
+ .set('fspiop-http-method', 'PUT')
109
+ .set('fspiop-uri', `/parties/MSISDN/${MSISDN}`)
110
+ .set('date', new Date().toISOString());
111
+
112
+ await testReq.get(`/callbacks/${MSISDN}`);
113
+
114
+ expect(cache.set.mock.calls[0][0]).toEqual(cache.get.mock.calls[0][0]);
115
+ });
116
+
117
+ test('POST /quotes requests cache get and set use same value', async () => {
118
+ await inboundReq
119
+ .post('/quotes')
120
+ .send(postQuotesBody)
121
+ .set(commonHttpHeaders)
122
+ .set('content-type', 'application/vnd.interoperability.quotes+json;version=1.0')
123
+ .set('fspiop-http-method', 'POST')
124
+ .set('fspiop-uri', '/quotes')
125
+ .set('date', new Date().toISOString());
126
+
127
+ await testReq.get(`/requests/${postQuotesBody.quoteId}`);
128
+
129
+ expect(cache.set.mock.calls[0][0]).toEqual(cache.get.mock.calls[0][0]);
130
+ });
131
+
132
+ test('PUT /participants callbacks cache get and set use same value', async () => {
133
+ const participantId = '00000000-0000-1000-a000-000000000002';
134
+
135
+ await inboundReq
136
+ .put(`/participants/${participantId}`)
137
+ .send(putParticipantsBody)
138
+ .set(commonHttpHeaders)
139
+ .set('content-type', 'application/vnd.interoperability.participants+json;version=1.0')
140
+ .set('fspiop-http-method', 'PUT')
141
+ .set('fspiop-uri', `/participants/${participantId}`)
142
+ .set('date', new Date().toISOString());
143
+
144
+ await testReq.get(`/callbacks/${participantId}`);
145
+
146
+ expect(cache.set.mock.calls[0][0]).toEqual(cache.get.mock.calls[0][0]);
147
+ });
148
+
149
+ test('Subscribes to the keyevent set notification', async () => {
150
+ expect(testServer._wsapi._cache.subscribe).toBeCalledTimes(1);
151
+ expect(testServer._wsapi._cache.subscribe).toHaveBeenCalledWith(
152
+ testServer._wsapi._cache.EVENT_SET,
153
+ expect.any(Function),
154
+ );
155
+ });
156
+
157
+ test('WebSocket /callbacks and / endpoint triggers send to client when callback received to inbound server', async () => {
158
+ const participantId = '00000000-0000-1000-a000-000000000002';
159
+
160
+ const headers = {
161
+ ...commonHttpHeaders,
162
+ 'content-type': 'application/vnd.interoperability.participants+json;version=1.0',
163
+ 'fspiop-http-method': 'PUT',
164
+ 'fspiop-uri': `/participants/${participantId}`,
165
+ 'date': new Date().toISOString(),
166
+ };
167
+
168
+ const putParticipantWsClient = await createWsClient(
169
+ testServerPort,
170
+ `/callbacks/${participantId}`
171
+ );
172
+
173
+ const putParticipantEndpointMessageReceived = new Promise(resolve => {
174
+ putParticipantWsClient.on('message', resolve);
175
+ });
176
+ const serverCallbackEndpointMessageReceived = new Promise(resolve => {
177
+ wsClients.callbacks.on('message', resolve);
178
+ });
179
+ const serverRootEndpointMessageReceived = new Promise(resolve => {
180
+ wsClients.root.on('message', resolve);
181
+ });
182
+
183
+ // get the callback function that the test server subscribed with, and mock the cache by
184
+ // calling the callback when the inbound server sets a key in the cache.
185
+ const callback = testServer._wsapi._cache.subscribe.mock.calls[0][1];
186
+ inboundServer._api._cache.set = jest.fn(async (key) => await callback(
187
+ inboundServer._api._cache.EVENT_SET,
188
+ key,
189
+ 1,
190
+ ));
191
+ testServer._wsapi._cache.get = jest.fn(() => ({
192
+ data: putParticipantsBody,
193
+ headers,
194
+ }));
195
+
196
+ await inboundReq
197
+ .put(`/participants/${participantId}`)
198
+ .send(putParticipantsBody)
199
+ .set(headers);
200
+
201
+ expect(inboundServer._api._cache.set).toHaveBeenCalledTimes(1);
202
+ expect(inboundServer._api._cache.set).toHaveBeenCalledWith(
203
+ `${testServer._wsapi._cache.CALLBACK_PREFIX}${participantId}`,
204
+ {
205
+ data: putParticipantsBody,
206
+ headers: expect.objectContaining(headers),
207
+ }
208
+ );
209
+
210
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledTimes(1);
211
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledWith(
212
+ `${testServer._wsapi._cache.CALLBACK_PREFIX}${participantId}`
213
+ );
214
+
215
+ const expectedMessage = {
216
+ data: putParticipantsBody,
217
+ headers: expect.objectContaining(headers),
218
+ id: participantId
219
+ };
220
+
221
+ // Expect the client websockets to receive a message containing the callback headers and
222
+ // body
223
+ const callbackClientResult = JSON.parse(await serverCallbackEndpointMessageReceived);
224
+ expect(callbackClientResult).toEqual(expectedMessage);
225
+ const rootClientResult = JSON.parse(await serverRootEndpointMessageReceived);
226
+ expect(rootClientResult).toEqual(expectedMessage);
227
+ const putParticipantClientClientResult = JSON.parse(await putParticipantEndpointMessageReceived);
228
+ expect(putParticipantClientClientResult).toEqual(expectedMessage);
229
+ });
230
+
231
+ test('WebSocket /requests and / endpoint triggers send to client when callback received to inbound server', async () => {
232
+ const headers = {
233
+ ...commonHttpHeaders,
234
+ 'content-type': 'application/vnd.interoperability.quotes+json;version=1.0',
235
+ 'fspiop-http-method': 'POST',
236
+ 'fspiop-uri': '/quotes',
237
+ 'date': new Date().toISOString(),
238
+ };
239
+
240
+ const postQuoteWsClient = await createWsClient(
241
+ testServerPort,
242
+ `/requests/${postQuotesBody.quoteId}`
243
+ );
244
+
245
+ const postQuoteEndpointMessageReceived = new Promise(resolve => {
246
+ postQuoteWsClient.on('message', resolve);
247
+ });
248
+ const serverRequestEndpointMessageReceived = new Promise(resolve => {
249
+ wsClients.requests.on('message', resolve);
250
+ });
251
+ const serverRootEndpointMessageReceived = new Promise(resolve => {
252
+ wsClients.root.on('message', resolve);
253
+ });
254
+
255
+ // get the callback function that the test server subscribed with, and mock the cache by
256
+ // calling the callback when the inbound server sets a key in the cache.
257
+ const callback = testServer._wsapi._cache.subscribe.mock.calls[0][1];
258
+ inboundServer._api._cache.set = jest.fn(async (key) => await callback(
259
+ inboundServer._api._cache.EVENT_SET,
260
+ key,
261
+ 1,
262
+ ));
263
+ testServer._wsapi._cache.get = jest.fn(() => ({
264
+ data: postQuotesBody,
265
+ headers,
266
+ }));
267
+
268
+ await inboundReq
269
+ .post('/quotes')
270
+ .send(postQuotesBody)
271
+ .set(headers);
272
+
273
+ // Called twice for the quote request, once for the fulfilment
274
+ expect(inboundServer._api._cache.set).toHaveBeenCalledTimes(3);
275
+ expect(inboundServer._api._cache.set).toHaveBeenCalledWith(
276
+ `${testServer._wsapi._cache.REQUEST_PREFIX}${postQuotesBody.quoteId}`,
277
+ {
278
+ data: postQuotesBody,
279
+ headers: expect.objectContaining(headers),
280
+ }
281
+ );
282
+
283
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledTimes(1);
284
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledWith(
285
+ `${testServer._wsapi._cache.REQUEST_PREFIX}${postQuotesBody.quoteId}`
286
+ );
287
+
288
+ const expectedMessage = {
289
+ data: postQuotesBody,
290
+ headers: expect.objectContaining(headers),
291
+ id: postQuotesBody.quoteId,
292
+ };
293
+
294
+ // Expect the client websockets to receive a message containing the callback headers and
295
+ // body
296
+ const callbackClientResult = JSON.parse(await serverRequestEndpointMessageReceived);
297
+ expect(callbackClientResult).toEqual(expectedMessage);
298
+ const rootClientResult = JSON.parse(await serverRootEndpointMessageReceived);
299
+ expect(rootClientResult).toEqual(expectedMessage);
300
+ const postQuoteClientResult = JSON.parse(await postQuoteEndpointMessageReceived);
301
+ expect(postQuoteClientResult).toEqual(expectedMessage);
302
+ });
303
+
304
+ test('Websocket / endpoint receives both callbacks and requests', async () => {
305
+ const quoteRequestHeaders = {
306
+ ...commonHttpHeaders,
307
+ 'content-type': 'application/vnd.interoperability.quotes+json;version=1.0',
308
+ 'fspiop-http-method': 'POST',
309
+ 'fspiop-uri': '/quotes',
310
+ 'date': new Date().toISOString(),
311
+ };
312
+
313
+ const serverRootEndpointMessageReceived = new Promise(resolve => {
314
+ wsClients.root.on('message', resolve);
315
+ });
316
+
317
+ // get the callback function that the test server subscribed with, and mock the cache by
318
+ // calling the callback when the inbound server sets a key in the cache.
319
+ const callback = testServer._wsapi._cache.subscribe.mock.calls[0][1];
320
+ inboundServer._api._cache.set = jest.fn(async (key) => await callback(
321
+ inboundServer._api._cache.EVENT_SET,
322
+ key,
323
+ 1,
324
+ ));
325
+ testServer._wsapi._cache.get = jest.fn(() => ({
326
+ data: postQuotesBody,
327
+ headers: quoteRequestHeaders,
328
+ }));
329
+
330
+ await inboundReq
331
+ .post('/quotes')
332
+ .send(postQuotesBody)
333
+ .set(quoteRequestHeaders);
334
+
335
+ // Called twice for the quote request, once for the fulfilment
336
+ expect(inboundServer._api._cache.set).toHaveBeenCalledTimes(3);
337
+ expect(inboundServer._api._cache.set).toHaveBeenCalledWith(
338
+ `${testServer._wsapi._cache.REQUEST_PREFIX}${postQuotesBody.quoteId}`,
339
+ {
340
+ data: postQuotesBody,
341
+ headers: expect.objectContaining(quoteRequestHeaders),
342
+ }
343
+ );
344
+
345
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledTimes(1);
346
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledWith(
347
+ `${testServer._wsapi._cache.REQUEST_PREFIX}${postQuotesBody.quoteId}`
348
+ );
349
+
350
+ const expectedMessage = {
351
+ data: postQuotesBody,
352
+ headers: expect.objectContaining(quoteRequestHeaders),
353
+ id: postQuotesBody.quoteId,
354
+ };
355
+
356
+ // Expect the client websockets to receive a message containing the callback
357
+ // quoteRequestHeaders and body
358
+ const rootEndpointResult = JSON.parse(await serverRootEndpointMessageReceived);
359
+ expect(rootEndpointResult).toEqual(expectedMessage);
360
+
361
+ const participantId = '00000000-0000-1000-a000-000000000002';
362
+
363
+ const putParticipantsHeaders = {
364
+ ...commonHttpHeaders,
365
+ 'content-type': 'application/vnd.interoperability.participants+json;version=1.0',
366
+ 'fspiop-http-method': 'PUT',
367
+ 'fspiop-uri': `/participants/${participantId}`,
368
+ 'date': new Date().toISOString(),
369
+ };
370
+
371
+ await inboundReq
372
+ .put(`/participants/${participantId}`)
373
+ .send(putParticipantsBody)
374
+ .set(putParticipantsHeaders);
375
+
376
+ // Called thrice for the quote request earlier in this test, another time now for the put
377
+ // participants request
378
+ expect(inboundServer._api._cache.set).toHaveBeenCalledTimes(4);
379
+ expect(inboundServer._api._cache.set.mock.calls[3]).toEqual([
380
+ `${testServer._wsapi._cache.CALLBACK_PREFIX}${participantId}`,
381
+ {
382
+ data: putParticipantsBody,
383
+ headers: expect.objectContaining(putParticipantsHeaders),
384
+ }
385
+ ]);
386
+
387
+ // Called once for the quote request earlier in this test, another time now for the
388
+ // participants callback
389
+ expect(testServer._wsapi._cache.get).toHaveBeenCalledTimes(2);
390
+ expect(testServer._wsapi._cache.get.mock.calls[1]).toEqual([
391
+ `${testServer._wsapi._cache.CALLBACK_PREFIX}${participantId}`
392
+ ]);
393
+ });
394
+ });
@@ -0,0 +1,128 @@
1
+ /**************************************************************************
2
+ * (C) Copyright ModusBox Inc. 2019 - 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
+ * Yevhen Kyriukha - yevhen.kyriukha@modusbox.com *
9
+ **************************************************************************/
10
+
11
+ 'use strict';
12
+
13
+ jest.unmock('@mojaloop/sdk-standard-components');
14
+ jest.mock('redis');
15
+
16
+ const redis = require('redis');
17
+ const uuidv4 = require('uuidv4');
18
+ const {createValidators, createTestServers, destroyTestServers} = require('../utils');
19
+ const {createPostAccountsTester} = require('./utils');
20
+
21
+ const defaultConfig = require('../../data/defaultConfig');
22
+
23
+ // Accounts
24
+ const postAccountsSuccessResponse = require('./data/postAccountsSuccessResponse');
25
+ const postAccountsSuccessResponseWithError1 = require('./data/postAccountsSuccessResponseWithError1');
26
+ const postAccountsSuccessResponseWithError2 = require('./data/postAccountsSuccessResponseWithError2');
27
+ const postAccountsErrorTimeoutResponse = require('./data/postAccountsErrorTimeoutResponse');
28
+ const postAccountsErrorMojaloopResponse = require('./data/postAccountsErrorMojaloopResponse');
29
+
30
+ describe('Outbound Accounts API', () => {
31
+ let testPostAccounts;
32
+ let validatorsInfo;
33
+ let serversInfo;
34
+ let redisClient;
35
+
36
+ beforeAll(async () => {
37
+ validatorsInfo = await createValidators();
38
+ redisClient = redis.createClient();
39
+ });
40
+
41
+ beforeEach(async () => {
42
+ serversInfo = await createTestServers(defaultConfig);
43
+ testPostAccounts = createPostAccountsTester({
44
+ reqInbound: serversInfo.reqInbound,
45
+ reqOutbound: serversInfo.reqOutbound,
46
+ apiSpecsOutbound: validatorsInfo.apiSpecsOutbound,
47
+ });
48
+ });
49
+
50
+ afterEach(async () => {
51
+ await destroyTestServers(serversInfo);
52
+ });
53
+
54
+ afterAll(async () => {
55
+ redisClient.end();
56
+ });
57
+
58
+ describe('POST /accounts', () => {
59
+ beforeEach(() => {
60
+ uuidv4.__reset();
61
+ redisClient.flushdb();
62
+ });
63
+
64
+ test('should return success response', () => {
65
+ const putBodyFn = (body) => ({
66
+ partyList: body.partyList.map(party => ({
67
+ partyId: party,
68
+ })),
69
+ currency: body.currency,
70
+ });
71
+ return testPostAccounts(putBodyFn, 200,
72
+ postAccountsSuccessResponse);
73
+ });
74
+
75
+ test(
76
+ 'should return success response with error info on invalid currency (1)',
77
+ () => {
78
+ const putBodyFn = (body) => ({
79
+ partyList: body.partyList.map(party => ({
80
+ partyId: party,
81
+ })),
82
+ currency: undefined,
83
+ });
84
+ return testPostAccounts(putBodyFn, 200,
85
+ postAccountsSuccessResponseWithError1);
86
+ });
87
+
88
+ test(
89
+ 'should return success response with error info on errorInformation presence (2)',
90
+ () => {
91
+ const putBodyFn = (body) => ({
92
+ partyList: body.partyList.map(party => ({
93
+ partyId: party,
94
+ errorInformation: {
95
+ errorCode: '3204',
96
+ errorDescription: 'Party not found',
97
+ },
98
+ })),
99
+ currency: 'USD',
100
+ });
101
+ return testPostAccounts(putBodyFn, 200,
102
+ postAccountsSuccessResponseWithError2);
103
+ });
104
+
105
+ test('should return timeout error response', () => {
106
+ const putBodyFn = (body) => new Promise(
107
+ resolve => setTimeout(() => resolve({
108
+ partyList: body.partyList.map(party => ({
109
+ partyId: party,
110
+ })),
111
+ currency: body.currency,
112
+ }), 3000));
113
+ return testPostAccounts(putBodyFn, 504,
114
+ postAccountsErrorTimeoutResponse);
115
+ });
116
+
117
+ test('should return mojaloop error response', () => {
118
+ const putBodyFn = () => ({
119
+ errorInformation: {
120
+ errorCode: '3204',
121
+ errorDescription: 'Party not found',
122
+ },
123
+ });
124
+ return testPostAccounts(putBodyFn, 500,
125
+ postAccountsErrorMojaloopResponse);
126
+ });
127
+ });
128
+ });