| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| import { |
| ComparisonType, |
| FreeFormAdhocFilter, |
| RollingType, |
| TimeGranularity, |
| } from '@superset-ui/core'; |
| import buildQuery from '../../src/MixedTimeseries/buildQuery'; |
| |
| const formDataMixedChart = { |
| datasource: 'dummy', |
| viz_type: 'my_chart', |
| // query |
| // -- common |
| time_range: '1980 : 2000', |
| time_grain_sqla: TimeGranularity.WEEK, |
| granularity_sqla: 'ds', |
| // -- query a |
| groupby: ['foo'], |
| metrics: ['sum(sales)'], |
| adhoc_filters: [ |
| { |
| clause: 'WHERE', |
| expressionType: 'SQL', |
| sqlExpression: "foo in ('a', 'b')", |
| } as FreeFormAdhocFilter, |
| ], |
| limit: 5, |
| row_limit: 10, |
| timeseries_limit_metric: 'count', |
| order_desc: true, |
| truncate_metric: true, |
| show_empty_columns: true, |
| // -- query b |
| groupby_b: [], |
| metrics_b: ['count'], |
| adhoc_filters_b: [ |
| { |
| clause: 'WHERE', |
| expressionType: 'SQL', |
| sqlExpression: "name in ('c', 'd')", |
| } as FreeFormAdhocFilter, |
| ], |
| limit_b: undefined, |
| row_limit_b: 100, |
| timeseries_limit_metric_b: undefined, |
| order_desc_b: false, |
| truncate_metric_b: true, |
| show_empty_columns_b: true, |
| // chart configs |
| show_value: false, |
| show_valueB: undefined, |
| }; |
| const formDataMixedChartWithAA = { |
| ...formDataMixedChart, |
| rolling_type: RollingType.Cumsum, |
| time_compare: ['1 years ago'], |
| comparison_type: ComparisonType.Values, |
| resample_rule: '1AS', |
| resample_method: 'zerofill', |
| |
| rolling_type_b: RollingType.Sum, |
| rolling_periods_b: 1, |
| min_periods_b: 1, |
| comparison_type_b: ComparisonType.Difference, |
| time_compare_b: ['3 years ago'], |
| resample_rule_b: '1A', |
| resample_method_b: 'asfreq', |
| }; |
| |
| test('should compile query object A', () => { |
| const query = buildQuery(formDataMixedChart).queries[0]; |
| expect(query).toEqual({ |
| time_range: '1980 : 2000', |
| since: undefined, |
| until: undefined, |
| granularity: 'ds', |
| filters: [], |
| extras: { |
| having: '', |
| time_grain_sqla: 'P1W', |
| where: "(foo in ('a', 'b'))", |
| }, |
| applied_time_extras: {}, |
| columns: ['foo'], |
| metrics: ['sum(sales)'], |
| annotation_layers: [], |
| row_limit: 10, |
| row_offset: undefined, |
| series_columns: ['foo'], |
| series_limit: 5, |
| series_limit_metric: undefined, |
| group_others_when_limit_reached: false, |
| url_params: {}, |
| custom_params: {}, |
| custom_form_data: {}, |
| is_timeseries: true, |
| time_offsets: [], |
| post_processing: [ |
| { |
| operation: 'pivot', |
| options: { |
| aggregates: { |
| 'sum(sales)': { |
| operator: 'mean', |
| }, |
| }, |
| columns: ['foo'], |
| drop_missing_columns: false, |
| index: ['__timestamp'], |
| }, |
| }, |
| { |
| operation: 'rename', |
| options: { |
| columns: { |
| 'sum(sales)': null, |
| }, |
| inplace: true, |
| level: 0, |
| }, |
| }, |
| { |
| operation: 'flatten', |
| }, |
| ], |
| orderby: [['count', false]], |
| }); |
| }); |
| |
| test('should compile query object B', () => { |
| const query = buildQuery(formDataMixedChart).queries[1]; |
| expect(query).toEqual({ |
| time_range: '1980 : 2000', |
| since: undefined, |
| until: undefined, |
| granularity: 'ds', |
| filters: [], |
| extras: { |
| having: '', |
| time_grain_sqla: 'P1W', |
| where: "(name in ('c', 'd'))", |
| }, |
| applied_time_extras: {}, |
| columns: [], |
| metrics: ['count'], |
| annotation_layers: [], |
| row_limit: 100, |
| row_offset: undefined, |
| series_columns: [], |
| series_limit: 0, |
| series_limit_metric: undefined, |
| group_others_when_limit_reached: false, |
| url_params: {}, |
| custom_params: {}, |
| custom_form_data: {}, |
| is_timeseries: true, |
| time_offsets: [], |
| post_processing: [ |
| { |
| operation: 'pivot', |
| options: { |
| aggregates: { |
| count: { |
| operator: 'mean', |
| }, |
| }, |
| columns: [], |
| drop_missing_columns: false, |
| index: ['__timestamp'], |
| }, |
| }, |
| { |
| operation: 'flatten', |
| }, |
| ], |
| orderby: [['count', true]], |
| }); |
| }); |
| |
| test('should compile AA in query A', () => { |
| const query = buildQuery(formDataMixedChartWithAA).queries[0]; |
| // time comparison |
| expect(query.time_offsets).toEqual(['1 years ago']); |
| |
| // pivot |
| expect( |
| query.post_processing?.find(operator => operator?.operation === 'pivot'), |
| ).toEqual({ |
| operation: 'pivot', |
| options: { |
| index: ['__timestamp'], |
| columns: ['foo'], |
| drop_missing_columns: false, |
| aggregates: { |
| 'sum(sales)': { operator: 'mean' }, |
| 'sum(sales)__1 years ago': { operator: 'mean' }, |
| }, |
| }, |
| }); |
| // cumsum |
| expect( |
| // prettier-ignore |
| query |
| .post_processing |
| ?.find(operator => operator?.operation === 'cum') |
| ?.operation, |
| ).toEqual('cum'); |
| |
| // resample |
| expect( |
| // prettier-ignore |
| query |
| .post_processing |
| ?.find(operator => operator?.operation === 'resample'), |
| ).toEqual({ |
| operation: 'resample', |
| options: { |
| method: 'asfreq', |
| rule: '1AS', |
| fill_value: 0, |
| }, |
| }); |
| }); |
| |
| test('should compile AA in query B', () => { |
| const query = buildQuery(formDataMixedChartWithAA).queries[1]; |
| // time comparison |
| expect(query.time_offsets).toEqual(['3 years ago']); |
| |
| // rolling total |
| expect( |
| // prettier-ignore |
| query |
| .post_processing |
| ?.find(operator => operator?.operation === 'rolling'), |
| ).toEqual({ |
| operation: 'rolling', |
| options: { |
| rolling_type: 'sum', |
| window: 1, |
| min_periods: 1, |
| columns: { |
| count: 'count', |
| 'count__3 years ago': 'count__3 years ago', |
| }, |
| }, |
| }); |
| |
| // resample |
| expect( |
| // prettier-ignore |
| query |
| .post_processing |
| ?.find(operator => operator?.operation === 'resample'), |
| ).toEqual({ |
| operation: 'resample', |
| options: { |
| method: 'asfreq', |
| rule: '1A', |
| fill_value: null, |
| }, |
| }); |
| }); |
| |
| test("shouldn't convert a queryObject with axis", () => { |
| const { queries } = buildQuery(formDataMixedChart); |
| expect(queries[0]).toEqual( |
| expect.objectContaining({ |
| granularity: 'ds', |
| columns: ['foo'], |
| series_columns: ['foo'], |
| metrics: ['sum(sales)'], |
| is_timeseries: true, |
| extras: { |
| time_grain_sqla: 'P1W', |
| having: '', |
| where: "(foo in ('a', 'b'))", |
| }, |
| post_processing: [ |
| { |
| operation: 'pivot', |
| options: { |
| aggregates: { |
| 'sum(sales)': { |
| operator: 'mean', |
| }, |
| }, |
| columns: ['foo'], |
| drop_missing_columns: false, |
| index: ['__timestamp'], |
| }, |
| }, |
| { |
| operation: 'rename', |
| options: { columns: { 'sum(sales)': null }, inplace: true, level: 0 }, |
| }, |
| { |
| operation: 'flatten', |
| }, |
| ], |
| }), |
| ); |
| expect(queries[1]).toEqual( |
| expect.objectContaining({ |
| granularity: 'ds', |
| columns: [], |
| series_columns: [], |
| metrics: ['count'], |
| is_timeseries: true, |
| extras: { |
| time_grain_sqla: 'P1W', |
| having: '', |
| where: "(name in ('c', 'd'))", |
| }, |
| post_processing: [ |
| { |
| operation: 'pivot', |
| options: { |
| aggregates: { |
| count: { |
| operator: 'mean', |
| }, |
| }, |
| columns: [], |
| drop_missing_columns: false, |
| index: ['__timestamp'], |
| }, |
| }, |
| { |
| operation: 'flatten', |
| }, |
| ], |
| }), |
| ); |
| }); |
| |
| test('ensure correct pivot columns', () => { |
| const query = buildQuery({ ...formDataMixedChartWithAA, x_axis: 'ds' }) |
| .queries[0]; |
| |
| expect(query.time_offsets).toEqual(['1 years ago']); |
| |
| // pivot |
| expect( |
| query.post_processing?.find(operator => operator?.operation === 'pivot'), |
| ).toEqual({ |
| operation: 'pivot', |
| options: { |
| index: ['ds'], |
| columns: ['foo'], |
| drop_missing_columns: false, |
| aggregates: { |
| 'sum(sales)': { operator: 'mean' }, |
| 'sum(sales)__1 years ago': { operator: 'mean' }, |
| }, |
| }, |
| }); |
| }); |