0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-01 02:41:39 -05:00

Removed DomainEventsAnalytics

closes CA-11

- Segment events in Ghost core are not used currently
This commit is contained in:
Aileen Booker 2024-01-30 13:27:51 -04:00 committed by Aileen Booker
parent 3c56005d44
commit c4912665e5
4 changed files with 0 additions and 415 deletions

View file

@ -1,109 +0,0 @@
const {MilestoneCreatedEvent} = require('@tryghost/milestones');
const {StripeLiveEnabledEvent, StripeLiveDisabledEvent} = require('@tryghost/members-stripe-service').events;
/**
* @typedef {import('@tryghost/logging')} logging
*/
/**
* @typedef {import('analytics-node')} analytics
*/
/**
* @typedef {object} IExceptionHandler
* @prop {(err: Error) => void} captureException
*/
/**
* @typedef {import('@tryghost/domain-events')} DomainEvents
*/
/**
* @typedef {object} IDomainEventsAnalytics
* @param {analytics} analytics
* @param {logging} logging
* @param {object} trackDefaults
* @param {string} prefix
* @param {IExceptionHandler} exceptionHandler
* @param {DomainEvents} DomainEvents
* @prop {} subscribeToEvents
*/
module.exports = class DomainEventsAnalytics {
/** @type {analytics} */
#analytics;
/** @type {object} */
#trackDefaults;
/** @type {string} */
#prefix;
/** @type {IExceptionHandler} */
#exceptionHandler;
/** @type {logging} */
#logging;
/** @type {DomainEvents} */
#DomainEvents;
constructor(deps) {
this.#analytics = deps.analytics;
this.#trackDefaults = deps.trackDefaults;
this.#prefix = deps.prefix;
this.#exceptionHandler = deps.exceptionHandler;
this.#logging = deps.logging;
this.#DomainEvents = deps.DomainEvents;
}
/**
*
* @param {object} event
* @param {object} event.data
* @param {object} event.data.milestone
* @param {number} event.data.milestone.value
* @param {string} event.data.milestone.type
* @returns {Promise<void>}
*/
async #handleMilestoneCreatedEvent(event) {
if (event.data.milestone
&& event.data.milestone.value === 100
) {
const eventName = event.data.milestone.type === 'arr' ? '$100 ARR reached' : '100 Members reached';
try {
this.#analytics.track(Object.assign(this.#trackDefaults, {}, {event: this.#prefix + eventName}));
} catch (err) {
this.#logging.error(err);
this.#exceptionHandler.captureException(err);
}
}
}
/**
*
* @param {StripeLiveEnabledEvent|StripeLiveDisabledEvent} type
*
* @returns {Promise<void>}
*/
async #handleStripeEvent(type) {
const eventName = type === StripeLiveDisabledEvent ? 'Stripe Live Disabled' : 'Stripe Live Enabled';
try {
this.#analytics.track(Object.assign(this.#trackDefaults, {}, {event: this.#prefix + eventName}));
} catch (err) {
this.#logging.error(err);
this.#exceptionHandler.captureException(err);
}
}
subscribeToEvents() {
this.#DomainEvents.subscribe(MilestoneCreatedEvent, async (event) => {
await this.#handleMilestoneCreatedEvent(event);
});
this.#DomainEvents.subscribe(StripeLiveEnabledEvent, async () => {
await this.#handleStripeEvent(StripeLiveEnabledEvent);
});
this.#DomainEvents.subscribe(StripeLiveDisabledEvent, async () => {
await this.#handleStripeEvent(StripeLiveDisabledEvent);
});
}
};

View file

@ -1,25 +0,0 @@
const Analytics = require('analytics-node');
const config = require('../../../shared/config');
const sentry = require('../../../shared/sentry');
const logging = require('@tryghost/logging');
const DomainEvents = require('@tryghost/domain-events');
const DomainEventsAnalytics = require('./DomainEventsAnalytics');
module.exports.init = function () {
const analytics = new Analytics(config.get('segment:key'));
const trackDefaults = config.get('segment:trackDefaults') || {};
const prefix = config.get('segment:prefix') || '';
const subscribeToDomainEvents = new DomainEventsAnalytics({
analytics,
trackDefaults,
prefix,
exceptionHandler: sentry,
DomainEvents,
logging
});
// Listen to domain events
subscribeToDomainEvents.subscribeToEvents();
};

View file

@ -1,270 +0,0 @@
const assert = require('assert/strict');
const sinon = require('sinon');
const ObjectId = require('bson-objectid').default;
// To test
const DomainEventsAnalytics = require('../../../../../core/server/services/segment/DomainEventsAnalytics');
// Stubbed dependencies
const DomainEvents = require('@tryghost/domain-events');
const {MilestoneCreatedEvent} = require('@tryghost/milestones');
const {StripeLiveEnabledEvent, StripeLiveDisabledEvent} = require('@tryghost/members-stripe-service').events;
describe('DomainEventsAnalytics', function () {
describe('Constructor', function () {
it('doesn\'t throw', function () {
new DomainEventsAnalytics({});
});
});
describe('Domain events analytics service', function () {
let domainEventsAnalytics;
let analyticsStub;
let exceptionHandlerStub;
let loggingStub;
let domainEventsStub;
beforeEach(function () {
analyticsStub = sinon.stub();
exceptionHandlerStub = sinon.stub();
loggingStub = sinon.stub();
domainEventsStub = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it('subscribes to events', async function () {
domainEventsAnalytics = new DomainEventsAnalytics({
analytics: analyticsStub,
trackDefaults: {
userId: '1234',
properties: {email: 'john@test.com'}
},
prefix: 'Pro: ',
exceptionHandler: {
captureException: exceptionHandlerStub
},
DomainEvents: {
subscribe: domainEventsStub
},
logging: {
error: loggingStub
}
});
domainEventsAnalytics.subscribeToEvents();
assert(domainEventsStub.callCount === 3);
assert(loggingStub.callCount === 0);
});
it('handles milestone created event for 100 members', async function () {
domainEventsAnalytics = new DomainEventsAnalytics({
analytics: {
track: analyticsStub
},
trackDefaults: {
userId: '1234',
properties: {email: 'john@test.com'}
},
prefix: 'Pro: ',
exceptionHandler: {
captureException: exceptionHandlerStub
},
DomainEvents,
logging: {
error: loggingStub
}
});
domainEventsAnalytics.subscribeToEvents();
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'members',
value: 100,
createdAt: new Date(),
emailSentAt: new Date()
}
}));
await DomainEvents.allSettled();
assert(analyticsStub.callCount === 1);
assert(analyticsStub.calledWith({
userId: '1234',
properties: {email: 'john@test.com'},
event: 'Pro: 100 Members reached'
}));
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'members',
value: 1000,
createdAt: new Date(),
emailSentAt: new Date()
}
}));
await DomainEvents.allSettled();
// Analytics should not be called again
assert(analyticsStub.callCount === 1);
assert(loggingStub.callCount === 0);
});
it('handles milestone created event for $100 ARR', async function () {
domainEventsAnalytics = new DomainEventsAnalytics({
analytics: {
track: analyticsStub
},
trackDefaults: {
userId: '9876',
properties: {email: 'john+arr@test.com'}
},
prefix: 'Pro: ',
exceptionHandler: {
captureException: exceptionHandlerStub
},
DomainEvents,
logging: {
error: loggingStub
}
});
domainEventsAnalytics.subscribeToEvents();
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'arr',
currency: 'usd',
value: 100,
createdAt: new Date(),
emailSentAt: new Date()
}
}));
await DomainEvents.allSettled();
assert(analyticsStub.callCount === 1);
assert(analyticsStub.calledWith({
userId: '9876',
properties: {email: 'john+arr@test.com'},
event: 'Pro: $100 ARR reached'
}));
assert(loggingStub.callCount === 0);
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'arr',
currency: 'usd',
value: 1000,
createdAt: new Date(),
emailSentAt: new Date()
}
}));
await DomainEvents.allSettled();
// Analytics should not be called again
assert(analyticsStub.callCount === 1);
assert(loggingStub.callCount === 0);
});
it('handles Stripe live enabled and disabled events', async function () {
domainEventsAnalytics = new DomainEventsAnalytics({
analytics: {
track: analyticsStub
},
trackDefaults: {
userId: '9876',
properties: {email: 'john+stripe@test.com'}
},
prefix: 'Pro: ',
exceptionHandler: {
captureException: exceptionHandlerStub
},
DomainEvents,
logging: {
error: loggingStub
}
});
domainEventsAnalytics.subscribeToEvents();
DomainEvents.dispatch(StripeLiveEnabledEvent.create({
message: 'Stripe live mode enabled'
}));
await DomainEvents.allSettled();
assert(analyticsStub.callCount === 1);
assert(analyticsStub.getCall(0).calledWith({
userId: '9876',
properties: {email: 'john+stripe@test.com'},
event: 'Pro: Stripe Live Enabled'
}));
assert(loggingStub.callCount === 0);
DomainEvents.dispatch(StripeLiveDisabledEvent.create({
message: 'Stripe live mode disabled'
}));
await DomainEvents.allSettled();
assert(analyticsStub.callCount === 2);
assert(analyticsStub.getCall(1).calledWith({
userId: '9876',
properties: {email: 'john+stripe@test.com'},
event: 'Pro: Stripe Live Disabled'
}));
await DomainEvents.allSettled();
assert(loggingStub.callCount === 0);
});
it('can handle tracking errors', async function () {
let error = new Error('Test error');
domainEventsAnalytics = new DomainEventsAnalytics({
analytics: {
track: analyticsStub.throws(error)
},
trackDefaults: {},
prefix: '',
exceptionHandler: {
captureException: exceptionHandlerStub
},
DomainEvents,
logging: {
error: loggingStub
}
});
domainEventsAnalytics.subscribeToEvents();
try {
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'arr',
currency: 'usd',
value: 100,
createdAt: new Date(),
emailSentAt: new Date()
}
}));
await DomainEvents.allSettled();
} catch (err) {
assert(analyticsStub.callCount === 1);
assert(exceptionHandlerStub.callCount === 1);
assert(exceptionHandlerStub.calledWith(error));
assert(loggingStub.callCount === 1);
}
});
});
});

View file

@ -1,11 +0,0 @@
const assert = require('assert/strict');
describe('Segment Analytics Service', function () {
let segmentService;
it('Provides expected public API', async function () {
segmentService = require('../../../../../core/server/services/segment');
assert.ok(segmentService.init);
});
});