2021-03-02 00:31:07 +03:00
|
|
|
// Switch these lines once there are useful utils
|
|
|
|
// const testUtils = require('./utils');
|
|
|
|
require('./utils');
|
|
|
|
|
|
|
|
const sinon = require('sinon');
|
|
|
|
|
|
|
|
const {
|
2022-11-29 13:15:19 +03:00
|
|
|
EmailAnalyticsService
|
2021-03-02 00:31:07 +03:00
|
|
|
} = require('..');
|
|
|
|
const EventProcessingResult = require('../lib/event-processing-result');
|
|
|
|
|
|
|
|
describe('EmailAnalyticsService', function () {
|
2022-11-29 13:15:19 +03:00
|
|
|
let eventProcessor;
|
|
|
|
beforeEach(function () {
|
|
|
|
eventProcessor = {};
|
|
|
|
eventProcessor.handleDelivered = sinon.stub().callsFake(({emailId}) => {
|
|
|
|
return {
|
|
|
|
emailId,
|
|
|
|
emailRecipientId: emailId,
|
|
|
|
memberId: 1
|
|
|
|
};
|
|
|
|
});
|
|
|
|
eventProcessor.handleOpened = sinon.stub().callsFake(({emailId}) => {
|
|
|
|
return {
|
|
|
|
emailId,
|
|
|
|
emailRecipientId: emailId,
|
|
|
|
memberId: 1
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-03-02 00:31:07 +03:00
|
|
|
describe('fetchAll', function () {
|
|
|
|
let providers;
|
|
|
|
let queries;
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
providers = {
|
|
|
|
testing: {
|
|
|
|
async fetchAll(batchHandler) {
|
|
|
|
const result = new EventProcessingResult();
|
|
|
|
|
|
|
|
// first page
|
|
|
|
result.merge(await batchHandler([{
|
|
|
|
type: 'delivered',
|
|
|
|
emailId: 1,
|
|
|
|
memberId: 1
|
|
|
|
}, {
|
|
|
|
type: 'delivered',
|
|
|
|
emailId: 1,
|
|
|
|
memberId: 1
|
|
|
|
}]));
|
|
|
|
|
|
|
|
// second page
|
|
|
|
result.merge(await batchHandler([{
|
|
|
|
type: 'opened',
|
|
|
|
emailId: 1,
|
|
|
|
memberId: 1
|
|
|
|
}, {
|
|
|
|
type: 'opened',
|
|
|
|
emailId: 1,
|
|
|
|
memberId: 1
|
|
|
|
}]));
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
queries = {
|
|
|
|
shouldFetchStats: sinon.fake.resolves(true)
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
it('uses passed-in providers', async function () {
|
|
|
|
const service = new EmailAnalyticsService({
|
|
|
|
queries,
|
|
|
|
eventProcessor,
|
|
|
|
providers
|
|
|
|
});
|
|
|
|
|
|
|
|
const result = await service.fetchAll();
|
|
|
|
|
|
|
|
queries.shouldFetchStats.calledOnce.should.be.true();
|
|
|
|
eventProcessor.handleDelivered.calledTwice.should.be.true();
|
|
|
|
|
|
|
|
result.should.deepEqual(new EventProcessingResult({
|
|
|
|
delivered: 2,
|
|
|
|
opened: 2,
|
|
|
|
emailIds: [1],
|
|
|
|
memberIds: [1]
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('skips if queries.shouldFetchStats is falsy', async function () {
|
|
|
|
queries.shouldFetchStats = sinon.fake.resolves(false);
|
|
|
|
|
|
|
|
const service = new EmailAnalyticsService({
|
|
|
|
queries,
|
|
|
|
eventProcessor,
|
|
|
|
providers
|
|
|
|
});
|
|
|
|
|
|
|
|
const result = await service.fetchAll();
|
|
|
|
|
|
|
|
queries.shouldFetchStats.calledOnce.should.be.true();
|
|
|
|
eventProcessor.handleDelivered.called.should.be.false();
|
|
|
|
|
|
|
|
result.should.deepEqual(new EventProcessingResult());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('fetchLatest', function () {
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('processEventBatch', function () {
|
|
|
|
it('uses passed-in event processor', async function () {
|
|
|
|
const service = new EmailAnalyticsService({
|
|
|
|
eventProcessor
|
|
|
|
});
|
|
|
|
|
|
|
|
const result = await service.processEventBatch([{
|
|
|
|
type: 'delivered',
|
|
|
|
emailId: 1
|
|
|
|
}, {
|
|
|
|
type: 'delivered',
|
|
|
|
emailId: 2
|
|
|
|
}, {
|
|
|
|
type: 'opened',
|
|
|
|
emailId: 1
|
|
|
|
}]);
|
|
|
|
|
|
|
|
eventProcessor.handleDelivered.callCount.should.eql(2);
|
|
|
|
|
|
|
|
result.should.deepEqual(new EventProcessingResult({
|
|
|
|
delivered: 2,
|
2022-11-29 13:15:19 +03:00
|
|
|
opened: 1,
|
|
|
|
unprocessable: 0,
|
|
|
|
emailIds: [1, 2],
|
|
|
|
memberIds: [1]
|
2021-03-02 00:31:07 +03:00
|
|
|
}));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('aggregateStats', function () {
|
|
|
|
let service;
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
service = new EmailAnalyticsService({
|
|
|
|
queries: {
|
|
|
|
aggregateEmailStats: sinon.spy(),
|
|
|
|
aggregateMemberStats: sinon.spy()
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('calls appropriate query for each email id and member id', async function () {
|
|
|
|
await service.aggregateStats({
|
|
|
|
emailIds: ['e-1', 'e-2'],
|
|
|
|
memberIds: ['m-1', 'm-2']
|
|
|
|
});
|
|
|
|
|
|
|
|
service.queries.aggregateEmailStats.calledTwice.should.be.true();
|
|
|
|
service.queries.aggregateEmailStats.calledWith('e-1').should.be.true();
|
|
|
|
service.queries.aggregateEmailStats.calledWith('e-2').should.be.true();
|
|
|
|
|
|
|
|
service.queries.aggregateMemberStats.calledTwice.should.be.true();
|
|
|
|
service.queries.aggregateMemberStats.calledWith('m-1').should.be.true();
|
|
|
|
service.queries.aggregateMemberStats.calledWith('m-2').should.be.true();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|