mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
pass the value to the input instead to downshift (#6235)
* pass the value to the input instead to downshift Signed-off-by: blalov <boyko.lalov@tick42.com> * adjust expression input tests Signed-off-by: blalov <boyko.lalov@tick42.com> * improve ExpressionInput test coverage Signed-off-by: blalov <boyko.lalov@tick42.com>
This commit is contained in:
parent
95554074d8
commit
7293c859ab
|
@ -1,5 +1,5 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount, ReactWrapper } from 'enzyme';
|
||||||
import ExpressionInput from './ExpressionInput';
|
import ExpressionInput from './ExpressionInput';
|
||||||
import Downshift from 'downshift';
|
import Downshift from 'downshift';
|
||||||
import { Button, InputGroup, InputGroupAddon, Input } from 'reactstrap';
|
import { Button, InputGroup, InputGroupAddon, Input } from 'reactstrap';
|
||||||
|
@ -25,11 +25,15 @@ describe('ExpressionInput', () => {
|
||||||
executeQuery: (): void => {},
|
executeQuery: (): void => {},
|
||||||
loading: false,
|
loading: false,
|
||||||
};
|
};
|
||||||
const expressionInput = mount(<ExpressionInput {...expressionInputProps} />);
|
|
||||||
|
let expressionInput: ReactWrapper;
|
||||||
|
beforeEach(() => {
|
||||||
|
expressionInput = mount(<ExpressionInput {...expressionInputProps} />);
|
||||||
|
});
|
||||||
|
|
||||||
it('renders a downshift component', () => {
|
it('renders a downshift component', () => {
|
||||||
const downshift = expressionInput.find(Downshift);
|
const downshift = expressionInput.find(Downshift);
|
||||||
expect(downshift.prop('inputValue')).toEqual('node_cpu');
|
expect(downshift).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders an InputGroup', () => {
|
it('renders an InputGroup', () => {
|
||||||
|
@ -52,7 +56,6 @@ describe('ExpressionInput', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders an Input', () => {
|
it('renders an Input', () => {
|
||||||
const expressionInput = mount(<ExpressionInput {...expressionInputProps} />);
|
|
||||||
const input = expressionInput.find(Input);
|
const input = expressionInput.find(Input);
|
||||||
expect(input.prop('style')).toEqual({ height: 0 });
|
expect(input.prop('style')).toEqual({ height: 0 });
|
||||||
expect(input.prop('autoFocus')).toEqual(true);
|
expect(input.prop('autoFocus')).toEqual(true);
|
||||||
|
@ -84,6 +87,83 @@ describe('ExpressionInput', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('handleInput', () => {
|
||||||
|
it('should call setState', () => {
|
||||||
|
const instance: any = expressionInput.instance();
|
||||||
|
const stateSpy = jest.spyOn(instance, 'setState');
|
||||||
|
instance.handleInput();
|
||||||
|
expect(stateSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleDropdownSelection', () => {
|
||||||
|
it('should call setState with selected value', () => {
|
||||||
|
const instance: any = expressionInput.instance();
|
||||||
|
const stateSpy = jest.spyOn(instance, 'setState');
|
||||||
|
instance.handleDropdownSelection('foo');
|
||||||
|
expect(stateSpy).toHaveBeenCalledWith({ value: 'foo', height: 'auto' }, expect.anything());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleKeyPress', () => {
|
||||||
|
it('should call executeQuery on Enter key pressed', () => {
|
||||||
|
const spyExecuteQuery = jest.fn();
|
||||||
|
const input = mount(<ExpressionInput executeQuery={spyExecuteQuery} {...({} as any)} />);
|
||||||
|
const instance: any = input.instance();
|
||||||
|
instance.handleKeyPress({ preventDefault: jest.fn, key: 'Enter' });
|
||||||
|
expect(spyExecuteQuery).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
it('should NOT call executeQuery on Enter + Shift', () => {
|
||||||
|
const spyExecuteQuery = jest.fn();
|
||||||
|
const input = mount(<ExpressionInput executeQuery={spyExecuteQuery} {...({} as any)} />);
|
||||||
|
const instance: any = input.instance();
|
||||||
|
instance.handleKeyPress({ preventDefault: jest.fn, key: 'Enter', shiftKey: true });
|
||||||
|
expect(spyExecuteQuery).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSearchMatches', () => {
|
||||||
|
it('should return matched value', () => {
|
||||||
|
const instance: any = expressionInput.instance();
|
||||||
|
expect(instance.getSearchMatches('foo', ['barfoobaz', 'bazasdbaz'])).toHaveLength(1);
|
||||||
|
});
|
||||||
|
it('should return empty array if no match found', () => {
|
||||||
|
const instance: any = expressionInput.instance();
|
||||||
|
expect(instance.getSearchMatches('foo', ['barbaz', 'bazasdbaz'])).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createAutocompleteSection', () => {
|
||||||
|
it('should close menu if no matches found', () => {
|
||||||
|
const input = mount(<ExpressionInput autocompleteSections={{ title: ['foo', 'bar', 'baz'] }} {...({} as any)} />);
|
||||||
|
const instance: any = input.instance();
|
||||||
|
const spyCloseMenu = jest.fn();
|
||||||
|
instance.createAutocompleteSection({ inputValue: 'qqqqqq', closeMenu: spyCloseMenu });
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(spyCloseMenu).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not render lsit if inputValue not exist', () => {
|
||||||
|
const input = mount(<ExpressionInput autocompleteSections={{ title: ['foo', 'bar', 'baz'] }} {...({} as any)} />);
|
||||||
|
const instance: any = input.instance();
|
||||||
|
const spyCloseMenu = jest.fn();
|
||||||
|
instance.createAutocompleteSection({ closeMenu: spyCloseMenu });
|
||||||
|
setTimeout(() => expect(spyCloseMenu).toHaveBeenCalled());
|
||||||
|
});
|
||||||
|
it('should render autosuggest-dropdown', () => {
|
||||||
|
const input = mount(<ExpressionInput autocompleteSections={{ title: ['foo', 'bar', 'baz'] }} {...({} as any)} />);
|
||||||
|
const instance: any = input.instance();
|
||||||
|
const spyGetMenuProps = jest.fn();
|
||||||
|
const sections = instance.createAutocompleteSection({
|
||||||
|
inputValue: 'foo',
|
||||||
|
highlightedIndex: 0,
|
||||||
|
getMenuProps: spyGetMenuProps,
|
||||||
|
getItemProps: jest.fn,
|
||||||
|
});
|
||||||
|
expect(sections.props.className).toEqual('autosuggest-dropdown');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when downshift is open', () => {
|
describe('when downshift is open', () => {
|
||||||
it('closes the menu on "Enter"', () => {
|
it('closes the menu on "Enter"', () => {
|
||||||
const downshift = expressionInput.find(Downshift);
|
const downshift = expressionInput.find(Downshift);
|
||||||
|
@ -94,6 +174,18 @@ describe('ExpressionInput', () => {
|
||||||
expect(downshift.state('isOpen')).toBe(false);
|
expect(downshift.state('isOpen')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should blur input on escape', () => {
|
||||||
|
const downshift = expressionInput.find(Downshift);
|
||||||
|
const instance: any = expressionInput.instance();
|
||||||
|
const spyBlur = jest.fn();
|
||||||
|
instance.exprInputRef.current = { blur: spyBlur };
|
||||||
|
const input = downshift.find(Input);
|
||||||
|
downshift.setState({ isOpen: false });
|
||||||
|
const event = getKeyEvent('Escape');
|
||||||
|
input.simulate('keydown', event);
|
||||||
|
expect(spyBlur).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('noops on ArrowUp or ArrowDown', () => {
|
it('noops on ArrowUp or ArrowDown', () => {
|
||||||
const downshift = expressionInput.find(Downshift);
|
const downshift = expressionInput.find(Downshift);
|
||||||
const input = downshift.find(Input);
|
const input = downshift.find(Input);
|
||||||
|
@ -107,16 +199,6 @@ describe('ExpressionInput', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not render an autosuggest if there are no matches', () => {
|
it('does not render an autosuggest if there are no matches', () => {
|
||||||
const expressionInputProps = {
|
|
||||||
value: 'foo',
|
|
||||||
autocompleteSections: {
|
|
||||||
'Query History': [],
|
|
||||||
'Metric Names': [],
|
|
||||||
},
|
|
||||||
executeQuery: (): void => {},
|
|
||||||
loading: false,
|
|
||||||
};
|
|
||||||
const expressionInput = mount(<ExpressionInput {...expressionInputProps} />);
|
|
||||||
const downshift = expressionInput.find(Downshift);
|
const downshift = expressionInput.find(Downshift);
|
||||||
downshift.setState({ isOpen: true });
|
downshift.setState({ isOpen: true });
|
||||||
const ul = downshift.find('ul');
|
const ul = downshift.find('ul');
|
||||||
|
@ -126,12 +208,14 @@ describe('ExpressionInput', () => {
|
||||||
it('renders an autosuggest if there are matches', () => {
|
it('renders an autosuggest if there are matches', () => {
|
||||||
const downshift = expressionInput.find(Downshift);
|
const downshift = expressionInput.find(Downshift);
|
||||||
downshift.setState({ isOpen: true });
|
downshift.setState({ isOpen: true });
|
||||||
const ul = downshift.find('ul');
|
setTimeout(() => {
|
||||||
expect(ul.prop('className')).toEqual('autosuggest-dropdown-list');
|
const ul = downshift.find('ul');
|
||||||
const items = ul.find(SanitizeHTML);
|
expect(ul.prop('className')).toEqual('card list-group');
|
||||||
expect(items.map(item => item.text()).join(', ')).toEqual(
|
const items = ul.find(SanitizeHTML);
|
||||||
'node_cpu_guest_seconds_total, node_cpu_seconds_total, instance:node_cpu_utilisation:rate1m'
|
expect(items.map(item => item.text()).join(', ')).toEqual(
|
||||||
);
|
'node_cpu_guest_seconds_total, node_cpu_seconds_total, instance:node_cpu_utilisation:rate1m'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ class ExpressionInput extends Component<ExpressionInputProps, ExpressionInputSta
|
||||||
|
|
||||||
handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
if (event.key === 'Enter' && !event.shiftKey) {
|
if (event.key === 'Enter' && !event.shiftKey) {
|
||||||
this.props.executeQuery(this.exprInputRef.current!.value);
|
this.executeQuery();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -126,7 +126,7 @@ class ExpressionInput extends Component<ExpressionInputProps, ExpressionInputSta
|
||||||
render() {
|
render() {
|
||||||
const { value, height } = this.state;
|
const { value, height } = this.state;
|
||||||
return (
|
return (
|
||||||
<Downshift inputValue={value} onSelect={this.handleDropdownSelection}>
|
<Downshift onSelect={this.handleDropdownSelection}>
|
||||||
{downshift => (
|
{downshift => (
|
||||||
<div>
|
<div>
|
||||||
<InputGroup className="expression-input">
|
<InputGroup className="expression-input">
|
||||||
|
@ -171,6 +171,7 @@ class ExpressionInput extends Component<ExpressionInputProps, ExpressionInputSta
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
} as any)}
|
} as any)}
|
||||||
|
value={value}
|
||||||
/>
|
/>
|
||||||
<InputGroupAddon addonType="append">
|
<InputGroupAddon addonType="append">
|
||||||
<Button className="execute-btn" color="primary" onClick={this.executeQuery}>
|
<Button className="execute-btn" color="primary" onClick={this.executeQuery}>
|
||||||
|
|
Loading…
Reference in a new issue