diff --git a/test/unit/EventAccumulator.test.ts b/test/unit/EventAccumulator.test.ts new file mode 100644 index 0000000..528f167 --- /dev/null +++ b/test/unit/EventAccumulator.test.ts @@ -0,0 +1,153 @@ +/* eslint-disable no-console */ +import { expect } from 'chai' +import Countly from 'countly-sdk-nodejs' +import Sinon from 'sinon' +import { EventAccumulator } from '../../src/EventAccumulator.js' + +const sleep = async (ms: number): Promise => await new Promise(resolve => setTimeout(resolve, ms)) + +describe('EventAccumulator', () => { + it('should accumulate events', async () => { + Countly.add_event = Sinon.stub() + const accumulator = new EventAccumulator(Countly) + const event = { + key: 'test', + count: 1, + sum: 1, + segmentation: {} + } + // add the event twice with a 100ms delay between them, this is needed to test the duration. + accumulator.addEvent(event) + await sleep(100) + accumulator.addEvent(event) + // flush the event + accumulator.flush('test') + // check the event data + const { count, dur, key, sum, segmentation } = Countly.add_event.getCall(0).args[0] + expect(count).to.be.equal(2) + expect(dur).to.be.greaterThan(100) + expect(key).to.be.equal('test') + expect(sum).to.be.equal(2) + expect(segmentation).to.be.deep.equal({}) + expect(Countly.add_event.callCount).to.be.equal(1) + }) + + it('should flush events after the flush interval', async () => { + Countly.add_event = Sinon.stub() + const accumulator = new EventAccumulator(Countly, 100) + const event = { + key: 'test', + count: 1, + sum: 1, + segmentation: {} + } + accumulator.addEvent(event) + // wait for the flush interval to pass + await sleep(150) + // check the event data + const { count, dur, key, sum, segmentation } = Countly.add_event.getCall(0).args[0] + expect(count).to.be.equal(1) + expect(dur).to.be.greaterThanOrEqual(100) + expect(key).to.be.equal('test') + expect(sum).to.be.equal(1) + expect(segmentation).to.be.deep.equal({}) + expect(Countly.add_event.callCount).to.be.equal(1) + }) + + it('should flush events when flush=true', async () => { + Countly.add_event = Sinon.stub() + const accumulator = new EventAccumulator(Countly, 1000) + const event = { + key: 'test', + count: 1, + sum: 1, + segmentation: {} + } + // add the event twice with a 100ms delay between them, this is needed to test the duration. + accumulator.addEvent(event) + await sleep(100) + accumulator.addEvent(event, true) + // check the event data + const { count, dur, key, sum, segmentation } = Countly.add_event.getCall(0).args[0] + expect(count).to.be.equal(2) + expect(dur).to.be.greaterThanOrEqual(100) + expect(key).to.be.equal('test') + expect(sum).to.be.equal(2) + expect(segmentation).to.be.deep.equal({}) + expect(Countly.add_event.callCount).to.be.equal(1) + }) + + it('should accumulate segments', async () => { + Countly.add_event = Sinon.stub() + const accumulator = new EventAccumulator(Countly, 1000) + const event1 = { + key: 'test', + count: 1, + sum: 1, + segmentation: { + foo: 'bar' + } + } + const event2 = { + key: 'test', + count: 1, + sum: 1, + segmentation: { + bar: 'baz' + } + } + // add the event twice with a 100ms delay between them, this is needed to test the duration. + accumulator.addEvent(event1) + await sleep(100) + accumulator.addEvent(event2, true) + // check the event data + const { count, dur, key, sum, segmentation } = Countly.add_event.getCall(0).args[0] + expect(count).to.be.equal(2) + expect(dur).to.be.greaterThanOrEqual(100) + expect(key).to.be.equal('test') + expect(sum).to.be.equal(2) + expect(segmentation).to.be.deep.equal({ + foo: 'bar', + bar: 'baz' + }) + expect(Countly.add_event.callCount).to.be.equal(1) + }) + + it('should accumulate different types of events', async () => { + Countly.add_event = Sinon.stub() + const accumulator = new EventAccumulator(Countly, 100) + const event1 = { + key: 'test1', + count: 1, + sum: 1, + segmentation: { + foo: 'bar' + } + } + const event2 = { + key: 'test2', + count: 1, + sum: 1, + segmentation: { + bar: 'baz' + } + } + accumulator.addEvent(event1) + // adding the second event after 50ms so that the first event is flushed first + await sleep(50) + accumulator.addEvent(event2) + // wait for the flush interval to pass + await sleep(150) + // check the event data + const calls = [['test1', { foo: 'bar' }], ['test2', { bar: 'baz' }]] + calls.forEach(([testKey, segment], idx) => { + const { count, dur, key, sum, segmentation } = Countly.add_event.getCall(idx).args[0] + expect(count).to.be.equal(1) + expect(dur).to.be.greaterThanOrEqual(100) + expect(key).to.be.equal(testKey) + expect(sum).to.be.equal(1) + expect(segmentation).to.be.deep.equals(segment) + }) + expect(Countly.add_event.callCount).to.be.equal(2) + }) +})