Simplify Analytics API from analytics module POV

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-08-13 16:44:15 +02:00
parent edd5293d68
commit dffa1892cd
9 changed files with 100 additions and 86 deletions
@@ -38,7 +38,7 @@ describe('GoogleAnalytics', () => {
it('returns implementation', () => {
const api = GoogleAnalytics.fromConfig(basicValidConfig);
expect(api.getDecoratedTracker).toBeDefined();
expect(api.captureEvent).toBeDefined();
// Initializes GA with tracking ID.
expect(ReactGA.testModeAPI.calls[0]).toEqual([
@@ -94,8 +94,11 @@ describe('GoogleAnalytics', () => {
it('tracks basic pageview', () => {
const api = GoogleAnalytics.fromConfig(basicValidConfig);
const tracker = api.getDecoratedTracker({ domain });
tracker.captureEvent('navigate', '/');
api.captureEvent({
verb: 'navigate',
noun: '/',
domain,
});
const [command, data] = ReactGA.testModeAPI.calls[1];
expect(command).toBe('send');
@@ -107,12 +110,16 @@ describe('GoogleAnalytics', () => {
it('tracks basic event', () => {
const api = GoogleAnalytics.fromConfig(basicValidConfig);
const tracker = api.getDecoratedTracker({ domain });
const expectedAction = 'click';
const expectedLabel = 'on something';
const expectedValue = 42;
tracker.captureEvent(expectedAction, expectedLabel, expectedValue);
api.captureEvent({
verb: expectedAction,
noun: expectedLabel,
value: expectedValue,
domain,
});
const [command, data] = ReactGA.testModeAPI.calls[1];
expect(command).toBe('send');
@@ -127,8 +134,11 @@ describe('GoogleAnalytics', () => {
it('captures configured custom dimensions/metrics on pageviews', () => {
const api = GoogleAnalytics.fromConfig(advancedConfig);
const tracker = api.getDecoratedTracker({ domain });
tracker.captureEvent('navigate', '/a-page');
api.captureEvent({
verb: 'navigate',
noun: '/a-page',
domain,
});
// Expect a set command first.
const [setCommand, setData] = ReactGA.testModeAPI.calls[1];
@@ -149,14 +159,19 @@ describe('GoogleAnalytics', () => {
it('captures configured custom dimensions/metrics on events', () => {
const api = GoogleAnalytics.fromConfig(advancedConfig);
const tracker = api.getDecoratedTracker({ domain });
const expectedAction = 'search';
const expectedLabel = 'some query';
const expectedValue = 5;
tracker.captureEvent(expectedAction, expectedLabel, expectedValue, {
extraDimension: false,
extraMetric: 0,
api.captureEvent({
verb: expectedAction,
noun: expectedLabel,
value: expectedValue,
context: {
extraDimension: false,
extraMetric: 0,
},
domain,
});
const [command, data] = ReactGA.testModeAPI.calls[1];
@@ -176,10 +191,14 @@ describe('GoogleAnalytics', () => {
it('does not pass non-numeric data on metrics', () => {
const api = GoogleAnalytics.fromConfig(advancedConfig);
const tracker = api.getDecoratedTracker({ domain });
tracker.captureEvent('verb', 'noun', undefined, {
extraMetric: 'not a number',
api.captureEvent({
verb: 'verb',
noun: 'noun',
context: {
extraMetric: 'not a number',
},
domain,
});
const [, data] = ReactGA.testModeAPI.calls[1];
@@ -17,9 +17,9 @@
import ReactGA from 'react-ga';
import {
AnalyticsApi,
AnalyticsTracker,
AnalyticsDomainValue,
AnalyticsEventContext,
DomainDecoratedAnalyticsEvent,
} from '@backstage/core-plugin-api';
import { Config } from '@backstage/config';
@@ -92,31 +92,18 @@ export class GoogleAnalytics implements AnalyticsApi {
});
}
/**
* Returns the Google Analytics tracker to API consumers.
*/
getDecoratedTracker({
domain,
}: {
domain: AnalyticsDomainValue;
}): AnalyticsTracker {
return {
captureEvent: (...args) => this.captureEvent(domain, ...args),
};
}
/**
* Primary event capture implementation. Handles core navigate event as a
* pageview and the rest as custom events. All custom dimensions/metrics are
* applied as they should be (set on pageview, merged object on events).
*/
private captureEvent(
domain: AnalyticsDomainValue,
verb: string,
noun: string,
value?: number,
context?: AnalyticsEventContext,
) {
captureEvent({
domain,
verb,
noun,
value,
context,
}: DomainDecoratedAnalyticsEvent) {
const customMetadata = this.getCustomDimensionMetrics(domain, context);
if (verb === 'navigate' && domain?.componentName === 'App') {