Commit 2d5dc001 authored by Andrew Fontaine's avatar Andrew Fontaine Committed by Brandon Labuschagne

Add Snowplow Tracking to Environment Actions

We want to see how people are using these actions as part of getting a
better understanding on how people interact with environments as a
whole. This is in effort to later redesign the environments page.

Changelog: added
parent 6881e308
...@@ -776,23 +776,39 @@ export default { ...@@ -776,23 +776,39 @@ export default {
role="gridcell" role="gridcell"
> >
<div class="btn-group table-action-buttons" role="group"> <div class="btn-group table-action-buttons" role="group">
<pin-component v-if="canShowAutoStopDate" :auto-stop-url="autoStopUrl" /> <pin-component
v-if="canShowAutoStopDate"
:auto-stop-url="autoStopUrl"
data-track-action="click_button"
data-track-label="environment_pin"
/>
<external-url-component <external-url-component
v-if="externalURL && canReadEnvironment" v-if="externalURL && canReadEnvironment"
:external-url="externalURL" :external-url="externalURL"
data-track-action="click_button"
data-track-label="environment_url"
/> />
<monitoring-button-component <monitoring-button-component
v-if="monitoringUrl && canReadEnvironment" v-if="monitoringUrl && canReadEnvironment"
:monitoring-url="monitoringUrl" :monitoring-url="monitoringUrl"
data-track-action="click_button"
data-track-label="environment_monitoring"
/> />
<actions-component v-if="actions.length > 0" :actions="actions" /> <actions-component
v-if="actions.length > 0"
:actions="actions"
data-track-action="click_dropdown"
data-track-label="environment_actions"
/>
<terminal-button-component <terminal-button-component
v-if="model && model.terminal_path" v-if="model && model.terminal_path"
:terminal-path="model.terminal_path" :terminal-path="model.terminal_path"
data-track-action="click_button"
data-track-label="environment_terminal"
/> />
<rollback-component <rollback-component
...@@ -800,11 +816,23 @@ export default { ...@@ -800,11 +816,23 @@ export default {
:environment="model" :environment="model"
:is-last-deployment="isLastDeployment" :is-last-deployment="isLastDeployment"
:retry-url="retryUrl" :retry-url="retryUrl"
data-track-action="click_button"
data-track-label="environment_rollback"
/> />
<stop-component v-if="canStopEnvironment" :environment="model" /> <stop-component
v-if="canStopEnvironment"
:environment="model"
data-track-action="click_button"
data-track-label="environment_stop"
/>
<delete-component v-if="canDeleteEnvironment" :environment="model" /> <delete-component
v-if="canDeleteEnvironment"
:environment="model"
data-track-action="click_button"
data-track-label="environment_delete"
/>
</div> </div>
</div> </div>
</div> </div>
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { format } from 'timeago.js'; import { format } from 'timeago.js';
import { mockTracking, unmockTracking, triggerEvent } from 'helpers/tracking_helper';
import ActionsComponent from '~/environments/components/environment_actions.vue';
import DeleteComponent from '~/environments/components/environment_delete.vue'; import DeleteComponent from '~/environments/components/environment_delete.vue';
import ExternalUrlComponent from '~/environments/components/environment_external_url.vue';
import EnvironmentItem from '~/environments/components/environment_item.vue'; import EnvironmentItem from '~/environments/components/environment_item.vue';
import PinComponent from '~/environments/components/environment_pin.vue'; import PinComponent from '~/environments/components/environment_pin.vue';
import RollbackComponent from '~/environments/components/environment_rollback.vue';
import StopComponent from '~/environments/components/environment_stop.vue';
import TerminalButtonComponent from '~/environments/components/environment_terminal_button.vue';
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility'; import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
import { environment, folder, tableData } from './mock_data'; import { environment, folder, tableData } from './mock_data';
describe('Environment item', () => { describe('Environment item', () => {
let wrapper; let wrapper;
let tracking;
const factory = (options = {}) => { const factory = (options = {}) => {
// This destroys any wrappers created before a nested call to factory reassigns it // This destroys any wrappers created before a nested call to factory reassigns it
...@@ -28,6 +35,12 @@ describe('Environment item', () => { ...@@ -28,6 +35,12 @@ describe('Environment item', () => {
tableData, tableData,
}, },
}); });
tracking = mockTracking(undefined, wrapper.element, jest.spyOn);
});
afterEach(() => {
unmockTracking();
}); });
const findAutoStop = () => wrapper.find('.js-auto-stop'); const findAutoStop = () => wrapper.find('.js-auto-stop');
...@@ -62,7 +75,7 @@ describe('Environment item', () => { ...@@ -62,7 +75,7 @@ describe('Environment item', () => {
}); });
it('should not render the delete button', () => { it('should not render the delete button', () => {
expect(wrapper.find(DeleteComponent).exists()).toBe(false); expect(wrapper.findComponent(DeleteComponent).exists()).toBe(false);
}); });
describe('With user information', () => { describe('With user information', () => {
...@@ -176,12 +189,14 @@ describe('Environment item', () => { ...@@ -176,12 +189,14 @@ describe('Environment item', () => {
}); });
it('should not render the auto-stop button', () => { it('should not render the auto-stop button', () => {
expect(wrapper.find(PinComponent).exists()).toBe(false); expect(wrapper.findComponent(PinComponent).exists()).toBe(false);
}); });
}); });
describe('With auto-stop date', () => { describe('With auto-stop date', () => {
describe('in the future', () => { describe('in the future', () => {
let pin;
const futureDate = new Date(Date.now() + 100000); const futureDate = new Date(Date.now() + 100000);
beforeEach(() => { beforeEach(() => {
factory({ factory({
...@@ -195,6 +210,9 @@ describe('Environment item', () => { ...@@ -195,6 +210,9 @@ describe('Environment item', () => {
shouldShowAutoStopDate: true, shouldShowAutoStopDate: true,
}, },
}); });
tracking = mockTracking(undefined, wrapper.element, jest.spyOn);
pin = wrapper.findComponent(PinComponent);
}); });
it('renders the date', () => { it('renders the date', () => {
...@@ -202,7 +220,15 @@ describe('Environment item', () => { ...@@ -202,7 +220,15 @@ describe('Environment item', () => {
}); });
it('should render the auto-stop button', () => { it('should render the auto-stop button', () => {
expect(wrapper.find(PinComponent).exists()).toBe(true); expect(pin.exists()).toBe(true);
});
it('should tracks clicks', () => {
pin.trigger('click');
expect(tracking).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'environment_pin',
});
}); });
}); });
...@@ -227,33 +253,104 @@ describe('Environment item', () => { ...@@ -227,33 +253,104 @@ describe('Environment item', () => {
}); });
it('should not render the suto-stop button', () => { it('should not render the suto-stop button', () => {
expect(wrapper.find(PinComponent).exists()).toBe(false); expect(wrapper.findComponent(PinComponent).exists()).toBe(false);
}); });
}); });
}); });
}); });
describe('With manual actions', () => { describe('With manual actions', () => {
let actions;
beforeEach(() => {
actions = wrapper.findComponent(ActionsComponent);
});
it('should render actions component', () => { it('should render actions component', () => {
expect(wrapper.find('.js-manual-actions-container')).toBeDefined(); expect(actions.exists()).toBe(true);
});
it('should track clicks', () => {
actions.trigger('click');
expect(tracking).toHaveBeenCalledWith('_category_', 'click_dropdown', {
label: 'environment_actions',
});
}); });
}); });
describe('With external URL', () => { describe('With external URL', () => {
let externalUrl;
beforeEach(() => {
externalUrl = wrapper.findComponent(ExternalUrlComponent);
});
it('should render external url component', () => { it('should render external url component', () => {
expect(wrapper.find('.js-external-url-container')).toBeDefined(); expect(externalUrl.exists()).toBe(true);
});
it('should track clicks', () => {
externalUrl.trigger('click');
expect(tracking).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'environment_url',
});
}); });
}); });
describe('With stop action', () => { describe('With stop action', () => {
let stop;
beforeEach(() => {
stop = wrapper.findComponent(StopComponent);
});
it('should render stop action component', () => { it('should render stop action component', () => {
expect(wrapper.find('.js-stop-component-container')).toBeDefined(); expect(stop.exists()).toBe(true);
});
it('should track clicks', () => {
stop.trigger('click');
expect(tracking).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'environment_stop',
});
}); });
}); });
describe('With retry action', () => { describe('With retry action', () => {
let rollback;
beforeEach(() => {
rollback = wrapper.findComponent(RollbackComponent);
});
it('should render rollback component', () => { it('should render rollback component', () => {
expect(wrapper.find('.js-rollback-component-container')).toBeDefined(); expect(rollback.exists()).toBe(true);
});
it('should track clicks', () => {
rollback.trigger('click');
expect(tracking).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'environment_rollback',
});
});
});
describe('With terminal path', () => {
let terminal;
beforeEach(() => {
terminal = wrapper.findComponent(TerminalButtonComponent);
});
it('should render terminal action component', () => {
expect(terminal.exists()).toBe(true);
});
it('should track clicks', () => {
triggerEvent(terminal.element);
expect(tracking).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'environment_terminal',
});
}); });
}); });
}); });
...@@ -312,7 +409,17 @@ describe('Environment item', () => { ...@@ -312,7 +409,17 @@ describe('Environment item', () => {
}); });
it('should render the delete button', () => { it('should render the delete button', () => {
expect(wrapper.find(DeleteComponent).exists()).toBe(true); expect(wrapper.findComponent(DeleteComponent).exists()).toBe(true);
});
it('should trigger a tracking event', async () => {
tracking = mockTracking(undefined, wrapper.element, jest.spyOn);
await wrapper.findComponent(DeleteComponent).trigger('click');
expect(tracking).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'environment_delete',
});
}); });
}); });
}); });
...@@ -71,6 +71,8 @@ const environment = { ...@@ -71,6 +71,8 @@ const environment = {
state: 'stopped', state: 'stopped',
external_url: 'http://external.com', external_url: 'http://external.com',
environment_type: null, environment_type: null,
can_stop: true,
terminal_path: '/terminal',
last_deployment: { last_deployment: {
id: 66, id: 66,
iid: 6, iid: 6,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment