index.spec.tsx 6.1 KB

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