@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,628 @@
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
+ * Vassilis Barzokas - vassilis.barzokas@modusbox.com *
9
+ **************************************************************************/
10
+ 'use strict';
11
+
12
+ // we use a mock standard components lib to intercept and mock certain funcs
13
+ jest.mock('@mojaloop/sdk-standard-components');
14
+ jest.mock('redis');
15
+ jest.mock('../../../../lib/model/lib/requests',() => require('./mockedLibRequests'));
16
+
17
+ const defaultConfig = require('./data/defaultConfig');
18
+ const Model = require('../../../../lib/model').InboundTransfersModel;
19
+ const mockArguments = require('./data/mockArguments');
20
+ const mockTxnReqquestsArguments = require('./data/mockTxnRequestsArguments');
21
+ const { MojaloopRequests, Ilp, Logger } = require('@mojaloop/sdk-standard-components');
22
+ const { BackendRequests, HTTPResponseError } = require('../../../../lib/model/lib/requests');
23
+ const Cache = require('../../../../lib/cache');
24
+
25
+ const getTransfersBackendResponse = require('./data/getTransfersBackendResponse');
26
+ const getTransfersMojaloopResponse = require('./data/getTransfersMojaloopResponse');
27
+ const getBulkTransfersBackendResponse = require('./data/getBulkTransfersBackendResponse');
28
+ const getBulkTransfersMojaloopResponse = require('./data/getBulkTransfersMojaloopResponse');
29
+ const notificationToPayee = require('./data/notificationToPayee');
30
+
31
+ describe('inboundModel', () => {
32
+ let config;
33
+ let mockArgs;
34
+ let mockTxnReqArgs;
35
+ let logger;
36
+
37
+ beforeAll(async () => {
38
+ logger = new Logger.Logger({ context: { app: 'inbound-model-unit-tests' }, stringify: () => '' });
39
+ });
40
+
41
+ beforeEach(async () => {
42
+ config = JSON.parse(JSON.stringify(defaultConfig));
43
+
44
+ mockArgs = JSON.parse(JSON.stringify(mockArguments));
45
+ mockArgs.internalQuoteResponse.expiration = new Date(Date.now());
46
+ mockTxnReqArgs = JSON.parse(JSON.stringify(mockTxnReqquestsArguments));
47
+ });
48
+
49
+ describe('quoteRequest', () => {
50
+ let expectedQuoteResponseILP;
51
+ let model;
52
+ let cache;
53
+
54
+ beforeEach(async () => {
55
+ expectedQuoteResponseILP = Ilp.__response;
56
+ BackendRequests.__postQuoteRequests = jest.fn().mockReturnValue(Promise.resolve(mockArgs.internalQuoteResponse));
57
+
58
+ cache = new Cache({
59
+ host: 'dummycachehost',
60
+ port: 1234,
61
+ logger,
62
+ });
63
+ await cache.connect();
64
+
65
+ model = new Model({
66
+ ...config,
67
+ cache,
68
+ logger,
69
+ });
70
+ });
71
+
72
+ afterEach(async () => {
73
+ MojaloopRequests.__putQuotes.mockClear();
74
+ await cache.disconnect();
75
+ });
76
+
77
+ test('calls `mojaloopRequests.putQuotes` with the expected arguments.', async () => {
78
+ await model.quoteRequest(mockArgs.quoteRequest, mockArgs.fspId);
79
+
80
+ expect(MojaloopRequests.__putQuotes).toHaveBeenCalledTimes(1);
81
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][1].expiration).toBe(mockArgs.internalQuoteResponse.expiration);
82
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][1].ilpPacket).toBe(expectedQuoteResponseILP.ilpPacket);
83
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][1].condition).toBe(expectedQuoteResponseILP.condition);
84
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][2]).toBe(mockArgs.fspId);
85
+ });
86
+
87
+ test('adds a custom `expiration` property in case it is not defined.', async() => {
88
+ // set a custom mock time in the global Date object in order to avoid race conditions.
89
+ // Make sure to clear it at the end of the test case.
90
+ const currentTime = new Date().getTime();
91
+ const dateSpy = jest.spyOn(Date.prototype, 'getTime').mockImplementation(() => currentTime);
92
+ const expectedExpirationDate = new Date(currentTime + (config.expirySeconds * 1000)).toISOString();
93
+
94
+ delete mockArgs.internalQuoteResponse.expiration;
95
+
96
+ await model.quoteRequest(mockArgs.quoteRequest, mockArgs.fspId);
97
+
98
+ expect(MojaloopRequests.__putQuotes).toHaveBeenCalledTimes(1);
99
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][1].expiration).toBe(expectedExpirationDate);
100
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][1].ilpPacket).toBe(expectedQuoteResponseILP.ilpPacket);
101
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][1].condition).toBe(expectedQuoteResponseILP.condition);
102
+ expect(MojaloopRequests.__putQuotes.mock.calls[0][2]).toBe(mockArgs.fspId);
103
+
104
+ dateSpy.mockClear();
105
+ });
106
+
107
+
108
+ });
109
+
110
+ describe('bulkQuoteRequest', () => {
111
+ let expectedQuoteResponseILP;
112
+ let model;
113
+ let cache;
114
+
115
+ beforeEach(async () => {
116
+ // eslint-disable-next-line no-unused-vars
117
+ expectedQuoteResponseILP = Ilp.__response;
118
+ BackendRequests.__postBulkQuotes = jest.fn().mockReturnValue(Promise.resolve(mockArgs.internalBulkQuoteResponse));
119
+
120
+ cache = new Cache({
121
+ host: 'dummycachehost',
122
+ port: 1234,
123
+ logger,
124
+ });
125
+ await cache.connect();
126
+ // eslint-disable-next-line no-unused-vars
127
+ model = new Model({
128
+ ...config,
129
+ cache,
130
+ logger,
131
+ });
132
+ });
133
+
134
+ afterEach(async () => {
135
+ MojaloopRequests.__putBulkQuotes.mockClear();
136
+ await cache.disconnect();
137
+ });
138
+
139
+ test('calls mojaloopRequests.putBulkQuotes with the expected arguments.', async () => {
140
+ await model.bulkQuoteRequest(mockArgs.bulkQuoteRequest, mockArgs.fspId);
141
+
142
+ expect(MojaloopRequests.__putBulkQuotes).toHaveBeenCalledTimes(1);
143
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][1].expiration).toBe(mockArgs.internalBulkQuoteResponse.expiration);
144
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][1].individualQuoteResults[0].ilpPacket).toBe(expectedQuoteResponseILP.ilpPacket);
145
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][1].individualQuoteResults[0].condition).toBe(expectedQuoteResponseILP.condition);
146
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][2]).toBe(mockArgs.fspId);
147
+ });
148
+ test('adds a custom expiration property in case it is not defined.', async() => {
149
+ // set a custom mock time in the global Date object in order to avoid race conditions.
150
+ // Make sure to clear it at the end of the test case.
151
+ const currentTime = new Date().getTime();
152
+ const dateSpy = jest.spyOn(Date.prototype, 'getTime').mockImplementation(() => currentTime);
153
+ const expectedExpirationDate = new Date(currentTime + (config.expirySeconds * 1000)).toISOString();
154
+
155
+ delete mockArgs.internalBulkQuoteResponse.expiration;
156
+
157
+ await model.bulkQuoteRequest(mockArgs.bulkQuoteRequest, mockArgs.fspId);
158
+
159
+ expect(MojaloopRequests.__putBulkQuotes).toHaveBeenCalledTimes(1);
160
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][1].expiration).toBe(expectedExpirationDate);
161
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][1].individualQuoteResults[0].ilpPacket).toBe(expectedQuoteResponseILP.ilpPacket);
162
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][1].individualQuoteResults[0].condition).toBe(expectedQuoteResponseILP.condition);
163
+ expect(MojaloopRequests.__putBulkQuotes.mock.calls[0][2]).toBe(mockArgs.fspId);
164
+
165
+ dateSpy.mockClear();
166
+ });
167
+
168
+ });
169
+
170
+ describe('transactionRequest', () => {
171
+ let model;
172
+ let cache;
173
+
174
+ beforeEach(async () => {
175
+ BackendRequests.__postTransactionRequests = jest.fn().mockReturnValue(Promise.resolve(mockTxnReqArgs.internalTransactionRequestResponse));
176
+
177
+ cache = new Cache({
178
+ host: 'dummycachehost',
179
+ port: 1234,
180
+ logger,
181
+ });
182
+ await cache.connect();
183
+
184
+ model = new Model({
185
+ ...config,
186
+ cache,
187
+ logger,
188
+ });
189
+ });
190
+
191
+ afterEach(async () => {
192
+ MojaloopRequests.__putTransactionRequests.mockClear();
193
+ await cache.disconnect();
194
+ });
195
+
196
+ test('calls `mojaloopRequests.putTransactionRequests` with the expected arguments.', async () => {
197
+ await model.transactionRequest(mockTxnReqArgs.transactionRequest, mockTxnReqArgs.fspId);
198
+
199
+ expect(MojaloopRequests.__putTransactionRequests).toHaveBeenCalledTimes(1);
200
+ expect(MojaloopRequests.__putTransactionRequests.mock.calls[0][1].transactionRequestState).toBe(mockTxnReqArgs.internalTransactionRequestResponse.transactionRequestState);
201
+
202
+ });
203
+
204
+
205
+ });
206
+
207
+ describe('authorizations', () => {
208
+ let model;
209
+ let cache;
210
+
211
+ beforeEach(async () => {
212
+ BackendRequests.__getOTP = jest.fn().mockReturnValue(Promise.resolve(mockArgs.internalGetOTPResponse));
213
+
214
+ cache = new Cache({
215
+ host: 'dummycachehost',
216
+ port: 1234,
217
+ logger,
218
+ });
219
+ await cache.connect();
220
+
221
+ model = new Model({
222
+ ...config,
223
+ cache,
224
+ logger,
225
+ });
226
+ });
227
+
228
+ afterEach(async () => {
229
+ MojaloopRequests.__putAuthorizations.mockClear();
230
+ await cache.disconnect();
231
+ });
232
+
233
+ test('calls `mojaloopRequests.putAuthorizations` with the expected arguments.', async () => {
234
+ await model.getAuthorizations('123456', mockTxnReqArgs.fspId);
235
+
236
+ expect(MojaloopRequests.__putAuthorizations).toHaveBeenCalledTimes(1);
237
+
238
+ });
239
+
240
+
241
+ });
242
+
243
+ describe('transferPrepare:', () => {
244
+ let cache;
245
+
246
+ beforeEach(async () => {
247
+ MojaloopRequests.__putTransfersError.mockClear();
248
+ BackendRequests.__postTransfers = jest.fn().mockReturnValue(Promise.resolve({}));
249
+ MojaloopRequests.__putTransfers = jest.fn().mockReturnValue(Promise.resolve({}));
250
+
251
+ cache = new Cache({
252
+ host: 'dummycachehost',
253
+ port: 1234,
254
+ logger,
255
+ });
256
+ await cache.connect();
257
+ });
258
+
259
+ afterEach(async () => {
260
+ await cache.disconnect();
261
+ });
262
+
263
+ test('fail on quote `expiration` deadline.', async () => {
264
+ const TRANSFER_ID = 'fake-transfer-id';
265
+ const model = new Model({
266
+ ...config,
267
+ cache,
268
+ logger,
269
+ rejectTransfersOnExpiredQuotes: true,
270
+ });
271
+ cache.set(`quote_${TRANSFER_ID}`, {
272
+ mojaloopResponse: {
273
+ expiration: new Date(new Date().getTime() - 1000).toISOString(),
274
+ }
275
+ });
276
+ const args = {
277
+ transferId: TRANSFER_ID,
278
+ };
279
+
280
+ await model.prepareTransfer(args, mockArgs.fspId);
281
+
282
+ expect(MojaloopRequests.__putTransfersError).toHaveBeenCalledTimes(1);
283
+ const call = MojaloopRequests.__putTransfersError.mock.calls[0];
284
+ expect(call[0]).toEqual(TRANSFER_ID);
285
+ expect(call[1].errorInformation.errorCode).toEqual('3302');
286
+ });
287
+
288
+ test('getTransfer should return COMMITTED transfer', async () => {
289
+ const TRANSFER_ID = 'fake-transfer-id';
290
+
291
+ const backendResponse = JSON.parse(JSON.stringify(getTransfersBackendResponse));
292
+ backendResponse.to.fspId = config.dfspId;
293
+ BackendRequests.__getTransfers = jest.fn().mockReturnValue(Promise.resolve(backendResponse));
294
+
295
+ const model = new Model({
296
+ ...config,
297
+ cache,
298
+ logger,
299
+ });
300
+
301
+ await model.getTransfer(TRANSFER_ID, mockArgs.fspId);
302
+
303
+ expect(MojaloopRequests.__putTransfers).toHaveBeenCalledTimes(1);
304
+ const call = MojaloopRequests.__putTransfers.mock.calls[0];
305
+ expect(call[0]).toEqual(TRANSFER_ID);
306
+ expect(call[1]).toEqual(getTransfersMojaloopResponse);
307
+ expect(call[1].transferState).toEqual('COMMITTED');
308
+ });
309
+
310
+ test('getTransfer should not return fulfillment from payer', async () => {
311
+ const TRANSFER_ID = 'fake-transfer-id';
312
+
313
+ const backendResponse = JSON.parse(JSON.stringify(getTransfersBackendResponse));
314
+ backendResponse.to.fspId = 'payer-dfsp';
315
+ BackendRequests.__getTransfers = jest.fn().mockReturnValue(Promise.resolve(backendResponse));
316
+
317
+ const model = new Model({
318
+ ...config,
319
+ cache,
320
+ logger,
321
+ });
322
+
323
+ await model.getTransfer(TRANSFER_ID, mockArgs.fspId);
324
+
325
+ const call = MojaloopRequests.__putTransfers.mock.calls[0];
326
+ expect(call[0]).toEqual(TRANSFER_ID);
327
+ expect(call[1]).toEqual({...getTransfersMojaloopResponse, fulfilment: undefined});
328
+ expect(call[1].transferState).toEqual('COMMITTED');
329
+ });
330
+
331
+ test('getTransfer should return not found error', async () => {
332
+ const TRANSFER_ID = 'fake-transfer-id';
333
+
334
+ BackendRequests.__getTransfers = jest.fn().mockReturnValue(
335
+ Promise.reject(new HTTPResponseError({
336
+ res: {
337
+ data: {
338
+ statusCode: '3208'
339
+ },
340
+ }
341
+ })));
342
+
343
+ const model = new Model({
344
+ ...config,
345
+ cache,
346
+ logger,
347
+ });
348
+
349
+ await model.getTransfer(TRANSFER_ID, mockArgs.fspId);
350
+
351
+ expect(MojaloopRequests.__putTransfersError).toHaveBeenCalledTimes(1);
352
+ const call = MojaloopRequests.__putTransfersError.mock.calls[0];
353
+ expect(call[0]).toEqual(`${TRANSFER_ID}`);
354
+ expect(call[1].errorInformation.errorCode).toEqual('3208');
355
+ });
356
+
357
+ test('fail on transfer without quote.', async () => {
358
+ const TRANSFER_ID = 'without_quote-transfer-id';
359
+ const args = {
360
+ transferId: TRANSFER_ID,
361
+ amount: {
362
+ currency: 'USD',
363
+ amount: 20.13
364
+ },
365
+ ilpPacket: 'mockBase64encodedIlpPacket',
366
+ condition: 'mockGeneratedCondition'
367
+ };
368
+
369
+ const model = new Model({
370
+ ...config,
371
+ cache,
372
+ logger,
373
+ allowTransferWithoutQuote: false,
374
+ });
375
+
376
+ await model.prepareTransfer(args, mockArgs.fspId);
377
+
378
+ expect(MojaloopRequests.__putTransfersError).toHaveBeenCalledTimes(1);
379
+ const call = MojaloopRequests.__putTransfersError.mock.calls[0];
380
+ expect(call[0]).toEqual(TRANSFER_ID);
381
+ expect(call[1].errorInformation.errorCode).toEqual('2001');
382
+ });
383
+
384
+ test('pass on transfer without quote.', async () => {
385
+ const TRANSFER_ID = 'without_quote-transfer-id';
386
+ const args = {
387
+ transferId: TRANSFER_ID,
388
+ amount: {
389
+ currency: 'USD',
390
+ amount: 20.13
391
+ },
392
+ ilpPacket: 'mockBase64encodedIlpPacket',
393
+ condition: 'mockGeneratedCondition'
394
+ };
395
+
396
+ const model = new Model({
397
+ ...config,
398
+ cache,
399
+ logger,
400
+ allowTransferWithoutQuote: true,
401
+ });
402
+
403
+ await model.prepareTransfer(args, mockArgs.fspId);
404
+
405
+ expect(MojaloopRequests.__putTransfersError).toHaveBeenCalledTimes(0);
406
+ expect(BackendRequests.__postTransfers).toHaveBeenCalledTimes(1);
407
+ expect(MojaloopRequests.__putTransfers).toHaveBeenCalledTimes(1);
408
+ });
409
+ });
410
+
411
+ describe('prepareBulkTransfer:', () => {
412
+ let cache;
413
+
414
+ beforeEach(async () => {
415
+ MojaloopRequests.__putBulkTransfersError.mockClear();
416
+ MojaloopRequests.__putBulkTransfers = jest.fn().mockReturnValue(Promise.resolve({}));
417
+ BackendRequests.__postBulkTransfers = jest.fn().mockReturnValue(Promise.resolve({}));
418
+
419
+ cache = new Cache({
420
+ host: 'dummycachehost',
421
+ port: 1234,
422
+ logger,
423
+ });
424
+ await cache.connect();
425
+ });
426
+
427
+ afterEach(async () => {
428
+ await cache.disconnect();
429
+ });
430
+
431
+ test('fail on bulk quote `expiration` deadline.', async () => {
432
+ const BULK_TRANSFER_ID = 'fake-bulk-transfer-id';
433
+ const BULK_QUOTE_ID = 'fake-bulk-quote-id';
434
+ const model = new Model({
435
+ ...config,
436
+ cache,
437
+ logger,
438
+ rejectTransfersOnExpiredQuotes: true,
439
+ });
440
+ cache.set(`bulkQuotes_${BULK_QUOTE_ID}`, {
441
+ mojaloopResponse: {
442
+ expiration: new Date(new Date().getTime() - 1000).toISOString(),
443
+ individualQuoteResults: [],
444
+ }
445
+ });
446
+ const args = {
447
+ bulkTransferId: BULK_TRANSFER_ID,
448
+ bulkQuoteId: BULK_QUOTE_ID,
449
+ individualTransfers: [],
450
+ };
451
+
452
+ await model.prepareBulkTransfer(args, mockArgs.fspId);
453
+
454
+ expect(MojaloopRequests.__putBulkTransfersError).toHaveBeenCalledTimes(1);
455
+ const call = MojaloopRequests.__putBulkTransfersError.mock.calls[0];
456
+ expect(call[0]).toEqual(BULK_TRANSFER_ID);
457
+ expect(call[1].errorInformation.errorCode).toEqual('3302');
458
+ });
459
+
460
+ test('getBulkTransfer should return COMMITTED bulk transfer', async () => {
461
+ const BULK_TRANSFER_ID = 'fake-bulk-transfer-id';
462
+
463
+ const backendResponse = JSON.parse(JSON.stringify(getBulkTransfersBackendResponse));
464
+ BackendRequests.__getBulkTransfers = jest.fn().mockReturnValue(Promise.resolve(backendResponse));
465
+
466
+ const model = new Model({
467
+ ...config,
468
+ cache,
469
+ logger,
470
+ });
471
+
472
+ await model.getBulkTransfer(BULK_TRANSFER_ID, mockArgs.fspId);
473
+
474
+ expect(MojaloopRequests.__putBulkTransfers).toHaveBeenCalledTimes(1);
475
+ const call = MojaloopRequests.__putBulkTransfers.mock.calls[0];
476
+ expect(call[0]).toEqual(BULK_TRANSFER_ID);
477
+ expect(call[1]).toEqual(getBulkTransfersMojaloopResponse);
478
+ expect(call[1].bulkTransferState).toEqual('COMMITTED');
479
+ });
480
+
481
+ test('getBulkTransfer should not return fulfillment from payer', async () => {
482
+ const BULK_TRANSFER_ID = 'fake-bulk-transfer-id';
483
+
484
+ const backendResponse = JSON.parse(JSON.stringify(getBulkTransfersBackendResponse));
485
+ backendResponse.internalRequest.individualTransfers[0].to.fspId = 'payer-dfsp';
486
+ BackendRequests.__getBulkTransfers = jest.fn().mockReturnValue(Promise.resolve(backendResponse));
487
+
488
+ const model = new Model({
489
+ ...config,
490
+ cache,
491
+ logger,
492
+ });
493
+
494
+ await model.getBulkTransfer(BULK_TRANSFER_ID, mockArgs.fspId);
495
+
496
+ const call = MojaloopRequests.__putBulkTransfers.mock.calls[0];
497
+ expect(call[0]).toEqual(BULK_TRANSFER_ID);
498
+ expect(call[1].bulkTransferState).toEqual('COMMITTED');
499
+ const expectedResponse = {...getBulkTransfersMojaloopResponse};
500
+ expectedResponse.individualTransferResults[0].fulfilment = undefined;
501
+ expect(call[1]).toMatchObject(expectedResponse);
502
+ });
503
+
504
+ test('getBulkTransfer should return not found error', async () => {
505
+ const BULK_TRANSFER_ID = 'fake-bulk-transfer-id';
506
+
507
+ BackendRequests.__getBulkTransfers = jest.fn().mockReturnValue(
508
+ Promise.reject(new HTTPResponseError({
509
+ res: {
510
+ data: {
511
+ statusCode: '3208'
512
+ },
513
+ }
514
+ })));
515
+
516
+ const model = new Model({
517
+ ...config,
518
+ cache,
519
+ logger,
520
+ });
521
+
522
+ await model.getBulkTransfer(BULK_TRANSFER_ID, mockArgs.fspId);
523
+
524
+ expect(MojaloopRequests.__putBulkTransfersError).toHaveBeenCalledTimes(1);
525
+ const call = MojaloopRequests.__putBulkTransfersError.mock.calls[0];
526
+ expect(call[0]).toEqual(`${BULK_TRANSFER_ID}`);
527
+ expect(call[1].errorInformation.errorCode).toEqual('3208');
528
+ });
529
+
530
+ test('fail on bulk transfer without bulk quote.', async () => {
531
+ const BULK_TRANSFER_ID = 'without_bulk-quote-bulk-transfer-id';
532
+ const args = {
533
+ bulkTransferId: BULK_TRANSFER_ID,
534
+ ilpPacket: 'mockBase64encodedIlpPacket',
535
+ condition: 'mockGeneratedCondition',
536
+ individualTransfers: [
537
+ {
538
+ amount: {
539
+ currency: 'USD',
540
+ amount: 20.13
541
+ },
542
+ }
543
+ ]
544
+ };
545
+
546
+ const model = new Model({
547
+ ...config,
548
+ cache,
549
+ logger,
550
+ allowTransferWithoutQuote: false,
551
+ });
552
+
553
+ await model.prepareBulkTransfer(args, mockArgs.fspId);
554
+
555
+ expect(MojaloopRequests.__putBulkTransfersError).toHaveBeenCalledTimes(1);
556
+ const call = MojaloopRequests.__putBulkTransfersError.mock.calls[0];
557
+ expect(call[0]).toEqual(BULK_TRANSFER_ID);
558
+ expect(call[1].errorInformation.errorCode).toEqual('2001');
559
+ });
560
+
561
+ test('pass on bulk transfer without bulk quote.', async () => {
562
+ const BULK_TRANSFER_ID = 'without_bulk-quote-bulk-transfer-id';
563
+ const args = {
564
+ bulkTransferId: BULK_TRANSFER_ID,
565
+ individualTransfers: [
566
+ {
567
+ transferId: 'fake-transfer-id',
568
+ transferAmount: {
569
+ currency: 'USD',
570
+ amount: 20.13
571
+ },
572
+ ilpPacket: 'mockBase64encodedIlpPacket',
573
+ condition: 'mockGeneratedCondition',
574
+ }
575
+ ]
576
+ };
577
+
578
+ const model = new Model({
579
+ ...config,
580
+ cache,
581
+ logger,
582
+ allowTransferWithoutQuote: true,
583
+ rejectTransfersOnExpiredQuotes: false,
584
+ });
585
+
586
+ await model.prepareBulkTransfer(args, mockArgs.fspId);
587
+
588
+ expect(MojaloopRequests.__putBulkTransfersError).toHaveBeenCalledTimes(0);
589
+ expect(BackendRequests.__postBulkTransfers).toHaveBeenCalledTimes(1);
590
+ expect(MojaloopRequests.__putBulkTransfers).toHaveBeenCalledTimes(1);
591
+ });
592
+ });
593
+
594
+ describe('sendNotificationToPayee:', () => {
595
+ const transferId = '1234';
596
+ let cache;
597
+
598
+ beforeEach(async () => {
599
+ cache = new Cache({
600
+ host: 'dummycachehost',
601
+ port: 1234,
602
+ logger,
603
+ });
604
+ await cache.connect();
605
+ });
606
+
607
+ afterEach(async () => {
608
+ await cache.disconnect();
609
+ });
610
+
611
+ test('sends notification to fsp backend', async () => {
612
+ BackendRequests.__putTransfersNotification = jest.fn().mockReturnValue(Promise.resolve({}));
613
+ const backendResponse = JSON.parse(JSON.stringify(notificationToPayee));
614
+
615
+ const model = new Model({
616
+ ...config,
617
+ cache,
618
+ logger,
619
+ });
620
+
621
+ await model.sendNotificationToPayee(backendResponse.data, transferId);
622
+ expect(BackendRequests.__putTransfersNotification).toHaveBeenCalledTimes(1);
623
+ const call = BackendRequests.__putTransfersNotification.mock.calls[0];
624
+ expect(call[0]).toEqual(backendResponse.data);
625
+ expect(call[1]).toEqual(transferId);
626
+ });
627
+ });
628
+ });