Skip to content
Snippets Groups Projects
Verified Commit a729de6b authored by Ankit Panchal's avatar Ankit Panchal :rocket: Committed by GitLab
Browse files

Merge branch 'drosse/set-metrics-filter+metadata' into 'master'

Configure metrics FilteredSearch with search metadata

See merge request !142914



Merged-by: default avatarAnkit Panchal <apanchal@gitlab.com>
Approved-by: default avatarAnkit Panchal <apanchal@gitlab.com>
Reviewed-by: default avatarAnkit Panchal <apanchal@gitlab.com>
Co-authored-by: default avatarDaniele Rossetti <drossetti@gitlab.com>
parents d3969b31 4c344322
No related branches found
No related tags found
2 merge requests!144312Change service start (cut-off) date for code suggestions to March 15th,!142914Configure metrics FilteredSearch with search metadata
Pipeline #1159042259 passed with warnings
Pipeline: E2E Omnibus GitLab EE

#1159167616

    Pipeline: E2E GDK

    #1159046422

      Pipeline: [omniauth-salesforce gem] Ruby 3.0 pipeline

      #1159043293

        +25
        ......@@ -337,7 +337,7 @@ async function fetchMetrics(metricsUrl, { filters = {}, limit } = {}) {
        const SUPPORTED_METRICS_DIMENSION_FILTER_OPERATORS = ['=', '!=', '=~', '!~'];
        function addMetricsDimensionFilterToQueryParams(dimensionFilter, params) {
        function addMetricsAttributeFilterToQueryParams(dimensionFilter, params) {
        if (!dimensionFilter || !params) return;
        Object.entries(dimensionFilter).forEach(([filterName, values]) => {
        ......@@ -371,12 +371,12 @@ function addMetricsDateRangeFilterToQueryParams(dateRangeFilter, params) {
        function addGroupByFilterToQueryParams(groupByFilter, params) {
        if (!groupByFilter || !params) return;
        const { func, dimensions } = groupByFilter;
        const { func, attributes } = groupByFilter;
        if (func) {
        params.append('groupby_fn', func);
        }
        if (Array.isArray(dimensions) && dimensions.length > 0) {
        params.append('groupby_attrs', dimensions.join(','));
        if (Array.isArray(attributes) && attributes.length > 0) {
        params.append('groupby_attrs', attributes.join(','));
        }
        }
        ......@@ -394,10 +394,10 @@ async function fetchMetric(searchUrl, name, type, options = {}) {
        mtype: type,
        });
        const { dimensions, dateRange, groupBy } = options.filters ?? {};
        const { attributes, dateRange, groupBy } = options.filters ?? {};
        if (dimensions) {
        addMetricsDimensionFilterToQueryParams(dimensions, params);
        if (attributes) {
        addMetricsAttributeFilterToQueryParams(attributes, params);
        }
        if (dateRange) {
        ......@@ -442,17 +442,24 @@ async function fetchMetricSearchMetadata(searchMetadataUrl, name, type) {
        // });
        // return data;
        return {
        name: 'cpu_seconds_total',
        type: 'sum',
        description: 'some_description',
        last_ingested_at: 1705374438711900000,
        attribute_keys: ['host.name', 'host.dc', 'host.type'],
        supported_aggregations: ['1m', '1h'],
        supported_functions: ['min', 'max', 'avg', 'sum', 'count'],
        default_group_by_attributes: ['host.name'],
        default_group_by_function: ['avg'],
        };
        return new Promise((resolve) => {
        setTimeout(() =>
        resolve(
        {
        name: 'cpu_seconds_total',
        type: 'sum',
        description: 'some_description',
        last_ingested_at: 1705374438711900000,
        attribute_keys: ['host.name', 'host.dc', 'host.type'],
        supported_aggregations: ['1m', '1h'],
        supported_functions: ['min', 'max', 'avg', 'sum', 'count'],
        default_group_by_attributes: ['host.name'],
        default_group_by_function: 'avg',
        },
        1000,
        ),
        );
        });
        } catch (e) {
        return reportErrorAndThrow(e);
        }
        ......
        ......@@ -10,11 +10,11 @@ export default {
        groupByPlaceholderMultipleSelect: s__('ObservabilityMetrics|multiple'),
        },
        props: {
        searchConfig: {
        searchMetadata: {
        type: Object,
        required: true,
        },
        selectedDimensions: {
        selectedAttributes: {
        type: Array,
        required: true,
        },
        ......@@ -25,24 +25,24 @@ export default {
        },
        data() {
        return {
        groupByDimensions: this.selectedDimensions,
        groupByAttributes: this.selectedAttributes,
        groupByFunction: this.selectedFunction,
        };
        },
        computed: {
        availableGroupByFunctions() {
        return this.searchConfig.groupByFunctions.map((func) => ({ value: func, text: func }));
        return this.searchMetadata.supported_functions.map((func) => ({ value: func, text: func }));
        },
        availableGroupByDimensions() {
        return this.searchConfig.dimensions.map((d) => ({ value: d, text: d }));
        availableGroupByAttributes() {
        return this.searchMetadata.attribute_keys.map((d) => ({ value: d, text: d }));
        },
        groupByLabel() {
        return this.groupByDimensions.length > 1 ? this.groupByDimensions.join(', ') : '';
        return this.groupByAttributes.length > 1 ? this.groupByAttributes.join(', ') : '';
        },
        groupByToggleText() {
        if (this.groupByDimensions.length > 0) {
        if (this.groupByDimensions.length === 1) {
        return this.groupByDimensions[0];
        if (this.groupByAttributes.length > 0) {
        if (this.groupByAttributes.length === 1) {
        return this.groupByAttributes[0];
        }
        return this.$options.i18n.groupByPlaceholderMultipleSelect;
        }
        ......@@ -52,7 +52,7 @@ export default {
        methods: {
        onSelect() {
        this.$emit('groupBy', {
        dimensions: this.groupByDimensions,
        attributes: this.groupByAttributes,
        func: this.groupByFunction,
        });
        },
        ......@@ -70,11 +70,11 @@ export default {
        />
        <span>{{ __('by') }}</span>
        <gl-collapsible-listbox
        v-model="groupByDimensions"
        data-testid="group-by-dimensions-dropdown"
        v-model="groupByAttributes"
        data-testid="group-by-attributes-dropdown"
        :toggle-text="groupByToggleText"
        multiple
        :items="availableGroupByDimensions"
        :items="availableGroupByAttributes"
        @select="onSelect"
        />
        <span data-testid="group-by-label">{{ groupByLabel }}</span>
        ......
        ......@@ -14,14 +14,14 @@ export default {
        GroupByFilter,
        },
        i18n: {
        searchInputPlaceholder: s__('ObservabilityMetrics|Filter dimensions...'),
        searchInputPlaceholder: s__('ObservabilityMetrics|Filter attributes...'),
        },
        props: {
        searchConfig: {
        searchMetadata: {
        type: Object,
        required: true,
        },
        dimensionFilters: {
        attributeFilters: {
        type: Array,
        required: false,
        default: () => [],
        ......@@ -42,16 +42,16 @@ export default {
        shouldShowDateRangePicker: false,
        dateRange: this.dateRangeFilter,
        groupBy: this.groupByFilter ?? {
        dimensions: this.searchConfig.defaultGroupByDimensions ?? [],
        func: this.searchConfig.defaultGroupByFunction ?? '',
        attributes: this.searchMetadata.default_group_by_attributes ?? [],
        func: this.searchMetadata.default_group_by_function ?? '',
        },
        };
        },
        computed: {
        availableTokens() {
        return this.searchConfig.dimensions.map((dimension) => ({
        title: dimension,
        type: dimension,
        return this.searchMetadata.attribute_keys.map((attribute) => ({
        title: attribute,
        type: attribute,
        token: GlFilteredSearchToken,
        operators: [...OPERATORS_IS_NOT, ...OPERATORS_LIKE_NOT],
        }));
        ......@@ -60,7 +60,7 @@ export default {
        methods: {
        onFilter(filters) {
        this.$emit('filter', {
        dimensions: filters,
        attributes: filters,
        dateRange: this.dateRange,
        groupBy: this.groupBy,
        });
        ......@@ -68,8 +68,8 @@ export default {
        onDateRangeSelected({ value, startDate, endDate }) {
        this.dateRange = { value, startDate, endDate };
        },
        onGroupBy({ dimensions, func }) {
        this.groupBy = { dimensions, func };
        onGroupBy({ attributes, func }) {
        this.groupBy = { attributes, func };
        },
        },
        };
        ......@@ -85,7 +85,7 @@ export default {
        namespace="metrics-details-filtered-search"
        :search-input-placeholder="$options.i18n.searchInputPlaceholder"
        :tokens="availableTokens"
        :initial-filter-value="dimensionFilters"
        :initial-filter-value="attributeFilters"
        terms-as-tokens
        @onFilter="onFilter"
        />
        ......@@ -97,8 +97,8 @@ export default {
        <hr class="gl-my-3" />
        <group-by-filter
        :search-config="searchConfig"
        :selected-dimensions="groupBy.dimensions"
        :search-metadata="searchMetadata"
        :selected-attributes="groupBy.attributes"
        :selected-function="groupBy.func"
        @groupBy="onGroupBy"
        />
        ......
        ......@@ -53,10 +53,10 @@ export default {
        const defaultRange = periodToDate(DEFAULT_TIME_RANGE);
        return {
        metricData: [],
        searchConfig: null,
        searchMetadata: null,
        // TODO get filters from query params https://gitlab.com/gitlab-org/opstrace/opstrace/-/work_items/2605
        filters: {
        dimensions: [],
        attributes: [],
        dateRange: {
        value: DEFAULT_TIME_RANGE,
        startDarte: defaultRange.min,
        ......@@ -64,7 +64,6 @@ export default {
        },
        },
        loading: false,
        searchMetadata: null,
        };
        },
        computed: {
        ......@@ -76,9 +75,9 @@ export default {
        description: this.searchMetadata?.description,
        };
        },
        dimensionFiltersValue() {
        // only dimensions are used by the filtered_search component, so only those needs processing
        return prepareTokens(this.filters.dimensions);
        attributeFiltersValue() {
        // only attributes are used by the filtered_search component, so only those needs processing
        return prepareTokens(this.filters.attributes);
        },
        },
        created() {
        ......@@ -96,10 +95,7 @@ export default {
        try {
        const enabled = await this.observabilityClient.isObservabilityEnabled();
        if (enabled) {
        await this.fetchMetricSearchMetadata();
        if (this.searchMetadata) {
        await this.fetchMetricData();
        }
        await Promise.all([this.fetchMetricSearchMetadata(), await this.fetchMetricData()]);
        } else {
        this.goToMetricsIndex();
        }
        ......@@ -131,13 +127,6 @@ export default {
        this.metricType,
        { filters: this.filters },
        );
        // TODO fetch config from API https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2488
        this.searchConfig = {
        dimensions: ['dimension_one', 'dimension_two'],
        groupByFunctions: ['avg', 'sum', 'p50'],
        defaultGroupByFunction: 'avg',
        defaultGroupByDimensions: ['dimension_one', 'dimension_two'],
        };
        } catch (e) {
        createAlert({
        message: this.$options.i18n.error,
        ......@@ -149,10 +138,10 @@ export default {
        goToMetricsIndex() {
        visitUrl(this.metricsIndexUrl);
        },
        onFilter({ dimensions, dateRange, groupBy }) {
        onFilter({ attributes, dateRange, groupBy }) {
        this.filters = {
        // only dimensions are used by the filtered_search component, so only those needs processing
        dimensions: processFilteredSearchFilters(dimensions),
        // only attributes are used by the filtered_search component, so only those needs processing
        attributes: processFilteredSearchFilters(attributes),
        dateRange,
        groupBy,
        };
        ......@@ -182,9 +171,9 @@ export default {
        <div class="gl-my-6">
        <filtered-search
        v-if="searchConfig"
        :search-config="searchConfig"
        :dimension-filters="dimensionFiltersValue"
        v-if="searchMetadata"
        :search-metadata="searchMetadata"
        :attribute-filters="attributeFiltersValue"
        :date-range-filter="filters.dateRange"
        :group-by-filter="filters.groupBy"
        @filter="onFilter"
        ......
        ......@@ -5,11 +5,18 @@ describe('GroupByFilter', () => {
        let wrapper;
        const props = {
        searchConfig: {
        groupByFunctions: ['sum', 'avg'],
        dimensions: ['dimension_one', 'dimensions_two'],
        searchMetadata: {
        name: 'cpu_seconds_total',
        type: 'sum',
        description: 'some_description',
        last_ingested_at: 1705374438711900000,
        attribute_keys: ['attribute_one', 'attributes_two'],
        supported_aggregations: ['1m', '1h'],
        supported_functions: ['sum', 'avg'],
        default_group_by_attributes: ['attribute_one', 'attributes_two'],
        default_group_by_function: 'avg',
        },
        selectedDimensions: ['dimension_one'],
        selectedAttributes: ['attribute_one'],
        selectedFunction: 'sum',
        };
        ......@@ -35,13 +42,13 @@ describe('GroupByFilter', () => {
        );
        });
        it('renders the group by dimensions dropdown', () => {
        expect(wrapper.findByTestId('group-by-dimensions-dropdown').props('items')).toEqual([
        { value: 'dimension_one', text: 'dimension_one' },
        { value: 'dimensions_two', text: 'dimensions_two' },
        it('renders the group by attributes dropdown', () => {
        expect(wrapper.findByTestId('group-by-attributes-dropdown').props('items')).toEqual([
        { value: 'attribute_one', text: 'attribute_one' },
        { value: 'attributes_two', text: 'attributes_two' },
        ]);
        expect(wrapper.findByTestId('group-by-dimensions-dropdown').props('selected')).toEqual(
        props.selectedDimensions,
        expect(wrapper.findByTestId('group-by-attributes-dropdown').props('selected')).toEqual(
        props.selectedAttributes,
        );
        });
        ......@@ -51,22 +58,22 @@ describe('GroupByFilter', () => {
        expect(wrapper.emitted('groupBy')).toEqual([
        [
        {
        dimensions: props.selectedDimensions,
        attributes: props.selectedAttributes,
        func: 'avg',
        },
        ],
        ]);
        });
        it('emits groupBy on dimension change', async () => {
        it('emits groupBy on attribute change', async () => {
        await wrapper
        .findByTestId('group-by-dimensions-dropdown')
        .vm.$emit('select', ['dimension_two']);
        .findByTestId('group-by-attributes-dropdown')
        .vm.$emit('select', ['attribute_two']);
        expect(wrapper.emitted('groupBy')).toEqual([
        [
        {
        dimensions: ['dimension_two'],
        attributes: ['attribute_two'],
        func: props.selectedFunction,
        },
        ],
        ......@@ -74,23 +81,23 @@ describe('GroupByFilter', () => {
        });
        it('updates the group-by toggle text depending on value', async () => {
        expect(wrapper.findByTestId('group-by-dimensions-dropdown').props('toggleText')).toBe(
        'dimension_one',
        expect(wrapper.findByTestId('group-by-attributes-dropdown').props('toggleText')).toBe(
        'attribute_one',
        );
        await wrapper
        .findByTestId('group-by-dimensions-dropdown')
        .vm.$emit('select', ['dimension_two']);
        .findByTestId('group-by-attributes-dropdown')
        .vm.$emit('select', ['attribute_two']);
        expect(wrapper.findByTestId('group-by-dimensions-dropdown').props('toggleText')).toBe(
        'dimension_two',
        expect(wrapper.findByTestId('group-by-attributes-dropdown').props('toggleText')).toBe(
        'attribute_two',
        );
        await wrapper
        .findByTestId('group-by-dimensions-dropdown')
        .vm.$emit('select', ['dimension_two', 'dimensions_one']);
        .findByTestId('group-by-attributes-dropdown')
        .vm.$emit('select', ['attribute_two', 'attributes_one']);
        expect(wrapper.findByTestId('group-by-dimensions-dropdown').props('toggleText')).toBe(
        expect(wrapper.findByTestId('group-by-attributes-dropdown').props('toggleText')).toBe(
        'multiple',
        );
        });
        ......@@ -99,15 +106,15 @@ describe('GroupByFilter', () => {
        expect(wrapper.findByTestId('group-by-label').text()).toBe('');
        await wrapper
        .findByTestId('group-by-dimensions-dropdown')
        .vm.$emit('select', ['dimension_two']);
        .findByTestId('group-by-attributes-dropdown')
        .vm.$emit('select', ['attribute_two']);
        expect(wrapper.findByTestId('group-by-label').text()).toBe('');
        await wrapper
        .findByTestId('group-by-dimensions-dropdown')
        .vm.$emit('select', ['dimension_two', 'dimensions_one']);
        .findByTestId('group-by-attributes-dropdown')
        .vm.$emit('select', ['attribute_two', 'attributes_one']);
        expect(wrapper.findByTestId('group-by-label').text()).toBe('dimension_two, dimensions_one');
        expect(wrapper.findByTestId('group-by-label').text()).toBe('attribute_two, attributes_one');
        });
        });
        ......@@ -10,15 +10,22 @@ import { OPERATORS_LIKE_NOT } from '~/observability/constants';
        describe('MetricsFilteredSearch', () => {
        let wrapper;
        const defaultSearchConfig = {
        dimensions: ['dimension_one', 'dimension_two'],
        groupByFunctions: ['avg', 'sum', 'p50'],
        const defaultSearchMetadata = {
        name: 'cpu_seconds_total',
        type: 'sum',
        description: 'some_description',
        last_ingested_at: 1705374438711900000,
        attribute_keys: ['attribute_one', 'attribute_two'],
        supported_aggregations: ['1m', '1h'],
        supported_functions: ['avg', 'sum', 'p50'],
        default_group_by_attributes: ['host.name'],
        default_group_by_function: 'avg',
        };
        const mount = (props = {}, searchConfig = {}) => {
        const mount = (props = {}, searchMetadata = {}) => {
        wrapper = shallowMountExtended(MetricsFilteredSearch, {
        propsData: {
        searchConfig: { ...defaultSearchConfig, ...searchConfig },
        searchMetadata: { ...defaultSearchMetadata, ...searchMetadata },
        ...props,
        },
        });
        ......@@ -32,14 +39,14 @@ describe('MetricsFilteredSearch', () => {
        const findDateRangeFilter = () => wrapper.findComponent(DateRangeFilter);
        const findGroupByFilter = () => wrapper.findComponent(GroupByFilter);
        it('renders the filtered search component with tokens based on dimensions', () => {
        it('renders the filtered search component with tokens based on attributes', () => {
        const filteredSeach = findFilteredSearch();
        expect(filteredSeach.exists()).toBe(true);
        const tokens = filteredSeach.props('tokens');
        expect(tokens.length).toBe(defaultSearchConfig.dimensions.length);
        expect(tokens.length).toBe(defaultSearchMetadata.attribute_keys.length);
        tokens.forEach((token, index) => {
        expect(token.type).toBe(defaultSearchConfig.dimensions[index]);
        expect(token.title).toBe(defaultSearchConfig.dimensions[index]);
        expect(token.type).toBe(defaultSearchMetadata.attribute_keys[index]);
        expect(token.title).toBe(defaultSearchMetadata.attribute_keys[index]);
        expect(token.token).toBe(GlFilteredSearchToken);
        expect(token.operators).toEqual([...OPERATORS_IS_NOT, ...OPERATORS_LIKE_NOT]);
        });
        ......@@ -47,7 +54,7 @@ describe('MetricsFilteredSearch', () => {
        it('renders the filtered search component with with initial tokens', () => {
        const filters = [{ type: 'key.name', value: 'foo' }];
        mount({ dimensionFilters: filters });
        mount({ attributeFilters: filters });
        expect(findFilteredSearch().props('initialFilterValue')).toEqual(filters);
        });
        ......@@ -65,32 +72,36 @@ describe('MetricsFilteredSearch', () => {
        });
        describe('group-by filter', () => {
        it('renders the group-by filter with search config', () => {
        it('renders the group-by filter with search metadata', () => {
        const groupBy = findGroupByFilter();
        expect(groupBy.exists()).toBe(true);
        expect(groupBy.props('searchConfig')).toEqual(defaultSearchConfig);
        expect(groupBy.props('selectedFunction')).toBe('');
        expect(groupBy.props('selectedDimensions')).toEqual([]);
        expect(groupBy.props('searchMetadata')).toEqual(defaultSearchMetadata);
        expect(groupBy.props('selectedFunction')).toBe(
        defaultSearchMetadata.default_group_by_function,
        );
        expect(groupBy.props('selectedAttributes')).toEqual(
        defaultSearchMetadata.default_group_by_attributes,
        );
        });
        it('renders the group-by filter with defaults', () => {
        mount(
        {},
        {
        defaultGroupByFunction: 'avg',
        defaultGroupByDimensions: ['dimension_one', 'dimension_two'],
        default_group_by_function: 'avg',
        default_group_by_attributes: ['attribute_one', 'attribute_two'],
        },
        );
        const groupBy = findGroupByFilter();
        expect(groupBy.props('searchConfig')).toEqual({
        ...defaultSearchConfig,
        defaultGroupByFunction: 'avg',
        defaultGroupByDimensions: ['dimension_one', 'dimension_two'],
        expect(groupBy.props('searchMetadata')).toEqual({
        ...defaultSearchMetadata,
        default_group_by_function: 'avg',
        default_group_by_attributes: ['attribute_one', 'attribute_two'],
        });
        expect(groupBy.props('selectedFunction')).toBe('avg');
        expect(groupBy.props('selectedDimensions')).toEqual(['dimension_one', 'dimension_two']);
        expect(groupBy.props('selectedAttributes')).toEqual(['attribute_one', 'attribute_two']);
        });
        it('renders the group-by filter with specified prop', () => {
        ......@@ -98,32 +109,32 @@ describe('MetricsFilteredSearch', () => {
        {
        groupByFilter: {
        func: 'sum',
        dimensions: ['attr_1'],
        attributes: ['attr_1'],
        },
        },
        {
        defaultGroupByFunction: 'avg',
        defaultGroupByDimensions: ['dimension_one', 'dimension_two'],
        default_group_by_function: 'avg',
        default_group_by_attributes: ['attribute_one', 'attribute_two'],
        },
        );
        const groupBy = findGroupByFilter();
        expect(groupBy.props('selectedFunction')).toBe('sum');
        expect(groupBy.props('selectedDimensions')).toEqual(['attr_1']);
        expect(groupBy.props('selectedAttributes')).toEqual(['attr_1']);
        });
        });
        it('emits the filter event when the dimensions filter is changed', async () => {
        const filters = [{ dimension: 'namespace', operator: 'is not', value: 'test' }];
        it('emits the filter event when the attributes filter is changed', async () => {
        const filters = [{ attribute: 'namespace', operator: 'is not', value: 'test' }];
        await findFilteredSearch().vm.$emit('onFilter', filters);
        expect(wrapper.emitted('filter')).toEqual([
        [
        {
        dimensions: [{ dimension: 'namespace', operator: 'is not', value: 'test' }],
        attributes: [{ attribute: 'namespace', operator: 'is not', value: 'test' }],
        groupBy: {
        dimensions: [],
        func: '',
        attributes: defaultSearchMetadata.default_group_by_attributes,
        func: defaultSearchMetadata.default_group_by_function,
        },
        },
        ],
        ......@@ -145,11 +156,11 @@ describe('MetricsFilteredSearch', () => {
        expect(wrapper.emitted('filter')).toEqual([
        [
        {
        dimensions: [],
        attributes: [],
        dateRange,
        groupBy: {
        dimensions: [],
        func: '',
        attributes: defaultSearchMetadata.default_group_by_attributes,
        func: defaultSearchMetadata.default_group_by_function,
        },
        },
        ],
        ......@@ -161,8 +172,8 @@ describe('MetricsFilteredSearch', () => {
        mount(
        {},
        {
        defaultGroupByFunction: 'avg',
        defaultGroupByDimensions: ['dimension_one', 'dimension_two'],
        default_group_by_function: 'avg',
        default_group_by_attributes: ['attribute_one', 'attribute_two'],
        },
        );
        ......@@ -171,9 +182,9 @@ describe('MetricsFilteredSearch', () => {
        expect(wrapper.emitted('filter')).toEqual([
        [
        {
        dimensions: [],
        attributes: [],
        groupBy: {
        dimensions: ['dimension_one', 'dimension_two'],
        attributes: ['attribute_one', 'attribute_two'],
        func: 'avg',
        },
        },
        ......@@ -183,7 +194,7 @@ describe('MetricsFilteredSearch', () => {
        it('emits the filter event when the group-by is changed and the filtered-search onFilter is emitted', async () => {
        const groupBy = {
        dimensions: ['dimension_one'],
        attributes: ['attribute_one'],
        func: 'sum',
        };
        ......@@ -195,12 +206,12 @@ describe('MetricsFilteredSearch', () => {
        expect(wrapper.emitted('filter')).toEqual([
        [
        {
        dimensions: [],
        attributes: [],
        groupBy,
        },
        ],
        ]);
        expect(findGroupByFilter().props('selectedFunction')).toBe(groupBy.func);
        expect(findGroupByFilter().props('selectedDimensions')).toEqual(groupBy.dimensions);
        expect(findGroupByFilter().props('selectedAttributes')).toEqual(groupBy.attributes);
        });
        });
        ......@@ -133,16 +133,15 @@ describe('MetricsDetails', () => {
        describe('filtered search', () => {
        const findFilteredSearch = () => findMetricDetails().findComponent(FilteredSearch);
        it('renders the FilteredSearch component', () => {
        expect(findFilteredSearch().exists()).toBe(true);
        // TODO get searchConfig from API https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2488
        expect(Object.keys(findFilteredSearch().props('searchConfig'))).toEqual(
        expect.arrayContaining([
        'dimensions',
        'groupByFunctions',
        'defaultGroupByFunction',
        'defaultGroupByDimensions',
        ]),
        );
        const filteredSearch = findFilteredSearch();
        expect(filteredSearch.exists()).toBe(true);
        expect(filteredSearch.props('searchMetadata')).toBe(mockSearchMetadata);
        });
        it('does not render the filtered search component if fetching metadata fails', async () => {
        observabilityClientMock.fetchMetricSearchMetadata.mockRejectedValueOnce('error');
        await mountComponent();
        expect(findFilteredSearch().exists()).toBe(false);
        });
        it('sets the default date range', () => {
        ......@@ -156,7 +155,7 @@ describe('MetricsDetails', () => {
        it('fetches metrics with filters', () => {
        expect(observabilityClientMock.fetchMetric).toHaveBeenCalledWith(METRIC_ID, METRIC_TYPE, {
        filters: {
        dimensions: [],
        attributes: [],
        dateRange: {
        endDate: new Date('2020-07-06T00:00:00.000Z'),
        startDarte: new Date('2020-07-05T23:00:00.000Z'),
        ......@@ -167,9 +166,9 @@ describe('MetricsDetails', () => {
        });
        describe('on search submit', () => {
        const setFilters = async (dimensions, dateRange, groupBy) => {
        const setFilters = async (attributes, dateRange, groupBy) => {
        findFilteredSearch().vm.$emit('filter', {
        dimensions: prepareTokens(dimensions),
        attributes: prepareTokens(attributes),
        dateRange,
        groupBy,
        });
        ......@@ -188,7 +187,7 @@ describe('MetricsDetails', () => {
        },
        {
        func: 'avg',
        dimensions: ['attr_1', 'attr_2'],
        attributes: ['attr_1', 'attr_2'],
        },
        );
        });
        ......@@ -199,7 +198,7 @@ describe('MetricsDetails', () => {
        METRIC_TYPE,
        {
        filters: {
        dimensions: {
        attributes: {
        'key.one': [{ operator: '=', value: '12h' }],
        },
        dateRange: {
        ......@@ -209,7 +208,7 @@ describe('MetricsDetails', () => {
        },
        groupBy: {
        func: 'avg',
        dimensions: ['attr_1', 'attr_2'],
        attributes: ['attr_1', 'attr_2'],
        },
        },
        },
        ......@@ -222,14 +221,14 @@ describe('MetricsDetails', () => {
        startDarte: new Date('2020-07-05T23:00:00.000Z'),
        value: '30d',
        });
        expect(findFilteredSearch().props('dimensionFilters')).toEqual(
        expect(findFilteredSearch().props('attributeFilters')).toEqual(
        prepareTokens({
        'key.one': [{ operator: '=', value: '12h' }],
        }),
        );
        expect(findFilteredSearch().props('groupByFilter')).toEqual({
        func: 'avg',
        dimensions: ['attr_1', 'attr_2'],
        attributes: ['attr_1', 'attr_2'],
        });
        });
        });
        ......@@ -318,12 +317,6 @@ describe('MetricsDetails', () => {
        });
        });
        it('does not fetch metric data if fetching search metadata fails', async () => {
        observabilityClientMock.fetchMetricSearchMetadata.mockRejectedValueOnce('error');
        await mountComponent();
        expect(observabilityClientMock.fetchMetric).not.toHaveBeenCalled();
        });
        it('renders an alert if metricId is missing', async () => {
        await mountComponent({ metricId: undefined });
        ......
        ......@@ -33588,7 +33588,7 @@ msgstr ""
        msgid "ObservabilityMetrics|Failed to load metrics."
        msgstr ""
         
        msgid "ObservabilityMetrics|Filter dimensions..."
        msgid "ObservabilityMetrics|Filter attributes..."
        msgstr ""
         
        msgid "ObservabilityMetrics|Last ingested"
        ......@@ -785,11 +785,11 @@ describe('buildClient', () => {
        axiosMock.onGet(metricsSearchUrl).reply(200, { results: [] });
        });
        describe('dimension filter', () => {
        describe('attribute filter', () => {
        it('converts filter to proper query params', async () => {
        await client.fetchMetric('name', 'type', {
        filters: {
        dimensions: {
        attributes: {
        attr_1: [
        { operator: '=', value: 'foo' },
        { operator: '!=', value: 'bar' },
        ......@@ -811,7 +811,7 @@ describe('buildClient', () => {
        it('handles repeated params', async () => {
        await client.fetchMetric('name', 'type', {
        filters: {
        dimensions: {
        attributes: {
        attr_1: [
        { operator: '=', value: 'v1' },
        { operator: '=', value: 'v2' },
        ......@@ -824,7 +824,7 @@ describe('buildClient', () => {
        it('ignores empty filters', async () => {
        await client.fetchMetric('name', 'type', {
        filters: { dimensions: [] },
        filters: { attributes: [] },
        });
        expect(getQueryParam()).toBe('mname=name&mtype=type');
        ......@@ -832,7 +832,7 @@ describe('buildClient', () => {
        it('ignores undefined dimension filters', async () => {
        await client.fetchMetric('name', 'type', {
        filters: { dimensions: undefined },
        filters: { attributes: undefined },
        });
        expect(getQueryParam()).toBe('mname=name&mtype=type');
        ......@@ -841,7 +841,7 @@ describe('buildClient', () => {
        it('ignores non-array filters', async () => {
        await client.fetchMetric('name', 'type', {
        filters: {
        dimensions: {
        attributes: {
        attr_1: { operator: '=', value: 'foo' },
        },
        },
        ......@@ -853,7 +853,7 @@ describe('buildClient', () => {
        it('ignores unsupported operators', async () => {
        await client.fetchMetric('name', 'type', {
        filters: {
        dimensions: {
        attributes: {
        attr_1: [
        { operator: '*', value: 'foo' },
        { operator: '>', value: 'foo' },
        ......@@ -929,16 +929,16 @@ describe('buildClient', () => {
        expect(getQueryParam()).toContain(`groupby_fn=sum`);
        });
        it('handle group by dimension', async () => {
        it('handle group by attribute', async () => {
        await client.fetchMetric('name', 'type', {
        filters: { groupBy: { dimensions: ['attr_1'] } },
        filters: { groupBy: { attributes: ['attr_1'] } },
        });
        expect(getQueryParam()).toContain(`groupby_attrs=attr_1`);
        });
        it('handle group by multiple dimensions', async () => {
        it('handle group by multiple attributes', async () => {
        await client.fetchMetric('name', 'type', {
        filters: { groupBy: { dimensions: ['attr_1', 'attr_2'] } },
        filters: { groupBy: { attributes: ['attr_1', 'attr_2'] } },
        });
        expect(getQueryParam()).toContain(`groupby_attrs=attr_1,attr_2`);
        });
        ......@@ -951,7 +951,7 @@ describe('buildClient', () => {
        it('ignores empty list', async () => {
        await client.fetchMetric('name', 'type', {
        filters: { groupBy: { dimensions: [] } },
        filters: { groupBy: { attributes: [] } },
        });
        expect(getQueryParam()).toBe('mname=name&mtype=type');
        });
        ......
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Finish editing this message first!
        Please register or to comment