66import contextlib
77import json
88import uuid
9+ from pathlib import Path
10+ from typing import Generator , List , Optional , Union
911
1012import pytest
1113from dbt_project import DbtProject
1214
1315
1416@contextlib .contextmanager
15- def cleanup_file (path ) :
17+ def cleanup_file (path : Path ) -> Generator [ None , None , None ] :
1618 """Context manager to clean up a file after the test."""
1719 try :
1820 yield
@@ -21,7 +23,9 @@ def cleanup_file(path):
2123 path .unlink ()
2224
2325
24- def _parse_model_owners (model_owners_value ):
26+ def _parse_model_owners (
27+ model_owners_value : Optional [Union [str , List [str ]]]
28+ ) -> List [str ]:
2529 """
2630 Parse the model_owners column value which may be a JSON string or list.
2731 Returns a list of owner strings.
@@ -41,7 +45,28 @@ def _parse_model_owners(model_owners_value):
4145 return []
4246
4347
44- def test_single_parent_test_owner_attribution (dbt_project : DbtProject ):
48+ def _create_model_sql (owner : Optional [str ] = None , columns : str = "1 as id" ) -> str :
49+ """
50+ Create a dbt model SQL string with optional owner configuration.
51+
52+ Args:
53+ owner: The owner to set in the model's meta config. If None, no config is added.
54+ columns: The SELECT clause columns. Defaults to "1 as id".
55+
56+ Returns:
57+ A dbt model SQL string.
58+ """
59+ if owner is not None :
60+ return f"""
61+ {{{{ config(meta={{'owner': '{ owner } '}}) }}}}
62+ select { columns }
63+ """
64+ return f"""
65+ select { columns }
66+ """
67+
68+
69+ def test_single_parent_test_owner_attribution (dbt_project : DbtProject ) -> None :
4570 """
4671 Test that a test on a single model correctly inherits the owner from that model.
4772 This is the baseline case - single parent tests should have the parent's owner.
@@ -50,14 +75,7 @@ def test_single_parent_test_owner_attribution(dbt_project: DbtProject):
5075 model_name = f"model_single_owner_{ unique_id } "
5176 owner_name = "Alice"
5277
53- model_sql = (
54- """
55- {{ config(meta={'owner': '"""
56- + owner_name
57- + """'}) }}
58- select 1 as id
59- """
60- )
78+ model_sql = _create_model_sql (owner = owner_name )
6179
6280 schema_yaml = {
6381 "version" : 2 ,
@@ -99,7 +117,7 @@ def test_single_parent_test_owner_attribution(dbt_project: DbtProject):
99117@pytest .mark .skip_targets (["dremio" ])
100118def test_relationship_test_uses_primary_model_owner_only (
101119 dbt_project : DbtProject ,
102- ):
120+ ) -> None :
103121 """
104122 Test that a relationship test between two models with different owners
105123 only uses the owner from the PRIMARY model (the one being tested),
@@ -116,15 +134,10 @@ def test_relationship_test_uses_primary_model_owner_only(
116134 primary_owner = "Alice"
117135 referenced_owner = "Bob"
118136
119- primary_model_sql = f"""
120- {{{{ config(meta={{'owner': '{ primary_owner } '}}) }}}}
121- select 1 as id, 1 as ref_id
122- """
123-
124- referenced_model_sql = f"""
125- {{{{ config(meta={{'owner': '{ referenced_owner } '}}) }}}}
126- select 1 as id
127- """
137+ primary_model_sql = _create_model_sql (
138+ owner = primary_owner , columns = "1 as id, 1 as ref_id"
139+ )
140+ referenced_model_sql = _create_model_sql (owner = referenced_owner )
128141
129142 schema_yaml = {
130143 "version" : 2 ,
@@ -195,7 +208,7 @@ def test_relationship_test_uses_primary_model_owner_only(
195208
196209
197210@pytest .mark .skip_targets (["dremio" ])
198- def test_relationship_test_no_owner_on_primary_model (dbt_project : DbtProject ):
211+ def test_relationship_test_no_owner_on_primary_model (dbt_project : DbtProject ) -> None :
199212 """
200213 Test that when the primary model has no owner but the referenced model does,
201214 the test should have empty model_owners (not inherit from referenced model).
@@ -207,14 +220,8 @@ def test_relationship_test_no_owner_on_primary_model(dbt_project: DbtProject):
207220 test_name = f"rel_no_owner_{ unique_id } "
208221 referenced_owner = "Bob"
209222
210- primary_model_sql = """
211- select 1 as id, 1 as ref_id
212- """
213-
214- referenced_model_sql = f"""
215- {{{{ config(meta={{'owner': '{ referenced_owner } '}}) }}}}
216- select 1 as id
217- """
223+ primary_model_sql = _create_model_sql (owner = None , columns = "1 as id, 1 as ref_id" )
224+ referenced_model_sql = _create_model_sql (owner = referenced_owner )
218225
219226 schema_yaml = {
220227 "version" : 2 ,
@@ -284,18 +291,15 @@ def test_relationship_test_no_owner_on_primary_model(dbt_project: DbtProject):
284291 ), f"Expected model_owners to be empty (primary model has no owner), got { model_owners } . Referenced model owner '{ referenced_owner } ' should NOT be inherited."
285292
286293
287- def test_owner_deduplication (dbt_project : DbtProject ):
294+ def test_owner_deduplication (dbt_project : DbtProject ) -> None :
288295 """
289296 Test that duplicate owners in a model's owner field are deduplicated.
290297 For example, if owner is "Alice,Bob,Alice", the result should be ["Alice", "Bob"].
291298 """
292299 unique_id = str (uuid .uuid4 ()).replace ("-" , "_" )
293300 model_name = f"model_dup_owner_{ unique_id } "
294301
295- model_sql = """
296- {{ config(meta={'owner': 'Alice,Bob,Alice'}) }}
297- select 1 as id
298- """
302+ model_sql = _create_model_sql (owner = "Alice,Bob,Alice" )
299303
300304 schema_yaml = {
301305 "version" : 2 ,
0 commit comments