"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../index");
const field_1 = require("../types/field");
const filter_1 = require("../types/filter");
const fields_1 = require("./fields");
const fields_mock_1 = require("./fields.mock");
describe('getFieldsFromMetricQuery', () => {
    test('should return all valid fields', async () => {
        const result = (0, index_1.getFieldsFromMetricQuery)(fields_mock_1.metricQuery, fields_mock_1.explore);
        expect(Object.keys(result)).toEqual([
            'table1_dim1',
            'custom_dimension_1',
            'table1_metric1',
            'table1_additional_metric_1',
            'calc2',
        ]);
        // Check a few types of items
        expect((0, field_1.isField)(result.table1_metric1)).toEqual(true);
        expect((0, field_1.isField)(result.table1_metric1) && result.table1_metric1.fieldType).toEqual('metric');
        expect((0, field_1.isField)(result.table1_metric1) && result.table1_metric1.type).toEqual('average');
    });
    test('should test with empty explore', async () => {
        // With an empty explore, we can't get dimensions or metrics, but we still return table calculations and custom dimensions
        const result = (0, index_1.getFieldsFromMetricQuery)(fields_mock_1.metricQuery, fields_mock_1.emptyExplore);
        expect(Object.keys(result)).toEqual(['custom_dimension_1', 'calc2']);
    });
    test('should test with empty metric query', async () => {
        const result = (0, index_1.getFieldsFromMetricQuery)(fields_mock_1.emptyMetricQuery, fields_mock_1.explore);
        expect(Object.keys(result)).toEqual([]);
    });
    test('should not return custom metric or dimensions if not selected', async () => {
        const result = (0, index_1.getFieldsFromMetricQuery)({
            ...fields_mock_1.metricQuery,
            dimensions: ['table1_dim1', 'table2_dim2'],
            metrics: ['table1_metric1', 'table2_metric2'],
        }, fields_mock_1.explore);
        expect(Object.keys(result)).toEqual([
            'table1_dim1',
            'table1_metric1',
            'calc2',
            // 'custom_dimension_1',
            // 'table1_additional_metric_1',
        ]);
    });
});
describe('compareMetricAndCustomMetric', () => {
    test('should return exact match for simple custom metric', async () => {
        const result = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: fields_mock_1.customMetric,
            metric: fields_mock_1.metric,
        });
        expect(result.isExactMatch).toEqual(true);
        expect(result.isSuggestedMatch).toEqual(true);
    });
    const mismatchButSuggestCases = [
        ['name', 'diff_name'],
        ['label', 'diff label'],
    ];
    test.each(mismatchButSuggestCases)('should not match but suggest when %s has different value', (key, value) => {
        const result = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                [key]: value,
            },
            metric: fields_mock_1.metric,
        });
        expect(result.isExactMatch).toEqual(false);
        expect(result.isSuggestedMatch).toEqual(true);
    });
    const mismatchCases = [
        ['sql', 'diff_sql'],
        ['baseDimensionName', 'diff_baseDimensionName'],
        ['table', 'diff_table'],
        ['type', 'max'],
    ];
    test.each(mismatchCases)('should not match or suggest when %s has different value', (key, value) => {
        const result = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                [key]: value,
            },
            metric: fields_mock_1.metric,
        });
        expect(result.isExactMatch).toEqual(false);
        expect(result.isSuggestedMatch).toEqual(false);
    });
    test('should return exact match when comparing format expression with format object', async () => {
        const result = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                formatOptions: {
                    type: field_1.CustomFormatType.CURRENCY,
                    currency: 'JPY',
                    round: 3,
                    separator: field_1.NumberSeparator.COMMA_PERIOD,
                },
            },
            metric: {
                ...fields_mock_1.metric,
                format: '[$¥]#,##0.000',
            },
        });
        expect(result.isExactMatch).toEqual(true);
        expect(result.isSuggestedMatch).toEqual(true);
    });
    test('should return exact match with multiple filters', async () => {
        const result = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)(),
                    (0, fields_mock_1.metricFilterRule)({
                        fieldRef: 'b_dim2',
                        values: ['2', '4'],
                        operator: filter_1.FilterOperator.IN_BETWEEN,
                    }),
                    (0, fields_mock_1.metricFilterRule)({
                        operator: filter_1.FilterOperator.IN_THE_PAST,
                        settings: {
                            unitOfTime: filter_1.UnitOfTime.years,
                        },
                    }),
                ],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)(),
                    (0, fields_mock_1.metricFilterRule)({
                        fieldRef: 'b_dim2',
                        values: ['2', '4'],
                        operator: filter_1.FilterOperator.IN_BETWEEN,
                    }),
                    (0, fields_mock_1.metricFilterRule)({
                        operator: filter_1.FilterOperator.IN_THE_PAST,
                        settings: {
                            unitOfTime: filter_1.UnitOfTime.years,
                        },
                    }),
                ],
            },
        });
        expect(result.isExactMatch).toEqual(true);
        expect(result.isSuggestedMatch).toEqual(true);
    });
    test('should not match or suggest when filter has different value', async () => {
        // Different filters length
        const result = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [(0, fields_mock_1.metricFilterRule)(), (0, fields_mock_1.metricFilterRule)()],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [(0, fields_mock_1.metricFilterRule)()],
            },
        });
        expect(result.isExactMatch).toEqual(false);
        expect(result.isSuggestedMatch).toEqual(false);
        // Different operator
        const result2 = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [(0, fields_mock_1.metricFilterRule)()],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)({
                        operator: filter_1.FilterOperator.NOT_EQUALS,
                    }),
                ],
            },
        });
        expect(result2.isExactMatch).toEqual(false);
        expect(result2.isSuggestedMatch).toEqual(false);
        // Different values
        const result3 = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [(0, fields_mock_1.metricFilterRule)()],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)({
                        values: ['2'],
                    }),
                ],
            },
        });
        expect(result3.isExactMatch).toEqual(false);
        expect(result3.isSuggestedMatch).toEqual(false);
        // Different fieldRef
        const result4 = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [(0, fields_mock_1.metricFilterRule)()],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)({
                        fieldRef: 'b_dim2',
                    }),
                ],
            },
        });
        expect(result4.isExactMatch).toEqual(false);
        expect(result4.isSuggestedMatch).toEqual(false);
        // Different unit of time
        const result5 = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)({
                        operator: filter_1.FilterOperator.IN_THE_PAST,
                        settings: {
                            unitOfTime: filter_1.UnitOfTime.days,
                        },
                    }),
                ],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)({
                        operator: filter_1.FilterOperator.IN_THE_PAST,
                        settings: {
                            unitOfTime: filter_1.UnitOfTime.years,
                            completed: true,
                        },
                    }),
                ],
            },
        });
        expect(result5.isExactMatch).toEqual(false);
        expect(result5.isSuggestedMatch).toEqual(false);
        // Different filter types (one time filter, one not)
        const result6 = (0, fields_1.compareMetricAndCustomMetric)({
            customMetric: {
                ...fields_mock_1.customMetric,
                filters: [
                    (0, fields_mock_1.metricFilterRule)({
                        operator: filter_1.FilterOperator.IN_THE_PAST,
                        settings: {
                            unitOfTime: filter_1.UnitOfTime.days,
                        },
                    }),
                ],
            },
            metric: {
                ...fields_mock_1.metric,
                filters: [(0, fields_mock_1.metricFilterRule)()],
            },
        });
        expect(result6.isExactMatch).toEqual(false);
        expect(result6.isSuggestedMatch).toEqual(false);
    });
});
describe('getDimensionsWithValidParameters', () => {
    test('should return base table dimensions before joined table dimensions', () => {
        const result = (0, fields_1.getDimensionsWithValidParameters)(fields_mock_1.exploreWithJoinedTables, {});
        // Should have 4 dimensions total (2 from base, 2 from joined)
        expect(result).toHaveLength(4);
        // Get dimension names in order
        const dimensionNames = result.map((d) => d.name);
        // Base table dimensions (base_dim1, base_dim2) should come before
        // joined table dimensions (joined_dim1, joined_dim2)
        const baseDim1Idx = dimensionNames.indexOf('base_dim1');
        const baseDim2Idx = dimensionNames.indexOf('base_dim2');
        const joinedDim1Idx = dimensionNames.indexOf('joined_dim1');
        const joinedDim2Idx = dimensionNames.indexOf('joined_dim2');
        // All base table dimensions should come before any joined table dimension
        expect(baseDim1Idx).toBeLessThan(joinedDim1Idx);
        expect(baseDim1Idx).toBeLessThan(joinedDim2Idx);
        expect(baseDim2Idx).toBeLessThan(joinedDim1Idx);
        expect(baseDim2Idx).toBeLessThan(joinedDim2Idx);
    });
});
//# sourceMappingURL=fields.test.js.map