diff --git a/package.json b/package.json index dce0a261b..065b93605 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,9 @@ "mocha": "^10.2.0", "mock-require": "^3.0.3", "nyc": "^15.1.0", - "test-console": "^2.0.0" + "test-console": "^2.0.0", + "wiremock": "^3.10.0", + "wiremock-rest-client": "^1.11.0" }, "peerDependencies": { "asn1.js": "^5.4.1" diff --git a/test/integration/wiremock/testWiremockRunner.js b/test/integration/wiremock/testWiremockRunner.js new file mode 100644 index 000000000..17d4f3f6b --- /dev/null +++ b/test/integration/wiremock/testWiremockRunner.js @@ -0,0 +1,43 @@ +const assert = require('assert'); +const fs = require('fs'); +const net = require('net'); +const axios = require('axios'); +const { runWireMockAsync } = require('../../wiremockRunner'); +const os = require('os'); + +async function getFreePort() { + return new Promise(res => { + const srv = net.createServer(); + srv.listen(0, () => { + const port = srv.address().port; + srv.close(() => res(port)); + }); + }); +} + +if (os.platform !== 'win32') { + describe('Wiremock test', function () { + let port, wireMock; + before(async () => { + port = await getFreePort(); + wireMock = await runWireMockAsync(port); + }); + after(async () => { + await wireMock.global.shutdown(); + }); + it('Run Wiremock instance, wait, verify connection and shutdown', async function () { + assert.doesNotReject(async () => await wireMock.mappings.getAllMappings()); + }); + it('Add mappings', async function () { + const requests = JSON.parse(fs.readFileSync('wiremock/mappings/testMapping.json', 'utf8')); + for (const mapping of requests.mappings) { + await wireMock.mappings.createMapping(mapping); + } + const mappings = await wireMock.mappings.getAllMappings(); + assert.strictEqual(mappings.mappings.length, 2); + const response = await axios.get(`http://localhost:${port}/test/authorize.html`); + assert.strictEqual(response.status, 200); + }); + }); + +} diff --git a/test/wiremockRunner.js b/test/wiremockRunner.js new file mode 100644 index 000000000..3db88d0dc --- /dev/null +++ b/test/wiremockRunner.js @@ -0,0 +1,58 @@ +const WireMockRestClient = require('wiremock-rest-client').WireMockRestClient; +const { exec } = require('child_process'); +const Logger = require('../lib/logger'); +const fs = require('fs'); + + +async function runWireMockAsync(port) { + let timeoutHandle; + const waitingWireMockPromise = new Promise( (resolve, reject) => { + try { + exec(`npx wiremock --enable-browser-proxying --proxy-pass-through false --port ${port} `); + const wireMock = new WireMockRestClient(`http://localhost:${port}`, { logLevel: 'debug' }); + const readyWireMock = waitForWiremockStarted(wireMock); + resolve(readyWireMock); + } catch (err) { + reject(err); + } + }); + + const timeout = new Promise((resolve, reject) => + timeoutHandle = setTimeout( + () => reject('Wiremock unavailable after 60s.'), + 60000)); + return Promise.race([waitingWireMockPromise, timeout]) + .then(result => { + clearTimeout(timeoutHandle); + return result; + }); +} + +async function waitForWiremockStarted(wireMock) { + return fetch(wireMock.baseUri) + .then(async (resp) => { + if (resp.ok) { + return Promise.resolve(wireMock); + } else { + await new Promise(resolve => setTimeout(resolve, 1000)); + Logger.getInstance().info(`Retry connection to WireMock after wrong response status: ${resp.status}`); + return await waitForWiremockStarted(wireMock); + } + }) + .catch(async (err) => { + await new Promise(resolve => setTimeout(resolve, 1000)); + Logger.getInstance().info(`Retry connection to WireMock after error: ${err}`); + return await waitForWiremockStarted(wireMock); + }); +} + +async function addWireMockMappingsFromFile(wireMock, filePath) { + const requests = JSON.parse(fs.readFileSync(filePath, 'utf8')); + for (const mapping of requests.mappings) { + await wireMock.mappings.createMapping(mapping); + } +} + +exports.runWireMockAsync = runWireMockAsync; +exports.addWireMockMappingsFromFile = addWireMockMappingsFromFile; + diff --git a/wiremock/mappings/testMapping.json b/wiremock/mappings/testMapping.json new file mode 100644 index 000000000..c3ce742a3 --- /dev/null +++ b/wiremock/mappings/testMapping.json @@ -0,0 +1,34 @@ +{ + "mappings": [ + { + "scenarioName": "Test wiremock endpoint", + "request": { + "urlPathPattern": "/test/authorize.*", + "method": "GET" + }, + "response": { + "status": 200, + "fixedDelayMilliseconds": 500 + + } + }, + { + "scenarioName": "Test wiremock endpoint", + "request": { + "urlPathPattern": "/session/v1/login-request.*", + "method": "POST" + }, + "response": { + "status": 200, + "fixedDelayMilliseconds": 500, + "jsonBody": { + "data": { + "masterToken": "master token", + "token": "session token", + "validityInSeconds": 3600 + } + } + } + } + ] +} \ No newline at end of file