Ghost/ghost/email-analytics-service/test/email-analytics-service.test.js
Kevin Ansfield af7aff5352 Added email analytics service tests
no issue

- fixed destructuring error when  creating instances of `EmailAnalyticsService` or `EventProcessor` with no options object
- fixed unprocessable complained event incrementing complained count rather than unprocessable count
- fixed `fetchAll()` and `fetchLatest()` returning `undefined` instead of a blank EventProcessingResult
2021-03-01 21:31:07 +00:00

162 lines
5.0 KiB
JavaScript

// Switch these lines once there are useful utils
// const testUtils = require('./utils');
require('./utils');
const sinon = require('sinon');
const {
EmailAnalyticsService,
EventProcessor
} = require('..');
const EventProcessingResult = require('../lib/event-processing-result');
describe('EmailAnalyticsService', function () {
describe('fetchAll', function () {
let eventProcessor;
let providers;
let queries;
beforeEach(function () {
eventProcessor = new EventProcessor();
eventProcessor.handleDelivered = sinon.fake.resolves(true);
eventProcessor.handleOpened = sinon.fake.resolves(true);
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 eventProcessor = new EventProcessor();
eventProcessor.handleDelivered = sinon.stub().resolves(true);
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,
unprocessable: 1,
emailIds: [1, 2]
}));
});
});
describe('aggregateStats', function () {
let service;
beforeEach(function () {
service = new EmailAnalyticsService({
logging: sinon.spy(),
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();
});
});
});