util/mock-server.js (79 lines of code) (raw):

/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable functional/immutable-data */ /* eslint-disable no-console */ /* eslint-disable functional/no-let */ // Very simple mocking server for mimicking IDAPI /* eslint-env node */ const bodyParser = require('body-parser'); const express = require('express'); const PORT = 9000; const DEFAULT_RESPONSE = { status: 500, payload: 'Mock Server Error: No mock requests in queue', }; const app = express(); const responses = []; const permanent = new Map(); let permanentPatterns = []; const findPattern = (path) => permanentPatterns.find(({ pattern }) => new RegExp(pattern).test(path)); const payloads = []; app.use(bodyParser.json({ strict: false })); app.use(express.urlencoded({ extended: true })); app.get('/healthcheck', (_, res) => { console.log('healthcheck OK'); res.sendStatus(204); }); // Reset all mocks, including permanent app.get('/mock/purge', (_, res) => { console.log('purging all mocks'); responses.length = 0; permanent.clear(); permanentPatterns = []; payloads.length = 0; res.sendStatus(204); }); // Push mock onto mock stack app.post('/mock', (req, res) => { responses.unshift({ status: req.get('X-status'), payload: req.body, }); res.sendStatus(204); }); // Mock an endpoint with a pattern app.post('/mock/permanent-pattern', (req, res) => { permanentPatterns.push(req.body); res.sendStatus(204); }); // Always mock supplied endpoint app.post('/mock/permanent', (req, res) => { const { path, body: payload, status = 200 } = req.body; permanent.set(path, { payload, status }); res.sendStatus(204); }); // Return last POST or PATCH'd request payload app.get('/mock/payload', (_, res) => { res.json(payloads[payloads.length - 1]); }); // Return all POST or PATCH'd request payloads app.get('/mock/payloads', (_, res) => { res.json(payloads); }); // For any request, if permanent, return permanent mock, otherwise pop from mock stack. app.all('*', (req, res) => { const origin = req.header('Origin'); if (origin) { res.set('Access-Control-Allow-Origin', origin); } const { method } = req; if (method === 'POST' || method === 'PATCH') { payloads.push(req.body); } if (permanent.has(req.path)) { const { status, payload } = permanent.get(req.path); res.status(status).json(payload); // console.log(`Mocking: ${req.originalUrl}: ${status} ${inspect(payload)}`); return; } const patternResponse = findPattern(req.path); if (patternResponse) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { status, body, pattern } = patternResponse; res.status(status).json(body); // console.log( // `Mocking for pattern ${pattern}: ${req.originalUrl}: ${status} ${body}`, // ); return; } if (responses.length === 0) { res.status(DEFAULT_RESPONSE.status).json(DEFAULT_RESPONSE.body); } else { const { status, payload } = responses.pop(); // console.log(`Mocking: ${req.originalUrl}: ${status} ${inspect(payload)}`); res.status(status).json(payload); } }); app.listen(PORT); console.log('mock server running on port:', PORT);