From 85c13af84f6b925331175140adf79f7b984e37e3 Mon Sep 17 00:00:00 2001 From: maheskett Date: Thu, 18 Jul 2019 15:36:14 -0700 Subject: [PATCH 1/4] Add analytics --- .../app/components/events/eventCauseEmpty.jsx | 49 ++++++++++++++++-- .../events/eventCauseEmpty.spec.jsx | 51 ++++++++++++++++++- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx index 8a8c39e14253db..c1eb508e386a4f 100644 --- a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx +++ b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx @@ -13,6 +13,7 @@ import SentryTypes from 'app/sentryTypes'; import {snoozedDays} from 'app/utils/promptsActivity'; import space from 'app/styles/space'; import {t} from 'app/locale'; +import {trackAdhocEvent, trackAnalyticsEvent} from 'app/utils/analytics'; import Tooltip from 'app/components/tooltip'; import withApi from 'app/utils/withApi'; @@ -45,7 +46,17 @@ class EventCauseEmpty extends React.Component { }; componentDidMount() { + const {project, organization} = this.props; + this.fetchData(); + + // send to reload only due to high event volume + trackAdhocEvent({ + eventKey: 'feature.event_cause.viewed', + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); } async fetchData() { @@ -72,7 +83,7 @@ class EventCauseEmpty extends React.Component { return true; } - handleClick(action) { + handleClick({action, eventKey, eventName}) { const {api, project, organization} = this.props; const data = { @@ -82,6 +93,19 @@ class EventCauseEmpty extends React.Component { status: action, }; promptsUpdate(api, data).then(this.setState({shouldShow: false})); + this.trackAnalytics({eventKey, eventName}); + } + + trackAnalytics({eventKey, eventName}) { + const {project, organization} = this.props; + + trackAnalyticsEvent({ + eventKey, + eventName, + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); } render() { @@ -103,6 +127,13 @@ class EventCauseEmpty extends React.Component { size="small" priority="primary" href="https://docs.sentry.io/workflow/releases/#create-release" + onClick={() => + this.trackAnalytics({ + eventKey: 'feature.event_cause.docs_clicked', + eventName: 'Event Cause Docs Clicked', + }) + } + data-test-id="read-the-docs" > {t('Read the docs')} @@ -111,7 +142,13 @@ class EventCauseEmpty extends React.Component { this.handleClick('snoozed')} + onClick={() => + this.handleClick({ + action: 'snoozed', + eventKey: 'feature.event_cause.snoozed', + eventName: 'Event Cause Snoozed', + }) + } data-test-id="snoozed" > {t('Snooze')} @@ -119,7 +156,13 @@ class EventCauseEmpty extends React.Component { this.handleClick('dismissed')} + onClick={() => + this.handleClick({ + action: 'dismissed', + eventKey: 'feature.event_cause.dismissed', + eventName: 'Event Cause Dismissed', + }) + } data-test-id="dismissed" > {t('Dismiss')} diff --git a/tests/js/spec/components/events/eventCauseEmpty.spec.jsx b/tests/js/spec/components/events/eventCauseEmpty.spec.jsx index 90e9ddd0465e90..f3fbc2b3545ff1 100644 --- a/tests/js/spec/components/events/eventCauseEmpty.spec.jsx +++ b/tests/js/spec/components/events/eventCauseEmpty.spec.jsx @@ -3,12 +3,15 @@ import moment from 'moment'; import {mount} from 'enzyme'; import EventCauseEmpty from 'app/components/events/eventCauseEmpty'; +import {trackAdhocEvent, trackAnalyticsEvent} from 'app/utils/analytics'; + +jest.mock('app/utils/analytics'); describe('EventCauseEmpty', function() { let putMock; const routerContext = TestStubs.routerContext(); const organization = TestStubs.Organization(); - const project = TestStubs.Project(); + const project = TestStubs.Project({platform: 'javascript'}); beforeEach(function() { MockApiClient.clearMockResponses(); @@ -38,6 +41,13 @@ describe('EventCauseEmpty', function() { wrapper.update(); expect(wrapper.find('CommitRow').exists()).toBe(true); + + expect(trackAdhocEvent).toHaveBeenCalledWith({ + eventKey: 'feature.event_cause.viewed', + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); }); it('can be snoozed', async function() { @@ -68,6 +78,14 @@ describe('EventCauseEmpty', function() { ); expect(wrapper.find('CommitRow').exists()).toBe(false); + + expect(trackAnalyticsEvent).toHaveBeenCalledWith({ + eventKey: 'feature.event_cause.snoozed', + eventName: 'Event Cause Snoozed', + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); }); it('does not render when snoozed', async function() { @@ -142,6 +160,14 @@ describe('EventCauseEmpty', function() { ); expect(wrapper.find('CommitRow').exists()).toBe(false); + + expect(trackAnalyticsEvent).toHaveBeenCalledWith({ + eventKey: 'feature.event_cause.dismissed', + eventName: 'Event Cause Dismissed', + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); }); it('does not render when dismissed', async function() { @@ -161,4 +187,27 @@ describe('EventCauseEmpty', function() { expect(wrapper.find('CommitRow').exists()).toBe(false); }); + + it('can capture analytics on docs click', async function() { + const wrapper = mount( + , + routerContext + ); + + await tick(); + wrapper.update(); + + wrapper + .find('[data-test-id="read-the-docs"]') + .first() + .simulate('click'); + + expect(trackAnalyticsEvent).toHaveBeenCalledWith({ + eventKey: 'feature.event_cause.docs_clicked', + eventName: 'Event Cause Docs Clicked', + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); + }); }); From 49269d7e552f7ec43fc32cb110b7847ae8334fdf Mon Sep 17 00:00:00 2001 From: maheskett Date: Thu, 18 Jul 2019 16:56:28 -0700 Subject: [PATCH 2/4] Only log when renders --- .../app/components/events/eventCauseEmpty.jsx | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx index c1eb508e386a4f..2a0019507c7c31 100644 --- a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx +++ b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx @@ -46,17 +46,22 @@ class EventCauseEmpty extends React.Component { }; componentDidMount() { - const {project, organization} = this.props; - this.fetchData(); + } - // send to reload only due to high event volume - trackAdhocEvent({ - eventKey: 'feature.event_cause.viewed', - org_id: parseInt(organization.id, 10), - project_id: parseInt(project.id, 10), - platform: project.platform, - }); + componentDidUpdate(prevProps, prevState) { + const {project, organization} = this.props; + const {shouldShow} = this.state; + + if (!prevState.shouldShow && shouldShow) { + // send to reload only due to high event volume + trackAdhocEvent({ + eventKey: 'feature.event_cause.viewed', + org_id: parseInt(organization.id, 10), + project_id: parseInt(project.id, 10), + platform: project.platform, + }); + } } async fetchData() { From 7fa5686693c018bca620048e7a46253fe8cc46f3 Mon Sep 17 00:00:00 2001 From: maheskett Date: Fri, 19 Jul 2019 13:24:00 -0700 Subject: [PATCH 3/4] Remove feature prefix --- .../sentry/app/components/events/eventCauseEmpty.jsx | 10 +++++----- .../js/spec/components/events/eventCauseEmpty.spec.jsx | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx index 2a0019507c7c31..319a78033971df 100644 --- a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx +++ b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx @@ -49,14 +49,14 @@ class EventCauseEmpty extends React.Component { this.fetchData(); } - componentDidUpdate(prevProps, prevState) { + componentDidUpdate(_prevProps, prevState) { const {project, organization} = this.props; const {shouldShow} = this.state; if (!prevState.shouldShow && shouldShow) { // send to reload only due to high event volume trackAdhocEvent({ - eventKey: 'feature.event_cause.viewed', + eventKey: 'event_cause.viewed', org_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), platform: project.platform, @@ -134,7 +134,7 @@ class EventCauseEmpty extends React.Component { href="https://docs.sentry.io/workflow/releases/#create-release" onClick={() => this.trackAnalytics({ - eventKey: 'feature.event_cause.docs_clicked', + eventKey: 'event_cause.docs_clicked', eventName: 'Event Cause Docs Clicked', }) } @@ -150,7 +150,7 @@ class EventCauseEmpty extends React.Component { onClick={() => this.handleClick({ action: 'snoozed', - eventKey: 'feature.event_cause.snoozed', + eventKey: 'event_cause.snoozed', eventName: 'Event Cause Snoozed', }) } @@ -164,7 +164,7 @@ class EventCauseEmpty extends React.Component { onClick={() => this.handleClick({ action: 'dismissed', - eventKey: 'feature.event_cause.dismissed', + eventKey: 'event_cause.dismissed', eventName: 'Event Cause Dismissed', }) } diff --git a/tests/js/spec/components/events/eventCauseEmpty.spec.jsx b/tests/js/spec/components/events/eventCauseEmpty.spec.jsx index f3fbc2b3545ff1..b95841466b6ef7 100644 --- a/tests/js/spec/components/events/eventCauseEmpty.spec.jsx +++ b/tests/js/spec/components/events/eventCauseEmpty.spec.jsx @@ -43,7 +43,7 @@ describe('EventCauseEmpty', function() { expect(wrapper.find('CommitRow').exists()).toBe(true); expect(trackAdhocEvent).toHaveBeenCalledWith({ - eventKey: 'feature.event_cause.viewed', + eventKey: 'event_cause.viewed', org_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), platform: project.platform, @@ -80,7 +80,7 @@ describe('EventCauseEmpty', function() { expect(wrapper.find('CommitRow').exists()).toBe(false); expect(trackAnalyticsEvent).toHaveBeenCalledWith({ - eventKey: 'feature.event_cause.snoozed', + eventKey: 'event_cause.snoozed', eventName: 'Event Cause Snoozed', org_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), @@ -162,7 +162,7 @@ describe('EventCauseEmpty', function() { expect(wrapper.find('CommitRow').exists()).toBe(false); expect(trackAnalyticsEvent).toHaveBeenCalledWith({ - eventKey: 'feature.event_cause.dismissed', + eventKey: 'event_cause.dismissed', eventName: 'Event Cause Dismissed', org_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), @@ -203,7 +203,7 @@ describe('EventCauseEmpty', function() { .simulate('click'); expect(trackAnalyticsEvent).toHaveBeenCalledWith({ - eventKey: 'feature.event_cause.docs_clicked', + eventKey: 'event_cause.docs_clicked', eventName: 'Event Cause Docs Clicked', org_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), From f171a381987c1ae766a8e33c798192a5f04167b4 Mon Sep 17 00:00:00 2001 From: maheskett Date: Fri, 19 Jul 2019 14:15:33 -0700 Subject: [PATCH 4/4] Use organization_id for trackAnalyticsEvent --- .../static/sentry/app/components/events/eventCauseEmpty.jsx | 2 +- tests/js/spec/components/events/eventCauseEmpty.spec.jsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx index 319a78033971df..584acbafb7e8f7 100644 --- a/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx +++ b/src/sentry/static/sentry/app/components/events/eventCauseEmpty.jsx @@ -107,7 +107,7 @@ class EventCauseEmpty extends React.Component { trackAnalyticsEvent({ eventKey, eventName, - org_id: parseInt(organization.id, 10), + organization_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), platform: project.platform, }); diff --git a/tests/js/spec/components/events/eventCauseEmpty.spec.jsx b/tests/js/spec/components/events/eventCauseEmpty.spec.jsx index b95841466b6ef7..b8927913aaa3da 100644 --- a/tests/js/spec/components/events/eventCauseEmpty.spec.jsx +++ b/tests/js/spec/components/events/eventCauseEmpty.spec.jsx @@ -82,7 +82,7 @@ describe('EventCauseEmpty', function() { expect(trackAnalyticsEvent).toHaveBeenCalledWith({ eventKey: 'event_cause.snoozed', eventName: 'Event Cause Snoozed', - org_id: parseInt(organization.id, 10), + organization_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), platform: project.platform, }); @@ -164,7 +164,7 @@ describe('EventCauseEmpty', function() { expect(trackAnalyticsEvent).toHaveBeenCalledWith({ eventKey: 'event_cause.dismissed', eventName: 'Event Cause Dismissed', - org_id: parseInt(organization.id, 10), + organization_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), platform: project.platform, }); @@ -205,7 +205,7 @@ describe('EventCauseEmpty', function() { expect(trackAnalyticsEvent).toHaveBeenCalledWith({ eventKey: 'event_cause.docs_clicked', eventName: 'Event Cause Docs Clicked', - org_id: parseInt(organization.id, 10), + organization_id: parseInt(organization.id, 10), project_id: parseInt(project.id, 10), platform: project.platform, });