index.spec.tsx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import type {
  2. MetricsApiRequestQueryOptions,
  3. MetricsOperation,
  4. PageFilters,
  5. } from 'sentry/types';
  6. import {
  7. getAbsoluteDateTimeRange,
  8. getDateTimeParams,
  9. getDDMInterval,
  10. getMetricsApiRequestQuery,
  11. stringifyMetricWidget,
  12. } from 'sentry/utils/metrics';
  13. describe('getMetricsApiRequestQuery', () => {
  14. it('should return the correct query object with default values', () => {
  15. const metric = {field: 'sessions', query: 'error', groupBy: ['project']};
  16. const filters = {
  17. projects: [1],
  18. environments: ['production'],
  19. datetime: {start: '2023-01-01', end: '2023-01-31', period: null, utc: true},
  20. };
  21. const result = getMetricsApiRequestQuery(metric, filters);
  22. expect(result).toEqual({
  23. start: '2023-01-01T00:00:00.000Z',
  24. end: '2023-01-31T00:00:00.000Z',
  25. query: 'error',
  26. project: [1],
  27. environment: ['production'],
  28. field: 'sessions',
  29. useCase: 'custom',
  30. interval: '2h',
  31. groupBy: ['project'],
  32. orderBy: '-sessions',
  33. useNewMetricsLayer: true,
  34. });
  35. });
  36. it('should return the correct query object with default values (period)', () => {
  37. const metric = {field: 'sessions', query: 'error', groupBy: ['project']};
  38. const filters = {
  39. projects: [1],
  40. environments: ['production'],
  41. datetime: {period: '7d', utc: true} as PageFilters['datetime'],
  42. };
  43. const result = getMetricsApiRequestQuery(metric, filters);
  44. expect(result).toEqual({
  45. statsPeriod: '7d',
  46. query: 'error',
  47. project: [1],
  48. environment: ['production'],
  49. field: 'sessions',
  50. useCase: 'custom',
  51. interval: '30m',
  52. groupBy: ['project'],
  53. orderBy: '-sessions',
  54. useNewMetricsLayer: true,
  55. });
  56. });
  57. it('should return the correct query object with overridden values', () => {
  58. const metric = {field: 'sessions', query: 'error', groupBy: ['project']};
  59. const filters = {
  60. projects: [1],
  61. environments: ['production'],
  62. datetime: {start: '2023-01-01', end: '2023-01-02', period: null, utc: true},
  63. };
  64. const result = getMetricsApiRequestQuery(metric, filters, {groupBy: ['environment']});
  65. expect(result).toEqual({
  66. start: '2023-01-01T00:00:00.000Z',
  67. end: '2023-01-02T00:00:00.000Z',
  68. query: 'error',
  69. project: [1],
  70. environment: ['production'],
  71. field: 'sessions',
  72. useCase: 'custom',
  73. interval: '5m',
  74. groupBy: ['environment'],
  75. orderBy: '-sessions',
  76. useNewMetricsLayer: true,
  77. });
  78. });
  79. it('should not add a default orderBy if one is already present', () => {
  80. const metric = {
  81. field: 'sessions',
  82. query: 'error',
  83. groupBy: ['project'],
  84. orderBy: 'foo',
  85. };
  86. const filters = {
  87. projects: [1],
  88. environments: ['production'],
  89. datetime: {start: '2023-01-01', end: '2023-01-02', period: null, utc: true},
  90. };
  91. const result = getMetricsApiRequestQuery(metric, filters);
  92. expect(result).toEqual({
  93. start: '2023-01-01T00:00:00.000Z',
  94. end: '2023-01-02T00:00:00.000Z',
  95. query: 'error',
  96. project: [1],
  97. environment: ['production'],
  98. field: 'sessions',
  99. useCase: 'custom',
  100. interval: '5m',
  101. groupBy: ['project'],
  102. orderBy: 'foo',
  103. useNewMetricsLayer: true,
  104. });
  105. });
  106. it('should not add a default orderBy if there are no groups', () => {
  107. const metric = {
  108. field: 'sessions',
  109. query: 'error',
  110. groupBy: [],
  111. };
  112. const filters = {
  113. projects: [1],
  114. environments: ['production'],
  115. datetime: {start: '2023-01-01', end: '2023-01-02', period: null, utc: true},
  116. };
  117. const result = getMetricsApiRequestQuery(metric, filters);
  118. expect(result).toEqual({
  119. start: '2023-01-01T00:00:00.000Z',
  120. end: '2023-01-02T00:00:00.000Z',
  121. query: 'error',
  122. project: [1],
  123. environment: ['production'],
  124. field: 'sessions',
  125. useCase: 'custom',
  126. interval: '5m',
  127. groupBy: [],
  128. useNewMetricsLayer: true,
  129. });
  130. });
  131. it('should not add a default orderBy if there is no field', () => {
  132. const metric = {
  133. field: '',
  134. query: 'error',
  135. groupBy: [],
  136. };
  137. const filters = {
  138. projects: [1],
  139. environments: ['production'],
  140. datetime: {start: '2023-01-01', end: '2023-01-02', period: null, utc: true},
  141. };
  142. const result = getMetricsApiRequestQuery(metric, filters);
  143. expect(result).toEqual({
  144. start: '2023-01-01T00:00:00.000Z',
  145. end: '2023-01-02T00:00:00.000Z',
  146. query: 'error',
  147. project: [1],
  148. environment: ['production'],
  149. field: '',
  150. useCase: 'custom',
  151. interval: '5m',
  152. groupBy: [],
  153. useNewMetricsLayer: true,
  154. });
  155. });
  156. it('should not add all overrides into the request', () => {
  157. const metric = {
  158. field: '',
  159. query: 'error',
  160. groupBy: [],
  161. };
  162. const filters = {
  163. projects: [1],
  164. environments: ['production'],
  165. datetime: {start: '2023-01-01', end: '2023-01-02', period: null, utc: true},
  166. };
  167. const overrides: MetricsApiRequestQueryOptions = {fidelity: 'high'};
  168. const result = getMetricsApiRequestQuery(metric, filters, overrides);
  169. expect(result).toEqual({
  170. start: '2023-01-01T00:00:00.000Z',
  171. end: '2023-01-02T00:00:00.000Z',
  172. query: 'error',
  173. project: [1],
  174. environment: ['production'],
  175. field: '',
  176. useCase: 'custom',
  177. interval: '5m',
  178. groupBy: [],
  179. useNewMetricsLayer: true,
  180. });
  181. });
  182. });
  183. describe('getDDMInterval', () => {
  184. it('should return the correct interval for non-"1m" intervals', () => {
  185. const dateTimeObj = {start: '2023-01-01', end: '2023-01-31'};
  186. const useCase = 'sessions';
  187. const result = getDDMInterval(dateTimeObj, useCase);
  188. expect(result).toBe('2h');
  189. });
  190. it('should return "10s" interval for "1m" interval within 60 minutes and custom use case', () => {
  191. const dateTimeObj = {
  192. start: '2023-01-01T00:00:00.000Z',
  193. end: '2023-01-01T00:59:00.000Z',
  194. };
  195. const useCase = 'custom';
  196. const result = getDDMInterval(dateTimeObj, useCase, 'high');
  197. expect(result).toBe('10s');
  198. });
  199. it('should return "1m" interval for "1m" interval beyond 60 minutes', () => {
  200. const dateTimeObj = {start: '2023-01-01', end: '2023-01-01T01:05:00.000Z'};
  201. const useCase = 'sessions';
  202. const result = getDDMInterval(dateTimeObj, useCase);
  203. expect(result).toBe('1m');
  204. });
  205. });
  206. describe('getDateTimeParams', () => {
  207. it('should return the correct object with "statsPeriod" when period is provided', () => {
  208. const datetime = {start: '2023-01-01', end: '2023-01-31', period: '7d', utc: true};
  209. const result = getDateTimeParams(datetime);
  210. expect(result).toEqual({statsPeriod: '7d'});
  211. });
  212. it('should return the correct object with "start" and "end" when period is not provided', () => {
  213. const datetime = {start: '2023-01-01', end: '2023-01-31', period: null, utc: true};
  214. const result = getDateTimeParams(datetime);
  215. expect(result).toEqual({
  216. start: '2023-01-01T00:00:00.000Z',
  217. end: '2023-01-31T00:00:00.000Z',
  218. });
  219. });
  220. });
  221. describe('stringifyMetricWidget', () => {
  222. it('should format metric widget object into a string', () => {
  223. const result = stringifyMetricWidget({
  224. op: 'avg',
  225. mri: 'd:custom/sentry.process_profile.symbolicate.process@second',
  226. groupBy: ['result'],
  227. query: 'result:success',
  228. });
  229. expect(result).toEqual(
  230. 'avg(sentry.process_profile.symbolicate.process){result:success} by result'
  231. );
  232. });
  233. it('defaults to an empty string', () => {
  234. const result = stringifyMetricWidget({
  235. op: '' as MetricsOperation,
  236. mri: 'd:custom/sentry.process_profile.symbolicate.process@second',
  237. groupBy: [],
  238. query: '',
  239. });
  240. expect(result).toEqual('');
  241. });
  242. });
  243. describe('getAbsoluteDateTimeRange', () => {
  244. beforeAll(() => {
  245. jest.useFakeTimers();
  246. jest.setSystemTime(new Date('2024-01-01T00:00:00Z'));
  247. });
  248. it('should return the correct object with "start" and "end" when period is not provided', () => {
  249. const datetime = {
  250. start: '2023-01-01T00:00:00.000Z',
  251. end: '2023-01-01T00:00:00.000Z',
  252. period: null,
  253. utc: true,
  254. };
  255. const result = getAbsoluteDateTimeRange(datetime);
  256. expect(result).toEqual({
  257. start: '2023-01-01T00:00:00.000Z',
  258. end: '2023-01-01T00:00:00.000Z',
  259. });
  260. });
  261. it('should return the correct object with "start" and "end" when period is provided', () => {
  262. const datetime = {start: null, end: null, period: '7d', utc: true};
  263. const result = getAbsoluteDateTimeRange(datetime);
  264. expect(result).toEqual({
  265. start: '2023-12-25T00:00:00.000Z',
  266. end: '2024-01-01T00:00:00.000Z',
  267. });
  268. });
  269. afterAll(() => {
  270. jest.useRealTimers();
  271. });
  272. });