From d5d362205cd286a456c48a9f4bf7a5e80fa776f5 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Sat, 4 Mar 2023 14:22:07 +0000 Subject: [PATCH 1/5] Add LegacyRequestLib https://eaflood.atlassian.net/browse/WATER-3906 https://eaflood.atlassian.net/browse/WATER-3921 For the SROC supplementary bill run process we intend to take things as far as having the batch, invoice, invoice licence and transaction records created in the DB and the Charging Module API, and the bill run generated. Control will then be handed to the legacy service to complete the process. `src/modules/billing/jobs/create-charge.js` in the [water-abstraction-service](https://github.com/DEFRA/water-abstraction-service) has been our guide for this. After generating the bill run in the charging module it queues up the `src/modules/billing/jobs/refresh-totals.js` job. We've [added a new endpoint](https://github.com/DEFRA/water-abstraction-service/pull/2036) to the **water-abstraction-service** that allows us to do the same. The first step is to add a new `LegacyRequestLib` following the same pattern as `app/lib/charging-module-request.lib.js`. From 71f0decdf51970c817a65b0ca8b91ec4bd144493 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Sat, 4 Mar 2023 15:03:22 +0000 Subject: [PATCH 2/5] Add new legacy auth token env var The legacy services use a shared [JSON Web Token (JWT)](https://jwt.io/) which is saved as an env var in their own config files. Requests need to have this set in their `authorisation` header or they'll be rejected. TBH, it is a pointless authentication mechanism! All the legacy services share the same token, and read it from config files stored on the server instances. From a security point of view, it's the same as keeping your password on a post-it note stuck to your monitor. But, Rome wasn't built in a day. So, for now, our new system has to play along. --- .env.example | 3 +++ .github/workflows/ci.yml | 2 ++ config/services.config.js | 1 + 3 files changed, 6 insertions(+) diff --git a/.env.example b/.env.example index 3d9e1300b9..f8d38b01fa 100644 --- a/.env.example +++ b/.env.example @@ -36,6 +36,9 @@ TACTICAL_IDM_URL=http://localhost:8003 PERMIT_REPOSITORY_URL=http://localhost:8004 RETURNS_URL=http://localhost:8006 +# JWT Auth token shared by all legacy external services +LEGACY_AUTH_TOKEN=longvalueofnumbersandletters.inbothcases.splitin3by2periods + # External Charging Module JWT (AWS Cognito) service CHARGING_MODULE_TOKEN_URL=https://myinstance.amazoncognito.com CHARGING_MODULE_TOKEN_USERNAME=valuefullofnumbersandlettersinlowercase diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03c074db7f..cf3d0e965f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,8 @@ jobs: TACTICAL_IDM_URL: http://localhost:8003 PERMIT_REPOSITORY_URL: http://localhost:8004 RETURNS_URL: http://localhost:8006 + # JWT Auth token shared by all legacy external services + LEGACY_AUTH_TOKEN: longvalueofnumbersandletters.inbothcases.splitin3by2periods # External Charging Module JWT (AWS Cognito) service CHARGING_MODULE_TOKEN_URL: https://myinstance.amazoncognito.com CHARGING_MODULE_TOKEN_USERNAME: valuefullofnumbersandlettersinlowercase diff --git a/config/services.config.js b/config/services.config.js index df71148f4f..4485fab15f 100644 --- a/config/services.config.js +++ b/config/services.config.js @@ -21,6 +21,7 @@ const config = { password: process.env.CHARGING_MODULE_TOKEN_PASSWORD } }, + legacyAuthToken: process.env.LEGACY_AUTH_TOKEN, serviceForeground: { url: process.env.SERVICE_FOREGROUND_URL }, From a16880d16036198c68964115075eac6c697b4f41 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Sat, 4 Mar 2023 16:01:02 +0000 Subject: [PATCH 3/5] Small doc corrections to ChargingModuleRequestLib --- app/lib/charging-module-request.lib.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/lib/charging-module-request.lib.js b/app/lib/charging-module-request.lib.js index aea4d07d09..b73ee66305 100644 --- a/app/lib/charging-module-request.lib.js +++ b/app/lib/charging-module-request.lib.js @@ -24,9 +24,9 @@ async function get (path) { } /** - * Sends a PATCH request to the Charging Module for the provided route + * Sends a PATCH request to the Charging Module for the provided path * - * @param {string} path The route to send the request to (do not include the starting /) + * @param {string} path The path to send the request to (do not include the starting /) * * @returns {Object} result An object representing the result of the request * @returns {boolean} result.succeeded Whether the request was successful @@ -39,7 +39,7 @@ async function patch (path) { } /** - * Sends a POST request to the Charging Module for the provided route + * Sends a POST request to the Charging Module for the provided path * * @param {string} path The path to send the request to (do not include the starting /) * @param {Object} [body] The body of the request @@ -55,7 +55,7 @@ async function post (path, body = {}) { } /** - * Sends a request to the Charging Module to the provided using the provided RequestLib method + * Sends a request to the Charging Module using the provided RequestLib method * * @param {string} path The path that you wish to connect to (do not include the starting /) * @param {Object} method An instance of a RequestLib method which will be used to send the request From 88a24a50783fec35a15c8801b03dcf263feab5da Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Sat, 4 Mar 2023 16:53:47 +0000 Subject: [PATCH 4/5] Implement the new service --- app/lib/legacy-request.lib.js | 185 ++++++++++++++++++++++++ test/lib/legacy-request.lib.test.js | 212 ++++++++++++++++++++++++++++ 2 files changed, 397 insertions(+) create mode 100644 app/lib/legacy-request.lib.js create mode 100644 test/lib/legacy-request.lib.test.js diff --git a/app/lib/legacy-request.lib.js b/app/lib/legacy-request.lib.js new file mode 100644 index 0000000000..a54a9e76e5 --- /dev/null +++ b/app/lib/legacy-request.lib.js @@ -0,0 +1,185 @@ +'use strict' + +/** + * Use for making http requests to the legacy web services + * @module LegacyRequestLib + */ + +const RequestLib = require('./request.lib.js') + +const servicesConfig = require('../../config/services.config.js') + +const services = { + // REPO-NAME - PM2 NAME + // water-abstraction-service - service-background + background: { + base: servicesConfig.serviceBackground.url, + api: 'water/1.0' + }, + // water-abstraction-tactical-crm - tactical-crm + crm: { + base: servicesConfig.tacticalCrm.url, + api: 'crm/1.0' + }, + // water-abstraction-ui - ui + external: { + base: servicesConfig.externalUi.url, + api: '' + }, + // water-abstraction-tactical-idm - tactical-idm + idm: { + base: servicesConfig.tacticalIdm.url, + api: 'idm/1.0' + }, + // water-abstraction-import - import + import: { + base: servicesConfig.import.url, + api: 'import/1.0' + }, + // water-abstraction-ui - internal-ui + internal: { + base: servicesConfig.internalUi.url, + api: '' + }, + // water-abstraction-permit-repository - permit-repository + permits: { + base: servicesConfig.permitRepository.url, + api: 'API/1.0/' + }, + // water-abstraction-reporting - reporting + reporting: { + base: servicesConfig.reporting.url, + api: 'reporting/1.0' + }, + // water-abstraction-returns - returns + returns: { + base: servicesConfig.returns.url, + api: 'returns/1.0' + }, + // water-abstraction-service - water-api + water: { + base: servicesConfig.serviceForeground.url, + api: 'water/1.0' + } +} + +/** + * Sends a GET request to the legacy service for the provided path + * + * @param {string} serviceName name of the legacy service to call (background, crm, external, idm, import, internal, + * permits, reporting, returns or water) + * @param {string} path The path to send the request to (do not include the starting /) + * @param {boolean} apiRequest whether the request is to the service's API endpoints + * + * @returns {Object} result An object representing the result of the request + * @returns {boolean} result.succeeded Whether the request was successful + * @returns {Object} result.response The legacy service's response if successful or the error response if not. + */ +async function get (serviceName, path, apiRequest = true) { + return await _sendRequest(RequestLib.get, serviceName, path, apiRequest) +} + +/** + * Sends a POST request to the legacy service for the provided path + * + * @param {string} serviceName name of the legacy service to call (background, crm, external, idm, import, internal, + * permits, reporting, returns or water) + * @param {string} path the path to send the request to (do not include the starting /) + * @param {boolean} apiRequest whether the request is to the service's API endpoints + * @param {Object} [body] optional body to be sent to the service as json + * + * @returns {Object} result An object representing the result of the request + * @returns {boolean} result.succeeded Whether the request was successful + * @returns {Object} result.response The legacy service's response if successful or the error response if not. + */ +async function post (serviceName, path, apiRequest = true, body = {}) { + return await _sendRequest(RequestLib.post, serviceName, path, apiRequest, body) +} + +/** + * Sends a request to a legacy service using the provided RequestLib method + * + * @param {Object} method an instance of a RequestLib method which will be used to send the request + * @param {string} serviceName name of the legacy service (see `services`) + * @param {string} path the path that you wish to connect to (do not include the starting /) + * @param {boolean} apiRequest whether the request is to the service's API endpoints + * @param {Object} body body to be sent to the service as json + * + * @returns {Object} The result of the request passed back from RequestLib + */ +async function _sendRequest (method, serviceName, path, apiRequest, body) { + const service = _service(serviceName) + const options = _requestOptions(service, apiRequest, body) + + const result = await method(path, options) + + return _parseResult(result) +} + +function _service (serviceName) { + const service = services[serviceName.trim().toLowerCase()] + + if (!service) { + throw new Error(`Request to unknown legacy service ${serviceName}`) + } + + return service +} + +/** + * Additional options that will be added to the default options used by RequestLib + * + * We use it to set + * + * - the base URL for the request + * - the authorization header with shared legacy JWT Auth token + * - the body (which is always a JSON object) for our POST requests + * - the option to tell Got that we expect JSON responses. This means Got will automatically handle parsing the + * response to a JSON object for us + * + * @param {Object} service which legacy service we are connecting with + * @param {boolean} apiRequest whether the request is to the service's API endpoints + * @param {Object} body the request body if applicable + * + * @returns Legacy specific options to be passed to RequestLib + */ +function _requestOptions (service, apiRequest, body) { + const prefixUrl = apiRequest ? new URL(service.api, service.base).href : service.base + + return { + prefixUrl, + headers: { + authorization: `Bearer ${servicesConfig.legacyAuthToken}` + }, + responseType: 'json', + json: body + } +} + +/** + * Parses the charging module response returned from RequestLib + * + * @param {Object} result The result object returned by RequestLib + * + * @returns {Object} If result was not an error, a parsed version of the response + */ +function _parseResult (result) { + const { body, statusCode } = result.response + + if (body) { + return { + succeeded: result.succeeded, + response: { + statusCode, + body + } + } + } + + return result +} + +module.exports = { + get, + post +} diff --git a/test/lib/legacy-request.lib.test.js b/test/lib/legacy-request.lib.test.js new file mode 100644 index 0000000000..ebbacae2f8 --- /dev/null +++ b/test/lib/legacy-request.lib.test.js @@ -0,0 +1,212 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') +const Sinon = require('sinon') + +const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const servicesConfig = require('../../config/services.config.js') + +// Things we need to stub +const RequestLib = require('../../app/lib/request.lib.js') + +// Thing under test +const LegacyRequestLib = require('../../app/lib/legacy-request.lib.js') + +describe('LegacyRequestLib', () => { + const testPath = 'abstraction/info' + + afterEach(() => { + Sinon.restore() + }) + + describe('#get()', () => { + describe('when the request succeeds', () => { + beforeEach(async () => { + Sinon.stub(RequestLib, 'get').resolves({ + succeeded: true, + response: { + statusCode: 200, + body: { version: '3.1.2', commit: '70708cff586cc410c11af25cf8fd296f987d7f36' } + } + }) + }) + + it('calls the legacy service with the required options', async () => { + await LegacyRequestLib.get('import', testPath) + + const requestArgs = RequestLib.get.firstCall.args + + expect(requestArgs[0]).to.equal(testPath) + expect(requestArgs[1].prefixUrl).to.equal(`${servicesConfig.import.url}/import/1.0`) + expect(requestArgs[1].headers).to.equal({ authorization: `Bearer ${servicesConfig.legacyAuthToken}` }) + expect(requestArgs[1].responseType).to.equal('json') + expect(requestArgs[1].json).to.be.undefined() + }) + + it('returns a `true` success status', async () => { + const result = await LegacyRequestLib.get('import', testPath) + + expect(result.succeeded).to.be.true() + }) + + it('returns the response body as an object', async () => { + const result = await LegacyRequestLib.get('import', testPath) + + expect(result.response.body.version).to.equal('3.1.2') + expect(result.response.body.commit).to.equal('70708cff586cc410c11af25cf8fd296f987d7f36') + }) + + it('returns the status code', async () => { + const result = await LegacyRequestLib.get('import', testPath) + + expect(result.response.statusCode).to.equal(200) + }) + + it('can handle none API requests', async () => { + await LegacyRequestLib.get('import', testPath, false) + + const requestArgs = RequestLib.get.firstCall.args + + expect(requestArgs[1].prefixUrl).to.equal(servicesConfig.import.url) + }) + }) + + describe('when the request fails', () => { + beforeEach(async () => { + Sinon.stub(RequestLib, 'get').resolves({ + succeeded: false, + response: { + statusCode: 404, + statusMessage: 'Not Found', + body: { statusCode: 404, error: 'Not Found', message: 'Not Found' } + } + }) + }) + + it('returns a `false` success status', async () => { + const result = await LegacyRequestLib.get('import', testPath) + + expect(result.succeeded).to.be.false() + }) + + it('returns the error response', async () => { + const result = await LegacyRequestLib.get('import', testPath) + + expect(result.response.body.message).to.equal('Not Found') + }) + + it('returns the status code', async () => { + const result = await LegacyRequestLib.get('import', testPath) + + expect(result.response.statusCode).to.equal(404) + }) + }) + + describe('when the request is to an unknown legacy service', () => { + it('throws an error', async () => { + await expect(LegacyRequestLib.get('foobar', testPath)) + .to + .reject(Error, 'Request to unknown legacy service foobar') + }) + }) + }) + + describe('#post()', () => { + const requestBody = { name: 'water' } + + describe('when the request succeeds', () => { + beforeEach(async () => { + Sinon.stub(RequestLib, 'post').resolves({ + succeeded: true, + response: { + statusCode: 200, + body: { version: '3.1.2', commit: '70708cff586cc410c11af25cf8fd296f987d7f36' } + } + }) + }) + + it('calls the legacy service with the required options', async () => { + await LegacyRequestLib.post('import', testPath, true, requestBody) + + const requestArgs = RequestLib.post.firstCall.args + + expect(requestArgs[0]).to.equal(testPath) + expect(requestArgs[1].prefixUrl).to.equal(`${servicesConfig.import.url}/import/1.0`) + expect(requestArgs[1].headers).to.equal({ authorization: `Bearer ${servicesConfig.legacyAuthToken}` }) + expect(requestArgs[1].responseType).to.equal('json') + expect(requestArgs[1].json).to.equal(requestBody) + }) + + it('returns a `true` success status', async () => { + const result = await LegacyRequestLib.post('import', testPath, true, requestBody) + + expect(result.succeeded).to.be.true() + }) + + it('returns the response body as an object', async () => { + const result = await LegacyRequestLib.post('import', testPath, true, requestBody) + + expect(result.response.body.version).to.equal('3.1.2') + expect(result.response.body.commit).to.equal('70708cff586cc410c11af25cf8fd296f987d7f36') + }) + + it('returns the status code', async () => { + const result = await LegacyRequestLib.post('import', testPath, true, requestBody) + + expect(result.response.statusCode).to.equal(200) + }) + + it('can handle none API requests', async () => { + await LegacyRequestLib.post('import', testPath, false, requestBody) + + const requestArgs = RequestLib.post.firstCall.args + + expect(requestArgs[1].prefixUrl).to.equal(servicesConfig.import.url) + }) + }) + + describe('when the request fails', () => { + beforeEach(async () => { + Sinon.stub(RequestLib, 'post').resolves({ + succeeded: false, + response: { + statusCode: 404, + statusMessage: 'Not Found', + body: { statusCode: 404, error: 'Not Found', message: 'Not Found' } + } + }) + }) + + it('returns a `false` success status', async () => { + const result = await LegacyRequestLib.post('import', testPath, true, requestBody) + + expect(result.succeeded).to.be.false() + }) + + it('returns the error response', async () => { + const result = await LegacyRequestLib.post('import', testPath, true, requestBody) + + expect(result.response.body.message).to.equal('Not Found') + }) + + it('returns the status code', async () => { + const result = await LegacyRequestLib.post('import', testPath, true, requestBody) + + expect(result.response.statusCode).to.equal(404) + }) + }) + + describe('when the request is to an unknown legacy service', () => { + it('throws an error', async () => { + await expect(LegacyRequestLib.post('foobar', testPath, true, requestBody)) + .to + .reject(Error, 'Request to unknown legacy service foobar') + }) + }) + }) +}) From 92491f8c7179359b99d5a53bb48f57825898dbb0 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Sat, 4 Mar 2023 17:06:36 +0000 Subject: [PATCH 5/5] Update InfoService to use new LegacyRequestLib Now we have it, we might as well use it in the existing code. --- app/services/health/info.service.js | 31 ++++++------ test/services/health/info.service.test.js | 62 ++++++++--------------- 2 files changed, 36 insertions(+), 57 deletions(-) diff --git a/app/services/health/info.service.js b/app/services/health/info.service.js index 145254cbf5..61c6ea45e2 100644 --- a/app/services/health/info.service.js +++ b/app/services/health/info.service.js @@ -12,6 +12,7 @@ const exec = util.promisify(ChildProcess.exec) const ChargingModuleRequestLib = require('../../lib/charging-module-request.lib.js') const RequestLib = require('../../lib/request.lib.js') +const LegacyRequestLib = require('../../lib/legacy-request.lib.js') const servicesConfig = require('../../../config/services.config.js') @@ -103,27 +104,27 @@ function _getImportJobsData () { } async function _getAppData () { - const healthInfoPath = '/health/info' + const healthInfoPath = 'health/info' + const services = [ - { name: 'Service - foreground', url: new URL(healthInfoPath, servicesConfig.serviceForeground.url) }, - { name: 'Service - background', url: new URL(healthInfoPath, servicesConfig.serviceBackground.url) }, - { name: 'Reporting', url: new URL(healthInfoPath, servicesConfig.reporting.url) }, - { name: 'Import', url: new URL(healthInfoPath, servicesConfig.import.url) }, - { name: 'Tactical CRM', url: new URL(healthInfoPath, servicesConfig.tacticalCrm.url) }, - { name: 'External UI', url: new URL(healthInfoPath, servicesConfig.externalUi.url) }, - { name: 'Internal UI', url: new URL(healthInfoPath, servicesConfig.internalUi.url) }, - { name: 'Tactical IDM', url: new URL(healthInfoPath, servicesConfig.tacticalIdm.url) }, - { name: 'Permit repository', url: new URL(healthInfoPath, servicesConfig.permitRepository.url) }, - { name: 'Returns', url: new URL(healthInfoPath, servicesConfig.returns.url) } + { name: 'Service - foreground', serviceName: 'water' }, + { name: 'Service - background', serviceName: 'background' }, + { name: 'Reporting', serviceName: 'reporting' }, + { name: 'Import', serviceName: 'import' }, + { name: 'Tactical CRM', serviceName: 'crm' }, + { name: 'External UI', serviceName: 'external' }, + { name: 'Internal UI', serviceName: 'internal' }, + { name: 'Tactical IDM', serviceName: 'idm' }, + { name: 'Permit repository', serviceName: 'permits' }, + { name: 'Returns', serviceName: 'returns' } ] for (const service of services) { - const result = await RequestLib.get(service.url.href) + const result = await LegacyRequestLib.get(service.serviceName, healthInfoPath, false) if (result.succeeded) { - const data = JSON.parse(result.response.body) - service.version = data.version - service.commit = data.commit + service.version = result.response.body.version + service.commit = result.response.body.commit service.jobs = service.name === 'Import' ? _getImportJobsData() : [] } else { service.version = _parseFailedRequestResult(result) diff --git a/test/services/health/info.service.test.js b/test/services/health/info.service.test.js index c0fff081be..f1979c6136 100644 --- a/test/services/health/info.service.test.js +++ b/test/services/health/info.service.test.js @@ -14,6 +14,7 @@ const servicesConfig = require('../../../config/services.config.js') // Things we need to stub const ChargingModuleRequestLib = require('../../../app/lib/charging-module-request.lib.js') +const LegacyRequestLib = require('../../../app/lib/legacy-request.lib.js') const RequestLib = require('../../../app/lib/request.lib.js') // Thing under test @@ -34,44 +35,29 @@ describe('Info service', () => { } } }, - app: { succeeded: true, response: { statusCode: 200, body: '{ "version": "9.0.99", "commit": "99d0e8c" }' } } + app: { succeeded: true, response: { statusCode: 200, body: { version: '9.0.99', commit: '99d0e8c' } } } } let chargingModuleRequestLibStub + let legacyRequestLibStub let requestLibStub beforeEach(() => { + chargingModuleRequestLibStub = Sinon.stub(ChargingModuleRequestLib, 'get') + legacyRequestLibStub = Sinon.stub(LegacyRequestLib, 'get') requestLibStub = Sinon.stub(RequestLib, 'get') + // These requests will remain unchanged throughout the tests. We do alter the ones to the AddressFacade and the // water-api (foreground-service) though, which is why they are defined separately in each test. - requestLibStub - .withArgs(`${servicesConfig.serviceBackground.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.reporting.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.import.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.tacticalCrm.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.externalUi.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.internalUi.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.tacticalIdm.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.permitRepository.url}/health/info`) - .resolves(goodRequestResults.app) - requestLibStub - .withArgs(`${servicesConfig.returns.url}/health/info`) - .resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('background', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('reporting', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('import', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('crm', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('external', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('internal', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('idm', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('permits', 'health/info', false).resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('returns', 'health/info', false).resolves(goodRequestResults.app) - chargingModuleRequestLibStub = Sinon.stub(ChargingModuleRequestLib, 'get') chargingModuleRequestLibStub .withArgs('status') .resolves(goodRequestResults.chargingModule) @@ -87,9 +73,7 @@ describe('Info service', () => { requestLibStub .withArgs(`${servicesConfig.addressFacade.url}/address-service/hola`) .resolves(goodRequestResults.addressFacade) - requestLibStub - .withArgs(`${servicesConfig.serviceForeground.url}/health/info`) - .resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('water', 'health/info', false).resolves(goodRequestResults.app) // Unfortunately, this convoluted test setup is the only way we've managed to stub how the promisified version of // `child-process.exec()` behaves in the module under test. @@ -131,9 +115,7 @@ describe('Info service', () => { requestLibStub .withArgs(`${servicesConfig.addressFacade.url}/address-service/hola`) .resolves(goodRequestResults.addressFacade) - requestLibStub - .withArgs(`${servicesConfig.serviceForeground.url}/health/info`) - .resolves(goodRequestResults.app) + legacyRequestLibStub.withArgs('water', 'health/info', false).resolves(goodRequestResults.app) }) describe('is not running', () => { @@ -226,9 +208,7 @@ describe('Info service', () => { requestLibStub .withArgs(`${servicesConfig.addressFacade.url}/address-service/hola`) .resolves(badResult) - requestLibStub - .withArgs(`${servicesConfig.serviceForeground.url}/health/info`) - .resolves(badResult) + legacyRequestLibStub.withArgs('water', 'health/info', false).resolves(badResult) }) it('handles the error and still returns a result for the other services', async () => { @@ -246,14 +226,12 @@ describe('Info service', () => { describe('returns a 5xx response', () => { beforeEach(async () => { - const badResult = { succeeded: false, response: { statusCode: 500, body: 'Kaboom' } } + const badResult = { succeeded: false, response: { statusCode: 500, body: { message: 'Kaboom' } } } requestLibStub .withArgs(`${servicesConfig.addressFacade.url}/address-service/hola`) .resolves(badResult) - requestLibStub - .withArgs(`${servicesConfig.serviceForeground.url}/health/info`) - .resolves(badResult) + legacyRequestLibStub.withArgs('water', 'health/info', false).resolves(badResult) }) it('handles the error and still returns a result for the other services', async () => {