screenLoadSpansTable.spec.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import type {Location} from 'history';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {render, screen, within} from 'sentry-test/reactTestingLibrary';
  4. import {useLocation} from 'sentry/utils/useLocation';
  5. import usePageFilters from 'sentry/utils/usePageFilters';
  6. import {ScreenLoadSpansTable} from 'sentry/views/insights/mobile/screenload/components/tables/screenLoadSpansTable';
  7. jest.mock('sentry/utils/useLocation');
  8. jest.mock('sentry/utils/usePageFilters');
  9. describe('ScreenLoadSpansTable', function () {
  10. const organization = OrganizationFixture({
  11. features: ['insights-initial-modules'],
  12. });
  13. jest.mocked(useLocation).mockReturnValue({
  14. action: 'PUSH',
  15. hash: '',
  16. key: '',
  17. pathname: '/organizations/org-slug/performance/mobile/screens/',
  18. query: {},
  19. search: '',
  20. state: undefined,
  21. } as Location);
  22. jest.mocked(usePageFilters).mockReturnValue({
  23. isReady: true,
  24. desyncedFilters: new Set(),
  25. pinnedFilters: new Set(),
  26. shouldPersist: true,
  27. selection: {
  28. datetime: {
  29. period: '10d',
  30. start: null,
  31. end: null,
  32. utc: false,
  33. },
  34. environments: [],
  35. projects: [],
  36. },
  37. });
  38. let eventsMock: jest.Mock;
  39. beforeEach(function () {
  40. MockApiClient.addMockResponse({
  41. url: `/organizations/${organization.slug}/releases/`,
  42. body: [],
  43. });
  44. eventsMock = MockApiClient.addMockResponse({
  45. url: `/organizations/${organization.slug}/events/`,
  46. body: {
  47. meta: {},
  48. data: [],
  49. },
  50. });
  51. });
  52. afterEach(function () {
  53. MockApiClient.clearMockResponses();
  54. jest.clearAllMocks();
  55. });
  56. it('renders table with the right columns', async function () {
  57. render(
  58. <ScreenLoadSpansTable
  59. transaction="MainActivity"
  60. primaryRelease="io.sentry.samples.android@7.0.0+2"
  61. secondaryRelease="io.sentry.samples.android@6.27.0+2"
  62. />,
  63. {organization}
  64. );
  65. expect(eventsMock).toHaveBeenCalledTimes(2);
  66. // Span op selector
  67. expect(eventsMock).toHaveBeenNthCalledWith(
  68. 1,
  69. expect.anything(),
  70. expect.objectContaining({
  71. query: expect.objectContaining({
  72. dataset: 'spansMetrics',
  73. environment: [],
  74. field: ['span.op', 'count()'],
  75. per_page: 25,
  76. project: [],
  77. query:
  78. 'transaction.op:ui.load transaction:MainActivity span.op:[file.read,file.write,ui.load,http.client,db,db.sql.room,db.sql.query,db.sql.transaction] has:span.description ( release:io.sentry.samples.android@7.0.0+2 OR release:io.sentry.samples.android@6.27.0+2 )',
  79. referrer: 'api.starfish.get-span-operations',
  80. statsPeriod: '14d',
  81. }),
  82. })
  83. );
  84. // Spans table
  85. expect(eventsMock).toHaveBeenNthCalledWith(
  86. 2,
  87. expect.anything(),
  88. expect.objectContaining({
  89. query: expect.objectContaining({
  90. dataset: 'spansMetrics',
  91. environment: [],
  92. field: [
  93. 'project.id',
  94. 'span.op',
  95. 'span.group',
  96. 'span.description',
  97. 'avg_if(span.self_time,release,io.sentry.samples.android@7.0.0+2)',
  98. 'avg_if(span.self_time,release,io.sentry.samples.android@6.27.0+2)',
  99. 'ttid_contribution_rate()',
  100. 'ttfd_contribution_rate()',
  101. 'count()',
  102. 'time_spent_percentage()',
  103. 'sum(span.self_time)',
  104. ],
  105. per_page: 25,
  106. project: [],
  107. query:
  108. 'transaction.op:ui.load transaction:MainActivity has:span.description span.op:[file.read,file.write,ui.load,http.client,db,db.sql.room,db.sql.query,db.sql.transaction] ( release:io.sentry.samples.android@7.0.0+2 OR release:io.sentry.samples.android@6.27.0+2 )',
  109. referrer: 'api.starfish.mobile-span-table',
  110. sort: '-time_spent_percentage()',
  111. statsPeriod: '14d',
  112. }),
  113. })
  114. );
  115. const header = await screen.findAllByTestId('grid-head-row');
  116. const headerCells = within(header[0]!).getAllByTestId('grid-head-cell');
  117. const headerCell = headerCells[4];
  118. expect(headerCell).toHaveTextContent('Affects TTID');
  119. expect(await screen.findByRole('link', {name: 'Affects TTID'})).toHaveAttribute(
  120. 'href',
  121. '/organizations/org-slug/performance/mobile/screens/?spansSort=-ttid_contribution_rate%28%29'
  122. );
  123. });
  124. it('sorts ttfd contribution', async function () {
  125. jest.mocked(useLocation).mockReturnValue({
  126. action: 'PUSH',
  127. hash: '',
  128. key: '',
  129. pathname: '/organizations/org-slug/performance/mobile/screens/',
  130. query: {spansSort: '-ttid_contribution_rate()'},
  131. search: '',
  132. state: undefined,
  133. } as Location);
  134. render(
  135. <ScreenLoadSpansTable
  136. transaction="MainActivity"
  137. primaryRelease="io.sentry.samples.android@7.0.0+2"
  138. secondaryRelease="io.sentry.samples.android@6.27.0+2"
  139. />,
  140. {organization}
  141. );
  142. const header = await screen.findAllByTestId('grid-head-row');
  143. const headerCells = within(header[0]!).getAllByTestId('grid-head-cell');
  144. const headerCell = headerCells[4];
  145. expect(headerCell).toHaveTextContent('Affects TTID');
  146. expect(await screen.findByRole('link', {name: 'Affects TTID'})).toHaveAttribute(
  147. 'href',
  148. '/organizations/org-slug/performance/mobile/screens/?spansSort=-ttfd_contribution_rate%28%29'
  149. );
  150. });
  151. });