LogsQueryField.test.tsx 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import { render, screen, fireEvent } from '@testing-library/react';
  2. import userEvent from '@testing-library/user-event';
  3. import { shallow } from 'enzyme';
  4. import _, { DebouncedFunc } from 'lodash'; // eslint-disable-line lodash/import-scope
  5. import React from 'react';
  6. import { act } from 'react-dom/test-utils';
  7. import { openMenu, select } from 'react-select-event';
  8. import { SelectableValue } from '@grafana/data';
  9. import { ExploreId } from '../../../../types';
  10. import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource';
  11. import { DescribeLogGroupsRequest } from '../types';
  12. import { CloudWatchLogsQueryField } from './LogsQueryField';
  13. jest
  14. .spyOn(_, 'debounce')
  15. .mockImplementation((func: (...args: any) => any, wait?: number) => func as DebouncedFunc<typeof func>);
  16. describe('CloudWatchLogsQueryField', () => {
  17. it('runs onRunQuery on blur of Log Groups', async () => {
  18. const onRunQuery = jest.fn();
  19. const ds = setupMockedDataSource();
  20. render(
  21. <CloudWatchLogsQueryField
  22. absoluteRange={{ from: 1, to: 10 }}
  23. exploreId={ExploreId.left}
  24. datasource={ds.datasource}
  25. query={{} as any}
  26. onRunQuery={onRunQuery}
  27. onChange={() => {}}
  28. />
  29. );
  30. const multiSelect = screen.getByLabelText('Log Groups');
  31. await act(async () => {
  32. fireEvent.blur(multiSelect);
  33. });
  34. expect(onRunQuery).toHaveBeenCalled();
  35. });
  36. it('updates upstream query log groups on region change', async () => {
  37. const onChange = jest.fn();
  38. const wrapper = shallow(
  39. <CloudWatchLogsQueryField
  40. history={[]}
  41. absoluteRange={{ from: 1, to: 10 }}
  42. exploreId={ExploreId.left}
  43. datasource={
  44. {
  45. getRegions() {
  46. return Promise.resolve([
  47. {
  48. label: 'region1',
  49. value: 'region1',
  50. text: 'region1',
  51. },
  52. {
  53. label: 'region2',
  54. value: 'region2',
  55. text: 'region2',
  56. },
  57. ]);
  58. },
  59. describeLogGroups(params: any) {
  60. if (params.region === 'region1') {
  61. return Promise.resolve(['log_group_1']);
  62. } else {
  63. return Promise.resolve(['log_group_2']);
  64. }
  65. },
  66. getVariables: jest.fn().mockReturnValue([]),
  67. } as any
  68. }
  69. query={{} as any}
  70. onRunQuery={() => {}}
  71. onChange={onChange}
  72. />
  73. );
  74. const getLogGroupSelect = () => wrapper.find({ label: 'Log Groups' }).props().inputEl;
  75. getLogGroupSelect().props.onChange([{ value: 'log_group_1' }]);
  76. expect(getLogGroupSelect().props.value.length).toBe(1);
  77. expect(getLogGroupSelect().props.value[0].value).toBe('log_group_1');
  78. // We select new region where the selected log group does not exist
  79. await (wrapper.instance() as CloudWatchLogsQueryField).onRegionChange('region2');
  80. // We clear the select
  81. expect(getLogGroupSelect().props.value.length).toBe(0);
  82. // Make sure we correctly updated the upstream state
  83. expect(onChange).toHaveBeenLastCalledWith({ logGroupNames: [] });
  84. });
  85. it('should merge results of remote log groups search with existing results', async () => {
  86. const allLogGroups = [
  87. 'AmazingGroup',
  88. 'AmazingGroup2',
  89. 'AmazingGroup3',
  90. 'BeautifulGroup',
  91. 'BeautifulGroup2',
  92. 'BeautifulGroup3',
  93. 'CrazyGroup',
  94. 'CrazyGroup2',
  95. 'CrazyGroup3',
  96. 'DeliciousGroup',
  97. 'DeliciousGroup2',
  98. 'DeliciousGroup3',
  99. 'EnjoyableGroup',
  100. 'EnjoyableGroup2',
  101. 'EnjoyableGroup3',
  102. 'FavouriteGroup',
  103. 'FavouriteGroup2',
  104. 'FavouriteGroup3',
  105. 'GorgeousGroup',
  106. 'GorgeousGroup2',
  107. 'GorgeousGroup3',
  108. 'HappyGroup',
  109. 'HappyGroup2',
  110. 'HappyGroup3',
  111. 'IncredibleGroup',
  112. 'IncredibleGroup2',
  113. 'IncredibleGroup3',
  114. 'JollyGroup',
  115. 'JollyGroup2',
  116. 'JollyGroup3',
  117. 'KoolGroup',
  118. 'KoolGroup2',
  119. 'KoolGroup3',
  120. 'LovelyGroup',
  121. 'LovelyGroup2',
  122. 'LovelyGroup3',
  123. 'MagnificentGroup',
  124. 'MagnificentGroup2',
  125. 'MagnificentGroup3',
  126. 'NiceGroup',
  127. 'NiceGroup2',
  128. 'NiceGroup3',
  129. 'OddGroup',
  130. 'OddGroup2',
  131. 'OddGroup3',
  132. 'PerfectGroup',
  133. 'PerfectGroup2',
  134. 'PerfectGroup3',
  135. 'QuietGroup',
  136. 'QuietGroup2',
  137. 'QuietGroup3',
  138. 'RestlessGroup',
  139. 'RestlessGroup2',
  140. 'RestlessGroup3',
  141. 'SurpriseGroup',
  142. 'SurpriseGroup2',
  143. 'SurpriseGroup3',
  144. 'TestingGroup',
  145. 'TestingGroup2',
  146. 'TestingGroup3',
  147. 'UmbrellaGroup',
  148. 'UmbrellaGroup2',
  149. 'UmbrellaGroup3',
  150. 'VelvetGroup',
  151. 'VelvetGroup2',
  152. 'VelvetGroup3',
  153. 'WaterGroup',
  154. 'WaterGroup2',
  155. 'WaterGroup3',
  156. 'XylophoneGroup',
  157. 'XylophoneGroup2',
  158. 'XylophoneGroup3',
  159. 'YellowGroup',
  160. 'YellowGroup2',
  161. 'YellowGroup3',
  162. 'ZebraGroup',
  163. 'ZebraGroup2',
  164. 'ZebraGroup3',
  165. ];
  166. const onChange = jest.fn();
  167. const wrapper = shallow<CloudWatchLogsQueryField>(
  168. <CloudWatchLogsQueryField
  169. history={[]}
  170. absoluteRange={{ from: 1, to: 10 }}
  171. exploreId={ExploreId.left}
  172. datasource={
  173. {
  174. getRegions() {
  175. return Promise.resolve([
  176. {
  177. label: 'region1',
  178. value: 'region1',
  179. text: 'region1',
  180. },
  181. {
  182. label: 'region2',
  183. value: 'region2',
  184. text: 'region2',
  185. },
  186. ]);
  187. },
  188. describeLogGroups(params: DescribeLogGroupsRequest) {
  189. const theLogGroups = allLogGroups
  190. .filter((logGroupName) => logGroupName.startsWith(params.logGroupNamePrefix ?? ''))
  191. .slice(0, Math.max(params.limit ?? 50, 50));
  192. return Promise.resolve(theLogGroups);
  193. },
  194. getVariables: jest.fn().mockReturnValue([]),
  195. } as any
  196. }
  197. query={{} as any}
  198. onRunQuery={() => {}}
  199. onChange={onChange}
  200. />
  201. );
  202. const initialAvailableGroups = allLogGroups
  203. .slice(0, 50)
  204. .map((logGroupName) => ({ value: logGroupName, label: logGroupName }));
  205. wrapper.setState({
  206. availableLogGroups: initialAvailableGroups,
  207. });
  208. await wrapper.instance().onLogGroupSearch('Water', 'default', { action: 'input-change' });
  209. let nextAvailableGroups = (wrapper.state('availableLogGroups') as Array<SelectableValue<string>>).map(
  210. (logGroup) => logGroup.value
  211. );
  212. expect(nextAvailableGroups).toEqual(
  213. initialAvailableGroups.map((logGroup) => logGroup.value).concat(['WaterGroup', 'WaterGroup2', 'WaterGroup3'])
  214. );
  215. await wrapper.instance().onLogGroupSearch('Velv', 'default', { action: 'input-change' });
  216. nextAvailableGroups = (wrapper.state('availableLogGroups') as Array<SelectableValue<string>>).map(
  217. (logGroup) => logGroup.value
  218. );
  219. expect(nextAvailableGroups).toEqual(
  220. initialAvailableGroups
  221. .map((logGroup) => logGroup.value)
  222. .concat(['WaterGroup', 'WaterGroup2', 'WaterGroup3', 'VelvetGroup', 'VelvetGroup2', 'VelvetGroup3'])
  223. );
  224. });
  225. it('should render template variables a selectable option', async () => {
  226. const { datasource } = setupMockedDataSource();
  227. const onChange = jest.fn();
  228. render(
  229. <CloudWatchLogsQueryField
  230. history={[]}
  231. absoluteRange={{ from: 1, to: 10 }}
  232. exploreId={ExploreId.left}
  233. datasource={datasource}
  234. query={{} as any}
  235. onRunQuery={() => {}}
  236. onChange={onChange}
  237. />
  238. );
  239. const logGroupSelector = await screen.findByLabelText('Log Groups');
  240. expect(logGroupSelector).toBeInTheDocument();
  241. await openMenu(logGroupSelector);
  242. const templateVariableSelector = await screen.findByText('Template Variables');
  243. expect(templateVariableSelector).toBeInTheDocument();
  244. userEvent.click(templateVariableSelector);
  245. await select(await screen.findByLabelText('Select option'), 'test');
  246. expect(await screen.findByText('test')).toBeInTheDocument();
  247. });
  248. });