mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Lens] Corrects incorrect copy for line chart & fix flaky test (#192734)
## Summary Corrects incorrect copy for line chart. Rewrites some of the tests to rtl. Unskips flaky or failing tests. Fixes https://github.com/elastic/kibana/issues/192476 Removes some errors from the console that appear during unit test running. --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
4d4afa55b3
commit
e1db296963
14 changed files with 499 additions and 965 deletions
|
@ -125,11 +125,11 @@ const datasourceMap = mockDatasourceMap();
|
|||
const visualizationMap = mockVisualizationMap();
|
||||
|
||||
describe('LensEditConfigurationFlyout', () => {
|
||||
function renderConfigFlyout(
|
||||
async function renderConfigFlyout(
|
||||
propsOverrides: Partial<EditConfigPanelProps> = {},
|
||||
query?: Query | AggregateQuery
|
||||
) {
|
||||
return renderWithReduxStore(
|
||||
const { container, ...rest } = renderWithReduxStore(
|
||||
<LensEditConfigurationFlyout
|
||||
attributes={lensAttributes}
|
||||
updatePanelState={jest.fn()}
|
||||
|
@ -155,12 +155,13 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
},
|
||||
}
|
||||
);
|
||||
await waitFor(() => container.querySelector('lnsEditFlyoutBody'));
|
||||
return { container, ...rest };
|
||||
}
|
||||
|
||||
it('should display the header and the link to editor if necessary props are given', async () => {
|
||||
const navigateToLensEditorSpy = jest.fn();
|
||||
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
displayFlyoutHeader: true,
|
||||
navigateToLensEditor: navigateToLensEditorSpy,
|
||||
});
|
||||
|
@ -170,7 +171,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
});
|
||||
|
||||
it('should display the header title correctly for a newly created panel', async () => {
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
displayFlyoutHeader: true,
|
||||
isNewPanel: true,
|
||||
});
|
||||
|
@ -182,7 +183,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
it('should call the closeFlyout callback if cancel button is clicked', async () => {
|
||||
const closeFlyoutSpy = jest.fn();
|
||||
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
closeFlyout: closeFlyoutSpy,
|
||||
});
|
||||
expect(screen.getByTestId('lns-layerPanel-0')).toBeInTheDocument();
|
||||
|
@ -192,7 +193,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
|
||||
it('should call the updatePanelState callback if cancel button is clicked', async () => {
|
||||
const updatePanelStateSpy = jest.fn();
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
updatePanelState: updatePanelStateSpy,
|
||||
});
|
||||
expect(screen.getByTestId('lns-layerPanel-0')).toBeInTheDocument();
|
||||
|
@ -203,7 +204,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
it('should call the updateByRefInput callback if cancel button is clicked and savedObjectId exists', async () => {
|
||||
const updateByRefInputSpy = jest.fn();
|
||||
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
closeFlyout: jest.fn(),
|
||||
updateByRefInput: updateByRefInputSpy,
|
||||
savedObjectId: 'id',
|
||||
|
@ -216,7 +217,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
const updateByRefInputSpy = jest.fn();
|
||||
const saveByRefSpy = jest.fn();
|
||||
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
closeFlyout: jest.fn(),
|
||||
updateByRefInput: updateByRefInputSpy,
|
||||
savedObjectId: 'id',
|
||||
|
@ -230,7 +231,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
it('should call the onApplyCb callback if apply button is clicked', async () => {
|
||||
const onApplyCbSpy = jest.fn();
|
||||
|
||||
renderConfigFlyout(
|
||||
await renderConfigFlyout(
|
||||
{
|
||||
closeFlyout: jest.fn(),
|
||||
onApplyCb: onApplyCbSpy,
|
||||
|
@ -254,14 +255,14 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
});
|
||||
|
||||
it('should not display the editor if canEditTextBasedQuery prop is false', async () => {
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
canEditTextBasedQuery: false,
|
||||
});
|
||||
expect(screen.queryByTestId('TextBasedLangEditor')).toBeNull();
|
||||
});
|
||||
|
||||
it('should not display the editor if canEditTextBasedQuery prop is true but the query is not text based', async () => {
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
canEditTextBasedQuery: true,
|
||||
attributes: {
|
||||
...lensAttributes,
|
||||
|
@ -278,14 +279,14 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
});
|
||||
|
||||
it('should not display the suggestions if hidesSuggestions prop is true', async () => {
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
hidesSuggestions: true,
|
||||
});
|
||||
expect(screen.queryByTestId('InlineEditingSuggestions')).toBeNull();
|
||||
});
|
||||
|
||||
it('should display the suggestions if canEditTextBasedQuery prop is true', async () => {
|
||||
renderConfigFlyout(
|
||||
await renderConfigFlyout(
|
||||
{
|
||||
canEditTextBasedQuery: true,
|
||||
},
|
||||
|
@ -298,7 +299,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
});
|
||||
|
||||
it('should display the ES|QL results table if canEditTextBasedQuery prop is true', async () => {
|
||||
renderConfigFlyout({
|
||||
await renderConfigFlyout({
|
||||
canEditTextBasedQuery: true,
|
||||
});
|
||||
await waitFor(() => expect(screen.getByTestId('ESQLQueryResults')).toBeInTheDocument());
|
||||
|
@ -317,7 +318,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
// todo: replace testDatasource with formBased or textBased as it's the only ones accepted
|
||||
// @ts-ignore
|
||||
newProps.attributes.state.datasourceStates.testDatasource = 'state';
|
||||
renderConfigFlyout(newProps);
|
||||
await renderConfigFlyout(newProps);
|
||||
expect(screen.getByRole('button', { name: /apply changes/i })).toBeDisabled();
|
||||
});
|
||||
it('save button should be disabled if expression cannot be generated', async () => {
|
||||
|
@ -337,7 +338,7 @@ describe('LensEditConfigurationFlyout', () => {
|
|||
},
|
||||
};
|
||||
|
||||
renderConfigFlyout(newProps);
|
||||
await renderConfigFlyout(newProps);
|
||||
expect(screen.getByRole('button', { name: /apply changes/i })).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,7 +41,7 @@ import type { FormBasedPrivateState } from './types';
|
|||
import { IndexPatternServiceAPI } from '../../data_views_service/service';
|
||||
import { FieldItem } from '../common/field_item';
|
||||
|
||||
export type Props = Omit<
|
||||
export type FormBasedDataPanelProps = Omit<
|
||||
DatasourceDataPanelProps<FormBasedPrivateState>,
|
||||
'core' | 'onChangeIndexPattern'
|
||||
> & {
|
||||
|
@ -97,7 +97,7 @@ export function FormBasedDataPanel({
|
|||
onIndexPatternRefresh,
|
||||
usedIndexPatterns,
|
||||
layerFields,
|
||||
}: Props) {
|
||||
}: FormBasedDataPanelProps) {
|
||||
const { indexPatterns, indexPatternRefs } = frame.dataViews;
|
||||
const { currentIndexPatternId } = state;
|
||||
|
||||
|
|
|
@ -187,8 +187,7 @@ function mountWithServices(component: React.ReactElement): ReactWrapper {
|
|||
* - Dimension trigger: Not tested here
|
||||
* - Dimension editor component: First half of the tests
|
||||
*/
|
||||
// Failing: See https://github.com/elastic/kibana/issues/192476
|
||||
describe.skip('FormBasedDimensionEditor', () => {
|
||||
describe('FormBasedDimensionEditor', () => {
|
||||
let state: FormBasedPrivateState;
|
||||
let setState: jest.Mock;
|
||||
let defaultProps: FormBasedDimensionEditorProps;
|
||||
|
@ -353,8 +352,7 @@ describe.skip('FormBasedDimensionEditor', () => {
|
|||
await userEvent.click(screen.getByRole('button', { name: /open list of options/i }));
|
||||
expect(screen.getByText(/There aren't any options available/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should list all field names and document as a whole in prioritized order', async () => {
|
||||
test('should list all field names and document as a whole in prioritized order', async () => {
|
||||
const { getVisibleFieldSelectOptions } = renderDimensionPanel();
|
||||
|
||||
const comboBoxButton = screen.getAllByRole('button', { name: /open list of options/i })[0];
|
||||
|
@ -372,14 +370,9 @@ describe.skip('FormBasedDimensionEditor', () => {
|
|||
];
|
||||
expect(allOptions.slice(0, 7)).toEqual(getVisibleFieldSelectOptions());
|
||||
|
||||
// keep hitting arrow down to scroll to the next options (react-window only renders visible options)
|
||||
await userEvent.type(comboBoxInput, '{ArrowDown}'.repeat(12));
|
||||
|
||||
expect(getVisibleFieldSelectOptions()).toEqual(allOptions.slice(5, 16));
|
||||
|
||||
// press again to go back to the beginning
|
||||
await userEvent.type(comboBoxInput, '{ArrowDown}');
|
||||
expect(getVisibleFieldSelectOptions()).toEqual(allOptions.slice(0, 9));
|
||||
// // press arrow up to go back to the beginning
|
||||
await userEvent.type(comboBoxInput, '{ArrowUp}{ArrowUp}');
|
||||
expect(getVisibleFieldSelectOptions()).toEqual(allOptions.slice(8));
|
||||
});
|
||||
|
||||
it('should hide fields that have no data', () => {
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { EuiComboBox } from '@elastic/eui';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { GenericOperationDefinition } from '../operations';
|
||||
import {
|
||||
averageOperation,
|
||||
|
@ -28,38 +29,8 @@ import { GenericIndexPatternColumn, FormBasedLayer, FormBasedPrivateState } from
|
|||
import { ReferenceBasedIndexPatternColumn } from '../operations/definitions/column_types';
|
||||
import { FieldSelect } from './field_select';
|
||||
import { IndexPattern, VisualizationDimensionGroupConfig } from '../../../types';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
jest.mock('../operations/layer_helpers', () => {
|
||||
const original = jest.requireActual('../operations/layer_helpers');
|
||||
|
||||
return {
|
||||
...original,
|
||||
insertOrReplaceColumn: () => {
|
||||
return {} as FormBasedLayer;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
indexPattern: createMockedIndexPattern(),
|
||||
currentFieldIsInvalid: false,
|
||||
incompleteField: null,
|
||||
incompleteOperation: undefined,
|
||||
incompleteParams: {},
|
||||
dimensionGroups: [] as VisualizationDimensionGroupConfig[],
|
||||
groupId: 'any',
|
||||
operationDefinitionMap: {
|
||||
terms: termsOperation,
|
||||
average: averageOperation,
|
||||
count: countOperation,
|
||||
differences: derivativeOperation,
|
||||
staticValue: staticValueOperation,
|
||||
min: minOperation,
|
||||
} as unknown as Record<string, GenericOperationDefinition>,
|
||||
};
|
||||
|
||||
function getStringBasedOperationColumn(field = 'source'): FieldBasedIndexPatternColumn {
|
||||
function getStringBasedOperationColumn(field = 'source') {
|
||||
return {
|
||||
label: `Top value of ${field}`,
|
||||
dataType: 'string',
|
||||
|
@ -109,12 +80,32 @@ function getCountOperationColumn(): GenericIndexPatternColumn {
|
|||
operationType: 'count',
|
||||
};
|
||||
}
|
||||
function getLayer(
|
||||
col1: GenericIndexPatternColumn = getStringBasedOperationColumn(),
|
||||
indexPattern?: IndexPattern
|
||||
) {
|
||||
const defaultDataView = createMockedIndexPattern();
|
||||
const defaultProps = {
|
||||
columnId: 'col1',
|
||||
layer: getLayer(),
|
||||
operationSupportMatrix: getDefaultOperationSupportMatrix(getLayer(), 'col1'),
|
||||
indexPattern: defaultDataView,
|
||||
currentFieldIsInvalid: false,
|
||||
incompleteField: null,
|
||||
incompleteOperation: undefined,
|
||||
incompleteParams: {},
|
||||
dimensionGroups: [] as VisualizationDimensionGroupConfig[],
|
||||
groupId: 'any',
|
||||
updateLayer: jest.fn(),
|
||||
operationDefinitionMap: {
|
||||
terms: termsOperation,
|
||||
average: averageOperation,
|
||||
count: countOperation,
|
||||
differences: derivativeOperation,
|
||||
staticValue: staticValueOperation,
|
||||
min: minOperation,
|
||||
} as unknown as Record<string, GenericOperationDefinition>,
|
||||
};
|
||||
|
||||
function getLayer(col1: GenericIndexPatternColumn = getStringBasedOperationColumn()) {
|
||||
return {
|
||||
indexPatternId: defaultProps.indexPattern.id,
|
||||
indexPatternId: defaultDataView.id,
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1,
|
||||
|
@ -135,53 +126,28 @@ function getDefaultOperationSupportMatrix(
|
|||
filterOperations: () => true,
|
||||
columnId,
|
||||
indexPatterns: {
|
||||
[defaultProps.indexPattern.id]: indexPattern ?? defaultProps.indexPattern,
|
||||
[defaultDataView.id]: indexPattern ?? defaultDataView,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const mockedReader = {
|
||||
hasFieldData: (dataViewId: string, fieldName: string) => {
|
||||
if (defaultProps.indexPattern.id !== dataViewId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const map: Record<string, boolean> = {};
|
||||
for (const field of defaultProps.indexPattern.fields) {
|
||||
map[field.name] = true;
|
||||
}
|
||||
|
||||
return map[fieldName];
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock('@kbn/unified-field-list/src/hooks/use_existing_fields', () => ({
|
||||
useExistingFieldsReader: jest.fn(() => mockedReader),
|
||||
}));
|
||||
|
||||
const renderFieldInput = (
|
||||
overrideProps?: Partial<FieldInputProps<FieldBasedIndexPatternColumn>>
|
||||
) => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
const layer = getLayer();
|
||||
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
|
||||
return render(
|
||||
<FieldInput
|
||||
{...defaultProps}
|
||||
layer={layer}
|
||||
columnId={'col1'}
|
||||
updateLayer={updateLayerSpy}
|
||||
operationSupportMatrix={operationSupportMatrix}
|
||||
{...overrideProps}
|
||||
/>
|
||||
);
|
||||
return render(<FieldInput {...defaultProps} {...overrideProps} />);
|
||||
};
|
||||
|
||||
const waitForComboboxToClose = async () =>
|
||||
await waitFor(() => expect(screen.queryByRole('listbox')).toBeNull());
|
||||
|
||||
const getErrorElement = (container: HTMLElement) => container.querySelector('.euiFormErrorText');
|
||||
const getLabelElement = () =>
|
||||
screen.getByTestId('indexPattern-field-selection-row').querySelector('label');
|
||||
|
||||
describe('FieldInput', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
it('should render a field select box', () => {
|
||||
renderFieldInput();
|
||||
expect(screen.getByTestId('indexPattern-dimension-field')).toBeInTheDocument();
|
||||
|
@ -248,6 +214,14 @@ describe('FieldInput', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should update the layer on field selection', async () => {
|
||||
renderFieldInput({ selectedColumn: getStringBasedOperationColumn() });
|
||||
await userEvent.click(screen.getByRole('combobox'));
|
||||
fireEvent.click(screen.getByTestId('lns-fieldOption-bytes'));
|
||||
expect(defaultProps.updateLayer).toHaveBeenCalled();
|
||||
await waitForComboboxToClose();
|
||||
});
|
||||
|
||||
it('should prioritize errors over help messages', () => {
|
||||
const helpMessage = 'My help message';
|
||||
renderFieldInput({ helpMessage, currentFieldIsInvalid: true });
|
||||
|
@ -256,32 +230,16 @@ describe('FieldInput', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should update the layer on field selection', async () => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
renderFieldInput({
|
||||
selectedColumn: getStringBasedOperationColumn(),
|
||||
updateLayer: updateLayerSpy,
|
||||
});
|
||||
await userEvent.click(screen.getByRole('combobox'));
|
||||
fireEvent.click(screen.getByTestId('lns-fieldOption-bytes'));
|
||||
expect(updateLayerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not trigger when the same selected field is selected again', async () => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
renderFieldInput({
|
||||
selectedColumn: getStringBasedOperationColumn(),
|
||||
updateLayer: updateLayerSpy,
|
||||
});
|
||||
|
||||
renderFieldInput({ selectedColumn: getStringBasedOperationColumn() });
|
||||
await userEvent.click(screen.getByRole('combobox'));
|
||||
fireEvent.click(screen.getByTestId('lns-fieldOption-source'));
|
||||
|
||||
expect(updateLayerSpy).not.toHaveBeenCalled();
|
||||
await waitForComboboxToClose();
|
||||
expect(defaultProps.updateLayer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should prioritize incomplete fields over selected column field to display', () => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
const layer = getLayer();
|
||||
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
|
||||
const instance = mount(
|
||||
|
@ -289,7 +247,7 @@ describe('FieldInput', () => {
|
|||
{...defaultProps}
|
||||
layer={layer}
|
||||
columnId={'col1'}
|
||||
updateLayer={updateLayerSpy}
|
||||
updateLayer={defaultProps.updateLayer}
|
||||
operationSupportMatrix={operationSupportMatrix}
|
||||
incompleteField={'dest'}
|
||||
selectedColumn={getStringBasedOperationColumn()}
|
||||
|
@ -305,7 +263,6 @@ describe('FieldInput', () => {
|
|||
});
|
||||
|
||||
it('should forward the onDeleteColumn function', () => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
const onDeleteColumn = jest.fn();
|
||||
const layer = getLayer();
|
||||
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
|
||||
|
@ -314,7 +271,7 @@ describe('FieldInput', () => {
|
|||
{...defaultProps}
|
||||
layer={layer}
|
||||
columnId={'col1'}
|
||||
updateLayer={updateLayerSpy}
|
||||
updateLayer={defaultProps.updateLayer}
|
||||
operationSupportMatrix={operationSupportMatrix}
|
||||
onDeleteColumn={onDeleteColumn}
|
||||
/>
|
||||
|
@ -325,7 +282,7 @@ describe('FieldInput', () => {
|
|||
});
|
||||
|
||||
expect(onDeleteColumn).toHaveBeenCalled();
|
||||
expect(updateLayerSpy).not.toHaveBeenCalled();
|
||||
expect(defaultProps.updateLayer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('time series group', () => {
|
||||
|
@ -341,7 +298,6 @@ describe('FieldInput', () => {
|
|||
return layer;
|
||||
}
|
||||
it('should not render the time dimension category if it has tsdb metric column but the group is not a breakdown', () => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
const layer = getLayerWithTSDBMetric();
|
||||
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
|
||||
const instance = mount(
|
||||
|
@ -359,7 +315,7 @@ describe('FieldInput', () => {
|
|||
])}
|
||||
layer={layer}
|
||||
columnId={'col1'}
|
||||
updateLayer={updateLayerSpy}
|
||||
updateLayer={defaultProps.updateLayer}
|
||||
operationSupportMatrix={operationSupportMatrix}
|
||||
/>
|
||||
);
|
||||
|
@ -368,7 +324,6 @@ describe('FieldInput', () => {
|
|||
});
|
||||
|
||||
it('should render the time dimension category if it has tsdb metric column and the group is a breakdown one', () => {
|
||||
const updateLayerSpy = jest.fn();
|
||||
const layer = getLayerWithTSDBMetric();
|
||||
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
|
||||
const instance = mount(
|
||||
|
@ -393,7 +348,7 @@ describe('FieldInput', () => {
|
|||
groupId="breakdown"
|
||||
layer={layer}
|
||||
columnId={'col1'}
|
||||
updateLayer={updateLayerSpy}
|
||||
updateLayer={defaultProps.updateLayer}
|
||||
operationSupportMatrix={operationSupportMatrix}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -63,7 +63,7 @@ const renderFormatSelector = (propsOverrides?: Partial<FormatSelectorProps>) =>
|
|||
// see for example the first two tests, they run the same code but expect
|
||||
// different results. With the updated userEvent code the tests no longer work
|
||||
// with this setup and should be refactored.
|
||||
describe.skip('FormatSelector', () => {
|
||||
describe('FormatSelector', () => {
|
||||
let user: UserEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -83,7 +83,7 @@ describe.skip('FormatSelector', () => {
|
|||
});
|
||||
it('updates the format decimals to upper range when input exceeds the range', async () => {
|
||||
renderFormatSelector();
|
||||
await user.type(screen.getByLabelText('Decimals'), '{backspace}10');
|
||||
await user.type(screen.getByLabelText('Decimals'), '{backspace}20');
|
||||
expect(props.onChange).toBeCalledWith({ id: 'bytes', params: { decimals: 15 } });
|
||||
});
|
||||
it('updates the format decimals to lower range when input is smaller than range', async () => {
|
||||
|
|
|
@ -13,6 +13,9 @@ import { getFieldByNameFactory } from './pure_helpers';
|
|||
import { TermsIndexPatternColumn } from './operations';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { value: 400 });
|
||||
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { value: 200 });
|
||||
|
||||
jest.mock('@kbn/unified-search-plugin/public', () => {
|
||||
const actual = jest.requireActual('@kbn/unified-search-plugin/public');
|
||||
return {
|
||||
|
@ -219,9 +222,7 @@ describe('Layer Data Panel', () => {
|
|||
};
|
||||
});
|
||||
|
||||
const renderLayerPanel = () => {
|
||||
return render(<LayerPanel {...defaultProps} />);
|
||||
};
|
||||
const renderLayerPanel = () => render(<LayerPanel {...defaultProps} />);
|
||||
|
||||
it('should list all index patterns', async () => {
|
||||
renderLayerPanel();
|
||||
|
|
|
@ -264,8 +264,8 @@ describe('chart_switch', () => {
|
|||
fireEvent.click(getMenuItem(subType));
|
||||
};
|
||||
|
||||
const waitForChartSwitchClosed = () => {
|
||||
waitFor(() => {
|
||||
const waitForChartSwitchClosed = async () => {
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('lnsChartSwitchList')).not.toBeInTheDocument();
|
||||
});
|
||||
};
|
||||
|
@ -448,14 +448,13 @@ describe('chart_switch', () => {
|
|||
await openChartSwitch();
|
||||
switchToVis('testVis2');
|
||||
|
||||
// expect(datasourceMap.testDatasource.publicAPIMock.getTableSpec).toHaveBeenCalled();
|
||||
expect(visualizationMap.testVis2.getSuggestions).toHaveBeenCalled();
|
||||
expect(visualizationMap.testVis2.initialize).toHaveBeenCalledWith(
|
||||
expect.any(Function), // generated layerId
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
waitForChartSwitchClosed();
|
||||
await waitForChartSwitchClosed();
|
||||
});
|
||||
|
||||
it('should use initial state if there is no suggestion from the target visualization', async () => {
|
||||
|
|
|
@ -444,52 +444,6 @@ describe('editor_frame', () => {
|
|||
instance.unmount();
|
||||
});
|
||||
|
||||
// this test doesn't test anything, it's buggy and should be rewritten when we find a way to user test drag and drop
|
||||
it.skip('should switch to best suggested visualization on field drop', async () => {
|
||||
const suggestionVisState = {};
|
||||
|
||||
visualizationMap = {
|
||||
testVis: {
|
||||
...mockVisualization,
|
||||
getSuggestions: () => [
|
||||
{
|
||||
score: 0.2,
|
||||
state: {},
|
||||
title: 'Suggestion1',
|
||||
previewIcon: 'empty',
|
||||
},
|
||||
{
|
||||
score: 0.8,
|
||||
state: suggestionVisState,
|
||||
title: 'Suggestion2',
|
||||
previewIcon: 'empty',
|
||||
},
|
||||
],
|
||||
},
|
||||
testVis2: mockVisualization2,
|
||||
};
|
||||
datasourceMap = {
|
||||
testDatasource: {
|
||||
...mockDatasource,
|
||||
getDatasourceSuggestionsForField: () => [generateSuggestion()],
|
||||
getDatasourceSuggestionsFromCurrentState: () => [generateSuggestion()],
|
||||
getDatasourceSuggestionsForVisualizeField: () => [generateSuggestion()],
|
||||
},
|
||||
};
|
||||
renderEditorFrame();
|
||||
|
||||
mockVisualization.getConfiguration.mockClear();
|
||||
act(() => {
|
||||
instance.find('[data-test-subj="lnsWorkspace"]').last().simulate('drop');
|
||||
});
|
||||
|
||||
expect(mockVisualization.getConfiguration).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
state: {},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should use the currently selected visualization if possible on field drop', async () => {
|
||||
mockDatasource.getLayers.mockReturnValue(['first', 'second', 'third']);
|
||||
const suggestionVisState = {};
|
||||
|
|
|
@ -14,6 +14,9 @@ import { css } from '@emotion/react';
|
|||
import { type IndexPatternRef } from '../../types';
|
||||
import { type ChangeIndexPatternTriggerProps, TriggerButton } from './trigger';
|
||||
|
||||
const MAX_WIDTH = 600;
|
||||
const MIN_WIDTH = 320;
|
||||
|
||||
export function ChangeIndexPattern({
|
||||
indexPatternRefs,
|
||||
isMissingCurrent,
|
||||
|
@ -52,8 +55,8 @@ export function ChangeIndexPattern({
|
|||
<div
|
||||
css={css`
|
||||
width: ${calculateWidthFromEntries(indexPatternRefs, ['name', 'id'], {
|
||||
minWidth: 320,
|
||||
maxWidth: 600,
|
||||
minWidth: MIN_WIDTH,
|
||||
maxWidth: MAX_WIDTH,
|
||||
})}px;
|
||||
`}
|
||||
>
|
||||
|
|
|
@ -142,12 +142,14 @@ describe('Legend Settings', () => {
|
|||
toolTipContent: 'Shows the average value',
|
||||
},
|
||||
],
|
||||
legendStats: [LegendValue.Average],
|
||||
onLegendStatsChange,
|
||||
});
|
||||
expect(screen.queryByRole('button', { name: 'Layout' })).toBeNull();
|
||||
fireEvent.click(screen.getByRole('combobox', { name: 'Statistics' }));
|
||||
fireEvent.click(screen.getByRole('option', { name: 'Current and last value' }));
|
||||
// expect(screen.getByRole('group', { name: 'Layout' })).toBeInTheDocument();
|
||||
expect(onLegendStatsChange).toBeCalledWith([LegendValue.CurrentAndLastValue], false);
|
||||
expect(onLegendStatsChange).toBeCalledWith(
|
||||
[LegendValue.Average, LegendValue.CurrentAndLastValue],
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,31 +6,25 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { VisualizationContainer } from './visualization_container';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
describe('VisualizationContainer', () => {
|
||||
const renderVisContainer = (props?: React.HTMLAttributes<HTMLDivElement>) => {
|
||||
return render(<VisualizationContainer {...props}>Hello!</VisualizationContainer>);
|
||||
};
|
||||
test('renders child content', () => {
|
||||
const component = mount(<VisualizationContainer>Hello!</VisualizationContainer>);
|
||||
|
||||
expect(component.text()).toEqual('Hello!');
|
||||
renderVisContainer();
|
||||
expect(screen.getByText('Hello!')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders style', () => {
|
||||
const component = mount(
|
||||
<VisualizationContainer style={{ color: 'blue' }}>Hello!</VisualizationContainer>
|
||||
);
|
||||
const el = component.find('.lnsVisualizationContainer').first();
|
||||
|
||||
expect(el.prop('style')).toEqual({ color: 'blue' });
|
||||
renderVisContainer({ style: { color: 'blue' } });
|
||||
expect(screen.getByText('Hello!')).toHaveStyle({ color: 'blue' });
|
||||
});
|
||||
|
||||
test('combines class names with container class', () => {
|
||||
const component = mount(
|
||||
<VisualizationContainer className="myClass">Hello!</VisualizationContainer>
|
||||
);
|
||||
const el = component.find('.lnsVisualizationContainer').first();
|
||||
|
||||
expect(el.prop('className')).toEqual('myClass lnsVisualizationContainer');
|
||||
renderVisContainer({ className: 'myClass' });
|
||||
expect(screen.getByText('Hello!')).toHaveClass('myClass lnsVisualizationContainer');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ import { createMockDatasource, createMockFramePublicAPI } from '../../../mocks';
|
|||
import { TableDimensionEditor } from './dimension_editor';
|
||||
import { ColumnState } from '../../../../common/expressions';
|
||||
import { capitalize } from 'lodash';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
describe('data table dimension editor', () => {
|
||||
let user: UserEvent;
|
||||
|
@ -60,7 +61,6 @@ describe('data table dimension editor', () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// Workaround for timeout via https://github.com/testing-library/user-event/issues/833#issuecomment-1171452841
|
||||
user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
|
||||
btnGroups = {
|
||||
colorMode: new EuiButtonGroupTestHarness('lnsDatatable_dynamicColoring_groups'),
|
||||
|
@ -123,10 +123,10 @@ describe('data table dimension editor', () => {
|
|||
) => {
|
||||
return render(<TableDimensionEditor {...props} {...overrideProps} />, {
|
||||
wrapper: ({ children }) => (
|
||||
<>
|
||||
<I18nProvider>
|
||||
<div ref={props.panelRef} />
|
||||
{children}
|
||||
</>
|
||||
</I18nProvider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
@ -243,6 +243,7 @@ describe('data table dimension editor', () => {
|
|||
renderTableDimensionEditor();
|
||||
|
||||
await user.click(screen.getByLabelText('Edit colors'));
|
||||
act(() => jest.advanceTimersByTime(256));
|
||||
|
||||
expect(screen.getByTestId(`lns-palettePanel-${flyout}`)).toBeInTheDocument();
|
||||
}
|
||||
|
|
|
@ -193,6 +193,18 @@ const areaShared = {
|
|||
}),
|
||||
};
|
||||
|
||||
const lineShared = {
|
||||
id: 'line',
|
||||
icon: IconChartLine,
|
||||
label: i18n.translate('xpack.lens.xyVisualization.lineLabel', {
|
||||
defaultMessage: 'Line',
|
||||
}),
|
||||
sortPriority: 2,
|
||||
description: i18n.translate('xpack.lens.line.visualizationDescription', {
|
||||
defaultMessage: 'Reveal variations in data over time.',
|
||||
}),
|
||||
};
|
||||
|
||||
export const visualizationSubtypes: VisualizationType[] = [
|
||||
{
|
||||
id: 'bar',
|
||||
|
@ -278,17 +290,7 @@ export const visualizationSubtypes: VisualizationType[] = [
|
|||
}),
|
||||
...areaShared,
|
||||
},
|
||||
{
|
||||
id: 'line',
|
||||
icon: IconChartLine,
|
||||
label: i18n.translate('xpack.lens.xyVisualization.lineLabel', {
|
||||
defaultMessage: 'Line',
|
||||
}),
|
||||
sortPriority: 2,
|
||||
description: i18n.translate('xpack.lens.line.visualizationDescription', {
|
||||
defaultMessage: 'Reveal variations in data over time.',
|
||||
}),
|
||||
},
|
||||
lineShared,
|
||||
];
|
||||
|
||||
export const visualizationTypes: VisualizationType[] = [
|
||||
|
@ -306,10 +308,7 @@ export const visualizationTypes: VisualizationType[] = [
|
|||
label: i18n.translate('xpack.lens.xyVisualization.barLabel', {
|
||||
defaultMessage: 'Bar',
|
||||
}),
|
||||
sortPriority: 1,
|
||||
description: i18n.translate('xpack.lens.bar.visualizationDescription', {
|
||||
defaultMessage: 'Compare categories or groups of data via bars.',
|
||||
}),
|
||||
...barShared,
|
||||
getCompatibleSubtype: (seriesType?: string) => {
|
||||
if (seriesType === 'area') {
|
||||
return 'bar';
|
||||
|
@ -342,15 +341,7 @@ export const visualizationTypes: VisualizationType[] = [
|
|||
},
|
||||
},
|
||||
{
|
||||
id: 'line',
|
||||
icon: IconChartLine,
|
||||
label: i18n.translate('xpack.lens.xyVisualization.lineLabel', {
|
||||
defaultMessage: 'Line',
|
||||
}),
|
||||
sortPriority: 2,
|
||||
description: i18n.translate('xpack.lens.line.visualizationDescription', {
|
||||
defaultMessage: 'Reveal variations in data over time or categorically.',
|
||||
}),
|
||||
...lineShared,
|
||||
subtypes: ['line'],
|
||||
},
|
||||
];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue