UNPKG

@villedemontreal/correlation-id

Version:

Express middleware to set a correlation in Express. The correlation id will be consistent across async calls within the handling of a request.

272 lines 13.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const express = require("express"); const http_header_fields_typed_1 = require("http-header-fields-typed"); const request = require("supertest"); const correlationIdService_1 = require("../services/correlationIdService"); const testingConfigurations_1 = require("../utils/testingConfigurations"); const correlationIdMiddleware_1 = require("./correlationIdMiddleware"); function delay(millis) { return new Promise((resolve) => setTimeout(() => { resolve(); }, millis)); } // ========================================== // Set Testing configurations // ========================================== (0, testingConfigurations_1.setTestingConfigurations)(); const uuidMatcher = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; // ========================================== // Correlation ID service // ========================================== // tslint:disable-next-line: max-func-body-length describe('Correlation ID Middleware', () => { it('should generate correlation id if it doesnt exists', async () => { const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', (req, res) => { const actual = correlationIdService_1.correlationIdService.getId(); chai_1.assert.match(actual, uuidMatcher); res.end(); }); await request(app).get('/').send(); }); it('should get correlation id from incoming request', async () => { const testId = 'correlation-id-123'; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', (req, res) => { const actual = correlationIdService_1.correlationIdService.getId(); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); res.end(); }); await request(app).get('/').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); }); it('should maintain correlation id with async callbacks', async () => { const testId = 'correlation-id-123'; let actual = ''; let actual2 = ''; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', async (req, res, next) => { actual = correlationIdService_1.correlationIdService.getId(); setTimeout(() => { actual2 = correlationIdService_1.correlationIdService.getId(); res.end(); }, 250); }); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); await request(app).get('/').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual2, testId, 'getId() should return id from x-correlation-id header of inbound request'); }); it('should maintain correlation id with async/await operations', async () => { const testId = 'correlation-id-123'; let actual = ''; let actual2 = ''; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', async (req, res, next) => { try { actual = correlationIdService_1.correlationIdService.getId(); await delay(250); actual2 = correlationIdService_1.correlationIdService.getId(); } catch (e) { next(e); } finally { res.end(); } }); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); await request(app).get('/').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual2, testId, 'getId() should return id from x-correlation-id header of inbound request'); }); it('should keep correlation ids in nested requests', async () => { const testId = 'correlation-id-123'; const testId2 = 'correlation-id-456'; let actual = ''; let actual2 = ''; let actual3 = ''; let actual4 = ''; let actual5 = ''; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', async (req, res, next) => { try { actual = correlationIdService_1.correlationIdService.getId(); await delay(250); actual2 = correlationIdService_1.correlationIdService.getId(); await request(app).get('/foo').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId2).send(); actual3 = correlationIdService_1.correlationIdService.getId(); } catch (e) { next(e); } finally { res.end(); } }); app.get('/foo', async (req, res, next) => { try { actual4 = correlationIdService_1.correlationIdService.getId(); await delay(250); actual5 = correlationIdService_1.correlationIdService.getId(); } catch (e) { next(e); } finally { res.end(); } }); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); await request(app).get('/').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual2, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual3, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual4, testId2, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual5, testId2, 'getId() should return id from x-correlation-id header of inbound request'); }); // tslint:disable: no-console it('should keep correlation ids separated in parallel requests', async function () { this.timeout(5000); const testId = 'correlation-id-123'; const testId2 = 'correlation-id-456'; let actual = ''; let actual2 = ''; let actual4 = ''; let actual5 = ''; let unlock; const lock = new Promise(async (resolve, reject) => { unlock = resolve; }); const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', async (req, res, next) => { try { actual = correlationIdService_1.correlationIdService.getId(); console.log('start of req1', actual); await lock; actual2 = correlationIdService_1.correlationIdService.getId(); console.log('end of req1', actual2); } catch (e) { next(e); } finally { res.end(); } }); app.get('/foo', async (req, res, next) => { try { actual4 = correlationIdService_1.correlationIdService.getId(); console.log('start of req2', actual4); unlock(); await this.timeout(200); actual5 = correlationIdService_1.correlationIdService.getId(); console.log('end of req2', actual5); } catch (e) { next(e); } finally { res.end(); } }); console.log('send req1'); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); const req1 = request(app).get('/').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); console.log('send req2'); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); const req2 = request(app) .get('/foo') .set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId2) .send(); await Promise.all([req1, req2]); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual2, testId, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual4, testId2, 'getId() should return id from x-correlation-id header of inbound request'); chai_1.assert.strictEqual(actual5, testId2, 'getId() should return id from x-correlation-id header of inbound request'); }); it('should work with operations causing errors', async () => { const testId = 'correlation-id-123'; let actual = ''; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', (req, res, next) => { actual = correlationIdService_1.correlationIdService.getId(); throw new Error('some error'); }); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); const result = await request(app) .get('/') .set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId) .send(); chai_1.assert.strictEqual(result.status, 500); chai_1.assert.isUndefined(correlationIdService_1.correlationIdService.getId()); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); }); it('a filter can be specified', async () => { const testId = 'correlation-id-123'; const filter = (req) => { if (req.path.startsWith('/ok/')) { return true; } return false; }; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)(filter)); app.get('/ok/1', (req, res) => { const actual = correlationIdService_1.correlationIdService.getId(); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); res.end(); }); app.get('/ok/2', (req, res) => { const actual = correlationIdService_1.correlationIdService.getId(); chai_1.assert.strictEqual(actual, testId, 'getId() should return id from x-correlation-id header of inbound request'); res.end(); }); app.get('/notok/1', (req, res) => { const actual = correlationIdService_1.correlationIdService.getId(); chai_1.assert.isUndefined(actual); res.end(); }); await request(app).get('/ok/1').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); await request(app).get('/ok/2').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); await request(app).get('/notok/1').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); }); it('getCidInfo() cid received', async () => { const testId = 'correlation-id-123'; const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', (req, res) => { const info = correlationIdService_1.correlationIdService.getCidInfo(req); chai_1.assert.strictEqual(info.current, testId); chai_1.assert.strictEqual(info.receivedInRequest, testId); chai_1.assert.isUndefined(info.generated); res.end(); }); await request(app).get('/').set(http_header_fields_typed_1.default.X_CORRELATION_ID, testId).send(); }); it('getCidInfo() cid generated', async () => { const app = express(); app.use((0, correlationIdMiddleware_1.createCorrelationIdMiddleware)()); app.get('/', (req, res) => { const info = correlationIdService_1.correlationIdService.getCidInfo(req); chai_1.assert.match(info.current, uuidMatcher); chai_1.assert.strictEqual(info.current, info.generated); chai_1.assert.isUndefined(info.receivedInRequest); res.end(); }); await request(app).get('/').send(); }); }); //# sourceMappingURL=correlationIdMiddleware.test.js.map