From 5ff148ce98aed2de01d841f7c288881fc7464a82 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Fri, 13 Sep 2024 14:17:59 +0200 Subject: [PATCH] lens config lyout --- .../dimension_panel/field_input.test.tsx | 149 ++++++------------ .../chart_switch/chart_switch.test.tsx | 7 +- .../editor_frame/editor_frame.test.tsx | 46 ------ .../legend/legend_settings_popover.test.tsx | 8 +- 4 files changed, 60 insertions(+), 150 deletions(-) diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx index 322c1ab855152..619d02f0bf28f 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx @@ -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, -}; - -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, +}; + +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 = {}; - 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> ) => { - const updateLayerSpy = jest.fn(); - const layer = getLayer(); - const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1'); - return render( - - ); + return render(); }; +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} /> ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch/chart_switch.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch/chart_switch.test.tsx index e8267dd388520..6795cd8caaa83 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch/chart_switch.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/chart_switch/chart_switch.test.tsx @@ -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 () => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx index 75cddd85b5803..7d41e326372e5 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx @@ -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 = {}; diff --git a/x-pack/plugins/lens/public/shared_components/legend/legend_settings_popover.test.tsx b/x-pack/plugins/lens/public/shared_components/legend/legend_settings_popover.test.tsx index 98a040ab04bb5..8538dcece585e 100644 --- a/x-pack/plugins/lens/public/shared_components/legend/legend_settings_popover.test.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend/legend_settings_popover.test.tsx @@ -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 + ); }); });