diff --git a/superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts b/superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts index 071d0aeb622f2..642991be4b8c0 100644 --- a/superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts +++ b/superset-frontend/plugins/plugin-chart-cartodiagram/src/util/transformPropsUtil.ts @@ -62,6 +62,7 @@ export const groupByLocationTs = (data: TimeseriesDataRecord[] | undefined) => { const currentLocation = locations[location]; if (Array.isArray(currentLocation)) { dataAtLocation = currentLocation.find( + // eslint-disable-next-line no-underscore-dangle dal => dal.__timestamp === timestamp, ); } diff --git a/superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts b/superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts index 9fa27fe7519d6..70ffbb73259e4 100644 --- a/superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts +++ b/superset-frontend/plugins/plugin-chart-cartodiagram/test/testData.ts @@ -19,7 +19,10 @@ const coord1 = '[1,2]'; const coord2 = '[3,4]'; -export const pieChartData: any = [ +export const geom1 = `{"type":"Point","coordinates":${coord1}}`; +export const geom2 = `{"type":"Point","coordinates":${coord2}}`; + +export const nonTimeSeriesChartData: any = [ { geom: `{"type":"Point","coordinates":${coord1}}`, my_value: 'apple', @@ -72,65 +75,32 @@ export const pieChartData: any = [ }, ]; -export const barChartData: any = [ - { - geom: `{"type":"Point","coordinates":${coord1}}`, - my_value: 'apple', - my_count: 347, - __timestamp: 1564275000000, - }, +export const timeseriesChartData = [ { - geom: `{"type":"Point","coordinates":${coord1}}`, - my_value: 'apple', - my_count: 360, + [geom1]: 347, + [geom2]: 360, __timestamp: 1564275000000, }, { - geom: `{"type":"Point","coordinates":${coord1}}`, - my_value: 'lemon', - my_count: 335, - __timestamp: 1564275000000, - }, - { - geom: `{"type":"Point","coordinates":${coord1}}`, - my_value: 'lemon', - my_count: 333, - __timestamp: 1564272000000, - }, - { - geom: `{"type":"Point","coordinates":${coord1}}`, - my_value: 'lemon', - my_count: 353, - __timestamp: 1564272000000, - }, - { - geom: `{"type":"Point","coordinates":${coord1}}`, - my_value: 'lemon', - my_count: 359, - __timestamp: 1564272000000, - }, - { - geom: `{"type":"Point","coordinates":${coord2}}`, - my_value: 'lemon', - my_count: 347, - __timestamp: 1564272000000, - }, - { - geom: `{"type":"Point","coordinates":${coord2}}`, - my_value: 'apple', - my_count: 335, + [geom1]: 353, + [geom2]: 328, __timestamp: 1564272000000, }, +]; + +export const groupedTimeseriesChartData = [ { - geom: `{"type":"Point","coordinates":${coord2}}`, - my_value: 'apple', - my_count: 356, + [`${geom1}, apple`]: 347, + [`${geom2}, apple`]: 360, + [`${geom1}, lemon`]: 352, + [`${geom2}, lemon`]: 364, __timestamp: 1564275000000, }, { - geom: `{"type":"Point","coordinates":${coord2}}`, - my_value: 'banana', - my_count: 218, - __timestamp: 1564275000000, + [`${geom1}, apple`]: 353, + [`${geom2}, apple`]: 328, + [`${geom1}, lemon`]: 346, + [`${geom2}, lemon`]: 333, + __timestamp: 1564272000000, }, ]; diff --git a/superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts b/superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts index ff46ddebc2ba7..f9fe2c2af37e8 100644 --- a/superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts +++ b/superset-frontend/plugins/plugin-chart-cartodiagram/test/util/transformPropsUtil.test.ts @@ -17,124 +17,147 @@ * under the License. */ -import { getChartTransformPropsRegistry } from '@superset-ui/core'; import { groupByLocationTs, groupByLocation, getEchartConfigs, parseSelectedChart, } from '../../src/util/transformPropsUtil'; -import { barChartData, pieChartData } from '../testData'; +import { + timeseriesChartData, + nonTimeSeriesChartData, + groupedTimeseriesChartData, + geom1, + geom2, +} from '../testData'; + +describe('transformPropsUtil', () => { + describe('groupByLocationTs', () => { + it('returns empty result when no timestamps provided', () => { + const result = groupByLocationTs(nonTimeSeriesChartData); + expect(result).toEqual({}); + }); -describe('groupByLocationTs', () => { - it('returns empty result when no timestamps provided', () => { - const result = groupByLocationTs(pieChartData); - expect(result).toEqual({}); - }); - it('returns correct structure on valid input', () => { - const result = groupByLocationTs(barChartData); - expect(false).toEqual(true); - }); -}); + it('groups in the correct count of geometries', () => { + const result = groupByLocationTs(timeseriesChartData); -describe('groupByLocation', () => { - const geometryColumn = 'geom'; - const result = groupByLocation(pieChartData, geometryColumn); + const countGeometries = Object.keys(result).length; + expect(countGeometries).toEqual(2); + }); - it('groups in the correct count of geometries', () => { - const countOfGeometries = Object.keys(result).length; - expect(countOfGeometries).toEqual(2); + it('removes the geometry from the data field for grouped data', () => { + const result = groupByLocationTs(groupedTimeseriesChartData); + + expect(result).toEqual( + expect.objectContaining({ + [geom1]: expect.arrayContaining([ + expect.objectContaining({ + __timestamp: 1564275000000, + apple: 347, + lemon: 352, + }), + ]), + }), + ); + }); }); - it('groups items with the correct geometry', () => { - Object.entries(result).forEach(([geom, items]) => { - const allGeomsAreTheSame = items.every((item: any) => geom === item.geom); - expect(allGeomsAreTheSame).toEqual(true); + describe('groupByLocation', () => { + it('groups in the correct count of geometries', () => { + const geometryColumn = 'geom'; + const result = groupByLocation(nonTimeSeriesChartData, geometryColumn); + const countOfGeometries = Object.keys(result).length; + expect(countOfGeometries).toEqual(2); }); - }); -}); -describe('getEchartConfigs', () => { - it('works for pie chart', () => { - const dummyTransformProps = 'dummyTransformProps'; - const chartQueryBuilderMock: jest.MockedFunction = jest.fn( - () => dummyTransformProps, - ); + it('groups items with the correct geometry', () => { + const geometryColumn = 'geom'; + const result = groupByLocation(nonTimeSeriesChartData, geometryColumn); + // @ts-ignore + const allGeom1 = result[geom1].every((item: any) => item.geom === geom1); + // @ts-ignore + const allGeom2 = result[geom2].every((item: any) => item.geom === geom2); + expect(allGeom1 && allGeom2).toBe(true); + }); + }); - const transformPropsRegistry = getChartTransformPropsRegistry(); - transformPropsRegistry.registerValue('pie', chartQueryBuilderMock); + describe('getEchartConfigs', () => { + let chartTransformer: jest.MockedFunction; const geomColumn = 'geom'; - - const chartTransformer = transformPropsRegistry.get('pie'); - const pieChartConfig = { params: {}, viz_type: 'pie', }; - const pieChartProps: any = { queriesData: [{}], }; + beforeEach(() => { + chartTransformer = jest.fn(); + }); - const result = getEchartConfigs( - pieChartData, - undefined, - pieChartConfig, - geomColumn, - pieChartProps, - chartTransformer, - ); - - const countLocations = 2; - expect(chartQueryBuilderMock.mock.calls).toHaveLength(countLocations); - - const expectedOutput = { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [1, 2], - }, - properties: dummyTransformProps, - }, - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [3, 4], - }, - properties: dummyTransformProps, - }, - ], - }; - expect(result).toEqual(expectedOutput); - }); - it('works for bar chart', () => { - // TODO - expect(false).toEqual(true); - }); - it('works for mixed time-series', () => { - // TODO - expect(false).toEqual(true); + it('calls the transformProps function for every location', () => { + getEchartConfigs( + nonTimeSeriesChartData, + undefined, + pieChartConfig, + geomColumn, + pieChartProps, + chartTransformer, + ); + + expect(chartTransformer).toHaveBeenCalledTimes(2); + }); + it('returns a geojson', () => { + const result = getEchartConfigs( + nonTimeSeriesChartData, + undefined, + pieChartConfig, + geomColumn, + pieChartProps, + chartTransformer, + ); + + expect(result).toEqual( + expect.objectContaining({ + type: 'FeatureCollection', + features: expect.arrayContaining([ + expect.objectContaining({ + type: 'Feature', + }), + ]), + }), + ); + }); + it('returns a feature for each location', () => { + const result = getEchartConfigs( + nonTimeSeriesChartData, + undefined, + pieChartConfig, + geomColumn, + pieChartProps, + chartTransformer, + ); + expect(result.features).toHaveLength(2); + expect(result.features[0].geometry).toEqual(JSON.parse(geom1)); + expect(result.features[1].geometry).toEqual(JSON.parse(geom2)); + }); }); -}); -describe('parseSelectedChart', () => { - it('parses the inline stringified JSON', () => { - const selectedChartObject = { - id: 278, - params: - '{"adhoc_filters":[],"applied_time_extras":{},"datasource":"24__table","viz_type":"pie","time_range":"No filter","groupby":["nuclide"],"metric":{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"nuclide","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"TEXT","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"isNew":false,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(nuclide)","optionName":"metric_k6d9mt9zujc_7v9szd1i0pl"},"dashboards":[]}', - slice_name: 'pie', - viz_type: 'pie', - }; - - const selectedChartString = JSON.stringify(selectedChartObject); - const result = parseSelectedChart(selectedChartString); - const expectedParams = JSON.parse(selectedChartObject.params); - - expect(result.params).toEqual(expectedParams); + describe('parseSelectedChart', () => { + it('parses the inline stringified JSON', () => { + const selectedChartObject = { + id: 278, + params: + '{"adhoc_filters":[],"applied_time_extras":{},"datasource":"24__table","viz_type":"pie","time_range":"No filter","groupby":["nuclide"],"metric":{"expressionType":"SIMPLE","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"nuclide","description":null,"expression":null,"filterable":true,"groupby":true,"id":772,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"TEXT","type_generic":1,"verbose_name":null,"warning_markdown":null},"aggregate":"COUNT","sqlExpression":null,"isNew":false,"datasourceWarning":false,"hasCustomLabel":false,"label":"COUNT(nuclide)","optionName":"metric_k6d9mt9zujc_7v9szd1i0pl"},"dashboards":[]}', + slice_name: 'pie', + viz_type: 'pie', + }; + + const selectedChartString = JSON.stringify(selectedChartObject); + const result = parseSelectedChart(selectedChartString); + const expectedParams = JSON.parse(selectedChartObject.params); + + expect(result.params).toEqual(expectedParams); + }); }); });