diff --git a/tests/functional/metrics/fixtures.py b/tests/functional/metrics/fixtures.py index 5a8373fbe5d..76049165e86 100644 --- a/tests/functional/metrics/fixtures.py +++ b/tests/functional/metrics/fixtures.py @@ -664,3 +664,38 @@ conversion_measure: num_orders entity: purchase """ + +filtered_metrics_yml = """ +version: 2 + +metrics: + + - name: collective_tenure_measure_filter_str + label: "Collective tenure1" + description: Total number of years of team experience + type: simple + type_params: + measure: + name: "years_tenure" + filter: "{{ Dimension('id__loves_dbt') }} is true" + + - name: collective_tenure_metric_filter_str + label: Collective tenure3 + description: Total number of years of team experience + type: simple + type_params: + measure: + name: "years_tenure" + filter: "{{ Dimension('id__loves_dbt') }} is true" + + + - name: average_tenure_filter_str + label: Average tenure of people who love dbt1 + description: Average tenure of people who love dbt + type: derived + type_params: + expr: "average_tenure" + metrics: + - name: average_tenure + filter: "{{ Dimension('id__loves_dbt') }} is true" +""" diff --git a/tests/functional/metrics/test_metrics.py b/tests/functional/metrics/test_metrics.py index 70ebcfa35b8..29371a6ce3e 100644 --- a/tests/functional/metrics/test_metrics.py +++ b/tests/functional/metrics/test_metrics.py @@ -28,6 +28,8 @@ semantic_model_people_yml, semantic_model_purchasing_yml, purchasing_model_sql, + filtered_metrics_yml, + basic_metrics_yml, ) @@ -399,3 +401,53 @@ def test_conversion_metric( ].type_params.conversion_type_params.entity == "purchase" ) + + +class TestFilterParsing: + @pytest.fixture(scope="class") + def models(self): + return { + "basic_metrics.yml": basic_metrics_yml, + "filtered_metrics.yml": filtered_metrics_yml, + "metricflow_time_spine.sql": metricflow_time_spine_sql, + "semantic_model_people.yml": semantic_model_people_yml, + "people.sql": models_people_sql, + } + + # Tests that filters are parsed to their appropriate type + def test_string_filter_parsing( + self, + project, + ): + runner = dbtRunner() + result = runner.invoke(["parse"]) + assert result.success + assert isinstance(result.result, Manifest) + + manifest = get_manifest(project.project_root) + assert manifest + + # Test metrics with input measure filters. + filters1 = ( + manifest.metrics["metric.test.collective_tenure_measure_filter_str"] + .input_measures[0] + .filter.where_filters + ) + assert len(filters1) == 1 + assert filters1[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true" + + # Test metrics with metric-level filters. + filters2 = manifest.metrics[ + "metric.test.collective_tenure_metric_filter_str" + ].filter.where_filters + assert len(filters2) == 1 + assert filters2[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true" + + # Test derived metrics with input metric filters. + filters3 = ( + manifest.metrics["metric.test.average_tenure_filter_str"] + .input_metrics[0] + .filter.where_filters + ) + assert len(filters3) == 1 + assert filters3[0].where_sql_template == "{{ Dimension('id__loves_dbt') }} is true" diff --git a/tests/functional/saved_queries/fixtures.py b/tests/functional/saved_queries/fixtures.py index 68565d82e08..6dde0c0dd9a 100644 --- a/tests/functional/saved_queries/fixtures.py +++ b/tests/functional/saved_queries/fixtures.py @@ -23,6 +23,16 @@ alias: my_export_alias export_as: table schema: my_export_schema_name + + - name: test_saved_query_where_str + description: "{{ doc('saved_query_description') }}" + label: Test Saved Query2 + query_params: + metrics: + - simple_metric + group_by: + - "Dimension('user__ds')" + where: "{{ Dimension('user__ds', 'DAY') }} <= now()" """ saved_query_with_extra_config_attributes_yml = """ diff --git a/tests/functional/saved_queries/test_saved_query_parsing.py b/tests/functional/saved_queries/test_saved_query_parsing.py index 84c8c78b5eb..aaabc386e72 100644 --- a/tests/functional/saved_queries/test_saved_query_parsing.py +++ b/tests/functional/saved_queries/test_saved_query_parsing.py @@ -32,7 +32,7 @@ def test_semantic_model_parsing(self, project): assert result.success assert isinstance(result.result, Manifest) manifest = result.result - assert len(manifest.saved_queries) == 1 + assert len(manifest.saved_queries) == 2 saved_query = manifest.saved_queries["saved_query.test.test_saved_query"] assert saved_query.name == "test_saved_query" assert len(saved_query.query_params.metrics) == 1 @@ -69,6 +69,31 @@ def models(self): "docs.md": saved_query_description, } + def test_saved_query_filter_types(self, project): + runner = dbtTestRunner() + result = runner.invoke(["parse"]) + assert result.success + + manifest = result.result + saved_query1 = manifest.saved_queries["saved_query.test.test_saved_query"] + saved_query2 = manifest.saved_queries["saved_query.test.test_saved_query_where_str"] + + # List filter + assert len(saved_query1.query_params.where.where_filters) == 2 + assert { + where_filter.where_sql_template + for where_filter in saved_query1.query_params.where.where_filters + } == { + "{{ Dimension('user__ds', 'DAY') }} <= now()", + "{{ Dimension('user__ds', 'DAY') }} >= '2023-01-01'", + } + # String filter + assert len(saved_query2.query_params.where.where_filters) == 1 + assert ( + saved_query2.query_params.where.where_filters[0].where_sql_template + == "{{ Dimension('user__ds', 'DAY') }} <= now()" + ) + def test_saved_query_metrics_changed(self, project): # First, use the default saved_queries.yml to define our saved_queries, and # run the dbt parse command