httpDomainSummaryPage.spec.tsx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {render, screen, waitForElementToBeRemoved} from 'sentry-test/reactTestingLibrary';
  3. import {useLocation} from 'sentry/utils/useLocation';
  4. import useOrganization from 'sentry/utils/useOrganization';
  5. import usePageFilters from 'sentry/utils/usePageFilters';
  6. import {HTTPDomainSummaryPage} from 'sentry/views/performance/http/httpDomainSummaryPage';
  7. jest.mock('sentry/utils/useLocation');
  8. jest.mock('sentry/utils/usePageFilters');
  9. jest.mock('sentry/utils/useOrganization');
  10. describe('HTTPSummaryPage', function () {
  11. const organization = OrganizationFixture();
  12. let domainChartsRequestMock, domainTransactionsListRequestMock;
  13. jest.mocked(usePageFilters).mockReturnValue({
  14. isReady: true,
  15. desyncedFilters: new Set(),
  16. pinnedFilters: new Set(),
  17. shouldPersist: true,
  18. selection: {
  19. datetime: {
  20. period: '10d',
  21. start: null,
  22. end: null,
  23. utc: false,
  24. },
  25. environments: [],
  26. projects: [],
  27. },
  28. });
  29. jest.mocked(useLocation).mockReturnValue({
  30. pathname: '',
  31. search: '',
  32. query: {domain: '*.sentry.dev', statsPeriod: '10d', transactionsCursor: '0:20:0'},
  33. hash: '',
  34. state: undefined,
  35. action: 'PUSH',
  36. key: '',
  37. });
  38. jest.mocked(useOrganization).mockReturnValue(organization);
  39. beforeEach(function () {
  40. domainTransactionsListRequestMock = MockApiClient.addMockResponse({
  41. url: `/organizations/${organization.slug}/events/`,
  42. method: 'GET',
  43. body: {
  44. data: [],
  45. },
  46. });
  47. domainChartsRequestMock = MockApiClient.addMockResponse({
  48. url: `/organizations/${organization.slug}/events-stats/`,
  49. method: 'GET',
  50. body: {
  51. 'spm()': {
  52. data: [
  53. [1699907700, [{count: 7810.2}]],
  54. [1699908000, [{count: 1216.8}]],
  55. ],
  56. },
  57. },
  58. });
  59. });
  60. afterAll(function () {
  61. jest.resetAllMocks();
  62. });
  63. it('fetches module data', async function () {
  64. render(<HTTPDomainSummaryPage />);
  65. expect(domainChartsRequestMock).toHaveBeenNthCalledWith(
  66. 1,
  67. `/organizations/${organization.slug}/events-stats/`,
  68. expect.objectContaining({
  69. method: 'GET',
  70. query: {
  71. cursor: undefined,
  72. dataset: 'spansMetrics',
  73. environment: [],
  74. excludeOther: 0,
  75. field: [],
  76. interval: '30m',
  77. orderby: undefined,
  78. partial: 1,
  79. per_page: 50,
  80. project: [],
  81. query: 'span.module:http span.domain:"\\*.sentry.dev"',
  82. referrer: 'api.starfish.http-module-domain-summary-throughput-chart',
  83. statsPeriod: '10d',
  84. topEvents: undefined,
  85. yAxis: 'spm()',
  86. },
  87. })
  88. );
  89. expect(domainChartsRequestMock).toHaveBeenNthCalledWith(
  90. 2,
  91. `/organizations/${organization.slug}/events-stats/`,
  92. expect.objectContaining({
  93. method: 'GET',
  94. query: {
  95. cursor: undefined,
  96. dataset: 'spansMetrics',
  97. environment: [],
  98. excludeOther: 0,
  99. field: [],
  100. interval: '30m',
  101. orderby: undefined,
  102. partial: 1,
  103. per_page: 50,
  104. project: [],
  105. query: 'span.module:http span.domain:"\\*.sentry.dev"',
  106. referrer: 'api.starfish.http-module-domain-summary-duration-chart',
  107. statsPeriod: '10d',
  108. topEvents: undefined,
  109. yAxis: 'avg(span.self_time)',
  110. },
  111. })
  112. );
  113. expect(domainChartsRequestMock).toHaveBeenNthCalledWith(
  114. 3,
  115. `/organizations/${organization.slug}/events-stats/`,
  116. expect.objectContaining({
  117. method: 'GET',
  118. query: {
  119. cursor: undefined,
  120. dataset: 'spansMetrics',
  121. environment: [],
  122. excludeOther: 0,
  123. field: [],
  124. interval: '30m',
  125. orderby: undefined,
  126. partial: 1,
  127. per_page: 50,
  128. project: [],
  129. query: 'span.module:http span.domain:"\\*.sentry.dev"',
  130. referrer: 'api.starfish.http-module-domain-summary-response-code-chart',
  131. statsPeriod: '10d',
  132. topEvents: undefined,
  133. yAxis: [
  134. 'http_response_rate(3)',
  135. 'http_response_rate(4)',
  136. 'http_response_rate(5)',
  137. ],
  138. },
  139. })
  140. );
  141. expect(domainTransactionsListRequestMock).toHaveBeenNthCalledWith(
  142. 1,
  143. `/organizations/${organization.slug}/events/`,
  144. expect.objectContaining({
  145. method: 'GET',
  146. query: {
  147. dataset: 'spansMetrics',
  148. environment: [],
  149. field: [
  150. 'spm()',
  151. 'avg(span.self_time)',
  152. 'sum(span.self_time)',
  153. 'http_response_rate(3)',
  154. 'http_response_rate(4)',
  155. 'http_response_rate(5)',
  156. 'time_spent_percentage()',
  157. ],
  158. per_page: 50,
  159. project: [],
  160. query: 'span.module:http span.domain:"\\*.sentry.dev"',
  161. referrer: 'api.starfish.http-module-domain-summary-metrics-ribbon',
  162. statsPeriod: '10d',
  163. },
  164. })
  165. );
  166. expect(domainTransactionsListRequestMock).toHaveBeenNthCalledWith(
  167. 2,
  168. `/organizations/${organization.slug}/events/`,
  169. expect.objectContaining({
  170. method: 'GET',
  171. query: {
  172. dataset: 'spansMetrics',
  173. environment: [],
  174. field: [
  175. 'project.id',
  176. 'transaction',
  177. 'transaction.method',
  178. 'spm()',
  179. 'http_response_rate(3)',
  180. 'http_response_rate(4)',
  181. 'http_response_rate(5)',
  182. 'avg(span.self_time)',
  183. 'sum(span.self_time)',
  184. 'time_spent_percentage()',
  185. ],
  186. per_page: 20,
  187. project: [],
  188. cursor: '0:20:0',
  189. query: 'span.module:http span.domain:"\\*.sentry.dev"',
  190. sort: '-time_spent_percentage()',
  191. referrer: 'api.starfish.http-module-domain-summary-transactions-list',
  192. statsPeriod: '10d',
  193. },
  194. })
  195. );
  196. await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator'));
  197. });
  198. it('renders a list of queries', async function () {
  199. MockApiClient.addMockResponse({
  200. url: `/organizations/${organization.slug}/events/`,
  201. method: 'GET',
  202. match: [
  203. MockApiClient.matchQuery({
  204. referrer: 'api.starfish.http-module-domain-summary-transactions-list',
  205. }),
  206. ],
  207. body: {
  208. data: [
  209. {
  210. 'project.id': 8,
  211. transaction: '/api/users',
  212. 'transaction.method': 'GET',
  213. 'spm()': 17.88,
  214. 'http_response_rate(3)': 0.97,
  215. 'http_response_rate(4)': 0.025,
  216. 'http_response_rate(5)': 0.005,
  217. 'avg(span.self_time)': 204.5,
  218. 'sum(span.self_time)': 177238,
  219. },
  220. ],
  221. meta: {
  222. fields: {
  223. 'spm()': 'rate',
  224. 'avg(span.self_time)': 'duration',
  225. 'http_response_rate(3)': 'percentage',
  226. 'http_response_rate(4)': 'percentage',
  227. 'http_response_rate(5)': 'percentage',
  228. 'sum(span.self_time)': 'duration',
  229. },
  230. },
  231. },
  232. });
  233. render(<HTTPDomainSummaryPage />);
  234. await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator'));
  235. expect(screen.getByRole('table', {name: 'Transactions'})).toBeInTheDocument();
  236. expect(screen.getByRole('columnheader', {name: 'Found In'})).toBeInTheDocument();
  237. expect(
  238. screen.getByRole('columnheader', {name: 'Requests Per Minute'})
  239. ).toBeInTheDocument();
  240. expect(screen.getByRole('columnheader', {name: '3XXs'})).toBeInTheDocument();
  241. expect(screen.getByRole('columnheader', {name: '4XXs'})).toBeInTheDocument();
  242. expect(screen.getByRole('columnheader', {name: '5XXs'})).toBeInTheDocument();
  243. expect(screen.getByRole('columnheader', {name: 'Avg Duration'})).toBeInTheDocument();
  244. expect(screen.getByRole('columnheader', {name: 'Time Spent'})).toBeInTheDocument();
  245. expect(screen.getByRole('cell', {name: 'GET /api/users'})).toBeInTheDocument();
  246. expect(screen.getByRole('link', {name: 'GET /api/users'})).toHaveAttribute(
  247. 'href',
  248. '/organizations/org-slug/performance/http/domains/?domain=%2A.sentry.dev&project=8&statsPeriod=10d&transaction=%2Fapi%2Fusers&transactionMethod=GET&transactionsCursor=0%3A20%3A0'
  249. );
  250. expect(screen.getByRole('cell', {name: '17.9/s'})).toBeInTheDocument();
  251. expect(screen.getByRole('cell', {name: '97%'})).toBeInTheDocument();
  252. expect(screen.getByRole('cell', {name: '2.5%'})).toBeInTheDocument();
  253. expect(screen.getByRole('cell', {name: '0.5%'})).toBeInTheDocument();
  254. expect(screen.getByRole('cell', {name: '204.50ms'})).toBeInTheDocument();
  255. expect(screen.getByRole('cell', {name: '2.95min'})).toBeInTheDocument();
  256. });
  257. });