NativeSearch.test.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { render, screen, waitFor } from '@testing-library/react';
  2. import userEvent from '@testing-library/user-event';
  3. import { UserEvent } from '@testing-library/user-event/dist/types/setup';
  4. import React from 'react';
  5. import { TempoDatasource, TempoQuery } from '../datasource';
  6. import NativeSearch from './NativeSearch';
  7. const getOptions = jest.fn().mockImplementation(() => {
  8. return new Promise((resolve) => {
  9. setTimeout(() => {
  10. resolve([
  11. {
  12. value: 'customer',
  13. label: 'customer',
  14. },
  15. {
  16. value: 'driver',
  17. label: 'driver',
  18. },
  19. ]);
  20. }, 1000);
  21. });
  22. });
  23. jest.mock('../language_provider', () => {
  24. return jest.fn().mockImplementation(() => {
  25. return { getOptions };
  26. });
  27. });
  28. jest.mock('@grafana/runtime', () => ({
  29. ...jest.requireActual('@grafana/runtime'),
  30. getTemplateSrv: () => ({
  31. replace: jest.fn(),
  32. containsTemplate: (val: string): boolean => {
  33. return val.includes('$');
  34. },
  35. }),
  36. }));
  37. let mockQuery = {
  38. refId: 'A',
  39. queryType: 'nativeSearch',
  40. key: 'Q-595a9bbc-2a25-49a7-9249-a52a0a475d83-0',
  41. serviceName: 'driver',
  42. spanName: 'customer',
  43. } as TempoQuery;
  44. describe('NativeSearch', () => {
  45. let user: UserEvent;
  46. beforeEach(() => {
  47. jest.useFakeTimers();
  48. // Need to use delay: null here to work with fakeTimers
  49. // see https://github.com/testing-library/user-event/issues/833
  50. user = userEvent.setup({ delay: null });
  51. });
  52. afterEach(() => {
  53. jest.useRealTimers();
  54. });
  55. it('should show loader when there is a delay', async () => {
  56. render(
  57. <NativeSearch datasource={{} as TempoDatasource} query={mockQuery} onChange={jest.fn()} onRunQuery={jest.fn()} />
  58. );
  59. const select = screen.getByRole('combobox', { name: 'select-service-name' });
  60. await user.click(select);
  61. const loader = screen.getByText('Loading options...');
  62. expect(loader).toBeInTheDocument();
  63. jest.advanceTimersByTime(1000);
  64. await waitFor(() => expect(screen.queryByText('Loading options...')).not.toBeInTheDocument());
  65. });
  66. it('should call the `onChange` function on click of the Input', async () => {
  67. const promise = Promise.resolve();
  68. const handleOnChange = jest.fn(() => promise);
  69. const fakeOptionChoice = {
  70. key: 'Q-595a9bbc-2a25-49a7-9249-a52a0a475d83-0',
  71. queryType: 'nativeSearch',
  72. refId: 'A',
  73. serviceName: 'driver',
  74. spanName: 'customer',
  75. };
  76. render(
  77. <NativeSearch
  78. datasource={{} as TempoDatasource}
  79. query={mockQuery}
  80. onChange={handleOnChange}
  81. onRunQuery={() => {}}
  82. />
  83. );
  84. const select = await screen.findByRole('combobox', { name: 'select-service-name' });
  85. expect(select).toBeInTheDocument();
  86. await user.click(select);
  87. jest.advanceTimersByTime(1000);
  88. await user.type(select, 'd');
  89. const driverOption = await screen.findByText('driver');
  90. await user.click(driverOption);
  91. expect(handleOnChange).toHaveBeenCalledWith(fakeOptionChoice);
  92. });
  93. it('should filter the span dropdown when user types a search value', async () => {
  94. render(
  95. <NativeSearch datasource={{} as TempoDatasource} query={mockQuery} onChange={() => {}} onRunQuery={() => {}} />
  96. );
  97. const select = await screen.findByRole('combobox', { name: 'select-service-name' });
  98. await user.click(select);
  99. jest.advanceTimersByTime(1000);
  100. expect(select).toBeInTheDocument();
  101. await user.type(select, 'd');
  102. var option = await screen.findByText('driver');
  103. expect(option).toBeDefined();
  104. await user.type(select, 'a');
  105. option = await screen.findByText('Hit enter to add');
  106. expect(option).toBeDefined();
  107. });
  108. it('should add variable to select menu options', async () => {
  109. mockQuery = {
  110. ...mockQuery,
  111. refId: '121314',
  112. serviceName: '$service',
  113. spanName: '$span',
  114. };
  115. render(
  116. <NativeSearch datasource={{} as TempoDatasource} query={mockQuery} onChange={() => {}} onRunQuery={() => {}} />
  117. );
  118. const asyncServiceSelect = screen.getByRole('combobox', { name: 'select-service-name' });
  119. expect(asyncServiceSelect).toBeInTheDocument();
  120. await user.click(asyncServiceSelect);
  121. jest.advanceTimersByTime(3000);
  122. await user.type(asyncServiceSelect, '$');
  123. var serviceOption = await screen.findByText('$service');
  124. expect(serviceOption).toBeDefined();
  125. const asyncSpanSelect = screen.getByRole('combobox', { name: 'select-span-name' });
  126. expect(asyncSpanSelect).toBeInTheDocument();
  127. await user.click(asyncSpanSelect);
  128. jest.advanceTimersByTime(3000);
  129. await user.type(asyncSpanSelect, '$');
  130. var operationOption = await screen.findByText('$span');
  131. expect(operationOption).toBeDefined();
  132. });
  133. });