QueryVariableEditor.test.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { render, screen } from '@testing-library/react';
  2. import userEvent from '@testing-library/user-event';
  3. import React from 'react';
  4. import { DataSourceApi } from '@grafana/data';
  5. import { mockDataSource } from 'app/features/alerting/unified/mocks';
  6. import { DataSourceType } from 'app/features/alerting/unified/utils/datasource';
  7. import { describe, expect } from '../../../../test/lib/common';
  8. import { NEW_VARIABLE_ID } from '../constants';
  9. import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor';
  10. import { KeyedVariableIdentifier } from '../state/types';
  11. import { VariableModel } from '../types';
  12. import { Props, QueryVariableEditorUnConnected } from './QueryVariableEditor';
  13. import { initialQueryVariableModelState } from './reducer';
  14. const setupTestContext = (options: Partial<Props>) => {
  15. const variableDefaults: Partial<VariableModel> = { rootStateKey: 'key' };
  16. const extended = {
  17. VariableQueryEditor: LegacyVariableQueryEditor,
  18. dataSource: {} as unknown as DataSourceApi,
  19. };
  20. const defaults: Props = {
  21. variable: { ...initialQueryVariableModelState, ...variableDefaults },
  22. initQueryVariableEditor: jest.fn(),
  23. changeQueryVariableDataSource: jest.fn(),
  24. changeQueryVariableQuery: jest.fn(),
  25. changeVariableMultiValue: jest.fn(),
  26. extended,
  27. onPropChange: jest.fn(),
  28. };
  29. const props: Props & Record<string, any> = { ...defaults, ...options };
  30. const { rerender } = render(<QueryVariableEditorUnConnected {...props} />);
  31. return { rerender, props };
  32. };
  33. const mockDS = mockDataSource({
  34. name: 'CloudManager',
  35. type: DataSourceType.Alertmanager,
  36. });
  37. jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => {
  38. return {
  39. getDataSourceSrv: () => ({
  40. get: () => Promise.resolve(mockDS),
  41. getList: () => [mockDS],
  42. getInstanceSettings: () => mockDS,
  43. }),
  44. };
  45. });
  46. const defaultIdentifier: KeyedVariableIdentifier = { type: 'query', rootStateKey: 'key', id: NEW_VARIABLE_ID };
  47. describe('QueryVariableEditor', () => {
  48. describe('when the component is mounted', () => {
  49. it('then it should call initQueryVariableEditor', () => {
  50. const { props } = setupTestContext({});
  51. expect(props.initQueryVariableEditor).toHaveBeenCalledTimes(1);
  52. expect(props.initQueryVariableEditor).toHaveBeenCalledWith(defaultIdentifier);
  53. });
  54. });
  55. describe('when the user changes', () => {
  56. it.each`
  57. fieldName | propName | expectedArgs
  58. ${'query'} | ${'changeQueryVariableQuery'} | ${[defaultIdentifier, 't', 't']}
  59. ${'regex'} | ${'onPropChange'} | ${[{ propName: 'regex', propValue: 't', updateOptions: true }]}
  60. `(
  61. '$fieldName field and tabs away then $propName should be called with correct args',
  62. async ({ fieldName, propName, expectedArgs }) => {
  63. const { props } = setupTestContext({});
  64. const propUnderTest = props[propName];
  65. const fieldAccessor = fieldAccessors[fieldName];
  66. await userEvent.type(fieldAccessor(), 't');
  67. await userEvent.tab();
  68. expect(propUnderTest).toHaveBeenCalledTimes(1);
  69. expect(propUnderTest).toHaveBeenCalledWith(...expectedArgs);
  70. }
  71. );
  72. });
  73. describe('when the user changes', () => {
  74. it.each`
  75. fieldName | propName
  76. ${'query'} | ${'changeQueryVariableQuery'}
  77. ${'regex'} | ${'onPropChange'}
  78. `(
  79. '$fieldName field but reverts the change and tabs away then $propName should not be called',
  80. async ({ fieldName, propName }) => {
  81. const { props } = setupTestContext({});
  82. const propUnderTest = props[propName];
  83. const fieldAccessor = fieldAccessors[fieldName];
  84. await userEvent.type(fieldAccessor(), 't');
  85. await userEvent.type(fieldAccessor(), '{backspace}');
  86. await userEvent.tab();
  87. expect(propUnderTest).not.toHaveBeenCalled();
  88. }
  89. );
  90. });
  91. });
  92. const getQueryField = () =>
  93. screen.getByRole('textbox', { name: /variable editor form default variable query editor textarea/i });
  94. const getRegExField = () => screen.getByLabelText('Regex');
  95. const fieldAccessors: Record<string, () => HTMLElement> = {
  96. query: getQueryField,
  97. regex: getRegExField,
  98. };