quickTrace.spec.jsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. import moment from 'moment';
  2. import {mountWithTheme} from 'sentry-test/enzyme';
  3. import {trackAnalyticsEvent} from 'sentry/utils/analytics';
  4. import ConfigureDistributedTracing from 'sentry/views/organizationGroupDetails/quickTrace/configureDistributedTracing';
  5. jest.mock('sentry/utils/analytics');
  6. describe('ConfigureDistributedTracing', function () {
  7. let putMock;
  8. const organization = TestStubs.Organization({features: ['performance-view']});
  9. const project = TestStubs.Project({platform: 'javascript'});
  10. const event = TestStubs.Event({
  11. id: '2',
  12. eventID: '21098765432109876543210987654321',
  13. });
  14. beforeEach(function () {
  15. jest.clearAllMocks();
  16. MockApiClient.clearMockResponses();
  17. MockApiClient.addMockResponse({
  18. method: 'GET',
  19. url: '/prompts-activity/',
  20. body: {},
  21. });
  22. putMock = MockApiClient.addMockResponse({
  23. method: 'PUT',
  24. url: '/prompts-activity/',
  25. });
  26. });
  27. it('renders basic UI', async function () {
  28. const wrapper = mountWithTheme(
  29. <ConfigureDistributedTracing
  30. event={event}
  31. organization={organization}
  32. project={project}
  33. />
  34. );
  35. await tick();
  36. wrapper.update();
  37. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(true);
  38. expect(wrapper.find('Hovercard').exists()).toBe(true);
  39. });
  40. it('renders hover card when feature is disabled', async function () {
  41. const newOrganization = TestStubs.Organization();
  42. const wrapper = mountWithTheme(
  43. <ConfigureDistributedTracing
  44. event={event}
  45. organization={newOrganization}
  46. project={project}
  47. />
  48. );
  49. await tick();
  50. wrapper.update();
  51. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(true);
  52. expect(wrapper.find('Hovercard').exists()).toBe(true);
  53. });
  54. /**
  55. * Want to alternate between showing the configure suspect commits prompt and
  56. * the show configure distributed tracing prompt.
  57. */
  58. it('doesnt render when event id starts with odd char', async function () {
  59. const newEvent = TestStubs.Event({
  60. id: 'B',
  61. eventID: 'BAFEDCBAFEDCBAFEDCBAFEDCBAFEDCBA',
  62. });
  63. const wrapper = mountWithTheme(
  64. <ConfigureDistributedTracing
  65. event={newEvent}
  66. organization={organization}
  67. project={project}
  68. />
  69. );
  70. await tick();
  71. wrapper.update();
  72. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(false);
  73. });
  74. it('doesnt render when the project platform doesnt support tracing', async function () {
  75. const newProject = TestStubs.Project({platform: ''});
  76. const wrapper = mountWithTheme(
  77. <ConfigureDistributedTracing
  78. event={event}
  79. organization={organization}
  80. project={newProject}
  81. />
  82. );
  83. await tick();
  84. wrapper.update();
  85. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(false);
  86. });
  87. it('can be snoozed', async function () {
  88. const wrapper = mountWithTheme(
  89. <ConfigureDistributedTracing
  90. event={event}
  91. organization={organization}
  92. project={project}
  93. />
  94. );
  95. await tick();
  96. wrapper.update();
  97. wrapper.find('button[aria-label="Snooze"]').first().simulate('click');
  98. await tick();
  99. wrapper.update();
  100. expect(putMock).toHaveBeenCalledWith(
  101. '/prompts-activity/',
  102. expect.objectContaining({
  103. method: 'PUT',
  104. data: {
  105. organization_id: organization.id,
  106. project_id: project.id,
  107. feature: 'distributed_tracing',
  108. status: 'snoozed',
  109. },
  110. })
  111. );
  112. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(false);
  113. expect(trackAnalyticsEvent).toHaveBeenCalledWith({
  114. eventKey: 'quick_trace.missing_instrumentation.snoozed',
  115. eventName: 'Quick Trace: Missing Instrumentation Snoozed',
  116. organization_id: parseInt(organization.id, 10),
  117. project_id: parseInt(project.id, 10),
  118. platform: project.platform,
  119. });
  120. });
  121. it('does not render when snoozed', async function () {
  122. const snoozed_ts = moment().subtract(1, 'day').unix();
  123. MockApiClient.addMockResponse({
  124. method: 'GET',
  125. url: '/prompts-activity/',
  126. body: {data: {snoozed_ts}},
  127. });
  128. const wrapper = mountWithTheme(
  129. <ConfigureDistributedTracing
  130. event={event}
  131. organization={organization}
  132. project={project}
  133. />
  134. );
  135. await tick();
  136. wrapper.update();
  137. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(false);
  138. });
  139. it('can be dismissed', async function () {
  140. const wrapper = mountWithTheme(
  141. <ConfigureDistributedTracing
  142. event={event}
  143. organization={organization}
  144. project={project}
  145. />
  146. );
  147. await tick();
  148. wrapper.update();
  149. wrapper.find('button[aria-label="Dismiss"]').first().simulate('click');
  150. await tick();
  151. wrapper.update();
  152. expect(putMock).toHaveBeenCalledWith(
  153. '/prompts-activity/',
  154. expect.objectContaining({
  155. method: 'PUT',
  156. data: {
  157. organization_id: organization.id,
  158. project_id: project.id,
  159. feature: 'distributed_tracing',
  160. status: 'dismissed',
  161. },
  162. })
  163. );
  164. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(false);
  165. expect(trackAnalyticsEvent).toHaveBeenCalledWith({
  166. eventKey: 'quick_trace.missing_instrumentation.dismissed',
  167. eventName: 'Quick Trace: Missing Instrumentation Dismissed',
  168. organization_id: parseInt(organization.id, 10),
  169. project_id: parseInt(project.id, 10),
  170. platform: project.platform,
  171. });
  172. });
  173. it('does not render when dismissed', async function () {
  174. MockApiClient.addMockResponse({
  175. method: 'GET',
  176. url: '/prompts-activity/',
  177. body: {data: {dismissed_ts: moment().unix()}},
  178. });
  179. const wrapper = mountWithTheme(
  180. <ConfigureDistributedTracing
  181. event={event}
  182. organization={organization}
  183. project={project}
  184. />
  185. );
  186. await tick();
  187. wrapper.update();
  188. expect(wrapper.find('ExampleQuickTracePanel').exists()).toBe(false);
  189. });
  190. it('can capture analytics on docs click', async function () {
  191. const wrapper = mountWithTheme(
  192. <ConfigureDistributedTracing
  193. event={event}
  194. organization={organization}
  195. project={project}
  196. />
  197. );
  198. await tick();
  199. wrapper.update();
  200. wrapper.find('[aria-label="Read the docs"]').first().simulate('click');
  201. expect(trackAnalyticsEvent).toHaveBeenCalledWith({
  202. eventKey: 'quick_trace.missing_instrumentation.docs',
  203. eventName: 'Quick Trace: Missing Instrumentation Docs',
  204. organization_id: parseInt(organization.id, 10),
  205. project_id: parseInt(project.id, 10),
  206. platform: project.platform,
  207. });
  208. });
  209. });