index.spec.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import {
  2. MetricSeriesFilterUpdateType,
  3. type MetricsQuery,
  4. } from 'sentry/utils/metrics/types';
  5. import {ensureQuotedTextFilters, updateQueryWithSeriesFilter} from './index';
  6. describe('updateQueryWithSeriesFilter', () => {
  7. it('should add a filter an empty query stirng', () => {
  8. const query = {
  9. mri: 'd:transactions/duration@milisecond',
  10. aggregation: 'count',
  11. groupBy: [],
  12. query: '',
  13. } as MetricsQuery;
  14. const updatedQuery = updateQueryWithSeriesFilter(
  15. query,
  16. {project: '1'},
  17. MetricSeriesFilterUpdateType.ADD
  18. );
  19. expect(updatedQuery.query).toEqual('project:"1"');
  20. expect(updatedQuery.groupBy).toEqual([]);
  21. });
  22. it('should add a filter to an existing query string', () => {
  23. const query = {
  24. mri: 'd:transactions/duration@milisecond',
  25. aggregation: 'count',
  26. groupBy: [],
  27. query: 'release:"latest" AND (environment:production OR environment:staging)',
  28. } as MetricsQuery;
  29. const updatedQuery = updateQueryWithSeriesFilter(
  30. query,
  31. {project: '1'},
  32. MetricSeriesFilterUpdateType.ADD
  33. );
  34. expect(updatedQuery.query).toEqual(
  35. '( release:latest AND ( environment:production OR environment:staging ) ) project:"1"'
  36. );
  37. expect(updatedQuery.groupBy).toEqual([]);
  38. });
  39. it('should exclude a filter from an empty query string', () => {
  40. const query = {
  41. mri: 'd:transactions/duration@milisecond',
  42. aggregation: 'count',
  43. groupBy: [],
  44. query: '',
  45. } as MetricsQuery;
  46. const updatedQuery = updateQueryWithSeriesFilter(
  47. query,
  48. {project: '1'},
  49. MetricSeriesFilterUpdateType.EXCLUDE
  50. );
  51. expect(updatedQuery.query).toEqual('!project:"1"');
  52. expect(updatedQuery.groupBy).toEqual([]);
  53. });
  54. it('should exclude a filter from an existing query string', () => {
  55. const query = {
  56. mri: 'd:transactions/duration@milisecond',
  57. aggregation: 'count',
  58. groupBy: [],
  59. query: 'environment:prod1 OR environment:prod2',
  60. } as MetricsQuery;
  61. const updatedQuery = updateQueryWithSeriesFilter(
  62. query,
  63. {project: '2'},
  64. MetricSeriesFilterUpdateType.EXCLUDE
  65. );
  66. expect(updatedQuery.query).toEqual(
  67. '( environment:prod1 OR environment:prod2 ) !project:"2"'
  68. );
  69. expect(updatedQuery.groupBy).toEqual([]);
  70. });
  71. it('should add multiple filters and remove them from grouping', () => {
  72. const query = {
  73. mri: 'd:transactions/duration@milisecond',
  74. aggregation: 'count',
  75. groupBy: ['project', 'release', 'environment'],
  76. query: '',
  77. } as MetricsQuery;
  78. const updatedQuery = updateQueryWithSeriesFilter(
  79. query,
  80. {project: '1', release: 'latest'},
  81. MetricSeriesFilterUpdateType.ADD
  82. );
  83. expect(updatedQuery.query).toEqual('project:"1" release:"latest"');
  84. expect(updatedQuery.groupBy).toEqual(['environment']);
  85. });
  86. it('should add an empty filter value', () => {
  87. const query = {
  88. mri: 'd:transactions/duration@milisecond',
  89. aggregation: 'count',
  90. groupBy: [],
  91. query: '',
  92. } as MetricsQuery;
  93. const updatedQuery = updateQueryWithSeriesFilter(
  94. query,
  95. {project: ''},
  96. MetricSeriesFilterUpdateType.ADD
  97. );
  98. expect(updatedQuery.query).toEqual('project:""');
  99. expect(updatedQuery.groupBy).toEqual([]);
  100. });
  101. });
  102. describe('ensureQuotedTextFilters', () => {
  103. it('returns a query with all text filters quoted', () => {
  104. expect(ensureQuotedTextFilters('transaction:/{organization_slug}/')).toEqual(
  105. 'transaction:"/{organization_slug}/"'
  106. );
  107. // transaction.duration defaults to a number filter
  108. expect(ensureQuotedTextFilters('transaction.duration:100')).toEqual(
  109. 'transaction.duration:100'
  110. );
  111. });
  112. it('handles negated filters', () => {
  113. expect(ensureQuotedTextFilters('!transaction:/{organization_slug}/')).toEqual(
  114. '!transaction:"/{organization_slug}/"'
  115. );
  116. // transaction.duration defaults to a number filter
  117. expect(ensureQuotedTextFilters('!transaction.duration:100')).toEqual(
  118. '!transaction.duration:100'
  119. );
  120. });
  121. it('applies config overrides', () => {
  122. expect(
  123. ensureQuotedTextFilters('transaction:100', {
  124. numericKeys: new Set(['transaction']),
  125. })
  126. ).toEqual('transaction:100');
  127. expect(
  128. ensureQuotedTextFilters('transaction.duration:100', {
  129. numericKeys: new Set([]),
  130. })
  131. ).toEqual('transaction.duration:"100"');
  132. });
  133. });