From eaa0ce0c8476880ee472a22c11cfdc16de09dc7d Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Thu, 18 Jul 2024 09:17:01 -0500 Subject: [PATCH] feat(csi-22): add proxy lib to handlers (#1060) * feat(csi-22): add proxy lib to handlers * diff * add * int tests * fix hanging int tests * fixes? * unit fixes? * coverage * feat: refactor proxy cache integration * feat: restore default * feat: minor optimization * test: update coverage * test: remove try-catch * fix: fix disconnect error * feat: proxy cache update (#1061) * addressed comments --------- Co-authored-by: Steven Oderayi --- config/default.json | 8 + docker-compose.yml | 13 ++ docker/central-ledger/default.json | 8 + .../config-modifier/configs/central-ledger.js | 8 + package-lock.json | 17 +- package.json | 7 +- src/api/root/handler.js | 20 +- src/lib/config.js | 1 + src/lib/healthCheck/subServiceHealth.js | 14 +- src/lib/proxyCache.js | 48 +++++ src/shared/setup.js | 7 + .../handlers/positions/handlerBatch.test.js | 2 + .../handlers/transfers/fxFulfil.test.js | 2 + .../handlers/transfers/fxTimeout.test.js | 2 + .../handlers/transfers/handlers.test.js | 2 + test/integration-override/lib/proxyCache.js | 185 ++++++++++++++++++ .../domain/participant/index.test.js | 4 + test/integration/handlers/root.test.js | 7 +- .../handlers/transfers/handlers.test.js | 3 + test/integration/helpers/settlementModels.js | 2 + .../models/transfer/facade.test.js | 3 + .../models/transfer/ilpPacket.test.js | 3 + .../models/transfer/transferError.test.js | 3 + .../models/transfer/transferExtension.test.js | 3 + .../transfer/transferStateChange.test.js | 3 + test/scripts/test-integration.sh | 2 +- test/unit/api/index.test.js | 6 + .../api/ledgerAccountTypes/handler.test.js | 6 + test/unit/api/metrics/handler.test.js | 6 + test/unit/api/participants/handler.test.js | 6 + test/unit/api/root/handler.test.js | 51 ++++- test/unit/api/root/routes.test.js | 20 ++ test/unit/api/routes.test.js | 9 + .../unit/api/settlementModels/handler.test.js | 6 + test/unit/api/transactions/handler.test.js | 6 + test/unit/handlers/admin/handler.test.js | 5 + test/unit/handlers/api/handler.test.js | 6 + test/unit/handlers/bulk/get/handler.test.js | 5 + .../handlers/bulk/prepare/handler.test.js | 5 + test/unit/handlers/index.test.js | 8 +- test/unit/handlers/positions/handler.test.js | 5 + .../handlers/positions/handlerBatch.test.js | 5 + test/unit/handlers/register.test.js | 5 + test/unit/handlers/timeouts/handler.test.js | 5 + .../transfers/FxFulfilService.test.js | 5 + .../transfers/fxFuflilHandler.test.js | 5 + test/unit/handlers/transfers/handler.test.js | 6 +- test/unit/handlers/transfers/prepare.test.js | 5 + .../lib/healthCheck/subServiceHealth.test.js | 41 +++- test/unit/lib/proxyCache.test.js | 121 ++++++++++++ test/unit/models/position/facade.test.js | 20 +- test/unit/shared/setup.test.js | 71 +++++-- 52 files changed, 757 insertions(+), 59 deletions(-) create mode 100644 src/lib/proxyCache.js create mode 100644 test/integration-override/lib/proxyCache.js create mode 100644 test/unit/lib/proxyCache.test.js diff --git a/config/default.json b/config/default.json index a3aa5262e..1eeb55335 100644 --- a/config/default.json +++ b/config/default.json @@ -84,6 +84,14 @@ "MAX_BYTE_SIZE": 10000000, "EXPIRES_IN_MS": 1000 }, + "PROXY_CACHE": { + "enabled": true, + "type": "redis", + "proxyConfig": { + "host": "localhost", + "port": 6379 + } + }, "API_DOC_ENDPOINTS_ENABLED": true, "KAFKA": { "EVENT_TYPE_ACTION_TOPIC_MAP" : { diff --git a/docker-compose.yml b/docker-compose.yml index 89c1c33ae..9d64f4f10 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -219,3 +219,16 @@ services: - cl-mojaloop-net environment: - KAFKA_BROKERS=kafka:29092 + + redis: + image: redis:6.2.4-alpine + restart: "unless-stopped" + environment: + - ALLOW_EMPTY_PASSWORD=yes + - REDIS_PORT=6379 + - REDIS_REPLICATION_MODE=master + - REDIS_TLS_ENABLED=no + ports: + - "6379:6379" + networks: + - cl-mojaloop-net diff --git a/docker/central-ledger/default.json b/docker/central-ledger/default.json index 5571f464a..a62fbb223 100644 --- a/docker/central-ledger/default.json +++ b/docker/central-ledger/default.json @@ -82,6 +82,14 @@ "MAX_BYTE_SIZE": 10000000, "EXPIRES_IN_MS": 1000 }, + "PROXY_CACHE": { + "enabled": true, + "type": "redis", + "proxyConfig": { + "host": "localhost", + "port": 6379 + } + }, "KAFKA": { "TOPIC_TEMPLATES": { "PARTICIPANT_TOPIC_TEMPLATE": { diff --git a/docker/config-modifier/configs/central-ledger.js b/docker/config-modifier/configs/central-ledger.js index 2f91d0b10..99b265c90 100644 --- a/docker/config-modifier/configs/central-ledger.js +++ b/docker/config-modifier/configs/central-ledger.js @@ -12,6 +12,14 @@ module.exports = { PASSWORD: '', DATABASE: 'mlos' }, + PROXY_CACHE: { + enabled: true, + type: 'redis', + proxyConfig: { + host: 'redis', + port: 6379 + } + }, KAFKA: { EVENT_TYPE_ACTION_TOPIC_MAP: { POSITION: { diff --git a/package-lock.json b/package-lock.json index 3a4e65dd8..588f35680 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,10 +24,11 @@ "@mojaloop/central-services-stream": "11.3.1", "@mojaloop/database-lib": "11.0.6", "@mojaloop/event-sdk": "14.1.1", + "@mojaloop/inter-scheme-proxy-cache-lib": "^1.4.0", "@mojaloop/ml-number": "11.2.4", "@mojaloop/object-store-lib": "12.0.3", "@now-ims/hapi-now-auth": "2.1.0", - "ajv": "8.16.0", + "ajv": "8.17.1", "ajv-keywords": "5.1.0", "base64url": "3.0.1", "blipp": "4.0.2", @@ -2595,12 +2596,12 @@ } }, "node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { "fast-deep-equal": "^3.1.3", - "fast-uri": "^2.3.0", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" }, @@ -6410,9 +6411,9 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fast-uri": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.3.0.tgz", - "integrity": "sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" }, "node_modules/fastq": { "version": "1.15.0", diff --git a/package.json b/package.json index a7d9315e8..c5238d798 100644 --- a/package.json +++ b/package.json @@ -81,13 +81,13 @@ "wait-4-docker": "node ./scripts/_wait4_all.js" }, "dependencies": { + "@hapi/basic": "7.0.2", + "@hapi/catbox-memory": "6.0.2", "@hapi/good": "9.0.1", "@hapi/hapi": "21.3.10", - "@hapi/basic": "7.0.2", "@hapi/inert": "7.1.0", "@hapi/joi": "17.1.1", "@hapi/vision": "7.0.3", - "@hapi/catbox-memory": "6.0.2", "@mojaloop/central-services-error-handling": "13.0.1", "@mojaloop/central-services-health": "15.0.0", "@mojaloop/central-services-logger": "11.3.1", @@ -96,10 +96,11 @@ "@mojaloop/central-services-stream": "11.3.1", "@mojaloop/database-lib": "11.0.6", "@mojaloop/event-sdk": "14.1.1", + "@mojaloop/inter-scheme-proxy-cache-lib": "^1.4.0", "@mojaloop/ml-number": "11.2.4", "@mojaloop/object-store-lib": "12.0.3", "@now-ims/hapi-now-auth": "2.1.0", - "ajv": "8.16.0", + "ajv": "8.17.1", "ajv-keywords": "5.1.0", "base64url": "3.0.1", "blipp": "4.0.2", diff --git a/src/api/root/handler.js b/src/api/root/handler.js index 17cdc6d67..54199aee3 100644 --- a/src/api/root/handler.js +++ b/src/api/root/handler.js @@ -30,13 +30,23 @@ const { defaultHealthHandler } = require('@mojaloop/central-services-health') const packageJson = require('../../../package.json') const { getSubServiceHealthDatastore, - getSubServiceHealthBroker + getSubServiceHealthBroker, + getSubServiceHealthProxyCache } = require('../../lib/healthCheck/subServiceHealth') +const Config = require('../../lib/config') -const healthCheck = new HealthCheck(packageJson, [ - getSubServiceHealthDatastore, - getSubServiceHealthBroker -]) +const subServiceChecks = Config.PROXY_CACHE_CONFIG.enabled + ? [ + getSubServiceHealthDatastore, + getSubServiceHealthBroker, + getSubServiceHealthProxyCache + ] + : [ + getSubServiceHealthDatastore, + getSubServiceHealthBroker + ] + +const healthCheck = new HealthCheck(packageJson, subServiceChecks) /** * @function getHealth diff --git a/src/lib/config.js b/src/lib/config.js index de6f157fd..5c9e95526 100644 --- a/src/lib/config.js +++ b/src/lib/config.js @@ -23,6 +23,7 @@ module.exports = { HANDLERS_TIMEOUT_TIMEXP: RC.HANDLERS.TIMEOUT.TIMEXP, HANDLERS_TIMEOUT_TIMEZONE: RC.HANDLERS.TIMEOUT.TIMEZONE, CACHE_CONFIG: RC.CACHE, + PROXY_CACHE_CONFIG: RC.PROXY_CACHE, KAFKA_CONFIG: RC.KAFKA, PARTICIPANT_INITIAL_POSITION: RC.PARTICIPANT_INITIAL_POSITION, RUN_MIGRATIONS: !RC.MIGRATIONS.DISABLED, diff --git a/src/lib/healthCheck/subServiceHealth.js b/src/lib/healthCheck/subServiceHealth.js index 2ddc59591..6d3e7b1ec 100644 --- a/src/lib/healthCheck/subServiceHealth.js +++ b/src/lib/healthCheck/subServiceHealth.js @@ -26,7 +26,7 @@ const { statusEnum, serviceName } = require('@mojaloop/central-services-shared').HealthCheck.HealthCheckEnums const Logger = require('@mojaloop/central-services-logger') const Consumer = require('@mojaloop/central-services-stream').Util.Consumer - +const ProxyCache = require('../proxyCache') const MigrationLockModel = require('../../models/misc/migrationLock') /** @@ -82,7 +82,17 @@ const getSubServiceHealthDatastore = async () => { } } +const getSubServiceHealthProxyCache = async () => { + const proxyCache = ProxyCache.getCache() + const healthCheck = await proxyCache.healthCheck() + return { + name: 'proxyCache', + status: healthCheck ? statusEnum.OK : statusEnum.DOWN + } +} + module.exports = { getSubServiceHealthBroker, - getSubServiceHealthDatastore + getSubServiceHealthDatastore, + getSubServiceHealthProxyCache } diff --git a/src/lib/proxyCache.js b/src/lib/proxyCache.js new file mode 100644 index 000000000..8780a1bff --- /dev/null +++ b/src/lib/proxyCache.js @@ -0,0 +1,48 @@ +'use strict' +const { createProxyCache } = require('@mojaloop/inter-scheme-proxy-cache-lib') +const Config = require('./config.js') +const ParticipantService = require('../../src/domain/participant') + +let proxyCache + +const connect = async () => { + return getCache().connect() +} + +const disconnect = async () => { + return proxyCache?.isConnected && proxyCache.disconnect() +} + +const getCache = () => { + if (!proxyCache) { + proxyCache = Object.freeze(createProxyCache( + Config.PROXY_CACHE_CONFIG.type, + Config.PROXY_CACHE_CONFIG.proxyConfig + )) + } + return proxyCache +} + +const getFSPProxy = async (dfspId) => { + const participant = await ParticipantService.getByName(dfspId) + return { + inScheme: !!participant, + proxyId: !participant ? await getCache().lookupProxyByDfspId(dfspId) : null + } +} + +const checkSameCreditorDebtorProxy = async (debtorDfspId, creditorDfspId) => { + const [debtorProxyId, creditorProxyId] = await Promise.all([ + await getCache().lookupProxyByDfspId(debtorDfspId), + await getCache().lookupProxyByDfspId(creditorDfspId) + ]) + return debtorProxyId && creditorProxyId ? debtorProxyId === creditorProxyId : false +} + +module.exports = { + connect, + disconnect, + getCache, + getFSPProxy, + checkSameCreditorDebtorProxy +} diff --git a/src/shared/setup.js b/src/shared/setup.js index 19fd3b2e7..adf4cff3e 100644 --- a/src/shared/setup.js +++ b/src/shared/setup.js @@ -36,6 +36,7 @@ const Hapi = require('@hapi/hapi') const Migrator = require('../lib/migrator') const Db = require('../lib/db') +const ProxyCache = require('../lib/proxyCache') const ObjStoreDb = require('@mojaloop/object-store-lib').Db const Plugins = require('./plugins') const Config = require('../lib/config') @@ -265,6 +266,9 @@ const initialize = async function ({ service, port, modules = [], runMigrations await connectDatabase() await connectMongoose() await initializeCache() + if (Config.PROXY_CACHE_CONFIG.enabled) { + await ProxyCache.connect() + } let server switch (service) { @@ -303,6 +307,9 @@ const initialize = async function ({ service, port, modules = [], runMigrations Logger.isErrorEnabled && Logger.error(`Error while initializing ${err}`) await Db.disconnect() + if (Config.PROXY_CACHE_CONFIG.enabled) { + await ProxyCache.disconnect() + } process.exit(1) } } diff --git a/test/integration-override/handlers/positions/handlerBatch.test.js b/test/integration-override/handlers/positions/handlerBatch.test.js index db7f1239c..460921646 100644 --- a/test/integration-override/handlers/positions/handlerBatch.test.js +++ b/test/integration-override/handlers/positions/handlerBatch.test.js @@ -28,6 +28,7 @@ const Test = require('tape') const { randomUUID } = require('crypto') const Logger = require('@mojaloop/central-services-logger') const Config = require('#src/lib/config') +const ProxyCache = require('#src/lib/proxyCache') const Db = require('@mojaloop/database-lib').Db const Cache = require('#src/lib/cache') const Producer = require('@mojaloop/central-services-stream').Util.Producer @@ -1838,6 +1839,7 @@ Test('Handlers test', async handlersTest => { await testConsumer.destroy() // this disconnects the consumers await Producer.disconnect() + await ProxyCache.disconnect() if (debug) { const elapsedTime = Math.round(((new Date()) - startTime) / 100) / 10 diff --git a/test/integration-override/handlers/transfers/fxFulfil.test.js b/test/integration-override/handlers/transfers/fxFulfil.test.js index 74c10aa76..d758f7332 100644 --- a/test/integration-override/handlers/transfers/fxFulfil.test.js +++ b/test/integration-override/handlers/transfers/fxFulfil.test.js @@ -30,6 +30,7 @@ const { Producer } = require('@mojaloop/central-services-stream').Kafka const Config = require('#src/lib/config') const Cache = require('#src/lib/cache') +const ProxyCache = require('#src/lib/proxyCache') const fspiopErrorFactory = require('#src/shared/fspiopErrorFactory') const ParticipantCached = require('#src/models/participant/participantCached') const ParticipantCurrencyCached = require('#src/models/participant/participantCurrencyCached') @@ -275,6 +276,7 @@ Test('FxFulfil flow Integration Tests -->', async fxFulfilTest => { producer.disconnect(), testConsumer.destroy() ]) + await ProxyCache.disconnect() await new Promise(resolve => setTimeout(resolve, 5_000)) t.pass('teardown is finished') t.end() diff --git a/test/integration-override/handlers/transfers/fxTimeout.test.js b/test/integration-override/handlers/transfers/fxTimeout.test.js index a62ff09e5..c6add0417 100644 --- a/test/integration-override/handlers/transfers/fxTimeout.test.js +++ b/test/integration-override/handlers/transfers/fxTimeout.test.js @@ -30,6 +30,7 @@ const Logger = require('@mojaloop/central-services-logger') const Config = require('#src/lib/config') const Db = require('@mojaloop/database-lib').Db const Cache = require('#src/lib/cache') +const ProxyCache = require('#src/lib/proxyCache') const Producer = require('@mojaloop/central-services-stream').Util.Producer const Utility = require('@mojaloop/central-services-shared').Util.Kafka const Enum = require('@mojaloop/central-services-shared').Enum @@ -773,6 +774,7 @@ Test('Handlers test', async handlersTest => { await testConsumer.destroy() // this disconnects the consumers await Producer.disconnect() + await ProxyCache.disconnect() if (debug) { const elapsedTime = Math.round(((new Date()) - startTime) / 100) / 10 diff --git a/test/integration-override/handlers/transfers/handlers.test.js b/test/integration-override/handlers/transfers/handlers.test.js index 303968ee6..29c286605 100644 --- a/test/integration-override/handlers/transfers/handlers.test.js +++ b/test/integration-override/handlers/transfers/handlers.test.js @@ -30,6 +30,7 @@ const Logger = require('@mojaloop/central-services-logger') const Config = require('#src/lib/config') const Db = require('@mojaloop/database-lib').Db const Cache = require('#src/lib/cache') +const ProxyCache = require('#src/lib/proxyCache') const Producer = require('@mojaloop/central-services-stream').Util.Producer const Utility = require('@mojaloop/central-services-shared').Util.Kafka const Enum = require('@mojaloop/central-services-shared').Enum @@ -753,6 +754,7 @@ Test('Handlers test', async handlersTest => { await testConsumer.destroy() // this disconnects the consumers await Producer.disconnect() + await ProxyCache.disconnect() if (debug) { const elapsedTime = Math.round(((new Date()) - startTime) / 100) / 10 diff --git a/test/integration-override/lib/proxyCache.js b/test/integration-override/lib/proxyCache.js new file mode 100644 index 000000000..b228cdfe8 --- /dev/null +++ b/test/integration-override/lib/proxyCache.js @@ -0,0 +1,185 @@ +'use strict' + +const Test = require('tape') +const Sinon = require('sinon') +const Db = require('#src/lib/db') +const Cache = require('#src/lib/cache') +const Logger = require('@mojaloop/central-services-logger') +const Config = require('#src/lib/config') +const ProxyCache = require('#src/lib/proxyCache') +const ParticipantService = require('#src/domain/participant') +const ParticipantCached = require('#src/models/participant/participantCached') +const ParticipantCurrencyCached = require('#src/models/participant/participantCurrencyCached') +const ParticipantLimitCached = require('#src/models/participant/participantLimitCached') +const ParticipantHelper = require('../../integration/helpers/participant') + +const debug = false + +Test('Participant service', async (participantTest) => { + let sandbox + const participantFixtures = [] + const participantMap = new Map() + + const testData = { + currency: 'USD', + fsp1Name: 'dfsp1', + fsp2Name: 'dfsp2', + endpointBase: 'http://localhost:1080', + fsp3Name: 'payerfsp', + fsp4Name: 'payeefsp', + simulatorBase: 'http://localhost:8444', + notificationEmail: 'test@example.com', + proxyParticipant: 'xnProxy' + } + + await participantTest.test('setup', async (test) => { + try { + sandbox = Sinon.createSandbox() + await Db.connect(Config.DATABASE) + await ParticipantCached.initialize() + await ParticipantCurrencyCached.initialize() + await ParticipantLimitCached.initialize() + await Cache.initCache() + await ProxyCache.connect() + test.pass() + test.end() + } catch (err) { + Logger.error(`Setup for test failed with error - ${err}`) + test.fail() + test.end() + } + }) + + await participantTest.test('create participants', async (assert) => { + try { + let getByNameResult, result + getByNameResult = await ParticipantService.getByName(testData.fsp1Name) + result = await ParticipantHelper.prepareData(testData.fsp1Name, testData.currency, undefined, !!getByNameResult) + participantFixtures.push(result.participant) + getByNameResult = await ParticipantService.getByName(testData.fsp2Name) + result = await ParticipantHelper.prepareData(testData.fsp2Name, testData.currency, undefined, !!getByNameResult) + participantFixtures.push(result.participant) + getByNameResult = await ParticipantService.getByName(testData.fsp3Name) + result = await ParticipantHelper.prepareData(testData.fsp3Name, testData.currency, undefined, !!getByNameResult) + participantFixtures.push(result.participant) + getByNameResult = await ParticipantService.getByName(testData.fsp4Name) + result = await ParticipantHelper.prepareData(testData.fsp4Name, testData.currency, undefined, !!getByNameResult) + participantFixtures.push(result.participant) + for (const participant of participantFixtures) { + const read = await ParticipantService.getById(participant.participantId) + participantMap.set(participant.participantId, read) + if (debug) assert.comment(`Testing with participant \n ${JSON.stringify(participant, null, 2)}`) + assert.equal(read.name, participant.name, 'names are equal') + assert.deepEqual(read.currencyList, participant.currencyList, 'currency match') + assert.equal(read.isActive, participant.isActive, 'isActive flag matches') + assert.equal(read.createdDate.toString(), participant.createdDate.toString(), 'created date matches') + } + assert.end() + } catch (err) { + Logger.error(`create participant failed with error - ${err}`) + assert.fail() + assert.end() + } + }) + + await participantTest.test('getFSPProxy should return proxyId if fsp not in scheme', async (assert) => { + try { + const proxyCache = ProxyCache.getCache() + proxyCache.addDfspIdToProxyMapping('notInSchemeFsp', 'proxyId') + const result = await ProxyCache.getFSPProxy('notInSchemeFsp') + assert.equal(result.inScheme, false, 'not in scheme') + assert.equal(result.proxyId, 'proxyId', 'proxy id matches') + proxyCache.removeDfspIdFromProxyMapping('notInSchemeFsp') + assert.end() + } catch (err) { + Logger.error(`create participant failed with error - ${err}`) + assert.fail() + assert.end() + } + }) + + await participantTest.test('getFSPProxy should not return proxyId if fsp is in scheme', async (assert) => { + try { + const proxyCache = ProxyCache.getCache() + proxyCache.addDfspIdToProxyMapping('dfsp1', 'proxyId') + const result = await ProxyCache.getFSPProxy('dfsp1') + assert.equal(result.inScheme, true, 'is in scheme') + assert.equal(result.proxyId, null, 'proxy id is null') + proxyCache.removeDfspIdFromProxyMapping('dfsp1') + assert.end() + } catch (err) { + Logger.error(`create participant failed with error - ${err}`) + assert.fail() + assert.end() + } + }) + + await participantTest.test('checkSameCreditorDebtorProxy should return true if debtor and creditor proxy are the same', async (assert) => { + try { + const proxyCache = ProxyCache.getCache() + proxyCache.addDfspIdToProxyMapping('dfsp1', 'proxyId') + proxyCache.addDfspIdToProxyMapping('dfsp2', 'proxyId') + const result = await ProxyCache.checkSameCreditorDebtorProxy('dfsp1', 'dfsp2') + assert.equal(result, true, 'returned true') + proxyCache.removeDfspIdFromProxyMapping('dfsp1') + proxyCache.removeDfspIdFromProxyMapping('dfsp2') + assert.end() + } catch (err) { + Logger.error(`create participant failed with error - ${err}`) + assert.fail() + assert.end() + } + }) + + await participantTest.test('checkSameCreditorDebtorProxy should return false if debtor and creditor proxy are not the same', async (assert) => { + try { + const proxyCache = ProxyCache.getCache() + proxyCache.addDfspIdToProxyMapping('dfsp1', 'proxyId') + proxyCache.addDfspIdToProxyMapping('dfsp2', 'proxyId2') + const result = await ProxyCache.checkSameCreditorDebtorProxy('dfsp1', 'dfsp2') + assert.equal(result, false, 'returned false') + proxyCache.removeDfspIdFromProxyMapping('dfsp1') + proxyCache.removeDfspIdFromProxyMapping('dfsp2') + assert.end() + } catch (err) { + Logger.error(`create participant failed with error - ${err}`) + assert.fail() + assert.end() + } + }) + + await participantTest.test('teardown', async (assert) => { + try { + for (const participant of participantFixtures) { + if (participant.name === testData.fsp1Name || + participant.name === testData.fsp2Name || + participant.name === testData.fsp3Name || + participant.name === testData.fsp4Name) { + assert.pass(`participant ${participant.name} preserved`) + } else { + const result = await ParticipantHelper.deletePreparedData(participant.name) + assert.ok(result, `destroy ${participant.name} success`) + } + } + await Cache.destroyCache() + await Db.disconnect() + await ProxyCache.disconnect() + + assert.pass('database connection closed') + // @ggrg: Having the following 3 lines commented prevents the current test from exiting properly when run individually, + // BUT it is required in order to have successful run of all integration test scripts as a sequence, where + // the last script will actually disconnect topic-notification-event producer. + // const Producer = require('../../../../src/handlers/lib/kafka/producer') + // await Producer.getProducer('topic-notification-event').disconnect() + // assert.pass('producer to topic-notification-event disconnected') + sandbox.restore() + assert.end() + } catch (err) { + Logger.error(`teardown failed with error - ${err}`) + assert.fail() + assert.end() + } + }) + + await participantTest.end() +}) diff --git a/test/integration/domain/participant/index.test.js b/test/integration/domain/participant/index.test.js index 9ff7b4052..18ea8d815 100644 --- a/test/integration/domain/participant/index.test.js +++ b/test/integration/domain/participant/index.test.js @@ -32,6 +32,7 @@ const Test = require('tape') const Sinon = require('sinon') const Db = require('../../../../src/lib/db') const Cache = require('../../../../src/lib/cache') +const ProxyCache = require('../../../../src/lib/proxyCache') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../../src/lib/config') const ParticipantService = require('../../../../src/domain/participant') @@ -68,6 +69,7 @@ Test('Participant service', async (participantTest) => { try { sandbox = Sinon.createSandbox() await Db.connect(Config.DATABASE) + await ProxyCache.connect() await ParticipantCached.initialize() await ParticipantCurrencyCached.initialize() await ParticipantLimitCached.initialize() @@ -465,6 +467,8 @@ Test('Participant service', async (participantTest) => { } await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() + assert.pass('database connection closed') // @ggrg: Having the following 3 lines commented prevents the current test from exiting properly when run individually, // BUT it is required in order to have successful run of all integration test scripts as a sequence, where diff --git a/test/integration/handlers/root.test.js b/test/integration/handlers/root.test.js index 175459c4b..ee1d0d049 100644 --- a/test/integration/handlers/root.test.js +++ b/test/integration/handlers/root.test.js @@ -30,6 +30,7 @@ const Logger = require('@mojaloop/central-services-logger') const Db = require('@mojaloop/database-lib').Db const Config = require('../../../src/lib/config') +const ProxyCache = require('../../../src/lib/proxyCache') const Consumer = require('@mojaloop/central-services-stream').Util.Consumer // const Producer = require('@mojaloop/central-services-stream').Util.Producer const rootApiHandler = require('../../../src/api/root/handler') @@ -52,6 +53,7 @@ Test('Root handler test', async handlersTest => { await handlersTest.test('registerAllHandlers should', async registerAllHandlers => { await registerAllHandlers.test('setup handlers', async (test) => { await Db.connect(Config.DATABASE) + await ProxyCache.connect() await Handlers.transfers.registerPrepareHandler() await Handlers.positions.registerPositionHandler() await Handlers.transfers.registerFulfilHandler() @@ -88,7 +90,8 @@ Test('Root handler test', async handlersTest => { const expectedStatus = 200 const expectedServices = [ { name: 'datastore', status: 'OK' }, - { name: 'broker', status: 'OK' } + { name: 'broker', status: 'OK' }, + { name: 'proxyCache', status: 'OK' } ] // Act @@ -112,7 +115,7 @@ Test('Root handler test', async handlersTest => { try { await Db.disconnect() assert.pass('database connection closed') - + await ProxyCache.disconnect() // TODO: Replace this with KafkaHelper.topics const topics = [ 'topic-transfer-prepare', diff --git a/test/integration/handlers/transfers/handlers.test.js b/test/integration/handlers/transfers/handlers.test.js index a63f0ed7a..6d24657c5 100644 --- a/test/integration/handlers/transfers/handlers.test.js +++ b/test/integration/handlers/transfers/handlers.test.js @@ -29,6 +29,7 @@ const Test = require('tape') const { randomUUID } = require('crypto') const Logger = require('@mojaloop/central-services-logger') const Config = require('#src/lib/config') +const ProxyCache = require('#src/lib/proxyCache') const Time = require('@mojaloop/central-services-shared').Util.Time const Db = require('@mojaloop/database-lib').Db const Cache = require('#src/lib/cache') @@ -318,6 +319,7 @@ const prepareTestData = async (dataObj) => { Test('Handlers test', async handlersTest => { const startTime = new Date() await Db.connect(Config.DATABASE) + await ProxyCache.connect() await ParticipantCached.initialize() await ParticipantCurrencyCached.initialize() await ParticipantLimitCached.initialize() @@ -1346,6 +1348,7 @@ Test('Handlers test', async handlersTest => { await Handlers.timeouts.stop() await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() assert.pass('database connection closed') await testConsumer.destroy() // this disconnects the consumers diff --git a/test/integration/helpers/settlementModels.js b/test/integration/helpers/settlementModels.js index 975070586..560963ad2 100644 --- a/test/integration/helpers/settlementModels.js +++ b/test/integration/helpers/settlementModels.js @@ -34,6 +34,7 @@ const Enums = require('../../../src/lib/enumCached') const ErrorHandler = require('@mojaloop/central-services-error-handling') const Db = require('@mojaloop/database-lib').Db const Cache = require('../../../src/lib/cache') +const ProxyCache = require('../../../src/lib/proxyCache') const ParticipantCached = require('../../../src/models/participant/participantCached') const ParticipantCurrencyCached = require('../../../src/models/participant/participantCurrencyCached') const ParticipantLimitCached = require('../../../src/models/participant/participantLimitCached') @@ -66,6 +67,7 @@ const settlementModels = [ exports.prepareData = async () => { await Db.connect(Config.DATABASE) + await ProxyCache.connect() await Enums.initialize() await ParticipantCached.initialize() await ParticipantCurrencyCached.initialize() diff --git a/test/integration/models/transfer/facade.test.js b/test/integration/models/transfer/facade.test.js index 29b625f46..7d82d0397 100644 --- a/test/integration/models/transfer/facade.test.js +++ b/test/integration/models/transfer/facade.test.js @@ -32,6 +32,7 @@ const Test = require('tape') const Db = require('../../../../src/lib/db') const Cache = require('../../../../src/lib/cache') +const ProxyCache = require('../../../../src/lib/proxyCache') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../../src/lib/config') const TransferFacade = require('../../../../src/models/transfer/facade') @@ -44,6 +45,7 @@ Test('Transfer read model test', async (transferReadModelTest) => { try { await Db.connect(Config.DATABASE).then(async () => { await Cache.initCache() + await ProxyCache.connect() transferPrepareResult = await HelperModule.prepareNeededData('transferModel') assert.pass('setup OK') assert.end() @@ -88,6 +90,7 @@ Test('Transfer read model test', async (transferReadModelTest) => { try { await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() assert.pass('database connection closed') assert.end() } catch (err) { diff --git a/test/integration/models/transfer/ilpPacket.test.js b/test/integration/models/transfer/ilpPacket.test.js index 41eaa0461..13a01e5b8 100644 --- a/test/integration/models/transfer/ilpPacket.test.js +++ b/test/integration/models/transfer/ilpPacket.test.js @@ -30,6 +30,7 @@ const Test = require('tape') const Db = require('../../../../src/lib/db') +const ProxyCache = require('../../../../src/lib/proxyCache') const Cache = require('../../../../src/lib/cache') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../../src/lib/config') @@ -48,6 +49,7 @@ Test('Ilp service tests', async (ilpTest) => { await ilpTest.test('setup', async (assert) => { try { + await ProxyCache.connect() await Db.connect(Config.DATABASE).then(() => { assert.pass('setup OK') assert.end() @@ -178,6 +180,7 @@ Test('Ilp service tests', async (ilpTest) => { try { await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() assert.pass('database connection closed') assert.end() } catch (err) { diff --git a/test/integration/models/transfer/transferError.test.js b/test/integration/models/transfer/transferError.test.js index 2c851ed55..5946a299e 100644 --- a/test/integration/models/transfer/transferError.test.js +++ b/test/integration/models/transfer/transferError.test.js @@ -27,6 +27,7 @@ const Test = require('tape') const Db = require('../../../../src/lib/db') const Cache = require('../../../../src/lib/cache') +const ProxyCache = require('../../../../src/lib/proxyCache') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../../src/lib/config') const Model = require('../../../../src/models/transfer/transferError') @@ -38,6 +39,7 @@ Test('Transfer Error model test', async (transferErrorTest) => { try { await Db.connect(Config.DATABASE).then(async () => { await Cache.initCache() + await ProxyCache.connect() assert.pass('setup OK') assert.end() }).catch(err => { @@ -90,6 +92,7 @@ Test('Transfer Error model test', async (transferErrorTest) => { try { await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() assert.pass('database connection closed') assert.end() } catch (err) { diff --git a/test/integration/models/transfer/transferExtension.test.js b/test/integration/models/transfer/transferExtension.test.js index cf943240b..10f924b5d 100644 --- a/test/integration/models/transfer/transferExtension.test.js +++ b/test/integration/models/transfer/transferExtension.test.js @@ -31,6 +31,7 @@ const Test = require('tape') const Db = require('../../../../src/lib/db') const Cache = require('../../../../src/lib/cache') +const ProxyCache = require('../../../../src/lib/proxyCache') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../../src/lib/config') const Model = require('../../../../src/models/transfer/transferExtension') @@ -52,6 +53,7 @@ Test('Extension model test', async (extensionTest) => { await extensionTest.test('setup', async (assert) => { try { + await ProxyCache.connect() await Db.connect(Config.DATABASE).then(() => { assert.pass('setup OK') assert.end() @@ -196,6 +198,7 @@ Test('Extension model test', async (extensionTest) => { try { await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() assert.pass('database connection closed') assert.end() } catch (err) { diff --git a/test/integration/models/transfer/transferStateChange.test.js b/test/integration/models/transfer/transferStateChange.test.js index a1b33048c..b4555eb68 100644 --- a/test/integration/models/transfer/transferStateChange.test.js +++ b/test/integration/models/transfer/transferStateChange.test.js @@ -31,6 +31,7 @@ const Test = require('tape') const Db = require('../../../../src/lib/db') const Cache = require('../../../../src/lib/cache') +const ProxyCache = require('../../../../src/lib/proxyCache') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../../src/lib/config') const Model = require('../../../../src/models/transfer/transferStateChange') @@ -45,6 +46,7 @@ Test('Transfer State Change model test', async (stateChangeTest) => { await stateChangeTest.test('setup', async (assert) => { try { await Db.connect(Config.DATABASE).then(async () => { + await ProxyCache.connect() await ParticipantCached.initialize() await ParticipantCurrencyCached.initialize() await ParticipantLimitCached.initialize() @@ -127,6 +129,7 @@ Test('Transfer State Change model test', async (stateChangeTest) => { try { await Cache.destroyCache() await Db.disconnect() + await ProxyCache.disconnect() assert.pass('database connection closed') assert.end() } catch (err) { diff --git a/test/scripts/test-integration.sh b/test/scripts/test-integration.sh index 165572dd3..8df322ba3 100644 --- a/test/scripts/test-integration.sh +++ b/test/scripts/test-integration.sh @@ -21,7 +21,7 @@ mkdir ./test/results ## Start backend services echo "==> Starting Docker backend services" docker compose pull mysql kafka init-kafka -docker compose up -d mysql kafka init-kafka +docker compose up -d mysql kafka init-kafka redis docker compose ps npm run wait-4-docker diff --git a/test/unit/api/index.test.js b/test/unit/api/index.test.js index fbfa37bd9..4a87aa0d2 100644 --- a/test/unit/api/index.test.js +++ b/test/unit/api/index.test.js @@ -29,6 +29,7 @@ const Sinon = require('sinon') const Logger = require('@mojaloop/central-services-logger') const Config = require('../../../src/lib/config') +const ProxyCache = require('#src/lib/proxyCache') const Routes = require('../../../src/api/routes') const Setup = require('../../../src/shared/setup') @@ -39,6 +40,10 @@ Test('Api index', indexTest => { sandbox = Sinon.createSandbox() sandbox.stub(Setup) sandbox.stub(Logger) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) test.end() }) @@ -66,6 +71,7 @@ Test('Api index', indexTest => { runMigrations: true, runHandlers: !Config.HANDLERS_DISABLED })) + test.end() }) exportTest.end() diff --git a/test/unit/api/ledgerAccountTypes/handler.test.js b/test/unit/api/ledgerAccountTypes/handler.test.js index 7a8e82530..d25915311 100644 --- a/test/unit/api/ledgerAccountTypes/handler.test.js +++ b/test/unit/api/ledgerAccountTypes/handler.test.js @@ -29,6 +29,7 @@ const Sinon = require('sinon') const Logger = require('@mojaloop/central-services-logger') const Handler = require('../../../../src/api/ledgerAccountTypes/handler') const LedgerAccountTypeService = require('../../../../src/domain/ledgerAccountTypes') +const ProxyCache = require('#src/lib/proxyCache') Test('LedgerAccountTypes', ledgerAccountTypesHandlerTest => { let sandbox @@ -37,6 +38,11 @@ Test('LedgerAccountTypes', ledgerAccountTypesHandlerTest => { sandbox = Sinon.createSandbox() sandbox.stub(Logger) sandbox.stub(LedgerAccountTypeService) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) test.end() }) diff --git a/test/unit/api/metrics/handler.test.js b/test/unit/api/metrics/handler.test.js index 1163c94e4..44fdea444 100644 --- a/test/unit/api/metrics/handler.test.js +++ b/test/unit/api/metrics/handler.test.js @@ -28,6 +28,7 @@ const Test = require('tapes')(require('tape')) const Sinon = require('sinon') const Handler = require('../../../../src/api/metrics/handler') const Metrics = require('@mojaloop/central-services-metrics') +const ProxyCache = require('#src/lib/proxyCache') function createRequest (routes) { const value = routes || [] @@ -45,6 +46,11 @@ Test('metrics handler', (handlerTest) => { handlerTest.beforeEach(t => { sandbox = Sinon.createSandbox() sandbox.stub(Metrics) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) t.end() }) diff --git a/test/unit/api/participants/handler.test.js b/test/unit/api/participants/handler.test.js index 60ee170e5..3d768e538 100644 --- a/test/unit/api/participants/handler.test.js +++ b/test/unit/api/participants/handler.test.js @@ -9,6 +9,7 @@ const Participant = require('../../../../src/domain/participant') const EnumCached = require('../../../../src/lib/enumCached') const FSPIOPError = require('@mojaloop/central-services-error-handling').Factory.FSPIOPError const SettlementModel = require('../../../../src/domain/settlement') +const ProxyCache = require('#src/lib/proxyCache') const createRequest = ({ payload, params, query }) => { const sandbox = Sinon.createSandbox() @@ -163,6 +164,11 @@ Test('Participant', participantHandlerTest => { sandbox.stub(Participant) sandbox.stub(EnumCached) sandbox.stub(SettlementModel, 'getAll') + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) EnumCached.getEnums.returns(Promise.resolve({ POSITION: 1, SETTLEMENT: 2, HUB_RECONCILIATION: 3, HUB_MULTILATERAL_SETTLEMENT: 4, HUB_FEE: 5 })) Logger.isDebugEnabled = true test.end() diff --git a/test/unit/api/root/handler.test.js b/test/unit/api/root/handler.test.js index e84d7e8f4..0344998c3 100644 --- a/test/unit/api/root/handler.test.js +++ b/test/unit/api/root/handler.test.js @@ -28,19 +28,29 @@ const Test = require('tapes')(require('tape')) const Joi = require('joi') const Sinon = require('sinon') -const Handler = require('../../../../src/api/root/handler') const Consumer = require('@mojaloop/central-services-stream').Util.Consumer const MigrationLockModel = require('../../../../src/models/misc/migrationLock') +const ProxyCache = require('#src/lib/proxyCache') +const Config = require('#src/lib/config') const { createRequest, unwrapResponse } = require('../../../util/helpers') +const requireUncached = module => { + delete require.cache[require.resolve(module)] + return require(module) +} + Test('Root', rootHandlerTest => { let sandbox - rootHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().returns(Promise.resolve(true)) + }) test.end() }) @@ -54,6 +64,43 @@ Test('Root', rootHandlerTest => { rootHandlerTest.test('Handler Test', async handlerTest => { handlerTest.test('getHealth returns the detailed health check', async function (test) { // Arrange + const Handler = requireUncached('../../../../src/api/root/handler') + sandbox.stub(MigrationLockModel, 'getIsMigrationLocked').returns(false) + sandbox.stub(Consumer, 'getListOfTopics').returns(['admin']) + sandbox.stub(Consumer, 'isConnected').returns(Promise.resolve()) + const schema = Joi.compile({ + status: Joi.string().valid('OK').required(), + uptime: Joi.number().required(), + startTime: Joi.date().iso().required(), + versionNumber: Joi.string().required(), + services: Joi.array().required() + }) + const expectedStatus = 200 + const expectedServices = [ + { name: 'datastore', status: 'OK' }, + { name: 'broker', status: 'OK' }, + { name: 'proxyCache', status: 'OK' } + ] + + // Act + const { + responseBody, + responseCode + } = await unwrapResponse((reply) => Handler.getHealth(createRequest({}), reply)) + + // Assert + const validationResult = Joi.attempt(responseBody, schema) // We use Joi to validate the results as they rely on timestamps that are variable + test.equal(validationResult.error, undefined, 'The response matches the validation schema') + test.deepEqual(responseCode, expectedStatus, 'The response code matches') + test.deepEqual(responseBody.services, expectedServices, 'The sub-services are correct') + test.end() + }) + + handlerTest.test('getHealth returns the detailed health check without proxyCache if disabled', async function (test) { + // Arrange + Config.PROXY_CACHE_CONFIG.enabled = false + const Handler = requireUncached('../../../../src/api/root/handler') + sandbox.stub(MigrationLockModel, 'getIsMigrationLocked').returns(false) sandbox.stub(Consumer, 'getListOfTopics').returns(['admin']) sandbox.stub(Consumer, 'isConnected').returns(Promise.resolve()) diff --git a/test/unit/api/root/routes.test.js b/test/unit/api/root/routes.test.js index ad6378067..4a494e095 100644 --- a/test/unit/api/root/routes.test.js +++ b/test/unit/api/root/routes.test.js @@ -29,18 +29,31 @@ const Base = require('../../base') const AdminRoutes = require('../../../../src/api/routes') const Sinon = require('sinon') const Enums = require('../../../../src/lib/enumCached') +const ProxyCache = require('#src/lib/proxyCache') Test('test root routes - health', async function (assert) { + const sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) const req = Base.buildRequest({ url: '/health', method: 'GET' }) const server = await Base.setup(AdminRoutes) const res = await server.inject(req) assert.ok(res) await server.stop() + sandbox.restore() assert.end() }) Test('test root routes - enums', async function (assert) { const sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) sandbox.stub(Enums, 'getEnums').returns(Promise.resolve({})) const req = Base.buildRequest({ url: '/enums', method: 'GET' }) const server = await Base.setup(AdminRoutes) @@ -52,10 +65,17 @@ Test('test root routes - enums', async function (assert) { }) Test('test root routes - /', async function (assert) { + const sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) const req = Base.buildRequest({ url: '/', method: 'GET' }) const server = await Base.setup(AdminRoutes) const res = await server.inject(req) assert.ok(res) await server.stop() + sandbox.restore() assert.end() }) diff --git a/test/unit/api/routes.test.js b/test/unit/api/routes.test.js index 8a12ba533..87f85549b 100644 --- a/test/unit/api/routes.test.js +++ b/test/unit/api/routes.test.js @@ -27,12 +27,21 @@ const Test = require('tape') const Base = require('../base') const ApiRoutes = require('../../../src/api/routes') +const ProxyCache = require('#src/lib/proxyCache') +const Sinon = require('sinon') Test('test health', async function (assert) { + const sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) const req = Base.buildRequest({ url: '/health', method: 'GET' }) const server = await Base.setup(ApiRoutes) const res = await server.inject(req) assert.ok(res) await server.stop() + sandbox.restore() assert.end() }) diff --git a/test/unit/api/settlementModels/handler.test.js b/test/unit/api/settlementModels/handler.test.js index 98b826f31..c67ae3b6a 100644 --- a/test/unit/api/settlementModels/handler.test.js +++ b/test/unit/api/settlementModels/handler.test.js @@ -32,6 +32,7 @@ const Handler = require('../../../../src/api/settlementModels/handler') const SettlementService = require('../../../../src/domain/settlement') const EnumCached = require('../../../../src/lib/enumCached') const FSPIOPError = require('@mojaloop/central-services-error-handling').Factory.FSPIOPError +const ProxyCache = require('#src/lib/proxyCache') const createRequest = ({ payload, params, query }) => { const sandbox = Sinon.createSandbox() @@ -97,6 +98,11 @@ Test('SettlementModel', settlementModelHandlerTest => { sandbox.stub(Logger) sandbox.stub(SettlementService) sandbox.stub(EnumCached) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) EnumCached.getEnums.returns(Promise.resolve({ POSITION: 1, SETTLEMENT: 2, HUB_RECONCILIATION: 3, HUB_MULTILATERAL_SETTLEMENT: 4, HUB_FEE: 5 })) test.end() }) diff --git a/test/unit/api/transactions/handler.test.js b/test/unit/api/transactions/handler.test.js index 73502dba7..4da65d1bc 100644 --- a/test/unit/api/transactions/handler.test.js +++ b/test/unit/api/transactions/handler.test.js @@ -28,6 +28,7 @@ const Test = require('tapes')(require('tape')) const Sinon = require('sinon') const Handler = require('../../../../src/api/transactions/handler') const TransactionsService = require('../../../../src/domain/transactions') +const ProxyCache = require('#src/lib/proxyCache') Test('IlpPackets', IlpPacketsHandlerTest => { let sandbox @@ -74,6 +75,11 @@ Test('IlpPackets', IlpPacketsHandlerTest => { IlpPacketsHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() sandbox.stub(TransactionsService) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().resolves() + }) test.end() }) diff --git a/test/unit/handlers/admin/handler.test.js b/test/unit/handlers/admin/handler.test.js index 92539f4cb..7df647d17 100644 --- a/test/unit/handlers/admin/handler.test.js +++ b/test/unit/handlers/admin/handler.test.js @@ -11,6 +11,7 @@ const Logger = require('@mojaloop/central-services-logger') const Comparators = require('@mojaloop/central-services-shared').Util.Comparators const TransferService = require('../../../../src/domain/transfer') const Db = require('../../../../src/lib/db') +const ProxyCache = require('#src/lib/proxyCache') const Enum = require('@mojaloop/central-services-shared').Enum const TransferState = Enum.Transfers.TransferState const TransferInternalState = Enum.Transfers.TransferInternalState @@ -299,6 +300,10 @@ Test('Admin handler', adminHandlerTest => { adminHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) sandbox.stub(KafkaConsumer.prototype, 'constructor').resolves() sandbox.stub(KafkaConsumer.prototype, 'connect').resolves() sandbox.stub(KafkaConsumer.prototype, 'consume').resolves() diff --git a/test/unit/handlers/api/handler.test.js b/test/unit/handlers/api/handler.test.js index 33087ecc0..eb897d7de 100644 --- a/test/unit/handlers/api/handler.test.js +++ b/test/unit/handlers/api/handler.test.js @@ -29,6 +29,7 @@ const Sinon = require('sinon') const Handler = require('../../../../src/handlers/api/routes') const Consumer = require('@mojaloop/central-services-stream').Util.Consumer const MigrationLockModel = require('../../../../src/models/misc/migrationLock') +const ProxyCache = require('#src/lib/proxyCache') function createRequest (routes) { const value = routes || [] @@ -61,6 +62,11 @@ Test('route handler', (handlerTest) => { // Arrange sandbox.stub(MigrationLockModel, 'getIsMigrationLocked').returns(false) sandbox.stub(Consumer, 'isConnected').returns(Promise.resolve()) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub(), + healthCheck: sandbox.stub().returns(Promise.resolve(true)) + }) const jp = require('jsonpath') const healthHandler = jp.query(Handler, '$[?(@.path=="/health")]') diff --git a/test/unit/handlers/bulk/get/handler.test.js b/test/unit/handlers/bulk/get/handler.test.js index df076356e..80cebae0b 100644 --- a/test/unit/handlers/bulk/get/handler.test.js +++ b/test/unit/handlers/bulk/get/handler.test.js @@ -30,6 +30,7 @@ const { randomUUID } = require('crypto') const Sinon = require('sinon') const Proxyquire = require('proxyquire') +const ProxyCache = require('#src/lib/proxyCache') const Test = require('tapes')(require('tape')) const EventSdk = require('@mojaloop/event-sdk') const Kafka = require('@mojaloop/central-services-shared').Util.Kafka @@ -152,6 +153,10 @@ Test('Bulk Transfer GET handler', getHandlerTest => { getHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) SpanStub = { audit: sandbox.stub().callsFake(), error: sandbox.stub().callsFake(), diff --git a/test/unit/handlers/bulk/prepare/handler.test.js b/test/unit/handlers/bulk/prepare/handler.test.js index 554a70721..c3d2d4cc3 100644 --- a/test/unit/handlers/bulk/prepare/handler.test.js +++ b/test/unit/handlers/bulk/prepare/handler.test.js @@ -43,6 +43,7 @@ const BulkTransferService = require('#src/domain/bulkTransfer/index') const BulkTransferModel = require('#src/models/bulkTransfer/bulkTransfer') const BulkTransferModels = require('@mojaloop/object-store-lib').Models.BulkTransfer const ilp = require('#src/models/transfer/ilpPacket') +const ProxyCache = require('#src/lib/proxyCache') // Sample Bulk Transfer Message received by the Bulk API Adapter const fspiopBulkTransferMsg = { @@ -159,6 +160,10 @@ Test('Bulk Transfer PREPARE handler', handlerTest => { handlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) SpanStub = { audit: sandbox.stub().callsFake(), error: sandbox.stub().callsFake(), diff --git a/test/unit/handlers/index.test.js b/test/unit/handlers/index.test.js index 684803972..e89036b8d 100644 --- a/test/unit/handlers/index.test.js +++ b/test/unit/handlers/index.test.js @@ -7,6 +7,7 @@ const Proxyquire = require('proxyquire') const Plugin = require('../../../src/handlers/api/plugin') const MetricsPlugin = require('../../../src/api/metrics/plugin') const Logger = require('@mojaloop/central-services-logger') +const ProxyCache = require('#src/lib/proxyCache') Test('cli', async (cliTest) => { let sandbox @@ -35,9 +36,12 @@ Test('cli', async (cliTest) => { commanderTest.beforeEach(test => { sandbox = Sinon.createSandbox() - + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) SetupStub = { - initialize: sandbox.stub().returns(Promise.resolve()) + initialize: sandbox.stub().resolves() } process.argv = [] diff --git a/test/unit/handlers/positions/handler.test.js b/test/unit/handlers/positions/handler.test.js index b4278bee4..2384f341b 100644 --- a/test/unit/handlers/positions/handler.test.js +++ b/test/unit/handlers/positions/handler.test.js @@ -22,6 +22,7 @@ const Clone = require('lodash').clone const TransferState = Enum.Transfers.TransferState const TransferInternalState = Enum.Transfers.TransferInternalState const Proxyquire = require('proxyquire') +const ProxyCache = require('#src/lib/proxyCache') const transfer = { transferId: 'b51ec534-ee48-4575-b6a9-ead2955b8999', @@ -143,6 +144,10 @@ Test('Position handler', transferHandlerTest => { transferHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) SpanStub = { audit: sandbox.stub().callsFake(), error: sandbox.stub().callsFake(), diff --git a/test/unit/handlers/positions/handlerBatch.test.js b/test/unit/handlers/positions/handlerBatch.test.js index 590fd244e..ffc344700 100644 --- a/test/unit/handlers/positions/handlerBatch.test.js +++ b/test/unit/handlers/positions/handlerBatch.test.js @@ -40,6 +40,7 @@ const SettlementModelCached = require('../../../../src/models/settlement/settlem const Enum = require('@mojaloop/central-services-shared').Enum const Proxyquire = require('proxyquire') const Logger = require('@mojaloop/central-services-logger') +const ProxyCache = require('#src/lib/proxyCache') const topicName = 'topic-transfer-position-batch' @@ -128,6 +129,10 @@ Test('Position handler', positionBatchHandlerTest => { positionBatchHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) SpanStub = { audit: sandbox.stub().callsFake(), error: sandbox.stub().callsFake(), diff --git a/test/unit/handlers/register.test.js b/test/unit/handlers/register.test.js index 7da1df0e5..1a0f81f7c 100644 --- a/test/unit/handlers/register.test.js +++ b/test/unit/handlers/register.test.js @@ -12,6 +12,7 @@ const BulkProcessingHandlers = require('../../../src/handlers/bulk/processing/ha const BulkFulfilHandlers = require('../../../src/handlers/bulk/fulfil/handler') const BulkGetHandlers = require('../../../src/handlers/bulk/get/handler') const Proxyquire = require('proxyquire') +const ProxyCache = require('#src/lib/proxyCache') Test('handlers', handlersTest => { let sandbox @@ -26,6 +27,10 @@ Test('handlers', handlersTest => { sandbox.stub(BulkProcessingHandlers, 'registerAllHandlers').returns(Promise.resolve(true)) sandbox.stub(BulkFulfilHandlers, 'registerAllHandlers').returns(Promise.resolve(true)) sandbox.stub(BulkGetHandlers, 'registerAllHandlers').returns(Promise.resolve(true)) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) test.end() }) diff --git a/test/unit/handlers/timeouts/handler.test.js b/test/unit/handlers/timeouts/handler.test.js index 8b803478a..7436a81f3 100644 --- a/test/unit/handlers/timeouts/handler.test.js +++ b/test/unit/handlers/timeouts/handler.test.js @@ -36,6 +36,7 @@ const CronJob = require('cron').CronJob const TimeoutService = require('../../../../src/domain/timeout') const Config = require('../../../../src/lib/config') const { randomUUID } = require('crypto') +const ProxyCache = require('#src/lib/proxyCache') const Enum = require('@mojaloop/central-services-shared').Enum const Utility = require('@mojaloop/central-services-shared').Util.Kafka @@ -49,6 +50,10 @@ Test('Timeout handler', TimeoutHandlerTest => { sandbox.stub(CronJob.prototype, 'constructor').returns(Promise.resolve()) sandbox.stub(CronJob.prototype, 'start').returns(Promise.resolve(true)) sandbox.stub(CronJob.prototype, 'stop').returns(Promise.resolve(true)) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) Config.HANDLERS_TIMEOUT_DISABLED = false test.end() }) diff --git a/test/unit/handlers/transfers/FxFulfilService.test.js b/test/unit/handlers/transfers/FxFulfilService.test.js index b655fecf5..e0a507d7f 100644 --- a/test/unit/handlers/transfers/FxFulfilService.test.js +++ b/test/unit/handlers/transfers/FxFulfilService.test.js @@ -36,6 +36,7 @@ const FxTransferModel = require('../../../../src/models/fxTransfer') const Config = require('../../../../src/lib/config') const { ERROR_MESSAGES } = require('../../../../src/shared/constants') const { Logger } = require('../../../../src/shared/logger') +const ProxyCache = require('#src/lib/proxyCache') const fixtures = require('../../../fixtures') const mocks = require('./mocks') @@ -87,6 +88,10 @@ Test('FxFulfilService Tests -->', fxFulfilTest => { sandbox.stub(Db) sandbox.stub(FxTransferModel.fxTransfer) sandbox.stub(FxTransferModel.duplicateCheck) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) span = mocks.createTracerStub(sandbox).SpanStub test.end() }) diff --git a/test/unit/handlers/transfers/fxFuflilHandler.test.js b/test/unit/handlers/transfers/fxFuflilHandler.test.js index 1210b8da9..1584d6403 100644 --- a/test/unit/handlers/transfers/fxFuflilHandler.test.js +++ b/test/unit/handlers/transfers/fxFuflilHandler.test.js @@ -49,6 +49,7 @@ const { logger } = require('../../../../src/shared/logger') const { checkErrorPayload } = require('../../../util/helpers') const fixtures = require('../../../fixtures') const mocks = require('./mocks') +const ProxyCache = require('#src/lib/proxyCache') const { Kafka, Comparators } = Util const { Action, Type } = Enum.Events.Event @@ -82,6 +83,10 @@ Test('FX Transfer Fulfil handler -->', fxFulfilTest => { commitMessageSync: async () => true }) sandbox.stub(Consumer, 'isConsumerAutoCommitEnabled').returns(false) + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) test.end() }) diff --git a/test/unit/handlers/transfers/handler.test.js b/test/unit/handlers/transfers/handler.test.js index 9d228e3ed..173345fee 100644 --- a/test/unit/handlers/transfers/handler.test.js +++ b/test/unit/handlers/transfers/handler.test.js @@ -52,6 +52,7 @@ const Participant = require('../../../../src/domain/participant') const Cyril = require('../../../../src/domain/fx/cyril') const TransferObjectTransform = require('../../../../src/domain/transfer/transform') const ilp = require('../../../../src/models/transfer/ilpPacket') +const ProxyCache = require('#src/lib/proxyCache') const { getMessagePayloadOrThrow } = require('../../../util/helpers') const mocks = require('./mocks') @@ -261,7 +262,10 @@ Test('Transfer handler', transferHandlerTest => { transferHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() - + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) const stubs = mocks.createTracerStub(sandbox) SpanStub = stubs.SpanStub diff --git a/test/unit/handlers/transfers/prepare.test.js b/test/unit/handlers/transfers/prepare.test.js index 651ea7dd0..deef4d13e 100644 --- a/test/unit/handlers/transfers/prepare.test.js +++ b/test/unit/handlers/transfers/prepare.test.js @@ -54,6 +54,7 @@ const Config = require('../../../../src/lib/config') const fxTransferModel = require('../../../../src/models/fxTransfer') const fxDuplicateCheck = require('../../../../src/models/fxTransfer/duplicateCheck') const fxTransferStateChange = require('../../../../src/models/fxTransfer/stateChange') +const ProxyCache = require('#src/lib/proxyCache') const { Action } = Enum.Events.Event @@ -318,6 +319,10 @@ Test('Transfer handler', transferHandlerTest => { transferHandlerTest.beforeEach(test => { sandbox = Sinon.createSandbox() + sandbox.stub(ProxyCache, 'getCache').returns({ + connect: sandbox.stub(), + disconnect: sandbox.stub() + }) SpanStub = { audit: sandbox.stub().callsFake(), error: sandbox.stub().callsFake(), diff --git a/test/unit/lib/healthCheck/subServiceHealth.test.js b/test/unit/lib/healthCheck/subServiceHealth.test.js index a02515f99..cd317a084 100644 --- a/test/unit/lib/healthCheck/subServiceHealth.test.js +++ b/test/unit/lib/healthCheck/subServiceHealth.test.js @@ -37,21 +37,23 @@ const { statusEnum, serviceName } = require('@mojaloop/central-services-shared') const MigrationLockModel = require('../../../../src/models/misc/migrationLock') const Consumer = require('@mojaloop/central-services-stream').Util.Consumer const Logger = require('@mojaloop/central-services-logger') +const ProxyCache = require('#src/lib/proxyCache') const { getSubServiceHealthBroker, - getSubServiceHealthDatastore + getSubServiceHealthDatastore, + getSubServiceHealthProxyCache } = require('../../../../src/lib/healthCheck/subServiceHealth.js') Test('SubServiceHealth test', subServiceHealthTest => { let sandbox - + let proxyCacheStub subServiceHealthTest.beforeEach(t => { sandbox = Sinon.createSandbox() sandbox.stub(Consumer, 'getListOfTopics') sandbox.stub(Consumer, 'isConnected') sandbox.stub(Logger, 'isDebugEnabled').value(true) - + proxyCacheStub = sandbox.stub(ProxyCache, 'getCache') t.end() }) @@ -151,5 +153,38 @@ Test('SubServiceHealth test', subServiceHealthTest => { datastoreTest.end() }) + subServiceHealthTest.test('getSubServiceHealthProxyCache', proxyCacheTest => { + proxyCacheTest.test('Reports up when not health', async test => { + // Arrange + proxyCacheStub.returns({ + healthCheck: sandbox.stub().returns(Promise.resolve(true)) + }) + const expected = { name: 'proxyCache', status: statusEnum.OK } + + // Act + const result = await getSubServiceHealthProxyCache() + + // Assert + test.deepEqual(result, expected, 'getSubServiceHealthBroker should match expected result') + test.end() + }) + + proxyCacheTest.test('Reports down when not health', async test => { + // Arrange + proxyCacheStub.returns({ + healthCheck: sandbox.stub().returns(Promise.resolve(false)) + }) + const expected = { name: 'proxyCache', status: statusEnum.DOWN } + + // Act + const result = await getSubServiceHealthProxyCache() + + // Assert + test.deepEqual(result, expected, 'getSubServiceHealthBroker should match expected result') + test.end() + }) + proxyCacheTest.end() + }) + subServiceHealthTest.end() }) diff --git a/test/unit/lib/proxyCache.test.js b/test/unit/lib/proxyCache.test.js new file mode 100644 index 000000000..d2f3dfc75 --- /dev/null +++ b/test/unit/lib/proxyCache.test.js @@ -0,0 +1,121 @@ +'use strict' + +const Test = require('tapes')(require('tape')) +const Sinon = require('sinon') +const ParticipantService = require('../../../src/domain/participant') +const Proxyquire = require('proxyquire') + +const connectStub = Sinon.stub() +const disconnectStub = Sinon.stub() +const lookupProxyByDfspIdStub = Sinon.stub() +lookupProxyByDfspIdStub.withArgs('existingDfspId1').resolves('proxyId') +lookupProxyByDfspIdStub.withArgs('existingDfspId2').resolves('proxyId') +lookupProxyByDfspIdStub.withArgs('existingDfspId3').resolves('proxyId1') +lookupProxyByDfspIdStub.withArgs('nonExistingDfspId1').resolves(null) +lookupProxyByDfspIdStub.withArgs('nonExistingDfspId2').resolves(null) + +const ProxyCache = Proxyquire('../../../src/lib/proxyCache', { + '@mojaloop/inter-scheme-proxy-cache-lib': { + createProxyCache: Sinon.stub().returns({ + connect: connectStub, + disconnect: disconnectStub, + lookupProxyByDfspId: lookupProxyByDfspIdStub + }) + } +}) + +Test('Proxy Cache test', async (proxyCacheTest) => { + let sandbox + + proxyCacheTest.beforeEach(t => { + sandbox = Sinon.createSandbox() + sandbox.stub(ParticipantService) + t.end() + }) + + proxyCacheTest.afterEach(t => { + sandbox.restore() + t.end() + }) + + await proxyCacheTest.test('connect', async (connectTest) => { + await connectTest.test('connect to cache', async (test) => { + await ProxyCache.connect() + Sinon.assert.calledOnce(connectStub) + test.end() + }) + + connectTest.end() + }) + + await proxyCacheTest.test('disconnect', async (disconnectTest) => { + await disconnectTest.test('disconnect from cache', async (test) => { + await ProxyCache.disconnect() + test.pass() + test.end() + }) + + disconnectTest.end() + }) + + await proxyCacheTest.test('getCache', async (getCacheTest) => { + await getCacheTest.test('resolve proxy id if participant not in scheme and proxyId is in cache', async (test) => { + await ProxyCache.getCache() + test.pass() + test.end() + }) + getCacheTest.end() + }) + + await proxyCacheTest.test('getFSPProxy', async (getFSPProxyTest) => { + await getFSPProxyTest.test('resolve proxy id if participant not in scheme and proxyId is in cache', async (test) => { + ParticipantService.getByName.returns(Promise.resolve(null)) + const result = await ProxyCache.getFSPProxy('existingDfspId1') + + test.deepEqual(result, { inScheme: false, proxyId: 'proxyId' }) + test.end() + }) + + await getFSPProxyTest.test('resolve proxy id if participant not in scheme and proxyId is not cache', async (test) => { + ParticipantService.getByName.returns(Promise.resolve(null)) + const result = await ProxyCache.getFSPProxy('nonExistingDfspId1') + + test.deepEqual(result, { inScheme: false, proxyId: null }) + test.end() + }) + + await getFSPProxyTest.test('not resolve proxyId if participant is in scheme', async (test) => { + ParticipantService.getByName.returns(Promise.resolve({ participantId: 1 })) + const result = await ProxyCache.getFSPProxy('existingDfspId1') + + test.deepEqual(result, { inScheme: true, proxyId: null }) + test.end() + }) + + getFSPProxyTest.end() + }) + + await proxyCacheTest.test('checkSameCreditorDebtorProxy', async (checkSameCreditorDebtorProxyTest) => { + await checkSameCreditorDebtorProxyTest.test('resolve true if proxy of debtor and creditor are truth and the same', async (test) => { + const result = await ProxyCache.checkSameCreditorDebtorProxy('existingDfspId1', 'existingDfspId2') + test.deepEqual(result, true) + test.end() + }) + + await checkSameCreditorDebtorProxyTest.test('resolve false if proxy of debtor and creditor are truth and different', async (test) => { + const result = await ProxyCache.checkSameCreditorDebtorProxy('existingDfspId1', 'existingDfspId3') + test.deepEqual(result, false) + test.end() + }) + + await checkSameCreditorDebtorProxyTest.test('resolve false if proxy of debtor and creditor are same but falsy', async (test) => { + const result = await ProxyCache.checkSameCreditorDebtorProxy('nonExistingDfspId1', 'nonExistingDfspId1') + test.deepEqual(result, false) + test.end() + }) + + checkSameCreditorDebtorProxyTest.end() + }) + + proxyCacheTest.end() +}) diff --git a/test/unit/models/position/facade.test.js b/test/unit/models/position/facade.test.js index c0879b082..8c1edea6b 100644 --- a/test/unit/models/position/facade.test.js +++ b/test/unit/models/position/facade.test.js @@ -319,11 +319,11 @@ Test('Position facade', async (positionFacadeTest) => { transacting: sandbox.stub().returns({ forUpdate: sandbox.stub().returns({ whereIn: sandbox.stub().returns({ - select: sandbox.stub().returns(Promise.resolve()) + select: sandbox.stub().resolves() }) }), where: sandbox.stub().returns({ - update: sandbox.stub().returns(Promise.resolve()), + update: sandbox.stub().resolves(), orderBy: sandbox.stub().returns({ first: sandbox.stub().resolves(Object.assign({}, transferStateChange)) }) @@ -405,11 +405,11 @@ Test('Position facade', async (positionFacadeTest) => { transacting: sandbox.stub().returns({ forUpdate: sandbox.stub().returns({ whereIn: sandbox.stub().returns({ - select: sandbox.stub().returns(Promise.resolve()) + select: sandbox.stub().resolves() }) }), where: sandbox.stub().returns({ - update: sandbox.stub().returns(Promise.resolve()), + update: sandbox.stub().resolves(), orderBy: sandbox.stub().returns({ first: sandbox.stub().resolves(Object.assign({}, transferStateChange)) }) @@ -488,11 +488,11 @@ Test('Position facade', async (positionFacadeTest) => { transacting: sandbox.stub().returns({ forUpdate: sandbox.stub().returns({ whereIn: sandbox.stub().returns({ - select: sandbox.stub().returns(Promise.resolve()) + select: sandbox.stub().resolves() }) }), where: sandbox.stub().returns({ - update: sandbox.stub().returns(Promise.resolve()), + update: sandbox.stub().resolves(), orderBy: sandbox.stub().returns({ first: sandbox.stub().resolves(incorrectTransferStateChange) }) @@ -598,11 +598,11 @@ Test('Position facade', async (positionFacadeTest) => { transacting: sandbox.stub().returns({ forUpdate: sandbox.stub().returns({ whereIn: sandbox.stub().returns({ - select: sandbox.stub().returns(Promise.resolve()) + select: sandbox.stub().resolves() }) }), where: sandbox.stub().returns({ - update: sandbox.stub().returns(Promise.resolve()), + update: sandbox.stub().resolves(), orderBy: sandbox.stub().returns({ first: sandbox.stub().resolves(MainUtil.clone(transferStateChange)) }) @@ -687,11 +687,11 @@ Test('Position facade', async (positionFacadeTest) => { transacting: sandbox.stub().returns({ forUpdate: sandbox.stub().returns({ whereIn: sandbox.stub().returns({ - select: sandbox.stub().returns(Promise.resolve()) + select: sandbox.stub().resolves() }) }), where: sandbox.stub().returns({ - update: sandbox.stub().returns(Promise.resolve()), + update: sandbox.stub().resolves(), orderBy: sandbox.stub().returns({ first: sandbox.stub().resolves(MainUtil.clone(transferStateChange)) }) diff --git a/test/unit/shared/setup.test.js b/test/unit/shared/setup.test.js index 81e646356..3613151a8 100644 --- a/test/unit/shared/setup.test.js +++ b/test/unit/shared/setup.test.js @@ -15,10 +15,12 @@ Test('setup', setupTest => { let oldMongoDbHost let oldMongoDbPort let oldMongoDbDatabase + let oldProxyCacheEnabled let mongoDbUri const hostName = 'http://test.com' let Setup let DbStub + let ProxyCacheStub let CacheStub let ObjStoreStub // let ObjStoreStubThrows @@ -36,7 +38,7 @@ Test('setup', setupTest => { sandbox = Sinon.createSandbox() processExitStub = sandbox.stub(process, 'exit') PluginsStub = { - registerPlugins: sandbox.stub().returns(Promise.resolve()) + registerPlugins: sandbox.stub().resolves() } serverStub = { @@ -59,22 +61,32 @@ Test('setup', setupTest => { } requestLoggerStub = { - logRequest: sandbox.stub().returns(Promise.resolve()), - logResponse: sandbox.stub().returns(Promise.resolve()) + logRequest: sandbox.stub().resolves(), + logResponse: sandbox.stub().resolves() } DbStub = { + connect: sandbox.stub().resolves(), + disconnect: sandbox.stub().resolves() + } + + ProxyCacheStub = { connect: sandbox.stub().returns(Promise.resolve()), - disconnect: sandbox.stub().returns(Promise.resolve()) + getCache: sandbox.stub().returns( + { + connect: sandbox.stub().returns(Promise.resolve(true)), + disconnect: sandbox.stub().returns(Promise.resolve(true)) + } + ) } CacheStub = { - initCache: sandbox.stub().returns(Promise.resolve()) + initCache: sandbox.stub().resolves() } ObjStoreStub = { Db: { - connect: sandbox.stub().returns(Promise.resolve()), + connect: sandbox.stub().resolves(), Mongoose: { set: sandbox.stub() } @@ -89,34 +101,35 @@ Test('setup', setupTest => { uuidStub = sandbox.stub() MigratorStub = { - migrate: sandbox.stub().returns(Promise.resolve()) + migrate: sandbox.stub().resolves() } RegisterHandlersStub = { - registerAllHandlers: sandbox.stub().returns(Promise.resolve()), + registerAllHandlers: sandbox.stub().resolves(), transfers: { - registerPrepareHandler: sandbox.stub().returns(Promise.resolve()), - registerGetHandler: sandbox.stub().returns(Promise.resolve()), - registerFulfilHandler: sandbox.stub().returns(Promise.resolve()) - // registerRejectHandler: sandbox.stub().returns(Promise.resolve()) + registerPrepareHandler: sandbox.stub().resolves(), + registerGetHandler: sandbox.stub().resolves(), + registerFulfilHandler: sandbox.stub().resolves() + // registerRejectHandler: sandbox.stub().resolves() }, positions: { - registerPositionHandler: sandbox.stub().returns(Promise.resolve()) + registerPositionHandler: sandbox.stub().resolves() }, positionsBatch: { - registerPositionHandler: sandbox.stub().returns(Promise.resolve()) + registerPositionHandler: sandbox.stub().resolves() }, timeouts: { - registerAllHandlers: sandbox.stub().returns(Promise.resolve()), - registerTimeoutHandler: sandbox.stub().returns(Promise.resolve()) + registerAllHandlers: sandbox.stub().resolves(), + registerTimeoutHandler: sandbox.stub().resolves() }, admin: { - registerAdminHandlers: sandbox.stub().returns(Promise.resolve()) + registerAdminHandlers: sandbox.stub().resolves() }, bulk: { - registerBulkPrepareHandler: sandbox.stub().returns(Promise.resolve()), - registerBulkFulfilHandler: sandbox.stub().returns(Promise.resolve()), - registerBulkProcessingHandler: sandbox.stub().returns(Promise.resolve()) + registerBulkPrepareHandler: sandbox.stub().resolves(), + registerBulkFulfilHandler: sandbox.stub().resolves(), + registerBulkProcessingHandler: sandbox.stub().resolves(), + registerBulkGetHandler: sandbox.stub().resolves() } } const ConfigStub = Config @@ -130,6 +143,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -147,12 +161,14 @@ Test('setup', setupTest => { oldMongoDbHost = Config.MONGODB_HOST oldMongoDbPort = Config.MONGODB_PORT oldMongoDbDatabase = Config.MONGODB_DATABASE + oldProxyCacheEnabled = Config.PROXY_CACHE_CONFIG.enabled Config.HOSTNAME = hostName Config.MONGODB_HOST = 'testhost' Config.MONGODB_PORT = '1111' Config.MONGODB_USER = 'user' Config.MONGODB_PASSWORD = 'pass' Config.MONGODB_DATABASE = 'mlos' + Config.PROXY_CACHE_CONFIG.enabled = true mongoDbUri = MongoUriBuilder({ username: Config.MONGODB_USER, password: Config.MONGODB_PASSWORD, @@ -173,6 +189,7 @@ Test('setup', setupTest => { Config.MONGODB_USER = oldMongoDbUsername Config.MONGODB_PASSWORD = oldMongoDbPassword Config.MONGODB_DATABASE = oldMongoDbDatabase + Config.PROXY_CACHE_CONFIG.enabled = oldProxyCacheEnabled test.end() }) @@ -193,6 +210,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -245,6 +263,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -361,6 +380,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -394,6 +414,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -428,6 +449,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -464,6 +486,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub, @@ -547,6 +570,11 @@ Test('setup', setupTest => { enabled: true } + const bulkGetHandler = { + type: 'bulkget', + enabled: true + } + const unknownHandler = { type: 'undefined', enabled: true @@ -563,6 +591,7 @@ Test('setup', setupTest => { bulkBrepareHandler, bulkFulfilHandler, bulkProcessingHandler, + bulkGetHandler, unknownHandler // rejectHandler ] @@ -578,6 +607,7 @@ Test('setup', setupTest => { test.ok(RegisterHandlersStub.bulk.registerBulkPrepareHandler.called) test.ok(RegisterHandlersStub.bulk.registerBulkFulfilHandler.called) test.ok(RegisterHandlersStub.bulk.registerBulkProcessingHandler.called) + test.ok(RegisterHandlersStub.bulk.registerBulkGetHandler.called) test.ok(processExitStub.called) test.end() }).catch(err => { @@ -706,6 +736,7 @@ Test('setup', setupTest => { }, '../handlers/register': RegisterHandlersStub, '../lib/db': DbStub, + '../lib/proxyCache': ProxyCacheStub, '../lib/cache': CacheStub, '@mojaloop/object-store-lib': ObjStoreStub, '../lib/migrator': MigratorStub,