gethue
Version:
Hue is an Open source SQL Query Editor for Databases/Warehouses
210 lines (171 loc) • 6.6 kB
text/typescript
import * as ApiUtils from '../api/utils';
import * as HueConfig from '../config/hueConfig';
// Since the our hueAnalytics is globally mocked in jest.init.js
// we need to use requireActual when testing the actual hueAnalytics module
const hueAnalyticsModule = jest.requireActual('./hueAnalytics');
const { hueAnalytics, setupGlobalListenersForAnalytics } = hueAnalyticsModule;
describe('hueAnalytics', () => {
let windowSpy;
const postSpy = jest.spyOn(ApiUtils, 'post').mockImplementation();
const getLastKnownConfigMock = jest.spyOn(HueConfig, 'getLastKnownConfig');
beforeEach(() => {
windowSpy = jest.spyOn(window, 'window', 'get');
});
afterEach(() => {
windowSpy.mockRestore();
postSpy.mockReset();
getLastKnownConfigMock.mockReset();
});
it('should log to console if dev mode, collect_usage and hueDebugAnalytics are true', () => {
const consoleSpy = jest.spyOn(console, 'info').mockImplementation();
getLastKnownConfigMock.mockImplementation(() => {
return { hue_config: { collect_usage: true } };
});
windowSpy.mockImplementation(() => ({
DEV: true,
hueDebugAnalytics: true
}));
hueAnalytics.log('area1', 'action1');
expect(consoleSpy).toHaveBeenCalledWith(
'Analytics debug:',
'event',
'area1',
expect.objectContaining({
action: 'action1'
})
);
});
it('should always log to backend if prioritised', () => {
const isPrio = true;
windowSpy.mockImplementation(() => ({}));
hueAnalytics.log('area1', 'action1', isPrio);
expect(postSpy).toHaveBeenCalledWith('/desktop/log_analytics', {
action: 'action1',
area: 'area1'
});
});
it('should log to google analytics if COLLECT_USAGE is true but not in dev mode', () => {
const gtagSpy = jest.fn();
getLastKnownConfigMock.mockImplementation(() => {
return { hue_config: { collect_usage: true } };
});
windowSpy.mockImplementation(() => ({
DEV: false,
gtag: gtagSpy
}));
hueAnalytics.log('area1', 'action1');
expect(gtagSpy).toHaveBeenCalledWith(
'event',
'area1',
expect.objectContaining({
action: 'action1'
})
);
});
it('should always log to backend when convert is used', () => {
windowSpy.mockImplementation(() => ({}));
hueAnalytics.convert('area1', 'action1');
expect(postSpy).toHaveBeenCalledWith('/desktop/log_analytics', {
action: 'action1',
area: 'area1'
});
});
it('should not log to backend or GA with incorrect parameters', () => {
const gtagSpy = jest.fn();
getLastKnownConfigMock.mockImplementation(() => {
return { hue_config: { collect_usage: true } };
});
windowSpy.mockImplementation(() => ({
DEV: false,
gtag: gtagSpy
}));
windowSpy.mockImplementation(() => ({}));
hueAnalytics.convert(null, 'action1');
hueAnalytics.convert(undefined, 'action1');
hueAnalytics.convert([], 'action1');
hueAnalytics.convert({}, 'action1');
hueAnalytics.convert(NaN, 'action1');
hueAnalytics.convert(1, 'action1');
hueAnalytics.convert(true, 'action1');
hueAnalytics.convert(new Date(), 'action1');
hueAnalytics.convert(BigInt(1), 'action1');
hueAnalytics.convert(Symbol(), 'action1');
hueAnalytics.convert('area1', null);
hueAnalytics.convert('area1', undefined);
hueAnalytics.convert('area1', []);
hueAnalytics.convert('area1', {});
hueAnalytics.convert('area1', NaN);
hueAnalytics.convert('area1', 1);
hueAnalytics.convert('area1', true);
hueAnalytics.convert('area1', new Date());
hueAnalytics.convert('area1', BigInt(1));
hueAnalytics.convert('area1', Symbol());
hueAnalytics.log(null, 'action1');
hueAnalytics.log(undefined, 'action1');
hueAnalytics.log([], 'action1');
hueAnalytics.log({}, 'action1');
hueAnalytics.log(NaN, 'action1');
hueAnalytics.log(1, 'action1');
hueAnalytics.log(true, 'action1');
hueAnalytics.log(new Date(), 'action1');
hueAnalytics.log(BigInt(1), 'action1');
hueAnalytics.log(Symbol(), 'action1');
hueAnalytics.log('area1', null);
hueAnalytics.log('area1', undefined);
hueAnalytics.log('area1', []);
hueAnalytics.log('area1', {});
hueAnalytics.log('area1', NaN);
hueAnalytics.log('area1', 1);
hueAnalytics.log('area1', true);
hueAnalytics.log('area1', new Date());
hueAnalytics.log('area1', BigInt(1));
hueAnalytics.log('area1', Symbol());
expect(gtagSpy).not.toHaveBeenCalled();
expect(postSpy).not.toHaveBeenCalled();
});
it('should use global listener to log clicks on element with attribute "data-hue-analytics"', () => {
const gtagSpy = jest.fn();
getLastKnownConfigMock.mockImplementation(() => {
return { hue_config: { collect_usage: true } };
});
windowSpy.mockImplementation(() => ({
DEV: false,
gtag: gtagSpy
}));
let globallyAddedEventListener!: EventListener;
jest.spyOn(document, 'addEventListener').mockImplementationOnce((eventType, listenerToTest) => {
globallyAddedEventListener = listenerToTest as EventListener;
});
setupGlobalListenersForAnalytics();
const button = document.createElement('button');
button.dataset.hueAnalytics = 'test-area:testbutton click';
const myEvent = new Event('click');
Object.defineProperty(myEvent, 'target', { writable: false, value: button });
globallyAddedEventListener(myEvent);
expect(gtagSpy).toHaveBeenCalledWith(
'event',
'test-area',
expect.objectContaining({
action: 'testbutton click'
})
);
});
it('should use global listener and backend API to log clicks on element with attribute "data-hue-analytics-prio"', () => {
windowSpy.mockImplementation(() => ({}));
let globallyAddedEventListener!: EventListener;
jest.spyOn(document, 'addEventListener').mockImplementationOnce((eventType, listenerToTest) => {
globallyAddedEventListener = listenerToTest as EventListener;
});
setupGlobalListenersForAnalytics();
const button = document.createElement('button');
button.dataset.hueAnalytics = 'test-area:testbutton click';
button.dataset.hueAnalyticsPrio = 'true';
const myEvent = new Event('click');
Object.defineProperty(myEvent, 'target', { writable: false, value: button });
globallyAddedEventListener(myEvent);
expect(postSpy).toHaveBeenCalledWith('/desktop/log_analytics', {
action: 'testbutton click',
area: 'test-area'
});
});
});