metrics.spec.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import {waitFor} from 'sentry-test/reactTestingLibrary';
  2. import {
  3. doMetricsRequest,
  4. fetchMetricsFields,
  5. fetchMetricsTags,
  6. } from 'sentry/actionCreators/metrics';
  7. import MetricsTagActions from 'sentry/actions/metricTagActions';
  8. import {Client} from 'sentry/api';
  9. import MetricsMetaStore from 'sentry/stores/metricsMetaStore';
  10. import MetricsTagStore from 'sentry/stores/metricsTagStore';
  11. import {SessionMetric} from 'sentry/utils/metrics/fields';
  12. describe('Metrics ActionCreator', function () {
  13. const api = new Client();
  14. const orgSlug = TestStubs.Organization().slug;
  15. describe('doMetricsRequest', function () {
  16. const options = {
  17. field: [SessionMetric.SESSION],
  18. orgSlug,
  19. cursor: undefined,
  20. environment: [],
  21. groupBy: ['session.status'],
  22. interval: '1h',
  23. limit: 5,
  24. orderBy: SessionMetric.SESSION,
  25. project: [TestStubs.Project().id],
  26. query: 'release:123',
  27. statsPeriod: '14d',
  28. };
  29. let mock;
  30. beforeEach(function () {
  31. MockApiClient.clearMockResponses();
  32. mock = MockApiClient.addMockResponse({
  33. url: `/organizations/${orgSlug}/metrics/data/`,
  34. body: {
  35. data: [],
  36. },
  37. });
  38. });
  39. it('requests metrics data', function () {
  40. doMetricsRequest(api, options);
  41. expect(mock).toHaveBeenCalledTimes(1);
  42. expect(mock).toHaveBeenLastCalledWith(
  43. `/organizations/${orgSlug}/metrics/data/`,
  44. expect.objectContaining({
  45. query: {
  46. environment: [],
  47. field: ['sentry.sessions.session'],
  48. groupBy: ['session.status'],
  49. interval: '1h',
  50. orderBy: 'sentry.sessions.session',
  51. per_page: 5,
  52. project: ['2'],
  53. query: 'release:123',
  54. statsPeriod: '14d',
  55. },
  56. })
  57. );
  58. });
  59. it('fills in interval based on start and end', function () {
  60. doMetricsRequest(api, {
  61. ...options,
  62. statsPeriod: undefined,
  63. interval: undefined,
  64. start: '2022-01-01T00:00:00',
  65. end: '2022-03-01T00:00:00',
  66. });
  67. expect(mock).toHaveBeenCalledTimes(1);
  68. expect(mock).toHaveBeenLastCalledWith(
  69. `/organizations/${orgSlug}/metrics/data/`,
  70. expect.objectContaining({
  71. query: {
  72. environment: [],
  73. field: ['sentry.sessions.session'],
  74. groupBy: ['session.status'],
  75. interval: '4h',
  76. orderBy: 'sentry.sessions.session',
  77. per_page: 5,
  78. project: ['2'],
  79. query: 'release:123',
  80. start: '2022-01-01T00:00:00.000',
  81. end: '2022-03-01T00:00:00.000',
  82. },
  83. })
  84. );
  85. });
  86. it('ignores falsy fields and groupBys', function () {
  87. doMetricsRequest(api, {
  88. ...options,
  89. field: [SessionMetric.SESSION, ''],
  90. groupBy: ['session.status', ''],
  91. });
  92. expect(mock).toHaveBeenCalledTimes(1);
  93. expect(mock).toHaveBeenLastCalledWith(
  94. `/organizations/${orgSlug}/metrics/data/`,
  95. expect.objectContaining({
  96. query: expect.objectContaining({
  97. field: ['sentry.sessions.session'],
  98. groupBy: ['session.status'],
  99. }),
  100. })
  101. );
  102. });
  103. });
  104. describe('fetchMetricsTags', function () {
  105. let mock;
  106. const tags = [{key: 'release'}, {key: 'environment'}];
  107. beforeEach(function () {
  108. MockApiClient.clearMockResponses();
  109. mock = MockApiClient.addMockResponse({
  110. url: `/organizations/${orgSlug}/metrics/tags/`,
  111. body: tags,
  112. });
  113. jest.restoreAllMocks();
  114. jest.spyOn(MetricsTagActions, 'loadMetricsTagsSuccess');
  115. jest.spyOn(MetricsTagStore, 'reset');
  116. });
  117. it('fetches api and updates store', async function () {
  118. fetchMetricsTags(api, orgSlug, [1], [`sum(${SessionMetric.SESSION})`]);
  119. await waitFor(() => expect(MetricsTagStore.reset).toHaveBeenCalledTimes(1));
  120. expect(mock).toHaveBeenCalledTimes(1);
  121. expect(mock).toHaveBeenLastCalledWith(
  122. `/organizations/${orgSlug}/metrics/tags/`,
  123. expect.objectContaining({
  124. query: {metric: ['sum(sentry.sessions.session)'], project: [1]},
  125. })
  126. );
  127. expect(MetricsTagActions.loadMetricsTagsSuccess).toHaveBeenCalledTimes(1);
  128. expect(MetricsTagActions.loadMetricsTagsSuccess).toHaveBeenCalledWith(tags);
  129. });
  130. });
  131. describe('fetchMetricsFields', function () {
  132. let mock;
  133. const meta = [
  134. {name: 'sentry.sessions.session', type: 'counter', operations: ['sum'], unit: null},
  135. {
  136. name: 'sentry.sessions.user',
  137. type: 'set',
  138. operations: ['count_unique'],
  139. unit: null,
  140. },
  141. ];
  142. beforeEach(function () {
  143. MockApiClient.clearMockResponses();
  144. mock = MockApiClient.addMockResponse({
  145. url: `/organizations/${orgSlug}/metrics/meta/`,
  146. body: meta,
  147. });
  148. jest.restoreAllMocks();
  149. jest.spyOn(MetricsMetaStore, 'loadSuccess');
  150. jest.spyOn(MetricsMetaStore, 'reset');
  151. });
  152. it('fetches api and updates store', async function () {
  153. fetchMetricsFields(api, orgSlug, [1]);
  154. await waitFor(() => expect(MetricsMetaStore.reset).toHaveBeenCalledTimes(1));
  155. expect(mock).toHaveBeenCalledTimes(1);
  156. expect(mock).toHaveBeenLastCalledWith(
  157. `/organizations/${orgSlug}/metrics/meta/`,
  158. expect.objectContaining({
  159. query: {project: [1]},
  160. })
  161. );
  162. expect(MetricsMetaStore.loadSuccess).toHaveBeenCalledTimes(1);
  163. expect(MetricsMetaStore.loadSuccess).toHaveBeenCalledWith(meta);
  164. });
  165. });
  166. });