@mojaloop/sdk-scheme-adapter 15.0.0 → 15.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/audit-resolve.json +43 -542
- package/docs/dfspInboundApi.yaml +11 -0
- package/package.json +25 -24
- package/src/ControlAgent/index.js +8 -11
- package/src/ControlServer/index.js +13 -13
- package/src/InboundServer/index.js +12 -61
- package/src/OAuthTestServer/index.js +0 -13
- package/src/OutboundServer/index.js +11 -54
- package/src/TestServer/index.js +6 -33
- package/src/config.js +1 -4
- package/src/index.js +163 -146
- package/src/lib/cache.js +93 -186
- package/src/lib/metrics.js +1 -1
- package/src/lib/model/InboundTransfersModel.js +10 -6
- package/src/lib/model/OutboundTransfersModel.js +1 -1
- package/test/__mocks__/redis.js +51 -26
- package/test/config/integration.env +1 -2
- package/test/integration/lib/cache.test.js +1 -2
- package/test/integration/testEnv.js +1 -4
- package/test/unit/ControlClient.test.js +1 -45
- package/test/unit/ControlServer/index.js +18 -22
- package/test/unit/ControlServer.test.js +0 -60
- package/test/unit/InboundServer.test.js +8 -8
- package/test/unit/TestServer.test.js +1 -1
- package/test/unit/api/accounts/accounts.test.js +2 -2
- package/test/unit/api/transfers/transfers.test.js +1 -1
- package/test/unit/api/utils.js +12 -4
- package/test/unit/config.test.js +1 -2
- package/test/unit/data/defaultConfig.json +1 -5
- package/test/unit/index.test.js +5 -64
- package/test/unit/lib/cache.test.js +5 -6
- package/test/unit/lib/model/AccountsModel.test.js +3 -4
- package/test/unit/lib/model/InboundTransfersModel.test.js +55 -16
- package/test/unit/lib/model/OutboundBulkQuotesModel.test.js +3 -4
- package/test/unit/lib/model/OutboundBulkTransfersModel.test.js +1 -2
- package/test/unit/lib/model/OutboundRequestToPayModel.test.js +3 -4
- package/test/unit/lib/model/OutboundRequestToPayTransferModel.test.js +3 -4
- package/test/unit/lib/model/OutboundTransfersModel.test.js +2 -3
- package/test/unit/lib/model/common/PersistentStateMachine.test.js +3 -4
- package/test/unit/lib/model/data/defaultConfig.json +1 -4
- package/test/unit/lib/model/data/notificationAbortedToPayee.json +10 -0
- package/test/unit/lib/model/data/notificationReservedToPayee.json +10 -0
|
@@ -139,7 +139,11 @@ class Server extends ws.Server {
|
|
|
139
139
|
|
|
140
140
|
// Close the server then wait for all the client sockets to close
|
|
141
141
|
async stop() {
|
|
142
|
-
|
|
142
|
+
const closing = new Promise(resolve => this.close(resolve));
|
|
143
|
+
for (const client of this.clients) {
|
|
144
|
+
client.terminate();
|
|
145
|
+
}
|
|
146
|
+
await closing;
|
|
143
147
|
this._logger.log('Control server shutdown complete');
|
|
144
148
|
}
|
|
145
149
|
|
|
@@ -186,9 +190,7 @@ class Server extends ws.Server {
|
|
|
186
190
|
* from other modules.
|
|
187
191
|
*/
|
|
188
192
|
registerInternalEvents() {
|
|
189
|
-
ControlServerEventEmitter.on(INTERNAL_EVENTS.SERVER.BROADCAST_CONFIG_CHANGE, (params) =>
|
|
190
|
-
this.broadcastConfigChange(params);
|
|
191
|
-
});
|
|
193
|
+
ControlServerEventEmitter.on(INTERNAL_EVENTS.SERVER.BROADCAST_CONFIG_CHANGE, (params) => this.broadcastConfigChange(params));
|
|
192
194
|
}
|
|
193
195
|
|
|
194
196
|
/**
|
|
@@ -196,28 +198,22 @@ class Server extends ws.Server {
|
|
|
196
198
|
*
|
|
197
199
|
* @param {object} params Updated configuration
|
|
198
200
|
*/
|
|
199
|
-
|
|
201
|
+
broadcastConfigChange(updatedConfig) {
|
|
200
202
|
const updateConfMsg = build.CONFIGURATION.PATCH({}, updatedConfig, generateSlug(4));
|
|
201
|
-
|
|
202
|
-
this._logger
|
|
203
|
-
.push({ message, ip: this._clientData.get(socket).ip, err })
|
|
204
|
-
.log('Error sending JWS keys notification to client');
|
|
205
|
-
return await this.broadcast(updateConfMsg, errorLogger);
|
|
203
|
+
this.broadcast(updateConfMsg);
|
|
206
204
|
}
|
|
207
205
|
|
|
208
206
|
/**
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
);
|
|
220
|
-
return await sendToAllClients(msg, errorLogger);
|
|
207
|
+
* Broadcasts a protocol message to all connected clients.
|
|
208
|
+
*
|
|
209
|
+
* @param {string} msg
|
|
210
|
+
*/
|
|
211
|
+
broadcast(msg) {
|
|
212
|
+
this.clients.forEach((client) => {
|
|
213
|
+
if (client.readyState === ws.WebSocket.OPEN) {
|
|
214
|
+
client.send(msg);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
221
217
|
}
|
|
222
218
|
}
|
|
223
219
|
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
const ControlServer = require('~/ControlServer');
|
|
3
|
-
const InboundServer = require('~/InboundServer');
|
|
4
|
-
const OutboundServer = require('~/OutboundServer');
|
|
5
|
-
const TestServer = require('~/TestServer');
|
|
6
|
-
const defaultConfig = require('./data/defaultConfig.json');
|
|
7
3
|
const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
8
4
|
|
|
9
5
|
jest.mock('~/lib/cache');
|
|
10
|
-
const Cache = require('~/lib/cache');
|
|
11
6
|
|
|
12
7
|
// TODO:
|
|
13
8
|
// - diff against master to determine what else needs testing
|
|
@@ -67,60 +62,5 @@ describe('ControlServer', () => {
|
|
|
67
62
|
const newConfEventData = await newConfigEvent;
|
|
68
63
|
expect(newConfEventData).toEqual(changedConfig);
|
|
69
64
|
});
|
|
70
|
-
|
|
71
|
-
it('sends new config to clients when instructed', async () => {
|
|
72
|
-
const client2 = await ControlServer.Client.Create({
|
|
73
|
-
address: 'localhost',
|
|
74
|
-
port: server.address().port,
|
|
75
|
-
logger
|
|
76
|
-
});
|
|
77
|
-
const changedConfig = { ...appConfig, some: 'thing' };
|
|
78
|
-
await client.send(ControlServer.build.CONFIGURATION.PATCH(appConfig, changedConfig));
|
|
79
|
-
const restart = server.reconfigure({ appConfig: changedConfig });
|
|
80
|
-
restart();
|
|
81
|
-
await server.notifyClientsOfCurrentConfig();
|
|
82
|
-
const [notification, notification2] =
|
|
83
|
-
await Promise.all([client.receive(), client2.receive()]);
|
|
84
|
-
const expected = ControlServer.build.CONFIGURATION.NOTIFY(changedConfig, notification.id);
|
|
85
|
-
expect(JSON.stringify(notification)).toEqual(expected);
|
|
86
|
-
expect(JSON.stringify(notification2)).toEqual(expected);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
describe('Server reconfigure methods', () => {
|
|
92
|
-
let conf, logger, cache;
|
|
93
|
-
|
|
94
|
-
const isPromise = (o) => Promise.resolve(o) === o;
|
|
95
|
-
|
|
96
|
-
beforeEach(() => {
|
|
97
|
-
conf = JSON.parse(JSON.stringify(defaultConfig));
|
|
98
|
-
logger = new Logger.Logger({ stringify: () => '' });
|
|
99
|
-
cache = new Cache({ ...conf.cacheConfig, logger: logger.push({ component: 'cache' }) });
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('InboundServer reconfigure method returns sync function', async () => {
|
|
103
|
-
const server = new InboundServer(conf, logger, cache);
|
|
104
|
-
const res = await server.reconfigure(conf, logger, cache);
|
|
105
|
-
expect(isPromise(res)).toEqual(false);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test('OutboundServer reconfigure method returns sync function', async () => {
|
|
109
|
-
const server = new OutboundServer(conf, logger, cache);
|
|
110
|
-
const res = await server.reconfigure(conf, logger, cache);
|
|
111
|
-
expect(isPromise(res)).toEqual(false);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
test('TestServer reconfigure method returns sync function', async () => {
|
|
115
|
-
const server = new TestServer({ logger, cache });
|
|
116
|
-
const res = await server.reconfigure({ logger, cache });
|
|
117
|
-
expect(isPromise(res)).toEqual(false);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
test('ControlServer reconfigure method returns sync function', async () => {
|
|
121
|
-
const server = new ControlServer.Server({ logger, appConfig: {} });
|
|
122
|
-
const res = await server.reconfigure({ logger, appConfig: {} });
|
|
123
|
-
expect(isPromise(res)).toEqual(false);
|
|
124
|
-
await server.close();
|
|
125
65
|
});
|
|
126
66
|
});
|
|
@@ -45,7 +45,7 @@ describe('Inbound Server', () => {
|
|
|
45
45
|
serverConfig.validateInboundJws = validateInboundJws;
|
|
46
46
|
serverConfig.validateInboundPutPartiesJws = validateInboundPutPartiesJws;
|
|
47
47
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
48
|
-
const cache = new Cache({
|
|
48
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
49
49
|
const svr = new InboundServer(serverConfig, logger, cache);
|
|
50
50
|
await svr.start();
|
|
51
51
|
await supertest(svr._server)
|
|
@@ -61,7 +61,7 @@ describe('Inbound Server', () => {
|
|
|
61
61
|
|
|
62
62
|
async function testPartiesHeaderValidation(contentType, expectedStatusCode, expectedBody = null) {
|
|
63
63
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
64
|
-
const cache = new Cache({
|
|
64
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
65
65
|
const svr = new InboundServer(serverConfig, logger, cache);
|
|
66
66
|
await svr.start();
|
|
67
67
|
const result = await supertest(svr._server)
|
|
@@ -141,7 +141,7 @@ describe('Inbound Server', () => {
|
|
|
141
141
|
serverConfig.validateInboundJws = validateInboundJws;
|
|
142
142
|
serverConfig.validateInboundPutPartiesJws = validateInboundPutPartiesJws;
|
|
143
143
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
144
|
-
const cache = new Cache({
|
|
144
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
145
145
|
const svr = new InboundServer(serverConfig, logger, cache);
|
|
146
146
|
await svr.start();
|
|
147
147
|
await supertest(svr._server)
|
|
@@ -158,7 +158,7 @@ describe('Inbound Server', () => {
|
|
|
158
158
|
|
|
159
159
|
async function testQuotesHeaderValidation(contentType, expectedStatusCode, expectedBody = null) {
|
|
160
160
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
161
|
-
const cache = new Cache({
|
|
161
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
162
162
|
const svr = new InboundServer(serverConfig, logger, cache);
|
|
163
163
|
await svr.start();
|
|
164
164
|
const result = await supertest(svr._server)
|
|
@@ -232,7 +232,7 @@ describe('Inbound Server', () => {
|
|
|
232
232
|
serverConfig.validateInboundJws = validateInboundJws;
|
|
233
233
|
serverConfig.validateInboundPutPartiesJws = validateInboundPutPartiesJws;
|
|
234
234
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
235
|
-
const cache = new Cache({
|
|
235
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
236
236
|
const svr = new InboundServer(serverConfig, logger, cache);
|
|
237
237
|
await svr.start();
|
|
238
238
|
await supertest(svr._server)
|
|
@@ -249,7 +249,7 @@ describe('Inbound Server', () => {
|
|
|
249
249
|
|
|
250
250
|
async function testParticipantsHeaderValidation(contentType, expectedStatusCode, expectedBody = null) {
|
|
251
251
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
252
|
-
const cache = new Cache({
|
|
252
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
253
253
|
const svr = new InboundServer(serverConfig, logger, cache);
|
|
254
254
|
await svr.start();
|
|
255
255
|
const result = await supertest(svr._server)
|
|
@@ -336,7 +336,7 @@ describe('Inbound Server', () => {
|
|
|
336
336
|
async function testTlsServer(enableTls) {
|
|
337
337
|
defConfig.inbound.tls.mutualTLS.enabled = enableTls;
|
|
338
338
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
339
|
-
const cache = new Cache({
|
|
339
|
+
const cache = new Cache({ cacheUrl: defConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
340
340
|
const server = new InboundServer(defConfig, logger, cache);
|
|
341
341
|
await server.start();
|
|
342
342
|
if (enableTls) {
|
|
@@ -369,7 +369,7 @@ describe('Inbound Server', () => {
|
|
|
369
369
|
fs.writeFileSync(mockFilePath, 'foo-key');
|
|
370
370
|
serverConfig.jwsVerificationKeysDirectory = keysDir;
|
|
371
371
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
372
|
-
const cache = new Cache({
|
|
372
|
+
const cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }) });
|
|
373
373
|
svr = new InboundServer(serverConfig, logger, cache);
|
|
374
374
|
await svr.start();
|
|
375
375
|
});
|
|
@@ -50,7 +50,7 @@ describe('Test Server', () => {
|
|
|
50
50
|
...JSON.parse(JSON.stringify(defaultConfig)),
|
|
51
51
|
enableTestFeatures: true,
|
|
52
52
|
};
|
|
53
|
-
cache = new Cache({
|
|
53
|
+
cache = new Cache({ cacheUrl: serverConfig.cacheUrl, logger: logger.push({ component: 'cache' }), enableTestFeatures: true });
|
|
54
54
|
|
|
55
55
|
testServer = new TestServer({ logger, cache });
|
|
56
56
|
await testServer.start();
|
|
@@ -35,7 +35,7 @@ describe('Outbound Accounts API', () => {
|
|
|
35
35
|
|
|
36
36
|
beforeAll(async () => {
|
|
37
37
|
validatorsInfo = await createValidators();
|
|
38
|
-
redisClient = redis.createClient();
|
|
38
|
+
redisClient = redis.createClient(defaultConfig);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
beforeEach(async () => {
|
|
@@ -52,7 +52,7 @@ describe('Outbound Accounts API', () => {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
afterAll(async () => {
|
|
55
|
-
redisClient.end();
|
|
55
|
+
// redisClient.end();
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
describe('POST /accounts', () => {
|
|
@@ -42,7 +42,7 @@ describe('Outbound Transfers API', () => {
|
|
|
42
42
|
|
|
43
43
|
beforeAll(async () => {
|
|
44
44
|
validatorsInfo = await createValidators();
|
|
45
|
-
redisClient = redis.createClient();
|
|
45
|
+
redisClient = redis.createClient({ cacheUrl: 'redis://dummy:1234' });
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
beforeEach(async () => {
|
package/test/unit/api/utils.js
CHANGED
|
@@ -7,7 +7,7 @@ const Validate = require('~/lib/validate');
|
|
|
7
7
|
const InboundServer = require('~/InboundServer');
|
|
8
8
|
const OutboundServer = require('~/OutboundServer');
|
|
9
9
|
const { MetricsClient } = require('~/lib/metrics');
|
|
10
|
-
const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
10
|
+
const { Logger, WSO2Auth } = require('@mojaloop/sdk-standard-components');
|
|
11
11
|
const Cache = require('~/lib/cache');
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -43,18 +43,26 @@ const createTestServers = async (config) => {
|
|
|
43
43
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
44
44
|
const defConfig = JSON.parse(JSON.stringify(config));
|
|
45
45
|
const cache = new Cache({
|
|
46
|
-
|
|
46
|
+
cacheUrl: defConfig.cacheUrl,
|
|
47
47
|
logger: logger.push({ component: 'cache' })
|
|
48
48
|
});
|
|
49
49
|
await cache.connect();
|
|
50
50
|
defConfig.requestProcessingTimeoutSeconds = 2;
|
|
51
51
|
const metricsClient = new MetricsClient();
|
|
52
52
|
metricsClient._prometheusRegister.clear();
|
|
53
|
-
const
|
|
53
|
+
const wso2 = {
|
|
54
|
+
auth: new WSO2Auth({
|
|
55
|
+
...defConfig.wso2.auth,
|
|
56
|
+
logger,
|
|
57
|
+
tlsCreds: defConfig.outbound.tls.mutualTLS.enabled && defConfig.outbound.tls.creds,
|
|
58
|
+
}),
|
|
59
|
+
retryWso2AuthFailureTimes: defConfig.wso2.requestAuthFailureRetryTimes,
|
|
60
|
+
};
|
|
61
|
+
const serverOutbound = new OutboundServer(defConfig, logger, cache, metricsClient, wso2);
|
|
54
62
|
await serverOutbound.start();
|
|
55
63
|
const reqOutbound = supertest(serverOutbound._server);
|
|
56
64
|
|
|
57
|
-
const serverInbound = new InboundServer(defConfig, logger, cache);
|
|
65
|
+
const serverInbound = new InboundServer(defConfig, logger, cache, wso2);
|
|
58
66
|
await serverInbound.start();
|
|
59
67
|
const reqInbound = supertest(serverInbound._server);
|
|
60
68
|
|
package/test/unit/config.test.js
CHANGED
|
@@ -26,8 +26,7 @@ describe('config', () => {
|
|
|
26
26
|
env = { ...process.env };
|
|
27
27
|
process.env.PEER_ENDPOINT = '172.17.0.3:4000';
|
|
28
28
|
process.env.BACKEND_ENDPOINT = '172.17.0.5:4000';
|
|
29
|
-
process.env.
|
|
30
|
-
process.env.CACHE_PORT = '6379';
|
|
29
|
+
process.env.CACHE_URL = 'redis://172.17.0.2:6379';
|
|
31
30
|
process.env.MGMT_API_WS_URL = '0.0.0.0';
|
|
32
31
|
certDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jest-'));
|
|
33
32
|
});
|
|
@@ -49,12 +49,8 @@
|
|
|
49
49
|
"jwsSignPutParties": false,
|
|
50
50
|
"jwsSigningKey": "/jwsSigningKey.key",
|
|
51
51
|
"jwsVerificationKeysDirectory": null,
|
|
52
|
-
"
|
|
53
|
-
"host": "localhost",
|
|
54
|
-
"port": 6379
|
|
55
|
-
},
|
|
52
|
+
"cacheUrl": "redis://localhost:6379",
|
|
56
53
|
"enableTestFeatures": false,
|
|
57
|
-
"testingDisableWSO2AuthStart": true,
|
|
58
54
|
"oauthTestServer": {
|
|
59
55
|
"enabled": false,
|
|
60
56
|
"listenPort": 6000
|
package/test/unit/index.test.js
CHANGED
|
@@ -17,15 +17,13 @@ jest.mock('dotenv', () => ({
|
|
|
17
17
|
const promClient = require('prom-client');
|
|
18
18
|
const defaultConfig = require('./data/defaultConfig.json');
|
|
19
19
|
const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
20
|
-
const { MetricsClient } = require('~/lib/metrics');
|
|
21
20
|
|
|
22
21
|
const TestControlServer = require('./ControlServer');
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
process.env.PEER_ENDPOINT = '172.17.0.3:4000';
|
|
26
25
|
process.env.BACKEND_ENDPOINT = '172.17.0.5:4000';
|
|
27
|
-
process.env.
|
|
28
|
-
process.env.CACHE_PORT = '6379';
|
|
26
|
+
process.env.CACHE_URL = 'redis://172.17.0.2:6379';
|
|
29
27
|
process.env.MGMT_API_WS_URL = '0.0.0.0';
|
|
30
28
|
|
|
31
29
|
const index = require('~/index.js');
|
|
@@ -35,24 +33,6 @@ describe('index.js', () => {
|
|
|
35
33
|
promClient.register.clear();
|
|
36
34
|
});
|
|
37
35
|
|
|
38
|
-
test('WSO2 error events in OutboundServer propagate to top-level server', () => {
|
|
39
|
-
const logger = new Logger.Logger({ stringify: () => '' });
|
|
40
|
-
const svr = new index.Server(defaultConfig, logger);
|
|
41
|
-
const cb = jest.fn();
|
|
42
|
-
svr.on('error', cb);
|
|
43
|
-
svr.outboundServer._api._wso2.auth.emit('error', 'msg');
|
|
44
|
-
expect(cb).toHaveBeenCalledTimes(1);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('WSO2 error events in InboundServer propagate to top-level server', () => {
|
|
48
|
-
const logger = new Logger.Logger({ stringify: () => '' });
|
|
49
|
-
const svr = new index.Server(defaultConfig, logger);
|
|
50
|
-
const cb = jest.fn();
|
|
51
|
-
svr.on('error', cb);
|
|
52
|
-
svr.inboundServer._api._wso2.auth.emit('error', 'msg');
|
|
53
|
-
expect(cb).toHaveBeenCalledTimes(1);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
36
|
test('Exports expected modules', () => {
|
|
57
37
|
expect(typeof(index.Server)).toBe('function');
|
|
58
38
|
expect(typeof(index.InboundServerMiddleware)).toBe('object');
|
|
@@ -77,6 +57,7 @@ describe('Server', () => {
|
|
|
77
57
|
conf.control.port = conf.control.mgmtAPIWsPort;
|
|
78
58
|
controlServer = new TestControlServer.Server({ logger, appConfig: conf });
|
|
79
59
|
server = new index.Server(conf, logger);
|
|
60
|
+
server.restart = jest.fn();
|
|
80
61
|
await server.start();
|
|
81
62
|
});
|
|
82
63
|
|
|
@@ -95,53 +76,13 @@ describe('Server', () => {
|
|
|
95
76
|
});
|
|
96
77
|
|
|
97
78
|
it('reconfigures and restarts constituent servers when triggered by control client', async () => {
|
|
98
|
-
|
|
99
|
-
Array.from({ length: 5 }).map(() => jest.fn());
|
|
100
|
-
server.inboundServer.reconfigure = jest.fn(() => restartInbound);
|
|
101
|
-
server.outboundServer.reconfigure = jest.fn(() => restartOutbound);
|
|
102
|
-
server.testServer.reconfigure = jest.fn(() => restartTest);
|
|
103
|
-
server.oauthTestServer.reconfigure = jest.fn(() => restartOAuthTest);
|
|
104
|
-
server.controlClient.reconfigure = jest.fn(() => restartControl);
|
|
105
|
-
|
|
106
|
-
await controlServer.broadcastConfigChange(newConf);
|
|
79
|
+
controlServer.broadcastConfigChange(newConf);
|
|
107
80
|
|
|
108
81
|
// We wait for the servers to get restarted
|
|
109
82
|
await new Promise((wait) => setTimeout(wait, 1000));
|
|
110
83
|
|
|
111
|
-
expect(server.
|
|
112
|
-
expect(server.
|
|
113
|
-
newConf, expect.any(Logger.Logger), expect.any(index.Cache)
|
|
114
|
-
);
|
|
115
|
-
expect(server.outboundServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
116
|
-
const metricsClient = new MetricsClient();
|
|
117
|
-
expect(server.outboundServer.reconfigure).toHaveBeenCalledWith(
|
|
118
|
-
newConf, expect.any(Logger.Logger), expect.any(index.Cache), metricsClient
|
|
119
|
-
);
|
|
120
|
-
expect(server.controlClient.reconfigure).toHaveBeenCalledTimes(1);
|
|
121
|
-
expect(server.controlClient.reconfigure).toHaveBeenCalledWith({
|
|
122
|
-
logger: expect.any(Logger.Logger),
|
|
123
|
-
port: newConf.control.port,
|
|
124
|
-
appConfig: newConf
|
|
125
|
-
});
|
|
126
|
-
expect(server.testServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
127
|
-
expect(server.testServer.reconfigure).toHaveBeenCalledWith({
|
|
128
|
-
logger: expect.any(Logger.Logger),
|
|
129
|
-
cache: expect.any(index.Cache),
|
|
130
|
-
port: newConf.test.port
|
|
131
|
-
});
|
|
132
|
-
expect(server.oauthTestServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
133
|
-
expect(server.oauthTestServer.reconfigure).toHaveBeenCalledWith({
|
|
134
|
-
logger: expect.any(Logger.Logger),
|
|
135
|
-
clientKey: newConf.oauthTestServer.clientKey,
|
|
136
|
-
clientSecret: newConf.oauthTestServer.clientSecret,
|
|
137
|
-
port: newConf.oauthTestServer.listenPort,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
expect(restartInbound).toHaveBeenCalledTimes(1);
|
|
141
|
-
expect(restartOutbound).toHaveBeenCalledTimes(1);
|
|
142
|
-
expect(restartTest).toHaveBeenCalledTimes(1);
|
|
143
|
-
expect(restartOAuthTest).toHaveBeenCalledTimes(1);
|
|
144
|
-
expect(restartControl).toHaveBeenCalledTimes(1);
|
|
84
|
+
expect(server.restart).toHaveBeenCalledTimes(1);
|
|
85
|
+
expect(server.restart).toHaveBeenCalledWith(newConf);
|
|
145
86
|
});
|
|
146
87
|
});
|
|
147
88
|
});
|
|
@@ -18,9 +18,8 @@ const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
|
18
18
|
const createCache = async() => {
|
|
19
19
|
const logger = new Logger.Logger({ context: { app: 'model-unit-tests-cache' }, stringify: () => '' });
|
|
20
20
|
const cache = new Cache({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
logger,
|
|
21
|
+
cacheUrl: 'redis://dummy:1234',
|
|
22
|
+
logger,
|
|
24
23
|
});
|
|
25
24
|
await cache.connect();
|
|
26
25
|
return cache;
|
|
@@ -75,11 +74,11 @@ describe('Cache', () => {
|
|
|
75
74
|
expect(cbId1).toBe(0);
|
|
76
75
|
|
|
77
76
|
// now we have subscribed, inject a message.
|
|
78
|
-
cache.publish(chan1, msg1);
|
|
77
|
+
return cache.publish(chan1, msg1);
|
|
79
78
|
});
|
|
80
79
|
});
|
|
81
80
|
|
|
82
|
-
// create a second promise that only gets
|
|
81
|
+
// create a second promise that only gets resolved if the second subscription gets the
|
|
83
82
|
// correct message
|
|
84
83
|
const cb2Promise = new Promise((resolve) => {
|
|
85
84
|
const mockCb2 = jest.fn((cn, msg) => {
|
|
@@ -99,7 +98,7 @@ describe('Cache', () => {
|
|
|
99
98
|
expect(cbId2).toBe(1);
|
|
100
99
|
|
|
101
100
|
// now we have subscribed, inject a message.
|
|
102
|
-
cache.publish(chan2, msg2);
|
|
101
|
+
return cache.publish(chan2, msg2);
|
|
103
102
|
});
|
|
104
103
|
});
|
|
105
104
|
|
|
@@ -28,6 +28,8 @@ const getTransfersMojaloopResponse = require('./data/getTransfersMojaloopRespons
|
|
|
28
28
|
const getBulkTransfersBackendResponse = require('./data/getBulkTransfersBackendResponse');
|
|
29
29
|
const getBulkTransfersMojaloopResponse = require('./data/getBulkTransfersMojaloopResponse');
|
|
30
30
|
const notificationToPayee = require('./data/notificationToPayee');
|
|
31
|
+
const notificationAbortedToPayee = require('./data/notificationAbortedToPayee');
|
|
32
|
+
const notificationReservedToPayee = require('./data/notificationReservedToPayee');
|
|
31
33
|
|
|
32
34
|
describe('inboundModel', () => {
|
|
33
35
|
let config;
|
|
@@ -63,8 +65,7 @@ describe('inboundModel', () => {
|
|
|
63
65
|
}));
|
|
64
66
|
|
|
65
67
|
cache = new Cache({
|
|
66
|
-
|
|
67
|
-
port: 1234,
|
|
68
|
+
cacheUrl: 'redis://dummy:1234',
|
|
68
69
|
logger,
|
|
69
70
|
});
|
|
70
71
|
await cache.connect();
|
|
@@ -132,8 +133,7 @@ describe('inboundModel', () => {
|
|
|
132
133
|
BackendRequests.__postBulkQuotes = jest.fn().mockReturnValue(Promise.resolve(mockArgs.internalBulkQuoteResponse));
|
|
133
134
|
|
|
134
135
|
cache = new Cache({
|
|
135
|
-
|
|
136
|
-
port: 1234,
|
|
136
|
+
cacheUrl: 'redis://dummy:1234',
|
|
137
137
|
logger,
|
|
138
138
|
});
|
|
139
139
|
await cache.connect();
|
|
@@ -189,8 +189,7 @@ describe('inboundModel', () => {
|
|
|
189
189
|
BackendRequests.__postTransactionRequests = jest.fn().mockReturnValue(Promise.resolve(mockTxnReqArgs.internalTransactionRequestResponse));
|
|
190
190
|
|
|
191
191
|
cache = new Cache({
|
|
192
|
-
|
|
193
|
-
port: 1234,
|
|
192
|
+
cacheUrl: 'redis://dummy:1234',
|
|
194
193
|
logger,
|
|
195
194
|
});
|
|
196
195
|
await cache.connect();
|
|
@@ -226,8 +225,7 @@ describe('inboundModel', () => {
|
|
|
226
225
|
BackendRequests.__getOTP = jest.fn().mockReturnValue(Promise.resolve(mockArgs.internalGetOTPResponse));
|
|
227
226
|
|
|
228
227
|
cache = new Cache({
|
|
229
|
-
|
|
230
|
-
port: 1234,
|
|
228
|
+
cacheUrl: 'redis://dummy:1234',
|
|
231
229
|
logger,
|
|
232
230
|
});
|
|
233
231
|
await cache.connect();
|
|
@@ -268,8 +266,7 @@ describe('inboundModel', () => {
|
|
|
268
266
|
}));
|
|
269
267
|
|
|
270
268
|
cache = new Cache({
|
|
271
|
-
|
|
272
|
-
port: 1234,
|
|
269
|
+
cacheUrl: 'redis://dummy:1234',
|
|
273
270
|
logger,
|
|
274
271
|
});
|
|
275
272
|
await cache.connect();
|
|
@@ -547,8 +544,7 @@ describe('inboundModel', () => {
|
|
|
547
544
|
BackendRequests.__postBulkTransfers = jest.fn().mockReturnValue(Promise.resolve({}));
|
|
548
545
|
|
|
549
546
|
cache = new Cache({
|
|
550
|
-
|
|
551
|
-
port: 1234,
|
|
547
|
+
cacheUrl: 'redis://dummy:1234',
|
|
552
548
|
logger,
|
|
553
549
|
});
|
|
554
550
|
await cache.connect();
|
|
@@ -727,8 +723,7 @@ describe('inboundModel', () => {
|
|
|
727
723
|
|
|
728
724
|
beforeEach(async () => {
|
|
729
725
|
cache = new Cache({
|
|
730
|
-
|
|
731
|
-
port: 1234,
|
|
726
|
+
cacheUrl: 'redis://dummy:1234',
|
|
732
727
|
logger,
|
|
733
728
|
});
|
|
734
729
|
await cache.connect();
|
|
@@ -759,14 +754,58 @@ describe('inboundModel', () => {
|
|
|
759
754
|
expect(call[0]).toEqual(expectedRequest);
|
|
760
755
|
expect(call[1]).toEqual(transferId);
|
|
761
756
|
});
|
|
757
|
+
|
|
758
|
+
test('sends ABORTED notification to fsp backend', async () => {
|
|
759
|
+
BackendRequests.__putTransfersNotification = jest.fn().mockReturnValue(Promise.resolve({}));
|
|
760
|
+
const notif = JSON.parse(JSON.stringify(notificationAbortedToPayee));
|
|
761
|
+
|
|
762
|
+
const expectedRequest = {
|
|
763
|
+
currentState: 'ABORTED',
|
|
764
|
+
finalNotification: notif.data,
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
const model = new Model({
|
|
768
|
+
...config,
|
|
769
|
+
cache,
|
|
770
|
+
logger,
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
await model.sendNotificationToPayee(notif.data, transferId);
|
|
774
|
+
expect(BackendRequests.__putTransfersNotification).toHaveBeenCalledTimes(1);
|
|
775
|
+
const call = BackendRequests.__putTransfersNotification.mock.calls[0];
|
|
776
|
+
expect(call[0]).toEqual(expectedRequest);
|
|
777
|
+
expect(call[1]).toEqual(transferId);
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
test('sends RESERVED notification to fsp backend', async () => {
|
|
781
|
+
BackendRequests.__putTransfersNotification = jest.fn().mockReturnValue(Promise.resolve({}));
|
|
782
|
+
const notif = JSON.parse(JSON.stringify(notificationReservedToPayee));
|
|
783
|
+
|
|
784
|
+
const expectedRequest = {
|
|
785
|
+
finalNotification: notif.data,
|
|
786
|
+
lastError: 'Final notification state not COMMITTED',
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const model = new Model({
|
|
790
|
+
...config,
|
|
791
|
+
cache,
|
|
792
|
+
logger,
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
await model.sendNotificationToPayee(notif.data, transferId);
|
|
796
|
+
expect(BackendRequests.__putTransfersNotification).toHaveBeenCalledTimes(1);
|
|
797
|
+
const call = BackendRequests.__putTransfersNotification.mock.calls[0];
|
|
798
|
+
expect(call[0]).toEqual(expectedRequest);
|
|
799
|
+
expect(call[1]).toEqual(transferId);
|
|
800
|
+
});
|
|
801
|
+
|
|
762
802
|
});
|
|
763
803
|
|
|
764
804
|
describe('error handling:', () => {
|
|
765
805
|
let cache;
|
|
766
806
|
beforeEach(async () => {
|
|
767
807
|
cache = new Cache({
|
|
768
|
-
|
|
769
|
-
port: 1234,
|
|
808
|
+
cacheUrl: 'redis://dummy:1234',
|
|
770
809
|
logger,
|
|
771
810
|
});
|
|
772
811
|
await cache.connect();
|
|
@@ -91,10 +91,9 @@ describe('OutboundBulkQuotesModel', () => {
|
|
|
91
91
|
MojaloopRequests.__putBulkQuotesError = jest.fn(() => Promise.resolve());
|
|
92
92
|
|
|
93
93
|
cache = new Cache({
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
94
|
+
cacheUrl: 'redis://dummy:1234',
|
|
95
|
+
logger,
|
|
96
|
+
});
|
|
98
97
|
await cache.connect();
|
|
99
98
|
});
|
|
100
99
|
|
|
@@ -83,8 +83,7 @@ describe('outboundBulkTransferModel', () => {
|
|
|
83
83
|
MojaloopRequests.__postBulkTransfers = jest.fn(() => Promise.resolve());
|
|
84
84
|
|
|
85
85
|
cache = new Cache({
|
|
86
|
-
|
|
87
|
-
port: 1234,
|
|
86
|
+
cacheUrl: 'redis://dummy:1234',
|
|
88
87
|
logger,
|
|
89
88
|
});
|
|
90
89
|
await cache.connect();
|
|
@@ -71,10 +71,9 @@ describe('outboundModel', () => {
|
|
|
71
71
|
MojaloopRequests.__postTransactionRequests = jest.fn(() => Promise.resolve());
|
|
72
72
|
|
|
73
73
|
cache = new Cache({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
74
|
+
cacheUrl: 'redis://dummy:1234',
|
|
75
|
+
logger,
|
|
76
|
+
});
|
|
78
77
|
await cache.connect();
|
|
79
78
|
});
|
|
80
79
|
|