mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-11-04 04:29:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1167 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1167 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import uuid
 | 
						|
from typing import List, Optional
 | 
						|
from unittest import TestCase
 | 
						|
 | 
						|
from metadata.generated.schema.api.data.createDashboardDataModel import (
 | 
						|
    CreateDashboardDataModelRequest,
 | 
						|
)
 | 
						|
from metadata.generated.schema.api.data.createTable import CreateTableRequest
 | 
						|
from metadata.generated.schema.api.services.createDatabaseService import (
 | 
						|
    CreateDatabaseServiceRequest,
 | 
						|
)
 | 
						|
from metadata.generated.schema.entity.data.dashboardDataModel import (
 | 
						|
    DashboardDataModel,
 | 
						|
    DataModelType,
 | 
						|
)
 | 
						|
from metadata.generated.schema.entity.data.table import (
 | 
						|
    Column,
 | 
						|
    ColumnName,
 | 
						|
    DataType,
 | 
						|
    Table,
 | 
						|
    TableConstraint,
 | 
						|
    TableType,
 | 
						|
)
 | 
						|
from metadata.generated.schema.type.basic import (
 | 
						|
    EntityExtension,
 | 
						|
    EntityName,
 | 
						|
    FullyQualifiedEntityName,
 | 
						|
    Markdown,
 | 
						|
)
 | 
						|
from metadata.generated.schema.type.entityReference import EntityReference
 | 
						|
from metadata.ingestion.models.custom_pydantic import BaseModel, CustomSecretStr
 | 
						|
 | 
						|
 | 
						|
class CustomPydanticValidationTest(TestCase):
 | 
						|
 | 
						|
    create_request = CreateTableRequest(
 | 
						|
        name=EntityName("Sales::>Territory"),
 | 
						|
        displayName="SalesTerritory",
 | 
						|
        description=Markdown(root="Sales territory lookup table."),
 | 
						|
        tableType="Regular",
 | 
						|
        columns=[
 | 
						|
            Column(
 | 
						|
                name=ColumnName(root="Sales::Last>Year"),
 | 
						|
                displayName="SalesLastYear",
 | 
						|
                dataType="NUMBER",
 | 
						|
                dataTypeDisplay="NUMBER",
 | 
						|
                description=Markdown(root="Sales total of previous year."),
 | 
						|
                constraint="NOT_NULL",
 | 
						|
                ordinalPosition=7,
 | 
						|
            ),
 | 
						|
            Column(
 | 
						|
                name=ColumnName(root="Bonus"),
 | 
						|
                displayName="Bonus",
 | 
						|
                dataType="NUMBER",
 | 
						|
                dataTypeDisplay="NUMBER",
 | 
						|
                description=Markdown(root="Bonus due if quota is met."),
 | 
						|
                constraint="NOT_NULL",
 | 
						|
                ordinalPosition=4,
 | 
						|
            ),
 | 
						|
            Column(
 | 
						|
                name=ColumnName(root="ModifiedDate"),
 | 
						|
                displayName="ModifiedDate",
 | 
						|
                dataType="DATETIME",
 | 
						|
                dataTypeDisplay="DATETIME",
 | 
						|
                description=Markdown(root="Date and time the record was last updated."),
 | 
						|
                constraint="NOT_NULL",
 | 
						|
                ordinalPosition=9,
 | 
						|
            ),
 | 
						|
        ],
 | 
						|
        tableConstraints=[
 | 
						|
            TableConstraint(constraintType="PRIMARY_KEY", columns=["Sales::Last>Year"])
 | 
						|
        ],
 | 
						|
        databaseSchema=FullyQualifiedEntityName(
 | 
						|
            root='New Gyro 360.New Gyro 360."AdventureWorks2017.HumanResources"'
 | 
						|
        ),
 | 
						|
        extension=EntityExtension(
 | 
						|
            root={
 | 
						|
                "DataQuality": '<div><p><b>Last evaluation:</b> 07/24/2023<br><b>Interval: </b>30 days <br><b>Next run:</b> 08/23/2023, 10:44:20<br><b>Measurement unit:</b> percent [%]</p><br><table><tbody><tr><th>Metric</th><th>Target</th><th>Latest result</th></tr><tr><td><p class="text-success">Completeness</p></td><td>90%</td><td><div class="bar fabric" style="width: 100%;"><strong>100%</strong></div></td></tr><tr><td><p class="text-success">Integrity</p></td><td>90%</td><td><div class="bar fabric" style="width: 100%;"><strong>100%</strong></div></td></tr><tr><td><p class="text-warning">Timeliness</p></td><td>90%</td><td><div class="bar fabric" style="width: 25%;"><strong>25%</strong></div></td></tr><tr><td><p class="text-warning">Uniqueness</p></td><td>90%</td><td><div class="bar fabric" style="width: 60%;"><strong>60%</strong></div></td></tr><tr><td><p class="text-success">Validity</p></td><td>90%</td><td><div class="bar fabric" style="width: 100%;"><strong>100%</strong></div></td></tr></tbody></table><h3>Overall score of the table is: 77%</h3><hr style="border-width: 5px;"></div>'
 | 
						|
            }
 | 
						|
        ),
 | 
						|
    )
 | 
						|
 | 
						|
    create_request_dashboard_datamodel = CreateDashboardDataModelRequest(
 | 
						|
        name=EntityName('test"dashboarddatamodel"'),
 | 
						|
        displayName='test"dashboarddatamodel"',
 | 
						|
        description=Markdown(
 | 
						|
            root="test__reserved__quote__dashboarddatamodel__reserved__quote__"
 | 
						|
        ),
 | 
						|
        dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
        service=FullyQualifiedEntityName(
 | 
						|
            root='New Gyro 360.New Gyro 360."AdventureWorks2017.HumanResources"'
 | 
						|
        ),
 | 
						|
        columns=[
 | 
						|
            Column(
 | 
						|
                name="struct",
 | 
						|
                dataType=DataType.STRUCT,
 | 
						|
                arrayDataType="UNKNOWN",
 | 
						|
                children=[
 | 
						|
                    Column(name='test "struct_children"', dataType=DataType.BIGINT)
 | 
						|
                ],
 | 
						|
            )
 | 
						|
        ],
 | 
						|
    )
 | 
						|
 | 
						|
    def test_replace_separator(self):
 | 
						|
        assert (
 | 
						|
            self.create_request.name.root
 | 
						|
            == "Sales__reserved__colon____reserved__arrow__Territory"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            self.create_request.columns[0].name.root
 | 
						|
            == "Sales__reserved__colon__Last__reserved__arrow__Year"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            self.create_request.tableConstraints[0].columns[0]
 | 
						|
            == "Sales__reserved__colon__Last__reserved__arrow__Year"
 | 
						|
        )
 | 
						|
 | 
						|
        assert (
 | 
						|
            self.create_request_dashboard_datamodel.name.root
 | 
						|
            == "test__reserved__quote__dashboarddatamodel__reserved__quote__"
 | 
						|
        )
 | 
						|
 | 
						|
        assert (
 | 
						|
            self.create_request_dashboard_datamodel.columns[0].children[0].name.root
 | 
						|
            == "test __reserved__quote__struct_children__reserved__quote__"
 | 
						|
        )
 | 
						|
 | 
						|
    def test_revert_separator(self):
 | 
						|
        fetch_response_revert_separator = Table(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name="test__reserved__colon__table",
 | 
						|
            databaseSchema=EntityReference(id=uuid.uuid4(), type="databaseSchema"),
 | 
						|
            fullyQualifiedName="test-service-table.test-db.test-schema.test",
 | 
						|
            columns=[Column(name="id", dataType=DataType.BIGINT)],
 | 
						|
        )
 | 
						|
        fetch_response_revert_separator_2 = Table(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name="test__reserved__colon__table__reserved__arrow__",
 | 
						|
            databaseSchema=EntityReference(id=uuid.uuid4(), type="databaseSchema"),
 | 
						|
            fullyQualifiedName="test-service-table.test-db.test-schema.test",
 | 
						|
            columns=[Column(name="id", dataType=DataType.BIGINT)],
 | 
						|
        )
 | 
						|
 | 
						|
        fetch_response_revert_separator_3 = DashboardDataModel(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name="test__reserved__quote__dashboarddatamodel__reserved__quote__",
 | 
						|
            fullyQualifiedName="test-service-table.test-db.test-schema.test__reserved__quote__dashboarddatamodel__reserved__quote__",
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name="struct",
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(name='test "struct_children"', dataType=DataType.BIGINT)
 | 
						|
                    ],
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
        assert fetch_response_revert_separator_3.name.root == 'test"dashboarddatamodel"'
 | 
						|
        assert (
 | 
						|
            fetch_response_revert_separator_3.columns[0].children[0].name.root
 | 
						|
            == 'test "struct_children"'
 | 
						|
        )
 | 
						|
        assert fetch_response_revert_separator.name.root == "test::table"
 | 
						|
        assert fetch_response_revert_separator_2.name.root == "test::table>"
 | 
						|
 | 
						|
 | 
						|
class NestedModel(BaseModel):
 | 
						|
    secret: CustomSecretStr
 | 
						|
    value: int
 | 
						|
 | 
						|
 | 
						|
class RootModel(BaseModel):
 | 
						|
    root_secret: CustomSecretStr
 | 
						|
    nested: NestedModel
 | 
						|
    items: List[NestedModel]
 | 
						|
 | 
						|
 | 
						|
data = {
 | 
						|
    "root_secret": "root_password",
 | 
						|
    "nested": {"secret": "nested_password", "value": 42},
 | 
						|
    "items": [
 | 
						|
        {"secret": "item1_password", "value": 1},
 | 
						|
        {"secret": "item2_password", "value": 2},
 | 
						|
    ],
 | 
						|
}
 | 
						|
 | 
						|
model = RootModel(**data)
 | 
						|
masked_data = model.model_dump(mask_secrets=True)
 | 
						|
 | 
						|
 | 
						|
def test_model_dump_secrets():
 | 
						|
    """Test model_dump_masked with root, nested, and list structures."""
 | 
						|
 | 
						|
    assert masked_data["root_secret"] == "**********"
 | 
						|
    assert masked_data["nested"]["secret"] == "**********"
 | 
						|
    assert masked_data["nested"]["value"] == 42
 | 
						|
    assert masked_data["items"][0]["secret"] == "**********"
 | 
						|
    assert masked_data["items"][0]["value"] == 1
 | 
						|
    assert masked_data["items"][1]["secret"] == "**********"
 | 
						|
    assert masked_data["items"][1]["value"] == 2
 | 
						|
 | 
						|
    plain_data = model.model_dump(mask_secrets=False)
 | 
						|
    assert plain_data["root_secret"] == "root_password"
 | 
						|
    assert plain_data["nested"]["secret"] == "nested_password"
 | 
						|
    assert plain_data["items"][0]["secret"] == "item1_password"
 | 
						|
 | 
						|
    default_dump = model.model_dump()
 | 
						|
    assert default_dump["root_secret"] == "root_password"
 | 
						|
    assert default_dump["nested"]["secret"] == "nested_password"
 | 
						|
    assert default_dump["items"][0]["secret"] == "item1_password"
 | 
						|
 | 
						|
 | 
						|
def test_model_dump_json_secrets():
 | 
						|
    assert (
 | 
						|
        model.model_validate_json(
 | 
						|
            model.model_dump_json()
 | 
						|
        ).root_secret.get_secret_value()
 | 
						|
        == "**********"
 | 
						|
    )
 | 
						|
    assert (
 | 
						|
        model.model_validate_json(
 | 
						|
            model.model_dump_json(mask_secrets=True)
 | 
						|
        ).root_secret.get_secret_value()
 | 
						|
        == "**********"
 | 
						|
    )
 | 
						|
    assert (
 | 
						|
        model.model_validate_json(
 | 
						|
            model.model_dump_json(mask_secrets=False)
 | 
						|
        ).root_secret.get_secret_value()
 | 
						|
        == "root_password"
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
# Additional comprehensive tests for enhanced functionality
 | 
						|
class ExtendedCustomPydanticValidationTest(TestCase):
 | 
						|
    """Extended test suite for comprehensive validation of custom Pydantic functionality."""
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        """Set up test data for extended tests."""
 | 
						|
        self.sample_table_id = uuid.uuid4()
 | 
						|
        self.sample_schema_ref = EntityReference(id=uuid.uuid4(), type="databaseSchema")
 | 
						|
 | 
						|
    def test_service_level_models_not_transformed(self):
 | 
						|
        """Test that service-level Create models are not transformed."""
 | 
						|
        # Test database service creation (should NOT be transformed)
 | 
						|
        service_request = CreateDatabaseServiceRequest(
 | 
						|
            name=EntityName('my::database>service"with_separators'), serviceType="Mysql"
 | 
						|
        )
 | 
						|
 | 
						|
        # Service names should remain unchanged (not transformed)
 | 
						|
        assert service_request.name.root == 'my::database>service"with_separators'
 | 
						|
 | 
						|
    def test_edge_cases_empty_and_none_values(self):
 | 
						|
        """Test handling of edge cases like empty strings and None values."""
 | 
						|
        # Test minimal name (empty string not allowed by EntityName validation)
 | 
						|
        table_empty = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name=EntityName("a"),
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="test.empty",
 | 
						|
            columns=[Column(name="id", dataType=DataType.BIGINT)],
 | 
						|
        )
 | 
						|
        assert table_empty.name.root == "a"
 | 
						|
 | 
						|
        # Test table with no columns (edge case)
 | 
						|
        table_no_columns = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="test__reserved__colon__table",
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="test.empty",
 | 
						|
            columns=[],
 | 
						|
        )
 | 
						|
        assert table_no_columns.name.root == "test::table"
 | 
						|
        assert len(table_no_columns.columns) == 0
 | 
						|
 | 
						|
    def test_complex_nested_structures(self):
 | 
						|
        """Test complex nested column structures with multiple levels."""
 | 
						|
        # Create deeply nested structure
 | 
						|
        level3_columns = [
 | 
						|
            Column(
 | 
						|
                name=ColumnName("deep__reserved__colon__field"),
 | 
						|
                dataType=DataType.STRING,
 | 
						|
            )
 | 
						|
        ]
 | 
						|
 | 
						|
        level2_columns = [
 | 
						|
            Column(
 | 
						|
                name=ColumnName("nested__reserved__arrow__struct"),
 | 
						|
                dataType=DataType.STRUCT,
 | 
						|
                children=level3_columns,
 | 
						|
            )
 | 
						|
        ]
 | 
						|
 | 
						|
        level1_column = Column(
 | 
						|
            name=ColumnName("root__reserved__quote__struct"),
 | 
						|
            dataType=DataType.STRUCT,
 | 
						|
            children=level2_columns,
 | 
						|
        )
 | 
						|
 | 
						|
        table = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="complex__reserved__colon__table",
 | 
						|
            columns=[level1_column],
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="test.complex",
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify transformations at all levels
 | 
						|
        assert table.name.root == "complex::table"
 | 
						|
        assert table.columns[0].name.root == 'root"struct'
 | 
						|
        assert table.columns[0].children[0].name.root == "nested>struct"
 | 
						|
        assert table.columns[0].children[0].children[0].name.root == "deep::field"
 | 
						|
 | 
						|
    def test_unicode_and_special_characters(self):
 | 
						|
        """Test handling of Unicode and international characters."""
 | 
						|
        # Test Unicode with separators
 | 
						|
        table_unicode = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="測試__reserved__colon__表格__reserved__arrow__名稱",
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="test.unicode",
 | 
						|
            columns=[
 | 
						|
                Column(name="unicode__reserved__quote__列", dataType=DataType.STRING)
 | 
						|
            ],
 | 
						|
        )
 | 
						|
        assert table_unicode.name.root == "測試::表格>名稱"
 | 
						|
        assert table_unicode.columns[0].name.root == 'unicode"列'
 | 
						|
 | 
						|
        # Test emojis with separators
 | 
						|
        table_emoji = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="table🚀__reserved__colon__data📊",
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="test.emoji",
 | 
						|
            columns=[
 | 
						|
                Column(name="emoji__reserved__arrow__field🎯", dataType=DataType.STRING)
 | 
						|
            ],
 | 
						|
        )
 | 
						|
        assert table_emoji.name.root == "table🚀::data📊"
 | 
						|
        assert table_emoji.columns[0].name.root == "emoji>field🎯"
 | 
						|
 | 
						|
    def test_all_separator_combinations(self):
 | 
						|
        """Test all combinations of separators in various scenarios."""
 | 
						|
        # Test all separators together
 | 
						|
        complex_name = 'test::colon>arrow"quote__reserved__mixed'
 | 
						|
        create_request = CreateTableRequest(
 | 
						|
            name=EntityName(complex_name),
 | 
						|
            columns=[Column(name=ColumnName("simple_col"), dataType=DataType.STRING)],
 | 
						|
            databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
        )
 | 
						|
 | 
						|
        expected = "test__reserved__colon__colon__reserved__arrow__arrow__reserved__quote__quote__reserved__mixed"
 | 
						|
        assert create_request.name.root == expected
 | 
						|
 | 
						|
    def test_table_types_and_properties(self):
 | 
						|
        """Test different table types and properties with name transformations."""
 | 
						|
        # Test with comprehensive table properties
 | 
						|
        table_full = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="full__reserved__colon__table__reserved__arrow__test",
 | 
						|
            displayName="Full Test Table",
 | 
						|
            description=Markdown(root="A comprehensive test table"),
 | 
						|
            tableType=TableType.Regular,
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="test.db.schema.full_table",
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("id__reserved__quote__primary"),
 | 
						|
                    displayName="ID Primary",
 | 
						|
                    dataType=DataType.BIGINT,
 | 
						|
                    description=Markdown(root="Primary key column"),
 | 
						|
                ),
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("data__reserved__arrow__field"),
 | 
						|
                    displayName="Data Field",
 | 
						|
                    dataType=DataType.STRING,
 | 
						|
                    description=Markdown(root="Data field column"),
 | 
						|
                ),
 | 
						|
            ],
 | 
						|
            tableConstraints=[
 | 
						|
                TableConstraint(
 | 
						|
                    constraintType="PRIMARY_KEY",
 | 
						|
                    columns=["id__reserved__quote__primary"],
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify all transformations
 | 
						|
        assert table_full.name.root == "full::table>test"
 | 
						|
        assert table_full.columns[0].name.root == 'id"primary'
 | 
						|
        assert table_full.columns[1].name.root == "data>field"
 | 
						|
        assert table_full.tableConstraints[0].columns[0] == 'id"primary'
 | 
						|
 | 
						|
    def test_dashboard_data_model_comprehensive(self):
 | 
						|
        """Test comprehensive DashboardDataModel scenarios."""
 | 
						|
        # Test with all data model types
 | 
						|
        data_model_types = [
 | 
						|
            DataModelType.TableauDataModel,
 | 
						|
            DataModelType.PowerBIDataModel,
 | 
						|
            DataModelType.SupersetDataModel,
 | 
						|
            DataModelType.MetabaseDataModel,
 | 
						|
        ]
 | 
						|
 | 
						|
        for model_type in data_model_types:
 | 
						|
            dashboard_model = DashboardDataModel(
 | 
						|
                id=uuid.uuid4(),
 | 
						|
                name=f"model__reserved__colon__{model_type.value.lower()}",
 | 
						|
                dataModelType=model_type,
 | 
						|
                columns=[
 | 
						|
                    Column(
 | 
						|
                        name=ColumnName(
 | 
						|
                            f"metric__reserved__arrow__{model_type.value.lower()}"
 | 
						|
                        ),
 | 
						|
                        dataType=DataType.DOUBLE,
 | 
						|
                    )
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
            expected_name = f"model::{model_type.value.lower()}"
 | 
						|
            expected_col = f"metric>{model_type.value.lower()}"
 | 
						|
 | 
						|
            assert dashboard_model.name.root == expected_name
 | 
						|
            assert dashboard_model.columns[0].name.root == expected_col
 | 
						|
 | 
						|
    def test_create_requests_comprehensive(self):
 | 
						|
        """Test comprehensive CreateRequest scenarios."""
 | 
						|
        # Test CreateTableRequest with all possible fields
 | 
						|
        comprehensive_request = CreateTableRequest(
 | 
						|
            name=EntityName('comprehensive::table>name"test'),
 | 
						|
            displayName='Comprehensive"Table>Test::Name',
 | 
						|
            description=Markdown(root="A comprehensive test table with all fields"),
 | 
						|
            tableType=TableType.Regular,
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("primary__reserved__quote__key"),
 | 
						|
                    displayName="Primary Key",
 | 
						|
                    dataType=DataType.BIGINT,
 | 
						|
                    constraint="NOT_NULL",
 | 
						|
                    ordinalPosition=1,
 | 
						|
                ),
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("foreign__reserved__arrow__key"),
 | 
						|
                    displayName="Foreign Key",
 | 
						|
                    dataType=DataType.BIGINT,
 | 
						|
                    constraint="NOT_NULL",
 | 
						|
                    ordinalPosition=2,
 | 
						|
                ),
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("nested__reserved__colon__struct"),
 | 
						|
                    displayName="Nested Struct",
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName("child__reserved__quote__field"),
 | 
						|
                            dataType=DataType.STRING,
 | 
						|
                        )
 | 
						|
                    ],
 | 
						|
                ),
 | 
						|
            ],
 | 
						|
            tableConstraints=[
 | 
						|
                TableConstraint(
 | 
						|
                    constraintType="PRIMARY_KEY",
 | 
						|
                    columns=["primary__reserved__quote__key"],
 | 
						|
                ),
 | 
						|
                TableConstraint(
 | 
						|
                    constraintType="UNIQUE", columns=["foreign__reserved__arrow__key"]
 | 
						|
                ),
 | 
						|
            ],
 | 
						|
            databaseSchema=FullyQualifiedEntityName("test__reserved__colon__db.schema"),
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify transformations
 | 
						|
        assert (
 | 
						|
            comprehensive_request.name.root
 | 
						|
            == "comprehensive__reserved__colon__table__reserved__arrow__name__reserved__quote__test"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            comprehensive_request.columns[0].name.root
 | 
						|
            == "primary__reserved__quote__key"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            comprehensive_request.columns[1].name.root
 | 
						|
            == "foreign__reserved__arrow__key"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            comprehensive_request.columns[2].name.root
 | 
						|
            == "nested__reserved__colon__struct"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            comprehensive_request.columns[2].children[0].name.root
 | 
						|
            == "child__reserved__quote__field"
 | 
						|
        )
 | 
						|
 | 
						|
    def test_mixed_separator_edge_cases(self):
 | 
						|
        """Test edge cases with mixed separators."""
 | 
						|
        edge_cases = [
 | 
						|
            # Consecutive separators
 | 
						|
            (
 | 
						|
                'test::>>""name',
 | 
						|
                "test__reserved__colon____reserved__arrow____reserved__arrow____reserved__quote____reserved__quote__name",
 | 
						|
            ),
 | 
						|
            # Separators at start and end
 | 
						|
            (
 | 
						|
                '::test>name"',
 | 
						|
                "__reserved__colon__test__reserved__arrow__name__reserved__quote__",
 | 
						|
            ),
 | 
						|
            # Only separators
 | 
						|
            ('::>"', "__reserved__colon____reserved__arrow____reserved__quote__"),
 | 
						|
            # Empty between separators
 | 
						|
            (
 | 
						|
                'test::>"name',
 | 
						|
                "test__reserved__colon____reserved__arrow____reserved__quote__name",
 | 
						|
            ),
 | 
						|
        ]
 | 
						|
 | 
						|
        for input_name, expected in edge_cases:
 | 
						|
            create_request = CreateTableRequest(
 | 
						|
                name=EntityName(input_name),
 | 
						|
                columns=[Column(name=ColumnName("col"), dataType=DataType.STRING)],
 | 
						|
                databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
            )
 | 
						|
            assert (
 | 
						|
                create_request.name.root == expected
 | 
						|
            ), f"Failed for input: {input_name}"
 | 
						|
 | 
						|
    def test_very_long_names_performance(self):
 | 
						|
        """Test performance with very long names."""
 | 
						|
        # Create very long names to test performance
 | 
						|
        long_base_name = "very_long_table_name_" * 3
 | 
						|
        long_name_with_separators = (
 | 
						|
            f'{long_base_name}::separator>{long_base_name}"quote{long_base_name}'
 | 
						|
        )
 | 
						|
 | 
						|
        create_request = CreateTableRequest(
 | 
						|
            name=EntityName(long_name_with_separators),
 | 
						|
            columns=[Column(name=ColumnName("col"), dataType=DataType.STRING)],
 | 
						|
            databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
        )
 | 
						|
 | 
						|
        # Should handle long names without issues
 | 
						|
        result_name = create_request.name.root
 | 
						|
        assert "__reserved__colon__" in result_name
 | 
						|
        assert "__reserved__arrow__" in result_name
 | 
						|
        assert "__reserved__quote__" in result_name
 | 
						|
 | 
						|
    def test_happy_path_simple_names(self):
 | 
						|
        """Test happy path with simple names that don't need transformation."""
 | 
						|
        # Test simple names without special characters
 | 
						|
        simple_create = CreateTableRequest(
 | 
						|
            name=EntityName("simple_table_name"),
 | 
						|
            columns=[
 | 
						|
                Column(name=ColumnName("simple_column"), dataType=DataType.STRING)
 | 
						|
            ],
 | 
						|
            databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
        )
 | 
						|
 | 
						|
        # Names should remain unchanged
 | 
						|
        assert simple_create.name.root == "simple_table_name"
 | 
						|
        assert simple_create.columns[0].name.root == "simple_column"
 | 
						|
 | 
						|
        # Test simple fetch model
 | 
						|
        simple_table = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="simple_table",
 | 
						|
            databaseSchema=self.sample_schema_ref,
 | 
						|
            fullyQualifiedName="db.schema.simple_table",
 | 
						|
            columns=[Column(name="simple_col", dataType=DataType.STRING)],
 | 
						|
        )
 | 
						|
 | 
						|
        assert simple_table.name.root == "simple_table"
 | 
						|
        assert simple_table.columns[0].name.root == "simple_col"
 | 
						|
 | 
						|
    def test_error_handling_invalid_models(self):
 | 
						|
        """Test error handling with None and invalid models."""
 | 
						|
        # Test with None entity
 | 
						|
        result = None
 | 
						|
        # This would normally be called by the validation system
 | 
						|
        # Just ensure no exceptions are thrown
 | 
						|
 | 
						|
        # Test with mock invalid object
 | 
						|
        class InvalidModel:
 | 
						|
            def __init__(self):
 | 
						|
                self.invalid_attr = "test"
 | 
						|
 | 
						|
        invalid_obj = InvalidModel()
 | 
						|
        # Should handle gracefully without transformation
 | 
						|
        assert hasattr(invalid_obj, "invalid_attr")
 | 
						|
 | 
						|
    def test_boundary_conditions(self):
 | 
						|
        """Test boundary conditions and edge cases."""
 | 
						|
        # Test single character names
 | 
						|
        single_char_create = CreateTableRequest(
 | 
						|
            name=EntityName("a"),
 | 
						|
            columns=[Column(name=ColumnName("b"), dataType=DataType.STRING)],
 | 
						|
            databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
        )
 | 
						|
        assert single_char_create.name.root == "a"
 | 
						|
 | 
						|
        # Test names with only separators
 | 
						|
        separator_only = CreateTableRequest(
 | 
						|
            name=EntityName("::"),
 | 
						|
            columns=[Column(name=ColumnName(">"), dataType=DataType.STRING)],
 | 
						|
            databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
        )
 | 
						|
        assert separator_only.name.root == "__reserved__colon__"
 | 
						|
        assert separator_only.columns[0].name.root == "__reserved__arrow__"
 | 
						|
 | 
						|
    def test_whitespace_handling(self):
 | 
						|
        """Test handling of whitespace in various scenarios."""
 | 
						|
        whitespace_cases = [
 | 
						|
            # Leading/trailing spaces
 | 
						|
            ("  test::name  ", "  test__reserved__colon__name  "),
 | 
						|
            # Spaces around separators
 | 
						|
            (" test :: name ", " test __reserved__colon__ name "),
 | 
						|
            # Multiple spaces
 | 
						|
            ("test  ::  name", "test  __reserved__colon__  name"),
 | 
						|
            # Tabs and newlines (should be preserved)
 | 
						|
            ("test\t::\nname", "test\t__reserved__colon__\nname"),
 | 
						|
        ]
 | 
						|
 | 
						|
        for input_name, expected in whitespace_cases:
 | 
						|
            create_request = CreateTableRequest(
 | 
						|
                name=EntityName(input_name),
 | 
						|
                columns=[Column(name=ColumnName("col"), dataType=DataType.STRING)],
 | 
						|
                databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
            )
 | 
						|
            assert (
 | 
						|
                create_request.name.root == expected
 | 
						|
            ), f"Failed for input: '{input_name}'"
 | 
						|
 | 
						|
    def test_table_constraints_comprehensive(self):
 | 
						|
        """Test comprehensive table constraints scenarios."""
 | 
						|
        constraint_types = ["PRIMARY_KEY", "UNIQUE", "FOREIGN_KEY"]
 | 
						|
        constraints = []
 | 
						|
        columns = []
 | 
						|
 | 
						|
        for i, constraint_type in enumerate(constraint_types):
 | 
						|
            col_name = f"col_{i}__reserved__colon__constraint"
 | 
						|
            columns.append(Column(name=ColumnName(col_name), dataType=DataType.STRING))
 | 
						|
            constraints.append(
 | 
						|
                TableConstraint(constraintType=constraint_type, columns=[col_name])
 | 
						|
            )
 | 
						|
 | 
						|
        create_request = CreateTableRequest(
 | 
						|
            name=EntityName("constraints__reserved__arrow__test"),
 | 
						|
            columns=columns,
 | 
						|
            tableConstraints=constraints,
 | 
						|
            databaseSchema=FullyQualifiedEntityName("db.schema"),
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify all constraints have transformed column names
 | 
						|
        for i, constraint in enumerate(create_request.tableConstraints):
 | 
						|
            expected_col = f"col_{i}__reserved__colon__constraint"
 | 
						|
            assert constraint.columns[0] == expected_col
 | 
						|
 | 
						|
    def test_entity_references_and_relationships(self):
 | 
						|
        """Test entity references and relationship handling."""
 | 
						|
        # Test with complex entity references
 | 
						|
        table_with_refs = Table(
 | 
						|
            id=self.sample_table_id,
 | 
						|
            name="table__reserved__colon__with__reserved__arrow__refs",
 | 
						|
            databaseSchema=EntityReference(
 | 
						|
                id=uuid.uuid4(),
 | 
						|
                type="databaseSchema",
 | 
						|
                name="schema__reserved__quote__name",
 | 
						|
            ),
 | 
						|
            fullyQualifiedName="service.db.schema__reserved__quote__name.table",
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("ref__reserved__colon__column"),
 | 
						|
                    dataType=DataType.STRING,
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify transformations
 | 
						|
        assert table_with_refs.name.root == "table::with>refs"
 | 
						|
        assert table_with_refs.columns[0].name.root == "ref::column"
 | 
						|
        # Entity references should not be transformed (they're separate entities)
 | 
						|
        assert table_with_refs.databaseSchema.name == "schema__reserved__quote__name"
 | 
						|
 | 
						|
 | 
						|
class CustomSecretStrExtendedTest(TestCase):
 | 
						|
    """Extended test suite for CustomSecretStr functionality."""
 | 
						|
 | 
						|
    def test_secret_creation_and_access(self):
 | 
						|
        """Test CustomSecretStr creation and value access."""
 | 
						|
        secret = CustomSecretStr("test_password")
 | 
						|
        assert secret.get_secret_value() == "test_password"
 | 
						|
        assert str(secret) == "**********"
 | 
						|
        assert repr(secret) == "SecretStr('**********')"
 | 
						|
 | 
						|
    def test_empty_and_none_secrets(self):
 | 
						|
        """Test handling of empty and None secret values."""
 | 
						|
        # Test empty secret
 | 
						|
        empty_secret = CustomSecretStr("")
 | 
						|
        assert empty_secret.get_secret_value() == ""
 | 
						|
        assert str(empty_secret) == ""
 | 
						|
 | 
						|
        # Test None secret handling
 | 
						|
        try:
 | 
						|
            none_secret = CustomSecretStr(None)
 | 
						|
            assert none_secret.get_secret_value() is None
 | 
						|
        except (TypeError, ValueError, AttributeError):
 | 
						|
            # This is acceptable behavior for None values
 | 
						|
            pass
 | 
						|
 | 
						|
    def test_long_secrets(self):
 | 
						|
        """Test handling of very long secret values."""
 | 
						|
        long_secret_value = "a" * 1000
 | 
						|
        long_secret = CustomSecretStr(long_secret_value)
 | 
						|
        assert long_secret.get_secret_value() == long_secret_value
 | 
						|
        assert (
 | 
						|
            str(long_secret) == "**********"
 | 
						|
        )  # Should still mask regardless of length
 | 
						|
 | 
						|
    def test_special_character_secrets(self):
 | 
						|
        """Test secrets with special characters."""
 | 
						|
        special_chars = "!@#$%^&*()_+-=[]{}|;':,.<>?/~`"
 | 
						|
        special_secret = CustomSecretStr(special_chars)
 | 
						|
        assert special_secret.get_secret_value() == special_chars
 | 
						|
        assert str(special_secret) == "**********"
 | 
						|
 | 
						|
    def test_unicode_secrets(self):
 | 
						|
        """Test secrets with Unicode characters."""
 | 
						|
        unicode_secret = CustomSecretStr("密码测试🔒")
 | 
						|
        assert unicode_secret.get_secret_value() == "密码测试🔒"
 | 
						|
        assert str(unicode_secret) == "**********"
 | 
						|
 | 
						|
    def test_secret_equality_and_hashing(self):
 | 
						|
        """Test secret equality and hashing behavior."""
 | 
						|
        secret1 = CustomSecretStr("password123")
 | 
						|
        secret2 = CustomSecretStr("password123")
 | 
						|
        secret3 = CustomSecretStr("different_password")
 | 
						|
 | 
						|
        # Test equality
 | 
						|
        assert secret1.get_secret_value() == secret2.get_secret_value()
 | 
						|
        assert secret1.get_secret_value() != secret3.get_secret_value()
 | 
						|
 | 
						|
        # Test that string representation is always masked
 | 
						|
        assert str(secret1) == str(secret2) == str(secret3) == "**********"
 | 
						|
 | 
						|
    def test_secret_in_nested_models_deep(self):
 | 
						|
        """Test secrets in deeply nested model structures."""
 | 
						|
 | 
						|
        class Level3Model(BaseModel):
 | 
						|
            deep_secret: CustomSecretStr
 | 
						|
            deep_value: str
 | 
						|
 | 
						|
        class Level2Model(BaseModel):
 | 
						|
            mid_secret: CustomSecretStr
 | 
						|
            level3: Level3Model
 | 
						|
 | 
						|
        class Level1Model(BaseModel):
 | 
						|
            top_secret: CustomSecretStr
 | 
						|
            level2: Level2Model
 | 
						|
 | 
						|
        deep_data = {
 | 
						|
            "top_secret": "top_password",
 | 
						|
            "level2": {
 | 
						|
                "mid_secret": "mid_password",
 | 
						|
                "level3": {"deep_secret": "deep_password", "deep_value": "not_secret"},
 | 
						|
            },
 | 
						|
        }
 | 
						|
 | 
						|
        deep_model = Level1Model(**deep_data)
 | 
						|
 | 
						|
        # Test masked dump
 | 
						|
        masked = deep_model.model_dump(mask_secrets=True)
 | 
						|
        assert masked["top_secret"] == "**********"
 | 
						|
        assert masked["level2"]["mid_secret"] == "**********"
 | 
						|
        assert masked["level2"]["level3"]["deep_secret"] == "**********"
 | 
						|
        assert masked["level2"]["level3"]["deep_value"] == "not_secret"
 | 
						|
 | 
						|
        # Test unmasked dump
 | 
						|
        unmasked = deep_model.model_dump(mask_secrets=False)
 | 
						|
        assert unmasked["top_secret"] == "top_password"
 | 
						|
        assert unmasked["level2"]["mid_secret"] == "mid_password"
 | 
						|
        assert unmasked["level2"]["level3"]["deep_secret"] == "deep_password"
 | 
						|
 | 
						|
    def test_secret_with_optional_fields(self):
 | 
						|
        """Test secrets with optional fields."""
 | 
						|
 | 
						|
        class OptionalSecretModel(BaseModel):
 | 
						|
            required_secret: CustomSecretStr
 | 
						|
            optional_secret: Optional[CustomSecretStr] = None
 | 
						|
            optional_value: Optional[str] = None
 | 
						|
 | 
						|
        # Test with all fields
 | 
						|
        full_model = OptionalSecretModel(
 | 
						|
            required_secret="required_pass",
 | 
						|
            optional_secret="optional_pass",
 | 
						|
            optional_value="some_value",
 | 
						|
        )
 | 
						|
 | 
						|
        masked_full = full_model.model_dump(mask_secrets=True)
 | 
						|
        assert masked_full["required_secret"] == "**********"
 | 
						|
        assert masked_full["optional_secret"] == "**********"
 | 
						|
        assert masked_full["optional_value"] == "some_value"
 | 
						|
 | 
						|
        # Test with only required fields
 | 
						|
        minimal_model = OptionalSecretModel(required_secret="required_pass")
 | 
						|
 | 
						|
        masked_minimal = minimal_model.model_dump(mask_secrets=True)
 | 
						|
        assert masked_minimal["required_secret"] == "**********"
 | 
						|
        assert masked_minimal["optional_secret"] is None
 | 
						|
        assert masked_minimal["optional_value"] is None
 | 
						|
 | 
						|
    def test_secret_lists_and_dictionaries(self):
 | 
						|
        """Test secrets in lists and dictionaries."""
 | 
						|
 | 
						|
        class ComplexSecretModel(BaseModel):
 | 
						|
            secret_list: List[CustomSecretStr]
 | 
						|
            nested_secrets: List[dict]
 | 
						|
 | 
						|
        complex_data = {
 | 
						|
            "secret_list": ["password1", "password2", "password3"],
 | 
						|
            "nested_secrets": [
 | 
						|
                {"name": "config1", "secret": CustomSecretStr("secret1")},
 | 
						|
                {"name": "config2", "secret": CustomSecretStr("secret2")},
 | 
						|
            ],
 | 
						|
        }
 | 
						|
 | 
						|
        complex_model = ComplexSecretModel(**complex_data)
 | 
						|
 | 
						|
        # Test that list secrets are handled
 | 
						|
        assert len(complex_model.secret_list) == 3
 | 
						|
        assert all(str(secret) == "**********" for secret in complex_model.secret_list)
 | 
						|
        assert all(
 | 
						|
            secret.get_secret_value() in ["password1", "password2", "password3"]
 | 
						|
            for secret in complex_model.secret_list
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class DashboardDataModelTransformationTest(TestCase):
 | 
						|
    """Test DashboardDataModel transformations with nested children and reserved keywords."""
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        """Set up test data."""
 | 
						|
        self.sample_service = FullyQualifiedEntityName(
 | 
						|
            root='TestService.PowerBI."Analysis>Services::Environment"'
 | 
						|
        )
 | 
						|
 | 
						|
    def test_create_dashboard_datamodel_with_nested_children(self):
 | 
						|
        """Test CreateDashboardDataModelRequest with nested children containing reserved keywords."""
 | 
						|
        create_request = CreateDashboardDataModelRequest(
 | 
						|
            name=EntityName('financial::report>model"quarterly'),
 | 
						|
            displayName="Financial Report Model",
 | 
						|
            description=Markdown(
 | 
						|
                root="Financial reporting model with special characters"
 | 
						|
            ),
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            service=self.sample_service,
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("revenue::metrics>summary"),
 | 
						|
                    displayName="Revenue Metrics",
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    description=Markdown(root="Revenue metrics structure"),
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName("total::revenue>amount"),
 | 
						|
                            displayName="Total Revenue",
 | 
						|
                            dataType=DataType.DECIMAL,
 | 
						|
                            description=Markdown(root="Total revenue amount"),
 | 
						|
                        ),
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName('currency::code>"USD"'),
 | 
						|
                            displayName="Currency Code",
 | 
						|
                            dataType=DataType.STRING,
 | 
						|
                            description=Markdown(root="Currency code with quotes"),
 | 
						|
                        ),
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName("nested::struct>data"),
 | 
						|
                            displayName="Nested Structure",
 | 
						|
                            dataType=DataType.STRUCT,
 | 
						|
                            children=[
 | 
						|
                                Column(
 | 
						|
                                    name=ColumnName('deep::field>"value"'),
 | 
						|
                                    displayName="Deep Field",
 | 
						|
                                    dataType=DataType.STRING,
 | 
						|
                                )
 | 
						|
                            ],
 | 
						|
                        ),
 | 
						|
                    ],
 | 
						|
                ),
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("expenses::breakdown>categories"),
 | 
						|
                    displayName="Expense Breakdown",
 | 
						|
                    dataType=DataType.ARRAY,
 | 
						|
                    arrayDataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName('category::name>"operations"'),
 | 
						|
                            displayName="Category Name",
 | 
						|
                            dataType=DataType.STRING,
 | 
						|
                        ),
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName("amount::value>total"),
 | 
						|
                            displayName="Amount Value",
 | 
						|
                            dataType=DataType.DECIMAL,
 | 
						|
                        ),
 | 
						|
                    ],
 | 
						|
                ),
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify main entity name transformation (ENCODE for Create operations)
 | 
						|
        assert (
 | 
						|
            create_request.name.root
 | 
						|
            == "financial__reserved__colon__report__reserved__arrow__model__reserved__quote__quarterly"
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify top-level column name transformations
 | 
						|
        assert (
 | 
						|
            create_request.columns[0].name.root
 | 
						|
            == "revenue__reserved__colon__metrics__reserved__arrow__summary"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            create_request.columns[1].name.root
 | 
						|
            == "expenses__reserved__colon__breakdown__reserved__arrow__categories"
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify nested children transformations (first level)
 | 
						|
        revenue_column = create_request.columns[0]
 | 
						|
        assert (
 | 
						|
            revenue_column.children[0].name.root
 | 
						|
            == "total__reserved__colon__revenue__reserved__arrow__amount"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            revenue_column.children[1].name.root
 | 
						|
            == "currency__reserved__colon__code__reserved__arrow____reserved__quote__USD__reserved__quote__"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            revenue_column.children[2].name.root
 | 
						|
            == "nested__reserved__colon__struct__reserved__arrow__data"
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify deeply nested children transformations (second level)
 | 
						|
        nested_struct = revenue_column.children[2]
 | 
						|
        assert (
 | 
						|
            nested_struct.children[0].name.root
 | 
						|
            == "deep__reserved__colon__field__reserved__arrow____reserved__quote__value__reserved__quote__"
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify array children transformations
 | 
						|
        expenses_column = create_request.columns[1]
 | 
						|
        assert (
 | 
						|
            expenses_column.children[0].name.root
 | 
						|
            == "category__reserved__colon__name__reserved__arrow____reserved__quote__operations__reserved__quote__"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            expenses_column.children[1].name.root
 | 
						|
            == "amount__reserved__colon__value__reserved__arrow__total"
 | 
						|
        )
 | 
						|
 | 
						|
    def test_fetch_dashboard_datamodel_with_nested_children(self):
 | 
						|
        """Test DashboardDataModel fetch with nested children containing encoded reserved keywords."""
 | 
						|
        dashboard_model = DashboardDataModel(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name="financial__reserved__colon__report__reserved__arrow__model__reserved__quote__quarterly",
 | 
						|
            displayName="Financial Report Model",
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            service=EntityReference(id=uuid.uuid4(), type="dashboardService"),
 | 
						|
            fullyQualifiedName="service.financial__reserved__colon__report__reserved__arrow__model__reserved__quote__quarterly",
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName(
 | 
						|
                        "revenue__reserved__colon__metrics__reserved__arrow__summary"
 | 
						|
                    ),
 | 
						|
                    displayName="Revenue Metrics",
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName(
 | 
						|
                                "total__reserved__colon__revenue__reserved__arrow__amount"
 | 
						|
                            ),
 | 
						|
                            displayName="Total Revenue",
 | 
						|
                            dataType=DataType.DECIMAL,
 | 
						|
                        ),
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName(
 | 
						|
                                "currency__reserved__colon__code__reserved__arrow____reserved__quote__USD__reserved__quote__"
 | 
						|
                            ),
 | 
						|
                            displayName="Currency Code",
 | 
						|
                            dataType=DataType.STRING,
 | 
						|
                        ),
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName(
 | 
						|
                                "nested__reserved__colon__struct__reserved__arrow__data"
 | 
						|
                            ),
 | 
						|
                            displayName="Nested Structure",
 | 
						|
                            dataType=DataType.STRUCT,
 | 
						|
                            children=[
 | 
						|
                                Column(
 | 
						|
                                    name=ColumnName(
 | 
						|
                                        "deep__reserved__colon__field__reserved__arrow____reserved__quote__value__reserved__quote__"
 | 
						|
                                    ),
 | 
						|
                                    displayName="Deep Field",
 | 
						|
                                    dataType=DataType.STRING,
 | 
						|
                                )
 | 
						|
                            ],
 | 
						|
                        ),
 | 
						|
                    ],
 | 
						|
                ),
 | 
						|
                Column(
 | 
						|
                    name=ColumnName(
 | 
						|
                        "expenses__reserved__colon__breakdown__reserved__arrow__categories"
 | 
						|
                    ),
 | 
						|
                    displayName="Expense Breakdown",
 | 
						|
                    dataType=DataType.ARRAY,
 | 
						|
                    arrayDataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName(
 | 
						|
                                "category__reserved__colon__name__reserved__arrow____reserved__quote__operations__reserved__quote__"
 | 
						|
                            ),
 | 
						|
                            displayName="Category Name",
 | 
						|
                            dataType=DataType.STRING,
 | 
						|
                        ),
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName(
 | 
						|
                                "amount__reserved__colon__value__reserved__arrow__total"
 | 
						|
                            ),
 | 
						|
                            displayName="Amount Value",
 | 
						|
                            dataType=DataType.DECIMAL,
 | 
						|
                        ),
 | 
						|
                    ],
 | 
						|
                ),
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify main entity name transformation (DECODE for fetch operations)
 | 
						|
        assert dashboard_model.name.root == 'financial::report>model"quarterly'
 | 
						|
 | 
						|
        # Verify top-level column name transformations
 | 
						|
        assert dashboard_model.columns[0].name.root == "revenue::metrics>summary"
 | 
						|
        assert dashboard_model.columns[1].name.root == "expenses::breakdown>categories"
 | 
						|
 | 
						|
        # Verify nested children transformations (first level)
 | 
						|
        revenue_column = dashboard_model.columns[0]
 | 
						|
        assert revenue_column.children[0].name.root == "total::revenue>amount"
 | 
						|
        assert revenue_column.children[1].name.root == 'currency::code>"USD"'
 | 
						|
        assert revenue_column.children[2].name.root == "nested::struct>data"
 | 
						|
 | 
						|
        # Verify deeply nested children transformations (second level)
 | 
						|
        nested_struct = revenue_column.children[2]
 | 
						|
        assert nested_struct.children[0].name.root == 'deep::field>"value"'
 | 
						|
 | 
						|
        # Verify array children transformations
 | 
						|
        expenses_column = dashboard_model.columns[1]
 | 
						|
        assert expenses_column.children[0].name.root == 'category::name>"operations"'
 | 
						|
        assert expenses_column.children[1].name.root == "amount::value>total"
 | 
						|
 | 
						|
    def test_dashboard_datamodel_round_trip_transformation(self):
 | 
						|
        """Test round-trip transformation: Create -> Fetch -> Create maintains data integrity."""
 | 
						|
        # Start with create request containing special characters
 | 
						|
        original_create = CreateDashboardDataModelRequest(
 | 
						|
            name=EntityName('analytics::dashboard>model"test'),
 | 
						|
            displayName="Analytics Dashboard Model",
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            service=self.sample_service,
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("metrics::summary>report"),
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName('total::count>"records"'),
 | 
						|
                            dataType=DataType.INT,
 | 
						|
                        )
 | 
						|
                    ],
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        # Simulate storage (encoded form)
 | 
						|
        stored_name = original_create.name.root  # Should be encoded
 | 
						|
        stored_column_name = original_create.columns[0].name.root  # Should be encoded
 | 
						|
        stored_nested_name = (
 | 
						|
            original_create.columns[0].children[0].name.root
 | 
						|
        )  # Should be encoded
 | 
						|
 | 
						|
        # Simulate fetch operation (create DashboardDataModel with stored values)
 | 
						|
        fetched_model = DashboardDataModel(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name=stored_name,
 | 
						|
            displayName="Analytics Dashboard Model",
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            service=EntityReference(id=uuid.uuid4(), type="dashboardService"),
 | 
						|
            fullyQualifiedName=f"service.{stored_name}",
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName(stored_column_name),
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    children=[
 | 
						|
                        Column(
 | 
						|
                            name=ColumnName(stored_nested_name), dataType=DataType.INT
 | 
						|
                        )
 | 
						|
                    ],
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify fetch operation decodes correctly
 | 
						|
        assert fetched_model.name.root == 'analytics::dashboard>model"test'
 | 
						|
        assert fetched_model.columns[0].name.root == "metrics::summary>report"
 | 
						|
        assert (
 | 
						|
            fetched_model.columns[0].children[0].name.root == 'total::count>"records"'
 | 
						|
        )
 | 
						|
 | 
						|
        # Verify create operation encodes correctly
 | 
						|
        assert (
 | 
						|
            stored_name
 | 
						|
            == "analytics__reserved__colon__dashboard__reserved__arrow__model__reserved__quote__test"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            stored_column_name
 | 
						|
            == "metrics__reserved__colon__summary__reserved__arrow__report"
 | 
						|
        )
 | 
						|
        assert (
 | 
						|
            stored_nested_name
 | 
						|
            == "total__reserved__colon__count__reserved__arrow____reserved__quote__records__reserved__quote__"
 | 
						|
        )
 | 
						|
 | 
						|
    def test_dashboard_datamodel_edge_cases(self):
 | 
						|
        """Test edge cases for DashboardDataModel transformations."""
 | 
						|
        # Test with empty children
 | 
						|
        model_empty_children = DashboardDataModel(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name="test__reserved__colon__model",
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            service=EntityReference(id=uuid.uuid4(), type="dashboardService"),
 | 
						|
            fullyQualifiedName="service.test__reserved__colon__model",
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("parent__reserved__arrow__column"),
 | 
						|
                    dataType=DataType.STRUCT,
 | 
						|
                    children=[],  # Empty children list
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        assert model_empty_children.name.root == "test::model"
 | 
						|
        assert model_empty_children.columns[0].name.root == "parent>column"
 | 
						|
 | 
						|
        # Test with None children
 | 
						|
        model_none_children = DashboardDataModel(
 | 
						|
            id=uuid.uuid4(),
 | 
						|
            name="test__reserved__quote__model",
 | 
						|
            dataModelType=DataModelType.PowerBIDataModel,
 | 
						|
            service=EntityReference(id=uuid.uuid4(), type="dashboardService"),
 | 
						|
            fullyQualifiedName="service.test__reserved__quote__model",
 | 
						|
            columns=[
 | 
						|
                Column(
 | 
						|
                    name=ColumnName("parent__reserved__quote__column"),
 | 
						|
                    dataType=DataType.STRING,
 | 
						|
                    children=None,  # None children
 | 
						|
                )
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
        assert model_none_children.name.root == 'test"model'
 | 
						|
        assert model_none_children.columns[0].name.root == 'parent"column'
 |