@mojaloop/central-ledger 9.2.2 → 15.1.3-snapshot.2

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 (256) hide show
  1. package/.circleci/config.yml +625 -204
  2. package/.env +3 -2
  3. package/.ncurc.yaml +9 -0
  4. package/.nvmrc +1 -1
  5. package/.versionrc +15 -0
  6. package/CHANGELOG.md +353 -0
  7. package/CODEOWNERS +31 -0
  8. package/Dockerfile +20 -14
  9. package/LICENSE.md +4 -4
  10. package/Onboarding.md +0 -7
  11. package/README.md +99 -22
  12. package/audit-resolve.json +136 -1
  13. package/config/default.json +82 -27
  14. package/docker/central-ledger/default.json +68 -21
  15. package/docker/ml-api-adapter/default.json +10 -1
  16. package/docker/wait-for/wait-for-objstore.sh +1 -6
  17. package/docker/wait-for/wait-for.env +1 -1
  18. package/docker-compose.integration.yml +8 -5
  19. package/docker-compose.yml +73 -16
  20. package/migrations/310203_transferParticipant-indexes.js +38 -0
  21. package/migrations/310503_participantLimit-indexes-composite.js +38 -0
  22. package/migrations/{400401_settlementWindowStateChange-indexes.js → 400401_settlmentWindowStateChange-indexes.js} +0 -0
  23. package/migrations/401301_settlementModel-indexes.js +2 -0
  24. package/migrations/500401_quote-hotfix-2719.js +58 -0
  25. package/migrations/500501_feature-fixSubIdRef.js +53 -0
  26. package/migrations/500601_party-2480.js +63 -0
  27. package/migrations/501001_quoteExtension-quote-service-174.js +46 -0
  28. package/migrations/501002_quoteExtension-2522.js +61 -0
  29. package/migrations/800101_feature-fixSubIdRef.js +90 -0
  30. package/migrations/910102_hotfix954.js +4 -1
  31. package/migrations/940100_quotePartyIdInfoExtension.js +52 -0
  32. package/migrations/940101_quotePartyIdInfoExtension-2522.js +64 -0
  33. package/migrations/950100_settlementContentAggregation-decimal184.js +40 -0
  34. package/migrations/950101_transferParticipantStateChange.js +46 -0
  35. package/migrations/950102_settlementModel-adjustPosition.js +42 -0
  36. package/migrations/950103_dropTransferParticipantStateChange.js +47 -0
  37. package/migrations/950104_settlementModel-settlementAccountTypeId.js +79 -0
  38. package/migrations/950106_unique_settlement_model_ledger_account_currency.js +38 -0
  39. package/migrations/950107_settlementWindowContent_foreign_settlementModel.js +60 -0
  40. package/package.json +99 -81
  41. package/scripts/_wait4_all.js +146 -0
  42. package/seeds/amountType.js +4 -6
  43. package/seeds/balanceOfPayments.js +4 -6
  44. package/seeds/bulkProcessingState.js +4 -6
  45. package/seeds/bulkTransferState.js +4 -6
  46. package/seeds/currency.js +4 -6
  47. package/seeds/endpointType.js +128 -7
  48. package/seeds/ledgerAccountType.js +11 -10
  49. package/seeds/ledgerEntryType.js +5 -7
  50. package/seeds/participant.js +4 -6
  51. package/seeds/participantLimitType.js +4 -6
  52. package/seeds/partyIdentifierType.js +4 -6
  53. package/seeds/partyType.js +4 -6
  54. package/seeds/settlementDelay.js +4 -6
  55. package/seeds/settlementGranularity.js +4 -6
  56. package/seeds/settlementInterchange.js +4 -6
  57. package/seeds/settlementState.js +4 -6
  58. package/seeds/settlementWindow1State.js +4 -6
  59. package/seeds/transactionInitiator.js +4 -6
  60. package/seeds/transactionInitiatorType.js +4 -6
  61. package/seeds/transactionScenario.js +4 -6
  62. package/seeds/transferParticipantRoleType.js +4 -6
  63. package/seeds/transferState.js +9 -6
  64. package/src/api/interface/swagger.json +728 -948
  65. package/src/api/ledgerAccountTypes/handler.js +55 -0
  66. package/src/api/ledgerAccountTypes/routes.js +63 -0
  67. package/src/api/metrics/handler.js +2 -2
  68. package/src/api/metrics/routes.js +1 -1
  69. package/src/api/participants/handler.js +43 -35
  70. package/src/api/participants/routes.js +13 -13
  71. package/src/api/root/routes.js +2 -2
  72. package/src/api/settlementModels/handler.js +9 -26
  73. package/src/api/settlementModels/routes.js +4 -4
  74. package/src/api/transactions/handler.js +46 -0
  75. package/src/api/transactions/routes.js +45 -0
  76. package/src/domain/bulkTransfer/index.js +6 -5
  77. package/src/domain/ledgerAccountTypes/index.js +58 -0
  78. package/src/domain/participant/index.js +55 -4
  79. package/src/domain/position/index.js +18 -2
  80. package/src/domain/settlement/index.js +39 -6
  81. package/src/domain/transactions/index.js +61 -0
  82. package/src/domain/transfer/index.js +22 -2
  83. package/src/domain/transfer/transform.js +3 -3
  84. package/src/handlers/admin/handler.js +24 -32
  85. package/src/handlers/bulk/fulfil/handler.js +89 -56
  86. package/src/handlers/bulk/get/handler.js +203 -0
  87. package/src/handlers/bulk/index.js +4 -1
  88. package/src/handlers/bulk/prepare/handler.js +30 -29
  89. package/src/handlers/bulk/processing/handler.js +61 -32
  90. package/src/handlers/bulk/shared/validator.js +13 -1
  91. package/src/handlers/index.js +18 -9
  92. package/src/handlers/positions/handler.js +67 -46
  93. package/src/handlers/register.js +7 -7
  94. package/src/handlers/timeouts/handler.js +9 -4
  95. package/src/handlers/transfers/handler.js +408 -182
  96. package/src/handlers/transfers/validator.js +41 -11
  97. package/src/lib/cache.js +8 -34
  98. package/src/lib/config.js +5 -7
  99. package/src/lib/enum.js +22 -22
  100. package/src/lib/enumCached.js +76 -0
  101. package/src/lib/healthCheck/subServiceHealth.js +2 -2
  102. package/src/lib/requestLogger.js +9 -9
  103. package/src/lib/urlParser.js +1 -1
  104. package/src/models/bulkTransfer/bulkTransfer.js +6 -6
  105. package/src/models/bulkTransfer/bulkTransferAssociation.js +3 -3
  106. package/src/models/bulkTransfer/bulkTransferDuplicateCheck.js +4 -4
  107. package/src/models/bulkTransfer/bulkTransferExtension.js +2 -2
  108. package/src/models/bulkTransfer/bulkTransferFulfilmentDuplicateCheck.js +4 -4
  109. package/src/models/bulkTransfer/bulkTransferStateChange.js +7 -7
  110. package/src/models/bulkTransfer/facade.js +54 -3
  111. package/src/models/bulkTransfer/individualTransfer.js +2 -2
  112. package/src/models/ilpPackets/ilpPacket.js +36 -0
  113. package/src/models/ledgerAccountType/ledgerAccountType.js +139 -3
  114. package/src/models/misc/migrationLock.js +1 -1
  115. package/src/models/misc/segment.js +1 -1
  116. package/src/models/participant/facade.js +226 -76
  117. package/src/models/participant/participant.js +6 -5
  118. package/src/models/participant/participantCached.js +8 -0
  119. package/src/models/participant/participantCurrency.js +7 -7
  120. package/src/models/participant/participantCurrencyCached.js +11 -1
  121. package/src/models/participant/participantLimit.js +13 -13
  122. package/src/models/participant/participantLimitCached.js +124 -0
  123. package/src/models/participant/participantPosition.js +34 -5
  124. package/src/models/participant/participantPositionChange.js +10 -2
  125. package/src/models/position/facade.js +112 -18
  126. package/src/models/position/participantPosition.js +6 -6
  127. package/src/models/settlement/settlementModel.js +92 -17
  128. package/src/models/settlement/settlementModelCached.js +139 -0
  129. package/src/models/transfer/facade.js +97 -32
  130. package/src/models/transfer/ilpPacket.js +4 -4
  131. package/src/models/transfer/transfer.js +7 -7
  132. package/src/models/transfer/transferDuplicateCheck.js +21 -5
  133. package/src/models/transfer/transferError.js +5 -5
  134. package/src/models/transfer/transferErrorDuplicateCheck.js +4 -4
  135. package/src/models/transfer/transferExtension.js +4 -4
  136. package/src/models/transfer/transferFulfilment.js +5 -5
  137. package/src/models/transfer/transferFulfilmentDuplicateCheck.js +4 -4
  138. package/src/models/transfer/transferParticipant.js +3 -3
  139. package/src/models/transfer/transferStateChange.js +11 -11
  140. package/src/models/transfer/transferTimeout.js +5 -5
  141. package/src/schema/bulkTransfer.js +4 -4
  142. package/src/shared/plugins.js +10 -9
  143. package/src/shared/setup.js +69 -46
  144. package/test/integration/domain/participant/index.test.js +2 -0
  145. package/test/integration/handlers/handlers.test.js +605 -166
  146. package/test/integration/handlers/root.test.js +1 -1
  147. package/test/integration/helpers/hubAccounts.js +62 -0
  148. package/test/integration/helpers/ilpPacket.js +1 -1
  149. package/test/integration/helpers/participantFundsInOut.js +80 -0
  150. package/test/integration/helpers/participantLimit.js +6 -1
  151. package/test/integration/helpers/settlementModels.js +88 -0
  152. package/test/integration/helpers/testConsumer.js +163 -0
  153. package/test/integration/helpers/testProducer.js +0 -1
  154. package/test/integration/helpers/transferDuplicateCheck.js +1 -1
  155. package/test/integration/helpers/transferStateChange.js +1 -1
  156. package/test/integration/helpers/transferTestHelper.js +3 -5
  157. package/test/integration/models/transfer/transferStateChange.test.js +6 -0
  158. package/test/unit/api/ledgerAccountTypes/handler.test.js +126 -0
  159. package/test/unit/api/ledgerAccountTypes/routes.test.js +52 -0
  160. package/test/unit/api/participants/handler.test.js +75 -33
  161. package/test/unit/api/root/handler.test.js +1 -1
  162. package/test/unit/api/root/routes.test.js +2 -2
  163. package/test/unit/api/settlementModels/handler.test.js +21 -57
  164. package/test/unit/api/transactions/handler.test.js +108 -0
  165. package/test/unit/api/transactions/routes.test.js +38 -0
  166. package/test/unit/domain/ledgerAccountTypes/index.test.js +197 -0
  167. package/test/unit/domain/participant/index.test.js +115 -2
  168. package/test/unit/domain/settlement/index.test.js +199 -29
  169. package/test/unit/domain/transactions/index.test.js +128 -0
  170. package/test/unit/domain/transfer/index.test.js +1 -0
  171. package/test/unit/domain/transfer/transform.test.js +2 -0
  172. package/test/unit/handlers/admin/handler.test.js +5 -5
  173. package/test/unit/handlers/bulk/get/handler.test.js +401 -0
  174. package/test/unit/handlers/index.test.js +6 -0
  175. package/test/unit/handlers/positions/handler.test.js +26 -0
  176. package/test/unit/handlers/register.test.js +2 -0
  177. package/test/unit/handlers/transfers/handler.test.js +491 -36
  178. package/test/unit/handlers/transfers/validator.test.js +31 -31
  179. package/test/unit/lib/cache.test.js +0 -64
  180. package/test/unit/lib/cachingOfEnums.test.js +121 -0
  181. package/test/unit/lib/config.test.js +34 -0
  182. package/test/unit/lib/enum.test.js +6 -1
  183. package/test/unit/lib/enumCached.test.js +82 -0
  184. package/test/unit/lib/healthCheck/subServiceHealth.test.js +2 -0
  185. package/test/unit/lib/requestLogger.test.js +14 -12
  186. package/test/unit/models/ilpPackets/ilpPacket.test.js +89 -0
  187. package/test/unit/models/ledgerAccountType/ledgerAccountType.test.js +255 -6
  188. package/test/unit/models/misc/migrationLock.test.js +4 -0
  189. package/test/unit/models/misc/segment.test.js +5 -0
  190. package/test/unit/models/participant/facade.test.js +493 -54
  191. package/test/unit/models/participant/participant.test.js +4 -0
  192. package/test/unit/models/participant/participantCurrency.test.js +22 -9
  193. package/test/unit/models/participant/participantCurrencyCached.test.js +1 -1
  194. package/test/unit/models/participant/participantLimit.test.js +97 -0
  195. package/test/unit/models/participant/participantLimitCached.test.js +232 -0
  196. package/test/unit/models/participant/participantPosition.test.js +217 -0
  197. package/test/unit/models/participant/participantPositionChange.test.js +3 -0
  198. package/test/unit/models/position/facade.test.js +318 -29
  199. package/test/unit/models/position/participantPosition.test.js +22 -7
  200. package/test/unit/models/settlement/settlementModel.test.js +18 -37
  201. package/test/unit/models/settlement/settlementModelCached.test.js +171 -0
  202. package/test/unit/models/transfer/facade.test.js +115 -0
  203. package/test/unit/models/transfer/ilpPacket.test.js +28 -11
  204. package/test/unit/models/transfer/transfer.test.js +13 -4
  205. package/test/unit/models/transfer/transferDuplicateCheck.test.js +4 -0
  206. package/test/unit/models/transfer/transferError.test.js +5 -1
  207. package/test/unit/models/transfer/transferErrorDuplicateCheck.test.js +4 -0
  208. package/test/unit/models/transfer/transferExtension.test.js +26 -9
  209. package/test/unit/models/transfer/transferFulfilment.test.js +14 -5
  210. package/test/unit/models/transfer/transferFulfilmentDuplicateCheck.test.js +4 -0
  211. package/test/unit/models/transfer/transferParticipant.test.js +14 -5
  212. package/test/unit/models/transfer/transferStateChange.test.js +3 -0
  213. package/test/unit/models/transfer/transferTimeout.test.js +6 -0
  214. package/test/unit/seeds/amountType.test.js +6 -22
  215. package/test/unit/seeds/balanceOfPayments.test.js +6 -22
  216. package/test/unit/seeds/bulkProcessingState.test.js +84 -0
  217. package/test/unit/{lib/sidecar/nullClient.test.js → seeds/bulkTransferState.test.js} +36 -39
  218. package/test/unit/seeds/currency.test.js +6 -22
  219. package/test/unit/seeds/endpointType.test.js +6 -22
  220. package/test/unit/seeds/ledgerAccountType.test.js +5 -22
  221. package/test/unit/seeds/ledgerEntryType.test.js +6 -22
  222. package/test/unit/seeds/participant.test.js +5 -22
  223. package/test/unit/seeds/participantLimitType.test.js +6 -22
  224. package/test/unit/seeds/partyIdentifierType.test.js +6 -22
  225. package/test/unit/seeds/partyType.test.js +6 -22
  226. package/test/unit/seeds/settlementState.test.js +5 -22
  227. package/test/unit/seeds/settlementWindow1State.test.js +5 -22
  228. package/test/unit/seeds/transactionInitiator.test.js +6 -22
  229. package/test/unit/seeds/transactionInitiatorType.test.js +6 -22
  230. package/test/unit/seeds/transactionScenario.test.js +6 -22
  231. package/test/unit/seeds/transferParticipantRoleType.test.js +6 -22
  232. package/test/unit/seeds/transferState.test.js +6 -22
  233. package/test/unit/shared/plugins.test.js +31 -1
  234. package/test/unit/shared/setup.test.js +25 -36
  235. package/test/util/helpers.js +37 -2
  236. package/test/util/randomTransfers.js +1 -1
  237. package/test/util/scripts/env.sh +6 -5
  238. package/test/util/scripts/populateTestData.sh +204 -181
  239. package/test/util/scripts/populateTestDataForLegacySimulator.sh +261 -0
  240. package/test/util/scripts/restartObjStore.sh +1 -1
  241. package/test-integration.Dockerfile +15 -15
  242. package/test.Dockerfile +12 -12
  243. package/.circleci/_set_up_deploy_envs.sh +0 -47
  244. package/.dockerignore +0 -17
  245. package/.ncurc.json +0 -3
  246. package/server.sh +0 -4
  247. package/sonar-project.properties +0 -17
  248. package/src/lib/sidecar/index.js +0 -47
  249. package/src/lib/sidecar/nullClient.js +0 -18
  250. package/test/.env +0 -8
  251. package/test/integration-config.json +0 -367
  252. package/test/integration-runner.env +0 -31
  253. package/test/integration-runner.sh +0 -264
  254. package/test/spec-runner.sh +0 -132
  255. package/test/unit/lib/sidecar/index.test.js +0 -148
  256. package/test/unit/models/position/participantLimit.test.js +0 -135
@@ -30,17 +30,33 @@
30
30
  const Test = require('tapes')(require('tape'))
31
31
  const Sinon = require('sinon')
32
32
  const Db = require('../../../../src/lib/db')
33
+ const Cache = require('../../../../src/lib/cache')
33
34
  const Logger = require('@mojaloop/central-services-logger')
34
- const Model = require('../../../../src/models/participant/facade')
35
+ const Proxyquire = require('proxyquire').callThru()
36
+ const Model = Proxyquire('../../../../src/models/participant/facade', {
37
+ '../../lib/config': {
38
+ HUB_NAME: 'Hub'
39
+ }
40
+ })
35
41
  const Enum = require('@mojaloop/central-services-shared').Enum
42
+ const ParticipantModel = require('../../../../src/models/participant/participantCached')
36
43
  const ParticipantCurrencyModel = require('../../../../src/models/participant/participantCurrencyCached')
44
+ const ParticipantLimitModel = require('../../../../src/models/participant/participantLimitCached')
45
+ const SettlementModel = require('../../../../src/models/settlement/settlementModel')
37
46
 
38
47
  Test('Participant facade', async (facadeTest) => {
39
48
  let sandbox
40
49
 
41
50
  facadeTest.beforeEach(t => {
42
51
  sandbox = Sinon.createSandbox()
52
+ sandbox.stub(ParticipantModel, 'getById')
53
+ sandbox.stub(ParticipantModel, 'getByName')
54
+ sandbox.stub(ParticipantCurrencyModel, 'findOneByParams')
43
55
  sandbox.stub(ParticipantCurrencyModel, 'invalidateParticipantCurrencyCache')
56
+ sandbox.stub(ParticipantLimitModel, 'getByParticipantCurrencyId')
57
+ sandbox.stub(ParticipantLimitModel, 'invalidateParticipantLimitCache')
58
+ sandbox.stub(SettlementModel, 'getAll')
59
+ sandbox.stub(Cache)
44
60
  Db.participant = {
45
61
  query: sandbox.stub()
46
62
  }
@@ -56,6 +72,9 @@ Test('Participant facade', async (facadeTest) => {
56
72
  Db.participantPosition = {
57
73
  query: sandbox.stub()
58
74
  }
75
+ Db.from = (table) => {
76
+ return Db[table]
77
+ }
59
78
  t.end()
60
79
  })
61
80
 
@@ -97,8 +116,38 @@ Test('Participant facade', async (facadeTest) => {
97
116
  name: 'ALARM_NOTIFICATION_URL'
98
117
  }
99
118
  ]
119
+ const settlementModelFixtures = [
120
+ {
121
+ settlementModelId: 1,
122
+ name: 'DEFERREDNET',
123
+ isActive: 1,
124
+ settlementGranularityId: 2,
125
+ settlementInterchangeId: 2,
126
+ settlementDelayId: 2,
127
+ currencyId: 'USD',
128
+ requireLiquidityCheck: 1,
129
+ ledgerAccountTypeId: 1,
130
+ autoPositionReset: 1,
131
+ adjustPosition: 0,
132
+ settlementAccountTypeId: 2
133
+ },
134
+ {
135
+ settlementModelId: 2,
136
+ name: 'INTERCHANGEFEE',
137
+ isActive: 1,
138
+ settlementGranularityId: 2,
139
+ settlementInterchangeId: 2,
140
+ settlementDelayId: 2,
141
+ currencyId: 'USD',
142
+ requireLiquidityCheck: 0,
143
+ ledgerAccountTypeId: 5,
144
+ autoPositionReset: 1,
145
+ adjustPosition: 0,
146
+ settlementAccountTypeId: 6
147
+ }
148
+ ]
100
149
 
101
- await facadeTest.test('getByNameAndCurrency', async (assert) => {
150
+ await facadeTest.test('getByNameAndCurrency (cache off)', async (assert) => {
102
151
  try {
103
152
  const builderStub = sandbox.stub()
104
153
  Db.participant.query.callsArgWith(0, builderStub)
@@ -126,7 +175,7 @@ Test('Participant facade', async (facadeTest) => {
126
175
  }
127
176
  })
128
177
 
129
- await facadeTest.test('getByNameAndCurrency', async (assert) => {
178
+ await facadeTest.test('getByNameAndCurrency (cache off)', async (assert) => {
130
179
  try {
131
180
  const builderStub = sandbox.stub()
132
181
  Db.participant.query.callsArgWith(0, builderStub)
@@ -156,7 +205,7 @@ Test('Participant facade', async (facadeTest) => {
156
205
  }
157
206
  })
158
207
 
159
- await facadeTest.test('getByNameAndCurrency should throw error', async (assert) => {
208
+ await facadeTest.test('getByNameAndCurrency should throw error (cache off)', async (assert) => {
160
209
  try {
161
210
  Db.participant.query.throws(new Error('message'))
162
211
  await Model.getByNameAndCurrency({ name: 'fsp1', currencyId: 'USD', ledgerAccountTypeId: 1 })
@@ -169,11 +218,11 @@ Test('Participant facade', async (facadeTest) => {
169
218
  }
170
219
  })
171
220
 
172
- await facadeTest.test('getByNameAndCurrency should throw error when participant not found', async (assert) => {
221
+ await facadeTest.test('getByNameAndCurrency should throw error when participant not found (cache off)', async (assert) => {
173
222
  try {
174
223
  Db.participant.query.throws(new Error('message'))
175
224
  await Model.getByNameAndCurrency({ name: 'fsp3', currencyId: 'USD', ledgerAccountTypeId: 1 })
176
- assert.fail(' should throw')
225
+ assert.fail('should throw')
177
226
  assert.end()
178
227
  } catch (err) {
179
228
  Logger.error(`getByNameAndCurrency failed with error - ${err}`)
@@ -182,6 +231,49 @@ Test('Participant facade', async (facadeTest) => {
182
231
  }
183
232
  })
184
233
 
234
+ await facadeTest.test('getByNameAndCurrency (cache on)', async (assert) => {
235
+ try {
236
+ Cache.isCacheEnabled.returns(true)
237
+
238
+ ParticipantModel.getByName.withArgs(participant.name).returns(participant)
239
+ ParticipantCurrencyModel.findOneByParams.withArgs({
240
+ participantId: participant.participantId,
241
+ currencyId: participant.currency,
242
+ ledgerAccountTypeId: Enum.Accounts.LedgerAccountType.POSITION
243
+ }).returns(participant)
244
+
245
+ const result = await Model.getByNameAndCurrency(participant.name, participant.currency, Enum.Accounts.LedgerAccountType.POSITION)
246
+ assert.deepEqual(result, participant)
247
+ assert.end()
248
+ } catch (err) {
249
+ Logger.error(`getByNameAndCurrency failed with error - ${err}`)
250
+ assert.fail()
251
+ assert.end()
252
+ }
253
+ })
254
+
255
+ await facadeTest.test('getByNameAndCurrency isCurrencyActive:true (cache on)', async (assert) => {
256
+ try {
257
+ Cache.isCacheEnabled.returns(true)
258
+
259
+ ParticipantModel.getByName.withArgs(participant.name).returns(participant)
260
+ ParticipantCurrencyModel.findOneByParams.withArgs({
261
+ participantId: participant.participantId,
262
+ currencyId: participant.currency,
263
+ ledgerAccountTypeId: Enum.Accounts.LedgerAccountType.POSITION,
264
+ isActive: true
265
+ }).returns(participant)
266
+
267
+ const result = await Model.getByNameAndCurrency(participant.name, participant.currency, Enum.Accounts.LedgerAccountType.POSITION, true)
268
+ assert.deepEqual(result, participant)
269
+ assert.end()
270
+ } catch (err) {
271
+ Logger.error(`getByNameAndCurrency failed with error - ${err}`)
272
+ assert.fail()
273
+ assert.end()
274
+ }
275
+ })
276
+
185
277
  await facadeTest.test('getEndpoint', async (assert) => {
186
278
  try {
187
279
  const builderStub = sandbox.stub()
@@ -438,7 +530,7 @@ Test('Participant facade', async (facadeTest) => {
438
530
  }
439
531
  })
440
532
 
441
- await facadeTest.test('addLimitAndInitialPosition', async (assert) => {
533
+ await facadeTest.test('addLimitAndInitialPosition with settlementModel', async (assert) => {
442
534
  try {
443
535
  const limitPositionObj = {
444
536
  currency: 'USD',
@@ -468,32 +560,89 @@ Test('Participant facade', async (facadeTest) => {
468
560
  insert: insertStub
469
561
  })
470
562
  })
471
- const participantPosition = {
472
- participantCurrencyId: 1,
473
- value: limitPositionObj.initialPosition,
474
- reservedValue: 0,
475
- participantPositionId: 1
476
- }
477
- const settlementPosition = {
478
- participantCurrencyId: 2,
479
- value: 0,
480
- reservedValue: 0,
481
- participantPositionId: 1
482
- }
483
- const participantLimit = {
484
- participantCurrencyId: 1,
485
- participantLimitTypeId: 1,
486
- value: limitPositionObj.limit.value,
487
- isActive: 1,
488
- createdBy: 'unknown',
489
- participantLimitId: 1
563
+ const builderStub = sandbox.stub()
564
+ Db.participant.query.callsArgWith(0, builderStub)
565
+ builderStub.where = sandbox.stub()
566
+
567
+ builderStub.where.returns({
568
+ andWhere: sandbox.stub().returns({
569
+ andWhere: sandbox.stub().returns({
570
+ innerJoin: sandbox.stub().returns({
571
+ select: sandbox.stub().returns({
572
+ first: sandbox.stub().returns(participant)
573
+ })
574
+ })
575
+ })
576
+ })
577
+ })
578
+
579
+ SettlementModel.getAll.returns(Promise.resolve(settlementModelFixtures))
580
+ const result = await Model.addLimitAndInitialPosition(participant.participantCurrencyId, participant.settlementAccountId, limitPositionObj)
581
+ assert.pass('completed successfully')
582
+ assert.ok(knexStub.withArgs('participantLimit').calledOnce, 'knex called with participantLimit once')
583
+ assert.equal(knexStub.withArgs('participantPosition').callCount, 4, 'knex called with participantPosition 4 times')
584
+ assert.equal(result, true)
585
+
586
+ assert.end()
587
+ } catch (err) {
588
+ Logger.error(`addLimitAndInitialPosition failed with error - ${err}`)
589
+ assert.fail()
590
+ assert.end()
591
+ }
592
+ })
593
+
594
+ await facadeTest.test('addLimitAndInitialPosition without settlementModel', async (assert) => {
595
+ try {
596
+ const limitPositionObj = {
597
+ currency: 'USD',
598
+ limit: {
599
+ type: 'NET_DEBIT_CAP',
600
+ value: 10000000
601
+ },
602
+ initialPosition: 0
490
603
  }
604
+ sandbox.stub(Db, 'getKnex')
605
+ const knexStub = sandbox.stub()
606
+ const trxStub = sandbox.stub()
607
+ trxStub.commit = sandbox.stub()
608
+ knexStub.transaction = sandbox.stub().callsArgWith(0, trxStub)
609
+ Db.getKnex.returns(knexStub)
610
+
611
+ const insertStub = sandbox.stub()
612
+ insertStub.returns([1])
613
+
614
+ knexStub.returns({
615
+ where: sandbox.stub().returns({
616
+ select: sandbox.stub().returns({
617
+ first: sandbox.stub().returns({ participantLimitTypeId: 1 })
618
+ })
619
+ }),
620
+ transacting: sandbox.stub().returns({
621
+ insert: insertStub
622
+ })
623
+ })
624
+ const builderStub = sandbox.stub()
625
+ Db.participant.query.callsArgWith(0, builderStub)
626
+ builderStub.where = sandbox.stub()
627
+
628
+ builderStub.where.returns({
629
+ andWhere: sandbox.stub().returns({
630
+ andWhere: sandbox.stub().returns({
631
+ innerJoin: sandbox.stub().returns({
632
+ select: sandbox.stub().returns({
633
+ first: sandbox.stub().returns(participant)
634
+ })
635
+ })
636
+ })
637
+ })
638
+ })
491
639
 
640
+ SettlementModel.getAll.returns(Promise.resolve([]))
492
641
  const result = await Model.addLimitAndInitialPosition(participant.participantCurrencyId, participant.settlementAccountId, limitPositionObj)
493
642
  assert.pass('completed successfully')
494
643
  assert.ok(knexStub.withArgs('participantLimit').calledOnce, 'knex called with participantLimit once')
495
- assert.ok(knexStub.withArgs('participantPosition').calledTwice, 'knex called with participantPosition once')
496
- assert.deepEqual(result, { participantLimit, participantPosition, settlementPosition })
644
+ assert.equal(knexStub.withArgs('participantPosition').callCount, 2, 'knex called with participantPosition 2 times')
645
+ assert.equal(result, true)
497
646
 
498
647
  assert.end()
499
648
  } catch (err) {
@@ -511,7 +660,8 @@ Test('Participant facade', async (facadeTest) => {
511
660
  type: 'NET_DEBIT_CAP',
512
661
  value: 10000000
513
662
  },
514
- initialPosition: 0
663
+ initialPosition: 0,
664
+ name: participant.name
515
665
  }
516
666
  sandbox.stub(Db, 'getKnex')
517
667
  const knexStub = sandbox.stub()
@@ -539,32 +689,28 @@ Test('Participant facade', async (facadeTest) => {
539
689
  })
540
690
  })
541
691
  })
542
- const participantPosition = {
543
- participantCurrencyId: 1,
544
- value: limitPositionObj.initialPosition,
545
- reservedValue: 0,
546
- participantPositionId: 1
547
- }
548
- const settlementPosition = {
549
- participantCurrencyId: 2,
550
- value: 0,
551
- reservedValue: 0,
552
- participantPositionId: 1
553
- }
554
- const participantLimit = {
555
- participantCurrencyId: 1,
556
- participantLimitTypeId: 1,
557
- value: limitPositionObj.limit.value,
558
- isActive: 1,
559
- createdBy: 'unknown',
560
- participantLimitId: 1
561
- }
692
+ const builderStub = sandbox.stub()
693
+ Db.participant.query.callsArgWith(0, builderStub)
694
+ builderStub.where = sandbox.stub()
562
695
 
696
+ builderStub.where.returns({
697
+ andWhere: sandbox.stub().returns({
698
+ andWhere: sandbox.stub().returns({
699
+ innerJoin: sandbox.stub().returns({
700
+ select: sandbox.stub().returns({
701
+ first: sandbox.stub().returns(participant)
702
+ })
703
+ })
704
+ })
705
+ })
706
+ })
707
+
708
+ SettlementModel.getAll.returns(Promise.resolve(settlementModelFixtures))
563
709
  const result = await Model.addLimitAndInitialPosition(participant.participantCurrencyId, participant.settlementAccountId, limitPositionObj, true)
564
710
  assert.pass('completed successfully')
565
711
  assert.ok(knexStub.withArgs('participantLimit').calledOnce, 'knex called with participantLimit once')
566
- assert.ok(knexStub.withArgs('participantPosition').calledTwice, 'knex called with participantPosition once')
567
- assert.deepEqual(result, { participantLimit, participantPosition, settlementPosition })
712
+ assert.equal(knexStub.withArgs('participantPosition').callCount, 4, 'knex called with participantPosition 4 times')
713
+ assert.equal(result, true)
568
714
 
569
715
  assert.end()
570
716
  } catch (err) {
@@ -1024,7 +1170,7 @@ Test('Participant facade', async (facadeTest) => {
1024
1170
  }
1025
1171
  })
1026
1172
 
1027
- await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit', async (assert) => {
1173
+ await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit (cache off)', async (assert) => {
1028
1174
  try {
1029
1175
  const participantLimit = {
1030
1176
  participantId: 1,
@@ -1061,7 +1207,7 @@ Test('Participant facade', async (facadeTest) => {
1061
1207
  }
1062
1208
  })
1063
1209
 
1064
- await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit should throw error', async (assert) => {
1210
+ await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit (cache off) should throw error', async (assert) => {
1065
1211
  try {
1066
1212
  const builderStub = sandbox.stub()
1067
1213
  Db.participant.query.callsArgWith(0, builderStub)
@@ -1073,7 +1219,6 @@ Test('Participant facade', async (facadeTest) => {
1073
1219
  await Model.getParticipantLimitByParticipantCurrencyLimit(participant.participantId, participant.currency, ledgerAccountTypeId, participantLimitTypeId)
1074
1220
  assert.fail(' should throw')
1075
1221
  assert.end()
1076
- assert.end()
1077
1222
  } catch (err) {
1078
1223
  Logger.error(`getParticipantLimitByParticipantCurrencyLimit failed with error - ${err}`)
1079
1224
  assert.pass('Error thrown')
@@ -1081,6 +1226,166 @@ Test('Participant facade', async (facadeTest) => {
1081
1226
  }
1082
1227
  })
1083
1228
 
1229
+ await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit (cache on)', async (assert) => {
1230
+ try {
1231
+ /* Setup case for full pass - return of data */
1232
+ Cache.isCacheEnabled.returns(true)
1233
+
1234
+ const participantLimitData = {
1235
+ participantId: 123,
1236
+ currencyId: 456,
1237
+ participantLimitTypeId: 789,
1238
+ value: 1000000
1239
+ }
1240
+ const ledgerAccountTypeId = 1
1241
+ const participantLimitTypeId = 2
1242
+
1243
+ const setupMockData = () => {
1244
+ ParticipantModel.getById.withArgs(participantLimitData.participantId).returns({
1245
+ participantId: participantLimitData.participantId,
1246
+ isActive: true
1247
+ })
1248
+ ParticipantCurrencyModel.findOneByParams.returns({
1249
+ participantCurrencyId: 321,
1250
+ currencyId: participantLimitData.currencyId,
1251
+ isActive: true
1252
+ })
1253
+ ParticipantLimitModel.getByParticipantCurrencyId.withArgs(321).returns({
1254
+ isActive: true,
1255
+ ...participantLimitData
1256
+ })
1257
+ }
1258
+
1259
+ const callGetParticipantLimitByParticipantCurrencyLimit = async () => {
1260
+ return Model.getParticipantLimitByParticipantCurrencyLimit(
1261
+ participantLimitData.participantId,
1262
+ participantLimitData.currency,
1263
+ ledgerAccountTypeId,
1264
+ participantLimitTypeId
1265
+ )
1266
+ }
1267
+
1268
+ /* Check the data is returned correctly for correct setup of data in cache */
1269
+ setupMockData()
1270
+ const result = await callGetParticipantLimitByParticipantCurrencyLimit()
1271
+ assert.deepEqual(result, participantLimitData, 'should return correct data')
1272
+
1273
+ /* Setup case for failure #1: can't find participant by participantId */
1274
+ ParticipantModel.getById.withArgs(participantLimitData.participantId).returns()
1275
+ const result2 = await callGetParticipantLimitByParticipantCurrencyLimit()
1276
+ assert.deepEqual(result2, undefined, 'should return nothing when cannot find by participantId')
1277
+
1278
+ /* Ensure the data is returned correctly for correct setup of data in cache */
1279
+ setupMockData()
1280
+ const result3 = await callGetParticipantLimitByParticipantCurrencyLimit()
1281
+ assert.deepEqual(result3, participantLimitData, 'should return correct data')
1282
+
1283
+ /* Setup case for failure #2: can't find participantCurrency */
1284
+ ParticipantCurrencyModel.findOneByParams.returns()
1285
+ const result4 = await callGetParticipantLimitByParticipantCurrencyLimit()
1286
+ assert.deepEqual(result4, undefined, 'should return nothing when cannot find participantCurrency')
1287
+
1288
+ /* Ensure the data is returned correctly for correct setup of data in cache */
1289
+ setupMockData()
1290
+ const result5 = await callGetParticipantLimitByParticipantCurrencyLimit()
1291
+ assert.deepEqual(result5, participantLimitData, 'should return correct data')
1292
+
1293
+ /* Setup case for failure #3: can't find participantLimit data */
1294
+ ParticipantLimitModel.getByParticipantCurrencyId.withArgs(321).returns()
1295
+ const result6 = await callGetParticipantLimitByParticipantCurrencyLimit()
1296
+ assert.deepEqual(result6, undefined, 'should return nothing when cannot find participantLimit')
1297
+
1298
+ assert.end()
1299
+ } catch (err) {
1300
+ Logger.error(`getParticipantLimitByParticipantCurrencyLimit failed with error - ${err}`)
1301
+ assert.fail()
1302
+ assert.end()
1303
+ }
1304
+ })
1305
+
1306
+ await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit returns undefined when participant not found by participantId (cache on)', async (assert) => {
1307
+ try {
1308
+ Cache.isCacheEnabled.returns(true)
1309
+
1310
+ const participantLimitData = {
1311
+ participantId: 123,
1312
+ currencyId: 456,
1313
+ participantLimitTypeId: 789,
1314
+ value: 1000000
1315
+ }
1316
+ const ledgerAccountTypeId = 1
1317
+ const participantLimitTypeId = 2
1318
+
1319
+ ParticipantModel.getById.withArgs(participantLimitData.participantId).returns()
1320
+
1321
+ const result = await Model.getParticipantLimitByParticipantCurrencyLimit(
1322
+ participantLimitData.participantId,
1323
+ participantLimitData.currency,
1324
+ ledgerAccountTypeId,
1325
+ participantLimitTypeId
1326
+ )
1327
+ assert.deepEqual(result, undefined, 'should return undefined')
1328
+ assert.end()
1329
+ } catch (err) {
1330
+ Logger.error(`getParticipantLimitByParticipantCurrencyLimit failed with error - ${err}`)
1331
+ assert.fail()
1332
+ assert.end()
1333
+ }
1334
+ })
1335
+
1336
+ await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit returns undefined when participantCurrency not found by currencyId (cache on)', async (assert) => {
1337
+ try {
1338
+ Cache.isCacheEnabled.returns(true)
1339
+
1340
+ const participantLimitData = {
1341
+ participantId: 123,
1342
+ currencyId: 456,
1343
+ participantLimitTypeId: 789,
1344
+ value: 1000000
1345
+ }
1346
+ const ledgerAccountTypeId = 1
1347
+ const participantLimitTypeId = 2
1348
+
1349
+ ParticipantModel.getById.withArgs(participantLimitData.participantId).returns({
1350
+ participantId: participantLimitData.participantId,
1351
+ isActive: true
1352
+ })
1353
+ ParticipantCurrencyModel.findOneByParams.returns()
1354
+
1355
+ const result = await Model.getParticipantLimitByParticipantCurrencyLimit(
1356
+ participantLimitData.participantId,
1357
+ participantLimitData.currency,
1358
+ ledgerAccountTypeId,
1359
+ participantLimitTypeId
1360
+ )
1361
+ assert.deepEqual(result, undefined, 'should return undefined')
1362
+ assert.end()
1363
+ } catch (err) {
1364
+ Logger.error(`getParticipantLimitByParticipantCurrencyLimit failed with error - ${err}`)
1365
+ assert.fail()
1366
+ assert.end()
1367
+ }
1368
+ })
1369
+
1370
+ await facadeTest.test('getParticipantLimitByParticipantCurrencyLimit (cache on) should throw error', async (assert) => {
1371
+ try {
1372
+ Cache.isCacheEnabled.returns(true)
1373
+
1374
+ const ledgerAccountTypeId = 1
1375
+ const participantLimitTypeId = 2
1376
+
1377
+ ParticipantModel.getById.withArgs(participant.participantId).throws(new Error())
1378
+ await Model.getParticipantLimitByParticipantCurrencyLimit(participant.participantId, participant.currency, ledgerAccountTypeId, participantLimitTypeId)
1379
+
1380
+ assert.fail('should throw')
1381
+ assert.end()
1382
+ } catch (err) {
1383
+ Logger.error(`getParticipantLimitByParticipantCurrencyLimit failed with error - ${err}`)
1384
+ assert.pass('Did throw')
1385
+ assert.end()
1386
+ }
1387
+ })
1388
+
1084
1389
  await facadeTest.test('addHubAccountAndInitPosition', async (assert) => {
1085
1390
  try {
1086
1391
  const participantPosition = {
@@ -1455,6 +1760,140 @@ Test('Participant facade', async (facadeTest) => {
1455
1760
  test.end()
1456
1761
  }
1457
1762
  })
1763
+ await facadeTest.test('getAllNonHubParticipantsWithCurrencies should', async (test) => {
1764
+ try {
1765
+ sandbox.stub(Db, 'getKnex')
1766
+ const knexStub = sandbox.stub()
1767
+ const trxStub = {
1768
+ get commit () {
1769
+
1770
+ },
1771
+ get rollback () {
1772
+
1773
+ }
1774
+ }
1775
+ const trxSpyCommit = sandbox.spy(trxStub, 'commit', ['get'])
1776
+
1777
+ knexStub.transaction = sandbox.stub().callsArgWith(0, trxStub)
1778
+ Db.getKnex.returns(knexStub)
1779
+ const transactingStub = sandbox.stub()
1780
+ const distinctStub = sandbox.stub()
1781
+ const fromStub = sandbox.stub()
1782
+ const innerJoinStub = sandbox.stub()
1783
+ const whereNotStub = sandbox.stub()
1784
+ const participantsWithCurrencies = [{
1785
+ participantId: 1,
1786
+ currencyId: 'USD'
1787
+ }]
1788
+ transactingStub.resolves(participantsWithCurrencies)
1789
+ whereNotStub.returns({ transacting: transactingStub })
1790
+ innerJoinStub.returns({ whereNot: whereNotStub })
1791
+ fromStub.returns({ innerJoin: innerJoinStub })
1792
+ knexStub.distinct = distinctStub.returns({ from: fromStub })
1793
+
1794
+ const response = await Model.getAllNonHubParticipantsWithCurrencies(trxStub)
1795
+ test.equal(whereNotStub.lastCall.args[0], 'participant.name', 'filter on participants name')
1796
+ test.equal(whereNotStub.lastCall.args[1], 'Hub', 'filter out the Hub')
1797
+ test.equal(transactingStub.lastCall.args[0], trxStub, 'run as transaction')
1798
+ test.equal(trxSpyCommit.get.calledOnce, false, 'not commit the transaction if transaction is passed')
1799
+ test.deepEqual(response, participantsWithCurrencies, 'return participants with currencies')
1800
+ test.end()
1801
+ } catch (err) {
1802
+ Logger.error(`getAllNonHubParticipantsWithCurrencies failed with error - ${err}`)
1803
+ test.fail('Error thrown')
1804
+ test.end()
1805
+ }
1806
+ })
1807
+
1808
+ await facadeTest.test('getAllNonHubParticipantsWithCurrencies should', async (test) => {
1809
+ try {
1810
+ sandbox.stub(Db, 'getKnex')
1811
+ const knexStub = sandbox.stub()
1812
+ const trxStub = {
1813
+ get commit () {
1814
+
1815
+ },
1816
+ get rollback () {
1817
+
1818
+ }
1819
+ }
1820
+ const trxSpyCommit = sandbox.spy(trxStub, 'commit', ['get'])
1821
+
1822
+ knexStub.transaction = sandbox.stub().callsArgWith(0, trxStub)
1823
+ Db.getKnex.returns(knexStub)
1824
+ const transactingStub = sandbox.stub()
1825
+ const distinctStub = sandbox.stub()
1826
+ const fromStub = sandbox.stub()
1827
+ const innerJoinStub = sandbox.stub()
1828
+ const whereNotStub = sandbox.stub()
1829
+ const participantsWithCurrencies = [{
1830
+ participantId: 1,
1831
+ currencyId: 'USD'
1832
+ }]
1833
+ transactingStub.resolves(participantsWithCurrencies)
1834
+ whereNotStub.returns({ transacting: transactingStub })
1835
+ innerJoinStub.returns({ whereNot: whereNotStub })
1836
+ fromStub.returns({ innerJoin: innerJoinStub })
1837
+ knexStub.distinct = distinctStub.returns({ from: fromStub })
1838
+
1839
+ const response = await Model.getAllNonHubParticipantsWithCurrencies()
1840
+ test.equal(whereNotStub.lastCall.args[0], 'participant.name', 'filter on participants name')
1841
+ test.equal(whereNotStub.lastCall.args[1], 'Hub', 'filter out the Hub')
1842
+ test.equal(transactingStub.lastCall.args[0], trxStub, 'run as transaction')
1843
+ test.equal(trxSpyCommit.get.calledOnce, true, 'commit the transaction if no transaction is passed')
1844
+
1845
+ test.deepEqual(response, participantsWithCurrencies, 'return participants with currencies')
1846
+ test.end()
1847
+ } catch (err) {
1848
+ Logger.error(`getAllNonHubParticipantsWithCurrencies failed with error - ${err}`)
1849
+ test.fail('Error thrown')
1850
+ test.end()
1851
+ }
1852
+ })
1853
+
1854
+ await facadeTest.test('getAllNonHubParticipantsWithCurrencies should', async (test) => {
1855
+ let trxStub
1856
+ try {
1857
+ sandbox.stub(Db, 'getKnex')
1858
+ const knexStub = sandbox.stub()
1859
+ trxStub = sandbox.stub()
1860
+ trxStub.commit = sandbox.stub()
1861
+ trxStub.rollback = sandbox.stub()
1862
+ knexStub.transaction = sandbox.stub().callsArgWith(0, trxStub)
1863
+ Db.getKnex.returns(knexStub)
1864
+ const transactingStub = sandbox.stub()
1865
+ const distinctStub = sandbox.stub()
1866
+ const fromStub = sandbox.stub()
1867
+ const innerJoinStub = sandbox.stub()
1868
+ const whereNotStub = sandbox.stub()
1869
+
1870
+ transactingStub.rejects(new Error())
1871
+ whereNotStub.returns({ transacting: transactingStub })
1872
+ innerJoinStub.returns({ whereNot: whereNotStub })
1873
+ fromStub.returns({ innerJoin: innerJoinStub })
1874
+ knexStub.distinct = distinctStub.returns({ from: fromStub })
1875
+ await Model.getAllNonHubParticipantsWithCurrencies()
1876
+ test.fail('have thrown an error')
1877
+ test.end()
1878
+ } catch (err) {
1879
+ test.pass('throw an error')
1880
+ test.equal(trxStub.rollback.callCount, 0, 'not rollback the transaction if transaction is passed')
1881
+ test.end()
1882
+ }
1883
+ })
1884
+
1885
+ await facadeTest.test('getAllNonHubParticipantsWithCurrencies should', async (test) => {
1886
+ try {
1887
+ sandbox.stub(Db, 'getKnex')
1888
+ Db.getKnex.throws(new Error())
1889
+ await Model.getAllNonHubParticipantsWithCurrencies()
1890
+ test.fail('have thrown an error')
1891
+ test.end()
1892
+ } catch (err) {
1893
+ test.pass('throw an error')
1894
+ test.end()
1895
+ }
1896
+ })
1458
1897
 
1459
1898
  await facadeTest.end()
1460
1899
  })
@@ -68,6 +68,10 @@ Test('Participant model', async (participantTest) => {
68
68
  destroy: sandbox.stub()
69
69
  }
70
70
 
71
+ Db.from = (table) => {
72
+ return Db[table]
73
+ }
74
+
71
75
  t.end()
72
76
  })
73
77