utils.spec.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import {
  2. addSpace,
  3. escapeTagValue,
  4. filterKeysFromQuery,
  5. getTagItemsFromKeys,
  6. removeSpace,
  7. } from 'sentry/components/smartSearchBar/utils';
  8. import {FieldKey, FieldKind, getFieldDefinition} from 'sentry/utils/fields';
  9. describe('addSpace()', function () {
  10. it('should add a space when there is no trailing space', function () {
  11. expect(addSpace('one')).toEqual('one ');
  12. });
  13. it('should not add another space when there is already one', function () {
  14. expect(addSpace('one ')).toEqual('one ');
  15. });
  16. it('should leave the empty string alone', function () {
  17. expect(addSpace('')).toEqual('');
  18. });
  19. });
  20. describe('removeSpace()', function () {
  21. it('should remove a trailing space', function () {
  22. expect(removeSpace('one ')).toEqual('one');
  23. });
  24. it('should not remove the last character if it is not a space', function () {
  25. expect(removeSpace('one')).toEqual('one');
  26. });
  27. it('should leave the empty string alone', function () {
  28. expect(removeSpace('')).toEqual('');
  29. });
  30. });
  31. describe('getTagItemsFromKeys()', function () {
  32. it('gets items from tags', () => {
  33. const supportedTags = {
  34. browser: {
  35. kind: FieldKind.FIELD,
  36. key: 'browser',
  37. name: 'Browser',
  38. },
  39. device: {
  40. kind: FieldKind.FIELD,
  41. key: 'device',
  42. name: 'Device',
  43. },
  44. someTag: {
  45. kind: FieldKind.TAG,
  46. key: 'someTag',
  47. name: 'someTag',
  48. },
  49. };
  50. const tagKeys = Object.keys(supportedTags);
  51. const items = getTagItemsFromKeys(tagKeys, supportedTags);
  52. expect(items).toMatchObject([
  53. {
  54. title: 'browser',
  55. value: 'browser:',
  56. kind: FieldKind.FIELD,
  57. documentation: '-',
  58. },
  59. {
  60. title: 'device',
  61. value: 'device:',
  62. kind: FieldKind.FIELD,
  63. documentation: '-',
  64. },
  65. {
  66. title: 'someTag',
  67. value: 'someTag:',
  68. kind: FieldKind.TAG,
  69. documentation: '-',
  70. },
  71. ]);
  72. });
  73. it('groups tags', () => {
  74. const supportedTags = {
  75. 'tag1.arch': {
  76. key: 'tag1.arch',
  77. name: 'Tag1 Arch',
  78. kind: FieldKind.FIELD,
  79. },
  80. 'tag1.family': {
  81. key: 'tag1.family',
  82. name: 'Tag1 Family',
  83. kind: FieldKind.FIELD,
  84. },
  85. test: {
  86. key: 'test',
  87. name: 'Test',
  88. kind: FieldKind.TAG,
  89. },
  90. };
  91. const tagKeys = Object.keys(supportedTags);
  92. const items = getTagItemsFromKeys(tagKeys, supportedTags);
  93. expect(items).toMatchObject([
  94. {
  95. title: 'tag1',
  96. value: null,
  97. kind: FieldKind.FIELD,
  98. documentation: '-',
  99. children: [
  100. {
  101. title: 'tag1.arch',
  102. value: 'tag1.arch:',
  103. kind: FieldKind.FIELD,
  104. documentation: '-',
  105. },
  106. {
  107. title: 'tag1.family',
  108. value: 'tag1.family:',
  109. kind: FieldKind.FIELD,
  110. documentation: '-',
  111. },
  112. ],
  113. },
  114. {
  115. title: 'test',
  116. value: 'test:',
  117. kind: FieldKind.TAG,
  118. documentation: '-',
  119. },
  120. ]);
  121. });
  122. it('groups tags with single word parent', () => {
  123. const supportedTags = {
  124. tag1: {
  125. kind: FieldKind.FIELD,
  126. key: 'tag1',
  127. name: 'Tag1',
  128. },
  129. 'tag1.family': {
  130. kind: FieldKind.FIELD,
  131. key: 'tag1.family',
  132. name: 'Tag1 Family',
  133. },
  134. test: {
  135. kind: FieldKind.TAG,
  136. key: 'test',
  137. name: 'Test',
  138. },
  139. };
  140. const tagKeys = Object.keys(supportedTags);
  141. const items = getTagItemsFromKeys(tagKeys, supportedTags);
  142. expect(items).toMatchObject([
  143. {
  144. title: 'tag1',
  145. value: 'tag1:',
  146. kind: FieldKind.FIELD,
  147. documentation: '-',
  148. children: [
  149. {
  150. title: 'tag1.family',
  151. value: 'tag1.family:',
  152. kind: FieldKind.FIELD,
  153. documentation: '-',
  154. },
  155. ],
  156. },
  157. {
  158. title: 'test',
  159. value: 'test:',
  160. kind: FieldKind.TAG,
  161. documentation: '-',
  162. },
  163. ]);
  164. });
  165. it('uses field definitions', () => {
  166. const supportedTags = {
  167. has: {
  168. key: 'has',
  169. name: 'Has',
  170. },
  171. 'device.family': {
  172. key: 'device.family',
  173. name: 'Device Family',
  174. },
  175. };
  176. const tagKeys = Object.keys(supportedTags).sort((a, b) => a.localeCompare(b));
  177. const items = getTagItemsFromKeys(tagKeys, supportedTags);
  178. expect(items).toMatchObject([
  179. {
  180. title: 'device.family',
  181. value: 'device.family:',
  182. kind: getFieldDefinition('device.family')?.kind,
  183. documentation: getFieldDefinition('device.family')?.desc,
  184. },
  185. {
  186. title: 'has',
  187. value: 'has:',
  188. kind: getFieldDefinition('has')?.kind,
  189. documentation: getFieldDefinition('has')?.desc,
  190. },
  191. ]);
  192. });
  193. });
  194. describe('filterKeysFromQuery', () => {
  195. it('filters', () => {
  196. expect(
  197. filterKeysFromQuery(
  198. [FieldKey.DEVICE_ARCH, FieldKey.DEVICE_CHARGING, FieldKey.EVENT_TYPE],
  199. 'event'
  200. )
  201. ).toMatchObject([FieldKey.EVENT_TYPE, FieldKey.DEVICE_CHARGING]);
  202. });
  203. it('filters via description only', () => {
  204. expect(
  205. filterKeysFromQuery(
  206. [FieldKey.DEVICE_ARCH, FieldKey.DEVICE_CHARGING, FieldKey.EVENT_TYPE],
  207. 'time'
  208. )
  209. ).toMatchObject([FieldKey.DEVICE_CHARGING]);
  210. });
  211. it('filters via key only', () => {
  212. expect(
  213. filterKeysFromQuery(
  214. [FieldKey.DEVICE_ARCH, FieldKey.DEVICE_CHARGING, FieldKey.EVENT_TYPE],
  215. 'device'
  216. )
  217. ).toMatchObject([FieldKey.DEVICE_ARCH, FieldKey.DEVICE_CHARGING]);
  218. });
  219. it('filters via lowercase key', () => {
  220. expect(
  221. filterKeysFromQuery([FieldKey.FIRST_SEEN, FieldKey.LAST_SEEN], 'firstseen')
  222. ).toMatchObject([FieldKey.FIRST_SEEN]);
  223. });
  224. it('filters via keywords', () => {
  225. expect(
  226. filterKeysFromQuery(
  227. [FieldKey.IS, FieldKey.DEVICE_CHARGING, FieldKey.EVENT_TYPE],
  228. 'unresolved'
  229. )
  230. ).toMatchObject([FieldKey.IS]);
  231. });
  232. });
  233. describe('escapeTagValue()', () => {
  234. it('wraps tags containing quotes in quotes', () => {
  235. expect(escapeTagValue('foo"bar')).toBe('"foo\\"bar"');
  236. });
  237. it('wraps tags containing spaces in quotes', () => {
  238. expect(escapeTagValue('foo bar')).toBe('"foo bar"');
  239. });
  240. it('does not escape tags in array style', () => {
  241. expect(escapeTagValue('[me, none]')).toBe('[me, none]');
  242. expect(escapeTagValue('[me, my_teams, none]')).toBe('[me, my_teams, none]');
  243. });
  244. });