visualizationStep.spec.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {act, render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  3. import {DEFAULT_DEBOUNCE_DURATION} from 'sentry/constants';
  4. import {Organization} from 'sentry/types';
  5. import {DashboardWidgetSource} from 'sentry/views/dashboardsV2/types';
  6. import WidgetBuilder from 'sentry/views/dashboardsV2/widgetBuilder';
  7. jest.unmock('lodash/debounce');
  8. function mockRequests(orgSlug: Organization['slug']) {
  9. const eventsv2Mock = MockApiClient.addMockResponse({
  10. url: `/organizations/${orgSlug}/eventsv2/`,
  11. method: 'GET',
  12. statusCode: 200,
  13. body: {
  14. meta: {},
  15. data: [],
  16. },
  17. });
  18. MockApiClient.addMockResponse({
  19. url: '/organizations/org-slug/tags/',
  20. method: 'GET',
  21. body: TestStubs.Tags(),
  22. });
  23. MockApiClient.addMockResponse({
  24. url: '/organizations/org-slug/users/',
  25. body: [],
  26. });
  27. MockApiClient.addMockResponse({
  28. url: '/organizations/org-slug/projects/',
  29. method: 'GET',
  30. body: [],
  31. });
  32. MockApiClient.addMockResponse({
  33. url: '/organizations/org-slug/measurements-meta/',
  34. method: 'GET',
  35. body: {'measurements.custom.measurement': {functions: ['p99']}},
  36. });
  37. MockApiClient.addMockResponse({
  38. url: '/organizations/org-slug/metrics-compatibility/',
  39. method: 'GET',
  40. body: {
  41. incompatible_projects: [],
  42. compatible_projects: [1],
  43. },
  44. });
  45. MockApiClient.addMockResponse({
  46. url: '/organizations/org-slug/metrics-compatibility-sums/',
  47. method: 'GET',
  48. body: {
  49. sum: {
  50. metrics: 988803,
  51. metrics_null: 0,
  52. metrics_unparam: 132,
  53. },
  54. },
  55. });
  56. return {eventsv2Mock};
  57. }
  58. describe('VisualizationStep', function () {
  59. const {organization, router, routerContext} = initializeOrg({
  60. ...initializeOrg(),
  61. organization: {
  62. features: ['dashboards-edit', 'global-views', 'dashboards-mep'],
  63. },
  64. router: {
  65. location: {
  66. query: {
  67. source: DashboardWidgetSource.DASHBOARDS,
  68. },
  69. },
  70. },
  71. });
  72. it('debounce works as expected and requests are not triggered often', async function () {
  73. const {eventsv2Mock} = mockRequests(organization.slug);
  74. jest.useFakeTimers();
  75. render(
  76. <WidgetBuilder
  77. route={{}}
  78. router={router}
  79. routes={router.routes}
  80. routeParams={router.params}
  81. location={router.location}
  82. dashboard={{
  83. id: 'new',
  84. title: 'Dashboard',
  85. createdBy: undefined,
  86. dateCreated: '2020-01-01T00:00:00.000Z',
  87. widgets: [],
  88. projects: [],
  89. filters: {},
  90. }}
  91. onSave={jest.fn()}
  92. params={{
  93. orgId: organization.slug,
  94. dashboardId: 'new',
  95. }}
  96. />,
  97. {
  98. context: routerContext,
  99. organization,
  100. }
  101. );
  102. await waitFor(() => expect(eventsv2Mock).toHaveBeenCalledTimes(1));
  103. userEvent.type(await screen.findByPlaceholderText('Alias'), 'abc');
  104. act(() => {
  105. jest.advanceTimersByTime(DEFAULT_DEBOUNCE_DURATION + 1);
  106. });
  107. await waitFor(() => expect(eventsv2Mock).toHaveBeenCalledTimes(2));
  108. });
  109. it('displays stored data alert', async function () {
  110. mockRequests(organization.slug);
  111. MockApiClient.addMockResponse({
  112. url: `/organizations/${organization.slug}/eventsv2/`,
  113. method: 'GET',
  114. statusCode: 200,
  115. body: {
  116. meta: {isMetricsData: false},
  117. data: [],
  118. },
  119. });
  120. render(
  121. <WidgetBuilder
  122. route={{}}
  123. router={router}
  124. routes={router.routes}
  125. routeParams={router.params}
  126. location={router.location}
  127. dashboard={{
  128. id: 'new',
  129. title: 'Dashboard',
  130. createdBy: undefined,
  131. dateCreated: '2020-01-01T00:00:00.000Z',
  132. widgets: [],
  133. projects: [],
  134. filters: {},
  135. }}
  136. onSave={jest.fn()}
  137. params={{
  138. orgId: organization.slug,
  139. dashboardId: 'new',
  140. }}
  141. />,
  142. {
  143. context: routerContext,
  144. organization: {
  145. ...organization,
  146. features: [
  147. ...organization.features,
  148. 'server-side-sampling',
  149. 'mep-rollout-flag',
  150. ],
  151. },
  152. }
  153. );
  154. await screen.findByText(/we've automatically adjusted your results/i);
  155. });
  156. it('uses release from URL params when querying', async function () {
  157. const {eventsv2Mock} = mockRequests(organization.slug);
  158. render(
  159. <WidgetBuilder
  160. route={{}}
  161. router={router}
  162. routes={router.routes}
  163. routeParams={router.params}
  164. location={{
  165. ...router.location,
  166. query: {
  167. ...router.location.query,
  168. release: ['v1'],
  169. },
  170. }}
  171. dashboard={{
  172. id: 'new',
  173. title: 'Dashboard',
  174. createdBy: undefined,
  175. dateCreated: '2020-01-01T00:00:00.000Z',
  176. widgets: [],
  177. projects: [],
  178. filters: {},
  179. }}
  180. onSave={jest.fn()}
  181. params={{
  182. orgId: organization.slug,
  183. dashboardId: 'new',
  184. }}
  185. />,
  186. {
  187. context: routerContext,
  188. organization,
  189. }
  190. );
  191. await waitFor(() =>
  192. expect(eventsv2Mock).toHaveBeenCalledWith(
  193. '/organizations/org-slug/eventsv2/',
  194. expect.objectContaining({
  195. query: expect.objectContaining({query: ' release:v1 '}),
  196. })
  197. )
  198. );
  199. });
  200. });