spanEvidencePreview.spec.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {
  3. MockSpan,
  4. ProblemSpan,
  5. TransactionEventBuilder,
  6. } from 'sentry-test/performance/utils';
  7. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  8. import * as useApi from 'sentry/utils/useApi';
  9. import {OrganizationContext} from 'sentry/views/organizationContext';
  10. import {RouteContext} from 'sentry/views/routeContext';
  11. import {SpanEvidencePreview} from './spanEvidencePreview';
  12. describe('SpanEvidencePreview', () => {
  13. beforeEach(() => {
  14. jest.useFakeTimers();
  15. jest.restoreAllMocks();
  16. });
  17. const {organization, router} = initializeOrg();
  18. const TestComponent: typeof SpanEvidencePreview = props => (
  19. <OrganizationContext.Provider value={organization}>
  20. <RouteContext.Provider
  21. value={{router, location: router.location, params: {}, routes: []}}
  22. >
  23. <SpanEvidencePreview {...props} />
  24. </RouteContext.Provider>
  25. </OrganizationContext.Provider>
  26. );
  27. it('does not fetch before hover', () => {
  28. const api = new MockApiClient();
  29. jest.spyOn(useApi, 'default').mockReturnValue(api);
  30. const spy = jest.spyOn(api, 'requestPromise');
  31. render(
  32. <TestComponent eventId="event-id" projectSlug="project-slug" groupId="group-id">
  33. Hover me
  34. </TestComponent>
  35. );
  36. jest.runAllTimers();
  37. expect(spy).not.toHaveBeenCalled();
  38. });
  39. it('fetches from event URL when event and project are provided', async () => {
  40. const mock = MockApiClient.addMockResponse({
  41. url: `/projects/org-slug/project-slug/events/event-id/`,
  42. body: null,
  43. });
  44. render(
  45. <TestComponent eventId="event-id" projectSlug="project-slug" groupId="group-id">
  46. Hover me
  47. </TestComponent>
  48. );
  49. userEvent.hover(screen.getByText('Hover me'));
  50. await waitFor(() => {
  51. expect(mock).toHaveBeenCalled();
  52. });
  53. });
  54. it('fetches from group URL when only group ID is provided', async () => {
  55. const mock = MockApiClient.addMockResponse({
  56. url: `/issues/group-id/events/latest/`,
  57. body: null,
  58. });
  59. render(<TestComponent groupId="group-id">Hover me</TestComponent>);
  60. userEvent.hover(screen.getByText('Hover me'));
  61. await waitFor(() => {
  62. expect(mock).toHaveBeenCalled();
  63. });
  64. });
  65. it('shows error when request fails', async () => {
  66. const api = new MockApiClient();
  67. jest.spyOn(useApi, 'default').mockReturnValue(api);
  68. jest.spyOn(api, 'requestPromise').mockRejectedValue(new Error());
  69. render(<TestComponent groupId="group-id">Hover me</TestComponent>);
  70. userEvent.hover(screen.getByText('Hover me'));
  71. await screen.findByText('Failed to load preview');
  72. });
  73. it('renders the span evidence correctly when request succeeds', async () => {
  74. const event = new TransactionEventBuilder()
  75. .addSpan(
  76. new MockSpan({
  77. startTimestamp: 0,
  78. endTimestamp: 100,
  79. op: 'http',
  80. description: 'do a thing',
  81. })
  82. )
  83. .addSpan(
  84. new MockSpan({
  85. startTimestamp: 100,
  86. endTimestamp: 200,
  87. op: 'db',
  88. description: 'SELECT col FROM table',
  89. })
  90. )
  91. .addSpan(
  92. new MockSpan({
  93. startTimestamp: 200,
  94. endTimestamp: 300,
  95. op: 'db',
  96. description: 'SELECT col2 FROM table',
  97. })
  98. )
  99. .addSpan(
  100. new MockSpan({
  101. startTimestamp: 200,
  102. endTimestamp: 300,
  103. op: 'db',
  104. description: 'SELECT col3 FROM table',
  105. })
  106. )
  107. .addSpan(
  108. new MockSpan({
  109. startTimestamp: 300,
  110. endTimestamp: 600,
  111. op: 'db',
  112. description: 'connect',
  113. problemSpan: ProblemSpan.PARENT,
  114. }).addChild(
  115. {
  116. startTimestamp: 300,
  117. endTimestamp: 600,
  118. op: 'db',
  119. description: 'group me',
  120. problemSpan: ProblemSpan.OFFENDER,
  121. },
  122. 9
  123. )
  124. )
  125. .getEvent();
  126. MockApiClient.addMockResponse({
  127. url: `/issues/group-id/events/latest/`,
  128. body: event,
  129. });
  130. render(<TestComponent groupId="group-id">Hover me</TestComponent>);
  131. userEvent.hover(screen.getByText('Hover me'));
  132. await screen.findByTestId('span-evidence-preview-body');
  133. expect(screen.getByRole('cell', {name: 'Transaction'})).toBeInTheDocument();
  134. expect(screen.getByRole('cell', {name: event.title})).toBeInTheDocument();
  135. expect(screen.getByRole('cell', {name: 'Parent Span'})).toBeInTheDocument();
  136. expect(screen.getByRole('cell', {name: 'db - connect'})).toBeInTheDocument();
  137. expect(screen.getByRole('cell', {name: 'Repeating Span'})).toBeInTheDocument();
  138. expect(screen.getByRole('cell', {name: 'db - group me'})).toBeInTheDocument();
  139. });
  140. });