traceTimeline.spec.tsx 4.4 KB

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