diff --git a/test/integration/pubsub-metrics-test.js b/test/integration/pubsub-metrics-test.js new file mode 100644 index 00000000..99dd58f7 --- /dev/null +++ b/test/integration/pubsub-metrics-test.js @@ -0,0 +1,138 @@ +'use strict'; + +const sinon = require('sinon'); +const assert = require('assert'); +const redis = require('redis'); +const TestClient = require('../support/test-client'); +const PubSubMetricsBackend = require('../../lib/backends/pubsub-metrics'); + +const metricsHeaders = { + 'Carto-Event': 'test-event', + 'Carto-Event-Source': 'test', + 'Carto-Event-Group-Id': '1' +}; + +const mapConfig = { + version: '1.7.0', + layers: [ + { + options: { + sql: 'select * FROM test_table_localhost_regular1', + cartocss: TestClient.CARTOCSS.POINTS, + cartocss_version: '2.3.0' + } + } + ] +}; + +function buildEventAttributes (statusCode) { + return { + event_source: 'test', + user_id: '1', + event_group_id: '1', + response_code: statusCode.toString(), + source_domain: 'localhost', + event_time: new Date().toISOString(), + event_version: '1' + }; +} + +const fakeTopic = { + name: 'test-topic', + publish: sinon.stub().returns(Promise.resolve()) +}; + +const fakePubSub = { + topic: () => fakeTopic +}; + +describe('pubsub metrics middleware', function () { + let redisClient; + let testClient; + let clock; + + before(function () { + redisClient = redis.createClient(global.environment.redis.port); + clock = sinon.useFakeTimers(); + sinon.stub(PubSubMetricsBackend, 'createPubSub').returns(fakePubSub); + }); + + after(function () { + clock.restore(); + PubSubMetricsBackend.createPubSub.restore(); + global.environment.pubSubMetrics.enabled = false; + }); + + afterEach(function (done) { + fakeTopic.publish.resetHistory(); + + redisClient.SELECT(0, () => { + redisClient.del('user:localhost:mapviews:global'); + + redisClient.SELECT(5, () => { + redisClient.del('user:localhost:mapviews:global'); + done(); + }); + }); + }); + + it('should not send event if not enabled', function (done) { + global.environment.pubSubMetrics.enabled = false; + testClient = new TestClient(mapConfig, 1234, metricsHeaders); + + testClient.getLayergroup((err, body) => { + if (err) { + return done(err); + } + + assert.strictEqual(typeof body.metadata, 'object'); + assert(fakeTopic.publish.notCalled); + return done(); + }); + }); + + it('should not send event if headers not present', function (done) { + global.environment.pubSubMetrics.enabled = true; + testClient = new TestClient(mapConfig, 1234); + + testClient.getLayergroup((err, body) => { + if (err) { + return done(err); + } + + assert.strictEqual(typeof body.metadata, 'object'); + assert(fakeTopic.publish.notCalled); + return done(); + }); + }); + + it('should send event for map requests', function (done) { + global.environment.pubSubMetrics.enabled = true; + const eventAttributes = buildEventAttributes(200); + testClient = new TestClient(mapConfig, 1234, metricsHeaders); + + testClient.getLayergroup((err, body) => { + if (err) { + return done(err); + } + + assert.strictEqual(typeof body.metadata, 'object'); + assert(fakeTopic.publish.calledOnceWith(Buffer.from('test-event'), eventAttributes)); + return done(); + }); + }); + + it('should send event when error', function (done) { + global.environment.pubSubMetrics.enabled = true; + const eventAttributes = buildEventAttributes(400); + eventAttributes.user_id = undefined; + + testClient = new TestClient({}, 1234, metricsHeaders); + + testClient.getLayergroup(() => { + assert(fakeTopic.publish.calledOnceWith(Buffer.from('test-event'), eventAttributes)); + assert(fakeTopic.publish.calledOnce); + return done(); + }); + }); +}); diff --git a/test/unit/backends/pubsub-metrics-test.js b/test/unit/backends/pubsub-metrics-test.js new file mode 100644 index 00000000..c08a93e5 --- /dev/null +++ b/test/unit/backends/pubsub-metrics-test.js @@ -0,0 +1,40 @@ +'use strict'; + +const sinon = require('sinon'); +const assert = require('assert'); +const PubSubMetricsBackend = require('../../../lib/backends/pubsub-metrics'); + +const fakeTopic = { + name: 'test-topic', + publish: sinon.stub().returns(Promise.resolve()) +}; + +const fakePubSub = { + topic: () => fakeTopic +}; + +const eventAttributes = { + event_source: 'test', + user_id: '123', + event_group_id: '1', + response_code: '200', + source_domain: 'localhost', + event_time: new Date().toISOString(), + event_version: '1' +}; + +describe('pubsub metrics backend', function () { + it('should not send event if not enabled', function () { + const pubSubMetricsService = new PubSubMetricsBackend(fakePubSub, false); + + pubSubMetricsService.sendEvent('test-event', eventAttributes); + assert(fakeTopic.publish.notCalled); + }); + + it('should send event if enabled', function () { + const pubSubMetricsService = new PubSubMetricsBackend(fakePubSub, true); + + pubSubMetricsService.sendEvent('test-event', eventAttributes); + assert(fakeTopic.publish.calledOnceWith(Buffer.from('test-event'), eventAttributes)); + }); +});