index.spec.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {render, screen, waitForElementToBeRemoved} from 'sentry-test/reactTestingLibrary';
  3. import type {DetailedOrganization} from 'sentry/types';
  4. import {useLocation} from 'sentry/utils/useLocation';
  5. import usePageFilters from 'sentry/utils/usePageFilters';
  6. import ResourcesLandingPage from 'sentry/views/performance/browser/resources';
  7. import {SpanFunction, SpanMetricsField} from 'sentry/views/starfish/types';
  8. const {
  9. SPAN_SELF_TIME,
  10. SPAN_GROUP,
  11. HTTP_RESPONSE_CONTENT_LENGTH,
  12. SPAN_DOMAIN,
  13. SPAN_DESCRIPTION,
  14. PROJECT_ID,
  15. RESOURCE_RENDER_BLOCKING_STATUS,
  16. SPAN_OP,
  17. } = SpanMetricsField;
  18. const {SPM, TIME_SPENT_PERCENTAGE} = SpanFunction;
  19. jest.mock('sentry/utils/useLocation');
  20. jest.mock('sentry/utils/usePageFilters');
  21. const requestMocks: Record<string, jest.Mock> = {};
  22. describe('ResourcesLandingPage', function () {
  23. const organization = OrganizationFixture({
  24. features: ['insights-initial-modules'],
  25. });
  26. beforeEach(() => {
  27. setupMocks();
  28. setupMockRequests(organization);
  29. });
  30. afterEach(function () {
  31. jest.resetAllMocks();
  32. });
  33. it('renders a list of resources', async () => {
  34. render(<ResourcesLandingPage />, {organization});
  35. await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator'));
  36. expect(
  37. screen.getByRole('cell', {name: 'https://*.sentry-cdn.com/123.js'})
  38. ).toBeInTheDocument();
  39. expect(
  40. screen.getByRole('cell', {name: 'https://*.sentry-cdn.com/456.js'})
  41. ).toBeInTheDocument();
  42. });
  43. it('contains correct query in charts', async () => {
  44. render(<ResourcesLandingPage />, {organization});
  45. await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator'));
  46. expect(requestMocks.mainTable.mock.calls).toMatchInlineSnapshot(`
  47. [
  48. [
  49. "/organizations/org-slug/events/",
  50. {
  51. "error": [Function],
  52. "method": "GET",
  53. "query": {
  54. "dataset": "spansMetrics",
  55. "environment": [],
  56. "field": [
  57. "span.description",
  58. "span.op",
  59. "count()",
  60. "avg(span.self_time)",
  61. "spm()",
  62. "span.group",
  63. "avg(http.response_content_length)",
  64. "project.id",
  65. "time_spent_percentage()",
  66. "sum(span.self_time)",
  67. ],
  68. "per_page": 100,
  69. "project": [],
  70. "query": "!span.description:"browser-extension://*" ( span.op:resource.script OR file_extension:css OR file_extension:[woff,woff2,ttf,otf,eot] OR file_extension:[jpg,jpeg,png,gif,svg,webp,apng,avif] OR span.op:resource.img ) ",
  71. "referrer": "api.performance.browser.resources.main-table",
  72. "sort": "-time_spent_percentage()",
  73. "statsPeriod": "10d",
  74. },
  75. "skipAbort": undefined,
  76. "success": [Function],
  77. },
  78. ],
  79. ]
  80. `);
  81. });
  82. });
  83. const setupMocks = () => {
  84. jest.mocked(usePageFilters).mockReturnValue({
  85. isReady: true,
  86. desyncedFilters: new Set(),
  87. pinnedFilters: new Set(),
  88. shouldPersist: true,
  89. selection: {
  90. datetime: {
  91. period: '10d',
  92. start: null,
  93. end: null,
  94. utc: false,
  95. },
  96. environments: [],
  97. projects: [],
  98. },
  99. });
  100. jest.mocked(useLocation).mockReturnValue({
  101. pathname: '',
  102. search: '',
  103. query: {statsPeriod: '10d'},
  104. hash: '',
  105. state: undefined,
  106. action: 'PUSH',
  107. key: '',
  108. });
  109. };
  110. const setupMockRequests = (organization: DetailedOrganization) => {
  111. requestMocks.mainTable = MockApiClient.addMockResponse({
  112. url: `/organizations/${organization.slug}/events/`,
  113. method: 'GET',
  114. match: [
  115. MockApiClient.matchQuery({
  116. referrer: 'api.performance.browser.resources.main-table',
  117. }),
  118. ],
  119. body: {
  120. data: [
  121. {
  122. [`avg(${HTTP_RESPONSE_CONTENT_LENGTH})`]: 123,
  123. [`avg(${SPAN_SELF_TIME})`]: 123,
  124. [RESOURCE_RENDER_BLOCKING_STATUS]: 123,
  125. [SPAN_DESCRIPTION]: 'https://*.sentry-cdn.com/123.js',
  126. [SPAN_DOMAIN]: ['https://*.sentry-cdn.com'],
  127. [PROJECT_ID]: 123,
  128. [SPAN_OP]: 'resource.script',
  129. [SPAN_GROUP]: 'group123',
  130. [`${SPM}()`]: 123,
  131. [`${TIME_SPENT_PERCENTAGE}()`]: 0.5,
  132. [`sum(${SPAN_SELF_TIME})`]: 123,
  133. 'count()': 123,
  134. },
  135. {
  136. [`avg(${HTTP_RESPONSE_CONTENT_LENGTH})`]: 123,
  137. [`avg(${SPAN_SELF_TIME})`]: 123,
  138. [RESOURCE_RENDER_BLOCKING_STATUS]: 123,
  139. [SPAN_DESCRIPTION]: 'https://*.sentry-cdn.com/456.js',
  140. [SPAN_DOMAIN]: ['https://*.sentry-cdn.com'],
  141. [PROJECT_ID]: 123,
  142. [SPAN_OP]: 'resource.script',
  143. [SPAN_GROUP]: 'group123',
  144. [`${SPM}()`]: 123,
  145. [`${TIME_SPENT_PERCENTAGE}()`]: 0.5,
  146. [`sum(${SPAN_SELF_TIME})`]: 123,
  147. 'count()': 123,
  148. },
  149. ],
  150. },
  151. });
  152. MockApiClient.addMockResponse({
  153. url: `/organizations/${organization.slug}/events/`,
  154. method: 'GET',
  155. match: [
  156. MockApiClient.matchQuery({
  157. referrer: 'api.performance.browser.resources.page-selector',
  158. }),
  159. ],
  160. body: {
  161. data: [{transaction: '/page/123/', 'count()': 1}],
  162. },
  163. });
  164. MockApiClient.addMockResponse({
  165. url: `/organizations/${organization.slug}/events/`,
  166. method: 'GET',
  167. match: [MockApiClient.matchQuery({referrer: 'api.starfish.get-span-domains'})],
  168. body: {
  169. data: [{'span.domain': ['*.sentry-cdn.com'], count: 1}],
  170. },
  171. });
  172. MockApiClient.addMockResponse({
  173. url: `/organizations/${organization.slug}/events-stats/`,
  174. method: 'GET',
  175. match: [MockApiClient.matchQuery({referrer: 'api.starfish.span-time-charts'})],
  176. body: {
  177. [`${SPM}()`]: {
  178. data: [
  179. [1699907700, [{count: 7810.2}]],
  180. [1699908000, [{count: 1216.8}]],
  181. ],
  182. },
  183. [`avg(${SPAN_SELF_TIME})`]: {
  184. data: [
  185. [1699907700, [{count: 1111.2}]],
  186. [1699908000, [{count: 2222.8}]],
  187. ],
  188. },
  189. },
  190. });
  191. };