@mojaloop/central-services-shared 18.6.0-snapshot.3 → 18.6.0

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/.nycrc.yml CHANGED
@@ -14,6 +14,5 @@ reporter: [
14
14
  "text-summary"
15
15
  ]
16
16
  exclude: [
17
- "**/node_modules/**",
18
- "src/util/proxies.js" # todo: increase test coverage
17
+ "**/node_modules/**"
19
18
  ]
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [18.6.0](https://github.com/mojaloop/central-services-shared/compare/v18.5.2...v18.6.0) (2024-07-05)
6
+
7
+
8
+ ### Features
9
+
10
+ * proxy calling ([#389](https://github.com/mojaloop/central-services-shared/issues/389)) ([b7a1615](https://github.com/mojaloop/central-services-shared/commit/b7a1615116214466a240d244376a8aaaa165951d))
11
+
5
12
  ### [18.5.2](https://github.com/mojaloop/central-services-shared/compare/v18.5.1...v18.5.2) (2024-07-04)
6
13
 
7
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/central-services-shared",
3
- "version": "18.6.0-snapshot.3",
3
+ "version": "18.6.0",
4
4
  "description": "Shared code for mojaloop central services",
5
5
  "license": "Apache-2.0",
6
6
  "author": "ModusBox",
@@ -44,6 +44,8 @@
44
44
  "test:xunit": "npx tape 'test/unit/**/**.test.js' | tap-xunit > ./test/results/xunit.xml",
45
45
  "test:coverage": "npx nyc --reporter=lcov --reporter=text-summary tapes -- 'test/unit/**/**.test.js'",
46
46
  "test:coverage-check": "npm run test:coverage && nyc check-coverage",
47
+ "test:functional": "true",
48
+ "test:integration": "true",
47
49
  "audit:fix": "npm audit fix",
48
50
  "audit:check": "npx audit-ci --config ./audit-ci.jsonc",
49
51
  "dep:check": "npx ncu -e 2",
@@ -54,6 +56,7 @@
54
56
  "dependencies": {
55
57
  "@hapi/catbox": "12.1.1",
56
58
  "@hapi/catbox-memory": "5.0.1",
59
+ "@mojaloop/inter-scheme-proxy-cache-lib": "1.2.0",
57
60
  "axios": "1.7.2",
58
61
  "clone": "2.1.2",
59
62
  "dotenv": "16.4.5",
@@ -105,7 +105,6 @@ const FspEndpointTemplates = {
105
105
  TRANSACTION_REQUEST_GET: '/transactionRequests/{{ID}}',
106
106
  TRANSACTION_REQUEST_PUT_ERROR: '/transactionRequests/{{ID}}/error',
107
107
  PARTICIPANT_ENDPOINTS_GET: '/participants/{{fsp}}/endpoints',
108
- PARTICIPANTS_GET_ALL: '/participants',
109
108
  PARTICIPANTS_GET: '/participants/{{fsp}}',
110
109
  PARTICIPANTS_POST: '/participants',
111
110
  PARTIES_GET: '/parties/{{fsp}}',
package/src/enums/http.js CHANGED
@@ -36,7 +36,6 @@ const Headers = {
36
36
  FSPIOP: {
37
37
  SOURCE: 'fspiop-source',
38
38
  DESTINATION: 'fspiop-destination',
39
- PROXY: 'fspiop-proxy',
40
39
  HTTP_METHOD: 'fspiop-http-method',
41
40
  SIGNATURE: 'fspiop-signature',
42
41
  URI: 'fspiop-uri'
package/src/index.d.ts CHANGED
@@ -9,7 +9,6 @@ declare namespace CentralServicesShared {
9
9
  FSPIOP: {
10
10
  SOURCE: string;
11
11
  DESTINATION: string;
12
- PROXY: string;
13
12
  HTTP_METHOD: string;
14
13
  SIGNATURE: string;
15
14
  URI: string;
@@ -598,26 +597,16 @@ declare namespace CentralServicesShared {
598
597
  };
599
598
  };
600
599
  }
601
-
602
- interface Cacheable {
603
- initializeCache(policyOptions: object, config: { hubName: string, hubNameRegex: RegExp }): Promise<boolean>
604
- stopCache(): Promise<void>
605
- }
606
-
607
- interface Endpoints extends Cacheable {
600
+ interface Endpoints {
601
+ fetchEndpoints(fspId: string): Promise<any>
608
602
  getEndpoint(switchUrl: string, fsp: string, endpointType: FspEndpointTypesEnum, options?: any): Promise<string>
603
+ initializeCache(policyOptions: object, config: { hubName: string, hubNameRegex: RegExp }): Promise<boolean>
609
604
  getEndpointAndRender(switchUrl: string, fsp: string, endpointType: FspEndpointTypesEnum, path: string, options?: any): Promise<string>
610
605
  }
611
606
 
612
- interface Participants extends Cacheable {
607
+ interface Participants {
613
608
  getParticipant(switchUrl: string, fsp: string): Promise<object>
614
- invalidateParticipantCache(fsp: string): Promise<void>
615
- }
616
-
617
- type ProxyNames = string[]
618
- interface Proxies extends Cacheable {
619
- getAllProxiesNames(switchUrl: string): Promise<ProxyNames>
620
- invalidateProxiesCache(): Promise<void>
609
+ initializeCache(policyOptions: object, config: { hubName: string, hubNameRegex: RegExp }): Promise<boolean>
621
610
  }
622
611
 
623
612
  interface ProtocolVersionsType {
@@ -652,7 +641,6 @@ declare namespace CentralServicesShared {
652
641
  interface Util {
653
642
  Endpoints: Endpoints;
654
643
  Participants: Participants;
655
- proxies: Proxies;
656
644
  Hapi: any;
657
645
  Kafka: Kafka;
658
646
  OpenapiBackend: any;
@@ -37,12 +37,14 @@ const partition = 'endpoint-cache'
37
37
  const clientOptions = { partition }
38
38
  const Mustache = require('mustache')
39
39
  const Metrics = require('@mojaloop/central-services-metrics')
40
+ const proxyLib = require('@mojaloop/inter-scheme-proxy-cache-lib')
40
41
 
41
42
  let client
42
43
  let policy
43
44
  let switchEndpoint
44
45
  let hubName
45
46
  let hubNameRegex
47
+ let proxy
46
48
 
47
49
  /**
48
50
  * @function fetchEndpoints
@@ -137,7 +139,7 @@ exports.initializeCache = async (policyOptions, config) => {
137
139
  *
138
140
  * @returns {string} - Returns the endpoint, throws error if failure occurs
139
141
  */
140
- exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderOptions = {}) => {
142
+ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderOptions = {}, proxyConfig = undefined) => {
141
143
  const histTimer = Metrics.getHistogram(
142
144
  'getEndpoint',
143
145
  'getEndpoint - Metrics for getEndpoint with cache hit rate',
@@ -145,11 +147,23 @@ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderO
145
147
  ).startTimer()
146
148
  switchEndpoint = switchUrl
147
149
  Logger.isDebugEnabled && Logger.debug(`participantEndpointCache::getEndpoint::endpointType - ${endpointType}`)
150
+ let proxyId
151
+ const result = url => proxyConfig ? { url, proxyId } : url
148
152
  try {
149
153
  // If a service passes in `getDecoratedValue` as true, then an object
150
154
  // { value, cached, report } is returned, where value is the cached value,
151
155
  // cached is null on a cache miss.
152
- const endpoints = await policy.get(fsp)
156
+ let endpoints = await policy.get(fsp)
157
+ if (!endpoints && proxyConfig) {
158
+ if (!proxy) {
159
+ const { type, ...config } = proxyConfig
160
+ proxy = proxyLib.createProxyCache(type, config)
161
+ await proxy.connect()
162
+ }
163
+ proxyId = await proxy.lookupProxyByDfspId(fsp)
164
+ endpoints = proxyId && await policy.get(proxyId)
165
+ }
166
+ if (!endpoints) throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND)
153
167
  if ('value' in endpoints && 'cached' in endpoints) {
154
168
  if (endpoints.cached === null) {
155
169
  histTimer({ success: true, hit: false })
@@ -159,16 +173,16 @@ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderO
159
173
  const endpoint = new Map(endpoints.value).get(endpointType)
160
174
  if (renderOptions.path) {
161
175
  const renderedEndpoint = (endpoint === undefined) ? endpoint : endpoint + renderOptions.path
162
- return Mustache.render(renderedEndpoint, options)
176
+ return result(Mustache.render(renderedEndpoint, options))
163
177
  }
164
- return Mustache.render(endpoint, options)
178
+ return result(Mustache.render(endpoint, options))
165
179
  }
166
180
  let endpoint = new Map(endpoints).get(endpointType)
167
181
  if (renderOptions.path) {
168
182
  endpoint = (endpoint === undefined) ? endpoint : endpoint + renderOptions.path
169
183
  }
170
184
  histTimer({ success: true, hit: false })
171
- return Mustache.render(endpoint, options)
185
+ return result(Mustache.render(endpoint, options))
172
186
  } catch (err) {
173
187
  histTimer({ success: false, hit: false })
174
188
  Logger.isErrorEnabled && Logger.error(`participantEndpointCache::getEndpoint:: ERROR:'${err}'`)
@@ -222,3 +236,28 @@ exports.stopCache = async () => {
222
236
  return client.stop()
223
237
  }
224
238
  }
239
+
240
+ /**
241
+ * @function stopProxy
242
+ *
243
+ * @description It stops the proxy client
244
+ *
245
+ * @returns {Promise<void>}
246
+ */
247
+ exports.stopProxy = async () => {
248
+ const result = await proxy?.disconnect()
249
+ proxy = undefined
250
+ return result
251
+ }
252
+
253
+ /**
254
+ * @function healthCheckProxy
255
+ *
256
+ * @description It checks the health of the proxy client
257
+ *
258
+ * @returns {Promise<boolean>}
259
+ */
260
+
261
+ exports.healthCheckProxy = async () => {
262
+ return proxy ? proxy.healthCheck() : true
263
+ }
package/src/util/index.js CHANGED
@@ -30,7 +30,6 @@ const _ = require('lodash')
30
30
  const Kafka = require('./kafka')
31
31
  const Endpoints = require('./endpoints')
32
32
  const Participants = require('./participants')
33
- const proxies = require('./proxies')
34
33
  const Request = require('./request')
35
34
  const Http = require('./http')
36
35
  const Hapi = require('./hapi')
@@ -239,7 +238,6 @@ module.exports = {
239
238
  filterExtensions,
240
239
  Kafka,
241
240
  Participants,
242
- proxies,
243
241
  Endpoints,
244
242
  Request,
245
243
  Http,
@@ -59,7 +59,6 @@ request.defaults.httpAgent.toJSON = () => ({})
59
59
  * @param {string} source id for which callback is being sent from
60
60
  * @param {string} destination id for which callback is being sent
61
61
  * @param {object | undefined} payload the body of the request being sent
62
- * @param {object | null} params URL parameters to be sent with the request. Must be a plain object, URLSearchParams object or null/undefined
63
62
  * @param {string} responseType the type of the response object
64
63
  * @param {object | undefined} span a span for event logging if this request is within a span
65
64
  * @param {object | undefined} jwsSigner the jws signer for signing the requests
@@ -76,7 +75,6 @@ const sendRequest = async ({
76
75
  destination,
77
76
  method = enums.Http.RestMethods.GET,
78
77
  payload = undefined,
79
- params,
80
78
  responseType = enums.Http.ResponseTypes.JSON,
81
79
  span = undefined,
82
80
  jwsSigner = undefined,
@@ -111,7 +109,6 @@ const sendRequest = async ({
111
109
  method,
112
110
  headers: transformedHeaders,
113
111
  data: payload,
114
- params,
115
112
  responseType,
116
113
  httpAgent: new http.Agent({ keepAlive: true }),
117
114
  ...axiosRequestOptionsOverride
@@ -5,9 +5,27 @@ const Mustache = require('mustache')
5
5
  const Catbox = require('@hapi/catbox')
6
6
  const Logger = require('@mojaloop/central-services-logger')
7
7
  const Sinon = require('sinon')
8
+ const Proxyquire = require('proxyquire')
8
9
 
9
10
  const src = '../../../src'
10
- const Cache = require(`${src}/util/endpoints`)
11
+ const Cache = Proxyquire(`${src}/util/endpoints`, {
12
+ '@mojaloop/inter-scheme-proxy-cache-lib': {
13
+ createProxyCache () {
14
+ return {
15
+ async connect () {},
16
+ lookupProxyByDfspId () {
17
+ return 'fsp'
18
+ },
19
+ async healthCheck () {
20
+ return true
21
+ },
22
+ async disconnect () {
23
+ return true
24
+ }
25
+ }
26
+ }
27
+ }
28
+ })
11
29
  const request = require(`${src}/util/request`)
12
30
  const Config = require('../../util/config')
13
31
  const Http = require(`${src}/util`).Http
@@ -96,6 +114,59 @@ Test('Cache Test', (cacheTest) => {
96
114
  }
97
115
  })
98
116
 
117
+ getEndpointTest.test('return the endpoint using proxy', async (test) => {
118
+ const fsp = 'fsp'
119
+ const proxiedFsp = 'proxied'
120
+ const url = Mustache.render(
121
+ Config.ENDPOINT_SOURCE_URL +
122
+ Enum.EndPoints.FspEndpointTemplates.PARTICIPANT_ENDPOINTS_GET,
123
+ { fsp }
124
+ )
125
+ const proxiedUrl = Mustache.render(
126
+ Config.ENDPOINT_SOURCE_URL +
127
+ Enum.EndPoints.FspEndpointTemplates.PARTICIPANT_ENDPOINTS_GET,
128
+ { fsp: proxiedFsp }
129
+ )
130
+ const endpointType = FSPIOP_CALLBACK_URL_TRANSFER_PUT
131
+ const expected = {
132
+ url: 'http://localhost:1080/transfers/97b01bd3-b223-415b-b37b-ab5bef9bdbed',
133
+ proxyId: 'fsp'
134
+ }
135
+
136
+ await Cache.initializeCache(Config.ENDPOINT_CACHE_CONFIG, {
137
+ hubName, hubNameRegex
138
+ })
139
+ request.sendRequest
140
+ .withArgs({ url, headers: Helper.defaultHeaders(), source: hubName, destination: hubName, hubNameRegex })
141
+ .returns(Promise.resolve(Helper.getEndPointsResponse))
142
+ request.sendRequest
143
+ .withArgs({ url: proxiedUrl, headers: Helper.defaultHeaders(), source: hubName, destination: hubName, hubNameRegex })
144
+ .rejects(new Error('Not found'))
145
+
146
+ try {
147
+ test.equal(await Cache.healthCheckProxy(), true, 'Health check proxy if not created')
148
+ test.equal(await Cache.stopProxy(), undefined, 'Stop proxy if not created')
149
+
150
+ const result = await Cache.getEndpoint(
151
+ Config.ENDPOINT_SOURCE_URL,
152
+ proxiedFsp,
153
+ endpointType,
154
+ { transferId: '97b01bd3-b223-415b-b37b-ab5bef9bdbed' },
155
+ undefined,
156
+ {}
157
+ )
158
+ test.deepEqual(result, expected, 'The results match')
159
+ test.equal(await Cache.healthCheckProxy(), true, 'Health check proxy')
160
+ test.equal(await Cache.stopProxy(), true, 'Stop proxy')
161
+
162
+ await Cache.stopCache()
163
+ test.end()
164
+ } catch (err) {
165
+ test.fail('Error thrown', err)
166
+ test.end()
167
+ }
168
+ })
169
+
99
170
  getEndpointTest.test(
100
171
  'return the endpoint if catbox returns decoratedValue object',
101
172
  async (test) => {
@@ -1,182 +0,0 @@
1
- /*****
2
- License
3
- --------------
4
- Copyright © 2017 Bill & Melinda Gates Foundation
5
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
-
9
- Contributors
10
- --------------
11
- This is the official list of the Mojaloop project contributors for this file.
12
- Names of the original copyright holders (individuals or organizations)
13
- should be listed with a '*' in the first column. People who have
14
- contributed from an organization can be listed under the organization
15
- that actually holds the copyright for their contributions (see the
16
- Gates Foundation organization for an example). Those individuals should have
17
- their names indented and be marked with a '-'. Email address can be added
18
- optionally within square brackets <email>.
19
- * Gates Foundation
20
- - Name Surname <name.surname@gatesfoundation.com>
21
-
22
- * Eugen Klymniuk <eugen.klymniuk@infitx.com>
23
- --------------
24
- **********/
25
-
26
- const Mustache = require('mustache')
27
- const Catbox = require('@hapi/catbox')
28
- const CatboxMemory = require('@hapi/catbox-memory')
29
- const ErrorHandler = require('@mojaloop/central-services-error-handling')
30
- const Logger = require('@mojaloop/central-services-logger')
31
- const Metrics = require('@mojaloop/central-services-metrics')
32
-
33
- const Enum = require('../enums')
34
- const Http = require('./http')
35
- const request = require('./request')
36
-
37
- const partition = 'proxies-cache'
38
- const clientOptions = { partition }
39
- const cacheKey = 'allProxies'
40
-
41
- let client
42
- let policy
43
- let switchEndpoint
44
- let hubName
45
- let hubNameRegex
46
-
47
- /**
48
- * @function fetchProxies
49
- * @description This populates the cache of proxies
50
- * @returns {array} proxies Returns the list containing proxies
51
- */
52
- const fetchProxies = async () => {
53
- const histTimer = Metrics.getHistogram(
54
- 'fetchProxies',
55
- 'fetchProxies - Metrics for fetchProxies',
56
- ['success']
57
- ).startTimer()
58
- try {
59
- Logger.isDebugEnabled && Logger.debug('proxiesCache::fetchProxies := Refreshing proxies cache')
60
- if (!hubName || !hubNameRegex) {
61
- throw Error('No hubName or hubNameRegex! Initialize the cache first.')
62
- }
63
- const defaultHeaders = Http.SwitchDefaultHeaders(hubName, Enum.Http.HeaderResources.PARTICIPANTS, hubName)
64
- const url = Mustache.render(switchEndpoint + Enum.EndPoints.FspEndpointTemplates.PARTICIPANTS_GET_ALL)
65
- const params = { isProxy: true }
66
- Logger.isDebugEnabled && Logger.debug(`proxiesCache::fetchProxies := URL: ${url} QS: ${JSON.stringify(params)}`)
67
- const response = await request.sendRequest({
68
- url,
69
- headers: defaultHeaders,
70
- source: hubName,
71
- destination: hubName,
72
- params,
73
- hubNameRegex
74
- })
75
- const proxies = response.data
76
- histTimer({ success: true })
77
- return proxies
78
- } catch (e) {
79
- histTimer({ success: false })
80
- Logger.isErrorEnabled && Logger.error(`proxiesCache::fetchProxies:: ERROR:'${e}'`)
81
- }
82
- }
83
-
84
- /**
85
- * @function initializeCache
86
- *
87
- * @description This initializes the cache for allProxies
88
- * @param {object} policyOptions The Endpoint_Cache_Config for the Cache being stored https://hapi.dev/module/catbox/api/?v=12.1.1#policy
89
- * @param {object} config The config object containing paramters used for the request function
90
- * @returns {boolean} Returns true on successful initialization of the cache, throws error on failures
91
- */
92
- exports.initializeCache = async (policyOptions, config) => {
93
- try {
94
- Logger.isDebugEnabled && Logger.debug(`proxiesCache::initializeCache::start::clientOptions - ${JSON.stringify(clientOptions)}`)
95
- client = new Catbox.Client(CatboxMemory, clientOptions)
96
- await client.start()
97
- policyOptions.generateFunc = fetchProxies
98
- Logger.isDebugEnabled && Logger.debug(`proxiesCache::initializeCache::start::policyOptions - ${JSON.stringify(policyOptions)}`)
99
- policy = new Catbox.Policy(policyOptions, client, partition)
100
- Logger.isDebugEnabled && Logger.debug('proxiesCache::initializeCache::Cache initialized successfully')
101
- hubName = config.hubName
102
- hubNameRegex = config.hubNameRegex
103
- return true
104
- } catch (err) {
105
- Logger.isErrorEnabled && Logger.error(`proxiesCache::Cache error:: ERROR:'${err}'`)
106
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
107
- }
108
- }
109
-
110
- /**
111
- * @function getAllProxiesNames
112
- * @description It returns a list of allProxies names from the cache if the cache is still valid, otherwise it will refresh the cache and return the value
113
- *
114
- * @param {string} switchUrl the endpoint for the switch
115
- *
116
- * @returns {string[]} - Returns list of allProxies names, throws error if failure occurs
117
- */
118
- exports.getAllProxiesNames = async (switchUrl) => {
119
- const histTimer = Metrics.getHistogram(
120
- 'getAllProxiesNames',
121
- 'getAllProxiesNames - Metrics for getAllProxies with cache hit rate',
122
- ['success', 'hit']
123
- ).startTimer()
124
- switchEndpoint = switchUrl
125
- Logger.isDebugEnabled && Logger.debug('proxiesCache::getAllProxiesNames')
126
- try {
127
- // If a service passes in `getDecoratedValue` as true, then an object
128
- // { value, cached, report } is returned, where value is the cached value,
129
- // cached is null on a cache miss.
130
- let proxies = await policy.get(cacheKey)
131
-
132
- if ('value' in proxies && 'cached' in proxies) {
133
- if (proxies.cached === null) {
134
- histTimer({ success: true, hit: false })
135
- } else {
136
- histTimer({ success: true, hit: true })
137
- }
138
- proxies = proxies.value
139
- } else {
140
- histTimer({ success: true, hit: false })
141
- }
142
-
143
- if (proxies.errorInformation) {
144
- // Drop error from cache
145
- await policy.drop(cacheKey)
146
- throw ErrorHandler.Factory.createFSPIOPErrorFromErrorInformation(proxies.errorInformation)
147
- }
148
- return proxies.map(p => p.name)
149
- } catch (err) {
150
- histTimer({ success: false, hit: false })
151
- Logger.isErrorEnabled && Logger.error(`proxiesCache::getAllProxiesNames:: ERROR:'${err}'`)
152
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
153
- }
154
- }
155
-
156
- /**
157
- * @function invalidateProxiesCache
158
- *
159
- * @description It drops the cache for all proxies
160
- *
161
- * @returns {void}
162
- */
163
- exports.invalidateProxiesCache = async () => {
164
- Logger.isDebugEnabled && Logger.debug('proxiesCache::invalidateProxiesCache::Invalidating the cache')
165
- if (policy) {
166
- return policy.drop(cacheKey)
167
- }
168
- }
169
-
170
- /**
171
- * @function stopCache
172
- *
173
- * @description It stops the cache client
174
- *
175
- * @returns {boolean} - Returns the status
176
- */
177
- exports.stopCache = async () => {
178
- Logger.isDebugEnabled && Logger.debug('proxiesCache::stopCache::Stopping the cache')
179
- if (client) {
180
- return client.stop()
181
- }
182
- }
@@ -1,48 +0,0 @@
1
- const Test = require('tapes')(require('tape'))
2
- const sinon = require('sinon')
3
- const proxyquire = require('proxyquire')
4
- const { Http } = require('../../src/enums')
5
-
6
- Test('sendRequest Tests -->', test => {
7
- let sandbox
8
- let axios
9
- let request
10
-
11
- test.beforeEach(t => {
12
- sandbox = sinon.createSandbox()
13
- axios = sandbox.stub()
14
- request = proxyquire('../../src/util/request', { axios })
15
- // sinon can't mock such way of using axios: axios(requestOptions)
16
- t.end()
17
- })
18
-
19
- test.afterEach(t => {
20
- sandbox.restore()
21
- t.end()
22
- })
23
-
24
- test.test('should add fspiop-signature header if jwsSigner is passed ', async test => {
25
- const signature = 'signature'
26
- const jwsSigner = {
27
- getSignature: sandbox.stub().callsFake(() => signature)
28
- }
29
-
30
- await request.sendRequest({
31
- url: 'http://localhost:1234',
32
- jwsSigner,
33
- headers: {
34
- [Http.Headers.FSPIOP.SOURCE]: 'source'
35
- },
36
- source: 'source',
37
- destination: 'destination',
38
- hubNameRegex: 'hubNameRegex'
39
- })
40
-
41
- test.ok(axios.calledOnce)
42
- const { headers } = axios.lastCall.args[0]
43
- test.equal(headers['fspiop-signature'], signature)
44
- test.end()
45
- })
46
-
47
- test.end()
48
- })