index.spec.tsx 4.3 KB

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