From e8b63fa09114ab41ff1c7068b2c180a6ba6586e1 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 6 Mar 2020 17:55:40 -0500 Subject: [PATCH] Fix jest tests --- .../visualization.test.tsx | 167 ++++++++---------- .../datatable_visualization/visualization.tsx | 14 +- .../editor_frame/chart_switch.test.tsx | 2 +- .../metric_expression.tsx | 5 + .../metric_visualization.test.ts | 44 ++++- .../xy_visualization/xy_config_panel.test.tsx | 2 +- .../xy_visualization/xy_suggestions.test.ts | 3 +- .../xy_visualization/xy_visualization.test.ts | 27 +-- 8 files changed, 144 insertions(+), 120 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx index 972bfe5007b544..28bfae29976bb6 100644 --- a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx +++ b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx @@ -4,14 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; import { createMockDatasource } from '../editor_frame_service/mocks'; import { DatatableVisualizationState, datatableVisualization } from './visualization'; -import { mount } from 'enzyme'; import { Operation, DataType, FramePublicAPI, TableSuggestionColumn } from '../types'; -import { generateId } from '../id_generator'; - -jest.mock('../id_generator'); function mockFrame(): FramePublicAPI { return { @@ -30,12 +25,11 @@ function mockFrame(): FramePublicAPI { describe('Datatable Visualization', () => { describe('#initialize', () => { it('should initialize from the empty state', () => { - (generateId as jest.Mock).mockReturnValueOnce('id'); expect(datatableVisualization.initialize(mockFrame(), undefined)).toEqual({ layers: [ { layerId: 'aaa', - columns: ['id'], + columns: [], }, ], }); @@ -84,7 +78,6 @@ describe('Datatable Visualization', () => { describe('#clearLayer', () => { it('should reset the layer', () => { - (generateId as jest.Mock).mockReturnValueOnce('testid'); const state: DatatableVisualizationState = { layers: [ { @@ -97,7 +90,7 @@ describe('Datatable Visualization', () => { layers: [ { layerId: 'baz', - columns: ['testid'], + columns: [], }, ], }); @@ -210,10 +203,30 @@ describe('Datatable Visualization', () => { }); }); - describe('DataTableLayer', () => { + describe('#getLayerOptions', () => { + it('returns a single layer option', () => { + const setState = jest.fn(); + const datasource = createMockDatasource('test'); + const frame = mockFrame(); + frame.datasourceLayers = { first: datasource.publicAPIMock }; + + expect( + datatableVisualization.getLayerOptions({ + layerId: 'first', + state: { + layers: [{ layerId: 'first', columns: [] }], + }, + setState, + frame, + }).dimensions + ).toHaveLength(1); + }); + it('allows all kinds of operations', () => { const setState = jest.fn(); + const datasource = createMockDatasource('test'); const frame = mockFrame(); + frame.datasourceLayers = { first: datasource.publicAPIMock }; const filterOperations = datatableVisualization.getLayerOptions({ layerId: 'first', @@ -239,108 +252,82 @@ describe('Datatable Visualization', () => { ); }); - it('allows columns to be removed', () => { - const setState = jest.fn(); - const datasource = createMockDatasource(); + it('reorders the rendered colums based on the order from the datasource', () => { + const datasource = createMockDatasource('test'); const layer = { layerId: 'a', columns: ['b', 'c'] }; const frame = mockFrame(); frame.datasourceLayers = { a: datasource.publicAPIMock }; - const component = mount( - {} }} - frame={frame} - layer={layer} - setState={setState} - state={{ layers: [layer] }} - /> - ); - - const onRemove = component - .find('[data-test-subj="datatable_multicolumnEditor"]') - .first() - .prop('onRemove') as (k: string) => {}; - - onRemove('b'); + datasource.publicAPIMock.getTableSpec.mockReturnValue([{ columnId: 'c' }, { columnId: 'b' }]); + + expect( + datatableVisualization.getLayerOptions({ + layerId: 'a', + state: { layers: [layer] }, + setState: jest.fn(), + frame, + }).dimensions[0].accessors + ).toEqual(['c', 'b']); + }); + }); - expect(setState).toHaveBeenCalledWith({ + describe('#removeDimension', () => { + it('allows columns to be removed', () => { + const layer = { layerId: 'layer1', columns: ['b', 'c'] }; + expect( + datatableVisualization.removeDimension({ + prevState: { layers: [layer] }, + layerId: 'layer1', + columnId: 'b', + dimensionId: '', + }) + ).toEqual({ layers: [ { - layerId: 'a', + layerId: 'layer1', columns: ['c'], }, ], }); }); + }); + describe('#setDimension', () => { it('allows columns to be added', () => { - (generateId as jest.Mock).mockReturnValueOnce('d'); - const setState = jest.fn(); - const datasource = createMockDatasource(); - const layer = { layerId: 'a', columns: ['b', 'c'] }; - const frame = mockFrame(); - frame.datasourceLayers = { a: datasource.publicAPIMock }; - const component = mount( - {} }} - frame={frame} - layer={layer} - setState={setState} - state={{ layers: [layer] }} - /> - ); - - const onAdd = component - .find('[data-test-subj="datatable_multicolumnEditor"]') - .first() - .prop('onAdd') as () => {}; - - onAdd(); - - expect(setState).toHaveBeenCalledWith({ + const layer = { layerId: 'layer1', columns: ['b', 'c'] }; + expect( + datatableVisualization.setDimension({ + prevState: { layers: [layer] }, + layerId: 'layer1', + columnId: 'd', + dimensionId: '', + }) + ).toEqual({ layers: [ { - layerId: 'a', + layerId: 'layer1', columns: ['b', 'c', 'd'], }, ], }); }); - it('reorders the rendered colums based on the order from the datasource', () => { - const datasource = createMockDatasource(); - const layer = { layerId: 'a', columns: ['b', 'c'] }; - const frame = mockFrame(); - frame.datasourceLayers = { a: datasource.publicAPIMock }; - const component = mount( - {} }} - frame={frame} - layer={layer} - setState={jest.fn()} - state={{ layers: [layer] }} - /> - ); - - const accessors = component - .find('[data-test-subj="datatable_multicolumnEditor"]') - .first() - .prop('accessors') as string[]; - - expect(accessors).toEqual(['b', 'c']); - - component.setProps({ - layer: { layerId: 'a', columns: ['c', 'b'] }, + it('does not set a duplicate dimension', () => { + const layer = { layerId: 'layer1', columns: ['b', 'c'] }; + expect( + datatableVisualization.setDimension({ + prevState: { layers: [layer] }, + layerId: 'layer1', + columnId: 'b', + dimensionId: '', + }) + ).toEqual({ + layers: [ + { + layerId: 'layer1', + columns: ['b', 'c'], + }, + ], }); - - const newAccessors = component - .find('[data-test-subj="datatable_multicolumnEditor"]') - .first() - .prop('accessors') as string[]; - - expect(newAccessors).toEqual(['c', 'b']); }); }); }); diff --git a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx index 7dd14e27f397d2..1f066e6f5103a2 100644 --- a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx +++ b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx @@ -128,12 +128,22 @@ export const datatableVisualization: Visualization< ]; }, - getLayerOptions({ state }) { + getLayerOptions({ state, frame, layerId }) { + const layer = state.layers.find(l => l.layerId === layerId); + if (!layer) { + return { dimensions: [] }; + } + + const datasource = frame.datasourceLayers[layer.layerId]; + const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId); + // When we add a column it could be empty, and therefore have no order + const sortedColumns = Array.from(new Set(originalOrder.concat(layer.columns))); + return { dimensions: [ { layerId: state.layers[0].layerId, - accessors: state.layers[0].columns, + accessors: sortedColumns, dimensionId: 'columns', dimensionLabel: i18n.translate('xpack.lens.datatable.columns', { defaultMessage: 'Columns', diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx index 1b60098fd45ad1..6698c9e68b98c0 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx @@ -84,7 +84,7 @@ describe('chart_switch', () => { } function mockDatasourceMap() { - const datasource = createMockDatasource(); + const datasource = createMockDatasource('testDatasource'); datasource.getDatasourceSuggestionsFromCurrentState.mockReturnValue([ { state: {}, diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx index 66ed963002f590..4d979a766cd2b9 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx @@ -91,6 +91,11 @@ export function MetricChart({ const { title, accessor, mode } = args; let value = '-'; const firstTable = Object.values(data.tables)[0]; + if (!accessor) { + return ( + + ); + } if (firstTable) { const column = firstTable.columns[0]; diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts index 571b578b876d40..237e1c40698981 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts +++ b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts @@ -24,8 +24,8 @@ function mockFrame(): FramePublicAPI { ...createMockFramePublicAPI(), addNewLayer: () => 'l42', datasourceLayers: { - l1: createMockDatasource().publicAPIMock, - l42: createMockDatasource().publicAPIMock, + l1: createMockDatasource('l1').publicAPIMock, + l42: createMockDatasource('l42').publicAPIMock, }, }; } @@ -36,10 +36,10 @@ describe('metric_visualization', () => { (generateId as jest.Mock).mockReturnValueOnce('test-id1'); const initialState = metricVisualization.initialize(mockFrame()); - expect(initialState.accessor).toBeDefined(); + expect(initialState.accessor).not.toBeDefined(); expect(initialState).toMatchInlineSnapshot(` Object { - "accessor": "test-id1", + "accessor": undefined, "layerId": "l42", } `); @@ -60,7 +60,7 @@ describe('metric_visualization', () => { it('returns a clean layer', () => { (generateId as jest.Mock).mockReturnValueOnce('test-id1'); expect(metricVisualization.clearLayer(exampleState(), 'l1')).toEqual({ - accessor: 'test-id1', + accessor: undefined, layerId: 'l1', }); }); @@ -73,15 +73,47 @@ describe('metric_visualization', () => { }); describe('#setDimension', () => { + it('sets the accessor', () => { + expect( + metricVisualization.setDimension({ + prevState: { + accessor: undefined, + layerId: 'l1', + }, + layerId: 'l1', + dimensionId: '', + columnId: 'newDimension', + }) + ).toEqual({ + accessor: 'newDimension', + layerId: 'l1', + }); + }); }); describe('#removeDimension', () => { + it('removes the accessor', () => { + expect( + metricVisualization.removeDimension({ + prevState: { + accessor: 'a', + layerId: 'l1', + }, + layerId: 'l1', + dimensionId: '', + columnId: 'a', + }) + ).toEqual({ + accessor: undefined, + layerId: 'l1', + }); + }); }); describe('#toExpression', () => { it('should map to a valid AST', () => { const datasource: DatasourcePublicAPI = { - ...createMockDatasource().publicAPIMock, + ...createMockDatasource('l1').publicAPIMock, getOperationForColumnId(_: string) { return { id: 'a', diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx index d0ea5d9040eb24..7544ed0f87b7d0 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx @@ -35,7 +35,7 @@ describe('LayerContextMenu', () => { beforeEach(() => { frame = createMockFramePublicAPI(); frame.datasourceLayers = { - first: createMockDatasource().publicAPIMock, + first: createMockDatasource('test').publicAPIMock, }; }); diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_suggestions.test.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_suggestions.test.ts index da49d4594c0871..ddbd9d11b5fada 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_suggestions.test.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_suggestions.test.ts @@ -240,7 +240,6 @@ describe('xy_suggestions', () => { }); test('only makes a seriesType suggestion for unchanged table without split', () => { - (generateId as jest.Mock).mockReturnValueOnce('dummyCol'); const currentState: XYState = { legend: { isVisible: true, position: 'bottom' }, preferredSeriesType: 'bar', @@ -249,7 +248,7 @@ describe('xy_suggestions', () => { accessors: ['price'], layerId: 'first', seriesType: 'bar', - splitAccessor: 'dummyCol', + splitAccessor: undefined, xAccessor: 'date', }, ], diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_visualization.test.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_visualization.test.ts index e6e9f1f9950ff6..1dd1074978de7d 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_visualization.test.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_visualization.test.ts @@ -9,7 +9,6 @@ import { Position } from '@elastic/charts'; import { Operation } from '../types'; import { State, SeriesType } from './types'; import { createMockDatasource, createMockFramePublicAPI } from '../editor_frame_service/mocks'; -import { generateId } from '../id_generator'; import { Ast } from '@kbn/interpreter/target/common'; jest.mock('../id_generator'); @@ -87,31 +86,22 @@ describe('xy_visualization', () => { describe('#initialize', () => { it('loads default state', () => { - (generateId as jest.Mock) - .mockReturnValueOnce('test-id1') - .mockReturnValueOnce('test-id2') - .mockReturnValue('test-id3'); const mockFrame = createMockFramePublicAPI(); const initialState = xyVisualization.initialize(mockFrame); expect(initialState.layers).toHaveLength(1); - expect(initialState.layers[0].xAccessor).toBeDefined(); - expect(initialState.layers[0].accessors[0]).toBeDefined(); - expect(initialState.layers[0].xAccessor).not.toEqual(initialState.layers[0].accessors[0]); + expect(initialState.layers[0].xAccessor).not.toBeDefined(); + expect(initialState.layers[0].accessors).toHaveLength(0); expect(initialState).toMatchInlineSnapshot(` Object { "layers": Array [ Object { - "accessors": Array [ - "test-id1", - ], + "accessors": Array [], "layerId": "", "position": "top", "seriesType": "bar_stacked", "showGridlines": false, - "splitAccessor": "test-id2", - "xAccessor": "test-id3", }, ], "legend": Object { @@ -167,14 +157,11 @@ describe('xy_visualization', () => { describe('#clearLayer', () => { it('clears the specified layer', () => { - (generateId as jest.Mock).mockReturnValue('test_empty_id'); const layer = xyVisualization.clearLayer(exampleState(), 'first').layers[0]; expect(layer).toMatchObject({ - accessors: ['test_empty_id'], + accessors: [], layerId: 'first', seriesType: 'bar', - splitAccessor: 'test_empty_id', - xAccessor: 'test_empty_id', }); }); }); @@ -185,13 +172,17 @@ describe('xy_visualization', () => { }); }); + describe('#setDimension', () => {}); + + describe('#removeDimension', () => {}); + describe('#toExpression', () => { let mockDatasource: ReturnType; let frame: ReturnType; beforeEach(() => { frame = createMockFramePublicAPI(); - mockDatasource = createMockDatasource(); + mockDatasource = createMockDatasource('testDatasource'); mockDatasource.publicAPIMock.getTableSpec.mockReturnValue([ { columnId: 'd' },