traceTimeline.spec.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import {EventFixture} from 'sentry-fixture/event';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {ProjectFixture} from 'sentry-fixture/project';
  4. import {UserFixture} from 'sentry-fixture/user';
  5. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  6. import ConfigStore from 'sentry/stores/configStore';
  7. import ProjectsStore from 'sentry/stores/projectsStore';
  8. import {TraceTimeline} from './traceTimeline';
  9. import type {TraceEventResponse} from './useTraceTimelineEvents';
  10. describe('TraceTimeline', () => {
  11. const organization = OrganizationFixture({features: ['issues-trace-timeline']});
  12. const event = EventFixture({
  13. contexts: {
  14. trace: {
  15. trace_id: '123',
  16. },
  17. },
  18. });
  19. const project = ProjectFixture();
  20. const issuePlatformBody: TraceEventResponse = {
  21. data: [
  22. {
  23. timestamp: '2024-01-24T09:09:03+00:00',
  24. 'issue.id': 1000,
  25. project: project.slug,
  26. 'project.name': project.name,
  27. title: 'Slow DB Query',
  28. id: 'abc',
  29. issue: 'SENTRY-ABC1',
  30. transaction: '/api/slow/',
  31. },
  32. ],
  33. meta: {fields: {}, units: {}},
  34. };
  35. const discoverBody: TraceEventResponse = {
  36. data: [
  37. {
  38. timestamp: '2024-01-23T22:11:42+00:00',
  39. 'issue.id': 4909507143,
  40. project: project.slug,
  41. 'project.name': project.name,
  42. title: 'AttributeError: Something Failed',
  43. id: event.id,
  44. issue: 'SENTRY-2EYS',
  45. transaction: 'important.task',
  46. 'event.type': 'error',
  47. 'stack.function': ['important.task', 'task.run'],
  48. },
  49. ],
  50. meta: {fields: {}, units: {}},
  51. };
  52. beforeEach(() => {
  53. // Can be removed with issueDetailsNewExperienceQ42023
  54. ProjectsStore.loadInitialData([project]);
  55. ConfigStore.set(
  56. 'user',
  57. UserFixture({
  58. options: {
  59. ...UserFixture().options,
  60. issueDetailsNewExperienceQ42023: true,
  61. },
  62. })
  63. );
  64. });
  65. it('renders items and highlights the current event', async () => {
  66. MockApiClient.addMockResponse({
  67. url: `/organizations/${organization.slug}/events/`,
  68. body: issuePlatformBody,
  69. match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
  70. });
  71. MockApiClient.addMockResponse({
  72. url: `/organizations/${organization.slug}/events/`,
  73. body: discoverBody,
  74. match: [MockApiClient.matchQuery({dataset: 'discover'})],
  75. });
  76. render(<TraceTimeline event={event} />, {organization});
  77. expect(await screen.findByLabelText('Current Event')).toBeInTheDocument();
  78. await userEvent.hover(screen.getByLabelText('Current Event'));
  79. expect(await screen.findByText('You are here')).toBeInTheDocument();
  80. });
  81. it('displays nothing if the only event is the current event', async () => {
  82. MockApiClient.addMockResponse({
  83. url: `/organizations/${organization.slug}/events/`,
  84. body: {
  85. data: [],
  86. meta: {fields: {}, units: {}},
  87. },
  88. match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
  89. });
  90. MockApiClient.addMockResponse({
  91. url: `/organizations/${organization.slug}/events/`,
  92. body: discoverBody,
  93. match: [MockApiClient.matchQuery({dataset: 'discover'})],
  94. });
  95. render(<TraceTimeline event={event} />, {organization});
  96. expect(await screen.findByTestId('trace-timeline-empty')).toBeInTheDocument();
  97. });
  98. it('displays nothing if there are no events', async () => {
  99. MockApiClient.addMockResponse({
  100. url: `/organizations/${organization.slug}/events/`,
  101. body: {
  102. data: [],
  103. meta: {fields: {}, units: {}},
  104. },
  105. match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
  106. });
  107. MockApiClient.addMockResponse({
  108. url: `/organizations/${organization.slug}/events/`,
  109. body: {
  110. data: [],
  111. meta: {fields: {}, units: {}},
  112. },
  113. match: [MockApiClient.matchQuery({dataset: 'discover'})],
  114. });
  115. render(<TraceTimeline event={event} />, {organization});
  116. expect(await screen.findByTestId('trace-timeline-empty')).toBeInTheDocument();
  117. });
  118. it('shows seconds for very short timelines', async () => {
  119. MockApiClient.addMockResponse({
  120. url: `/organizations/${organization.slug}/events/`,
  121. body: issuePlatformBody,
  122. match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
  123. });
  124. MockApiClient.addMockResponse({
  125. url: `/organizations/${organization.slug}/events/`,
  126. body: {
  127. data: [],
  128. meta: {fields: {}, units: {}},
  129. },
  130. match: [MockApiClient.matchQuery({dataset: 'discover'})],
  131. });
  132. render(<TraceTimeline event={event} />, {organization});
  133. // Checking for the presence of seconds
  134. expect(await screen.findAllByText(/\d{1,2}:\d{2}:\d{2} (AM|PM)/)).toHaveLength(3);
  135. });
  136. });