"""Test tenant-related schemas.""" from typing import Any, Dict, List, Optional from uuid import UUID, uuid4 import pytest from pdp.constants.constants import TenantType from pdp.fastapi.schemas.tenant import ( IdToUuidExchangeTenant, Tenant, TenantHierarchy, TenantWithMaybeHierarchy, TenantWithMaybeHierarchyResourceAttributes, UuidToIdExchangeTenant, ) TENANT_ACCOUNT_1 = Tenant( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=UUID("fff741c2-6def-4493-bfdf-c2bcb1128e02"), ) TENANT_ACCOUNT_2 = Tenant( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=UUID("f39efd58-82f5-4257-859a-36e29fa69cda"), ) TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1 = Tenant( tenant_type=TenantType.TENANT_TYPE_SUBACCOUNT, tenant_uuid=UUID("fff741c2-6def-4493-bfdf-c2bcb1128e02"), ) TENANT_SUBACCOUNT = Tenant( tenant_type=TenantType.TENANT_TYPE_SUBACCOUNT, tenant_uuid=UUID("2c03bd86-ba0d-42a6-bcaf-a273861412a8"), ) TENANT_COMPANY_BRAND = Tenant( tenant_type=TenantType.TENANT_TYPE_COMPANY_BRAND, tenant_uuid=UUID("fb22886e-5cfc-4092-991c-62acfa673c12"), ) TENANT_PARENT_COMPANY = Tenant( tenant_type=TenantType.TENANT_TYPE_PARENT_COMPANY, tenant_uuid=UUID("955a1bbd-b623-4ea1-ab5f-8d6620c442fb"), ) TENANT_LABEL_PARTICIPANT = Tenant( tenant_type=TenantType.TENANT_TYPE_LABEL_PARTICIPANT, tenant_uuid=UUID("780333d0-8ce0-45a7-a974-01aca9aa4bc8"), ) TENANT_MAYBE_HIERARCHY_ACCOUNT = TenantWithMaybeHierarchy( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=UUID("f8010ffc-94c1-4d22-9376-9f2f09a19798"), tenant_hierarchy=[UUID("fb22886e-5cfc-4092-991c-62acfa673c12")], ) TENANT_NO_HIERARCHY_LP = TenantWithMaybeHierarchy( tenant_type=TenantType.TENANT_TYPE_LABEL_PARTICIPANT, tenant_uuid=UUID("350029ac-a77d-404d-9f20-3487275a8567"), ) @pytest.mark.parametrize( "payload, expect_exception, expected", [ ({}, True, None), ( {}, True, None, ), ( { "tenant_type": "account", }, True, None, ), ( { "tenant_type": "account", "tenant_uuid": "123-456", }, True, None, ), ( { "tenant_type": "account", "tenant_uuid": "123-456", "version": "13", }, True, None, ), ( { "tenant_type": "account", "tenant_uuid": "123-456", "version": "13", }, True, None, ), ( { "tenant_type": "account", "tenant_uuid": " 89b79b52-de18-4644-bd2b-bd28fdbeebaa ", "version": "13", }, True, None, ), ( { "tenant_type": "account", "tenant_uuid": "89b79b52-de18-4644-bd2b-bd28fdbeebaa", "version": "13", }, False, { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), }, ), ( { "tenant_type": "company_brand", "tenant_uuid": "89b79b52-de18-4644-bd2b-bd28fdbeebaa", "version": "13", }, False, { "tenant_type": "company_brand", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), }, ), ( { "tenant_type": "label_participant", "tenant_uuid": "89b79b52-de18-4644-bd2b-bd28fdbeebaa", }, False, { "tenant_type": "label_participant", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), }, ), ( { "tenant_type": "parent_company", "tenant_uuid": "27fa6073-a059-450b-bbc8-25d76206c5be", }, False, { "tenant_type": "parent_company", "tenant_uuid": UUID("27fa6073-a059-450b-bbc8-25d76206c5be"), }, ), ], ) def test_tenant_response_model_validate( payload: Any, expect_exception: bool, expected: Dict[str, Any] ) -> None: """Parametrized testing of Tenant schema.""" if expect_exception: with pytest.raises(Exception): Tenant.model_validate(payload) else: actual = Tenant.model_validate(payload) assert actual == Tenant(**expected) def test_tenant_is_hashable(tenant_1_uuid: UUID) -> None: """Tenant should be hashable, and hashes should differ regardless of tenant type.""" tenant_account = Tenant( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=tenant_1_uuid ) tenant_subaccount = Tenant( tenant_type=TenantType.TENANT_TYPE_SUBACCOUNT, tenant_uuid=tenant_1_uuid ) tenant_company_brand = Tenant( tenant_type=TenantType.TENANT_TYPE_COMPANY_BRAND, tenant_uuid=tenant_1_uuid ) tenant_label_participant = Tenant( tenant_type=TenantType.TENANT_TYPE_LABEL_PARTICIPANT, tenant_uuid=tenant_1_uuid ) hash_tenant_account = hash(tenant_account) hash_tenant_subaccount = hash(tenant_subaccount) hash_tenant_company_brand = hash(tenant_company_brand) hash_tenant_label_participant = hash(tenant_label_participant) assert hash_tenant_account != hash_tenant_subaccount assert hash_tenant_account != hash_tenant_company_brand assert hash_tenant_account != hash_tenant_label_participant assert hash_tenant_subaccount != hash_tenant_company_brand assert hash_tenant_subaccount != hash_tenant_label_participant assert hash_tenant_company_brand != hash_tenant_label_participant def test_tenant_is_comparable(tenant_1_uuid: UUID) -> None: """Set operation can be performed on a list of non-unique tenants.""" tenant_1 = Tenant(tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=uuid4()) tenant_2 = Tenant(tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=uuid4()) tenant_3 = Tenant( tenant_type=TenantType.TENANT_TYPE_SUBACCOUNT, tenant_uuid=uuid4() ) tenant_4 = Tenant( tenant_type=TenantType.TENANT_TYPE_COMPANY_BRAND, tenant_uuid=uuid4() ) tenant_5 = Tenant( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=tenant_1_uuid ) tenant_6 = Tenant( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=tenant_1_uuid ) tenant_7 = Tenant( tenant_type=TenantType.TENANT_TYPE_LABEL_PARTICIPANT, tenant_uuid=tenant_1_uuid ) tenant_8 = Tenant( tenant_type=TenantType.TENANT_TYPE_LABEL_PARTICIPANT, tenant_uuid=uuid4() ) assert ( len( list( set( [ tenant_2, tenant_8, tenant_6, TENANT_NO_HIERARCHY_LP, tenant_5, tenant_7, tenant_1, tenant_5, TENANT_NO_HIERARCHY_LP, tenant_7, tenant_4, tenant_2, TENANT_MAYBE_HIERARCHY_ACCOUNT, tenant_3, tenant_2, tenant_8, tenant_4, TENANT_MAYBE_HIERARCHY_ACCOUNT, ] ) ) ) == 9 ), "Tenant type is immutable; it can be hashed and sorted" @pytest.mark.parametrize( "tenant, expected", [ ( TENANT_ACCOUNT_1, "TenantType.TENANT_TYPE_ACCOUNT#fff741c2-6def-4493-bfdf-c2bcb1128e02", ), ( TENANT_ACCOUNT_2, "TenantType.TENANT_TYPE_ACCOUNT#f39efd58-82f5-4257-859a-36e29fa69cda", ), ( TENANT_COMPANY_BRAND, "TenantType.TENANT_TYPE_COMPANY_BRAND#fb22886e-5cfc-4092-991c-62acfa673c12", ), ( TENANT_SUBACCOUNT, "TenantType.TENANT_TYPE_SUBACCOUNT#2c03bd86-ba0d-42a6-bcaf-a273861412a8", ), ( TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, "TenantType.TENANT_TYPE_SUBACCOUNT#fff741c2-6def-4493-bfdf-c2bcb1128e02", ), ( TENANT_LABEL_PARTICIPANT, "TenantType.TENANT_TYPE_LABEL_PARTICIPANT#780333d0-8ce0-45a7-a974-01aca9aa4bc8", # noqa: E501 ), ( TENANT_MAYBE_HIERARCHY_ACCOUNT, "TenantType.TENANT_TYPE_ACCOUNT#f8010ffc-94c1-4d22-9376-9f2f09a19798", ), ( TENANT_NO_HIERARCHY_LP, "TenantType.TENANT_TYPE_LABEL_PARTICIPANT#350029ac-a77d-404d-9f20-3487275a8567", ), ], ) def test_tenant_repr(tenant: Tenant, expected: str) -> None: """Test __repr__.""" assert repr(tenant) == expected @pytest.mark.parametrize( "tenant_1, tenant_2, expected, description", [ ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_1, False, "the same tenant is not less than itself", ), ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_2, False, "tenant account 1 is not less than tenant account 2", ), ( TENANT_ACCOUNT_2, TENANT_ACCOUNT_1, True, "tenant account 2 is less than tenant account 1", ), ( TENANT_ACCOUNT_1, TENANT_COMPANY_BRAND, True, "tenant account 1 is less than company brand", ), ( TENANT_COMPANY_BRAND, TENANT_ACCOUNT_1, False, "tenant company brand is not less than account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT, True, "tenant account 1 is less than subaccount", ), ( TENANT_SUBACCOUNT, TENANT_ACCOUNT_1, False, "tenant subaccount is not less than account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, True, "subaccount with same uuid is less than account", ), ], ) def test_tenant_lt( tenant_1: Tenant, tenant_2: Tenant, expected: bool, description: str ) -> None: """Test __lt__ operation.""" assert (tenant_1 < tenant_2) == expected, description @pytest.mark.parametrize( "tenant_1, tenant_2, expected, description", [ ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_1, True, "the same tenant is less than or equal", ), ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_2, False, "tenant account 1 is not less than or equal to tenant account 2", ), ( TENANT_ACCOUNT_2, TENANT_ACCOUNT_1, True, "tenant account 2 is less than or equal to tenant account 1", ), ( TENANT_ACCOUNT_1, TENANT_COMPANY_BRAND, True, "tenant account 1 is less than or equal to company brand", ), ( TENANT_COMPANY_BRAND, TENANT_ACCOUNT_1, False, "tenant company brand is not less than or equal to account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT, True, "tenant account 1 is less than or equal to subaccount", ), ( TENANT_SUBACCOUNT, TENANT_ACCOUNT_1, False, "tenant subaccount is not less than or equal to account", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, True, "subaccount with same uuid is less than or equal to account", ), ], ) def test_tenant_lte( tenant_1: Tenant, tenant_2: Tenant, expected: bool, description: str ) -> None: """Test __lte__ operation.""" assert (tenant_1 <= tenant_2) == expected, description @pytest.mark.parametrize( "tenant_1, tenant_2, expected, description", [ ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_1, True, "the same tenant is equal", ), ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_2, False, "tenant account 1 is not equal to tenant account 2", ), ( TENANT_ACCOUNT_1, TENANT_COMPANY_BRAND, False, "tenant account 1 is not equal to company brand", ), ( TENANT_COMPANY_BRAND, TENANT_ACCOUNT_1, False, "company brand is not equal to tenant account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT, False, "tenant account 1 is not equal to subaccount", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, False, "subaccount with same uuid is not equal to account", ), ], ) def test_tenant_eq( tenant_1: Tenant, tenant_2: Tenant, expected: bool, description: str ) -> None: """Test __eq__ operation.""" assert (tenant_1 == tenant_2) == expected, description @pytest.mark.parametrize( "tenant_1, tenant_2, expected, description", [ ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_1, False, "the same tenant is equal", ), ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_2, True, "tenant account 1 is not equal to tenant account 2", ), ( TENANT_ACCOUNT_1, TENANT_COMPANY_BRAND, True, "tenant account 1 is not equal to company brand", ), ( TENANT_COMPANY_BRAND, TENANT_ACCOUNT_1, True, "company brand is not equal to tenant account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT, True, "tenant account 1 is not equal to subaccount", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, True, "subaccount with same uuid is not equal to account", ), ], ) def test_tenant_ne( tenant_1: Tenant, tenant_2: Tenant, expected: bool, description: str ) -> None: """Test __ne__ operation.""" assert (tenant_1 != tenant_2) == expected, description @pytest.mark.parametrize( "tenant_1, tenant_2, expected, description", [ ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_1, False, "the same tenant is not greater than", ), ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_2, True, "tenant account 1 is greater than tenant account 2", ), ( TENANT_ACCOUNT_2, TENANT_ACCOUNT_1, False, "tenant account 2 is not greater than tenant account 1", ), ( TENANT_ACCOUNT_1, TENANT_COMPANY_BRAND, False, "tenant account 1 is not greater than company brand", ), ( TENANT_COMPANY_BRAND, TENANT_ACCOUNT_1, True, "tenant company brand is greater than account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT, False, "tenant account 1 is not greater than subaccount", ), ( TENANT_SUBACCOUNT, TENANT_ACCOUNT_1, True, "tenant subaccount is greater than account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, False, "subaccount with same uuid is not greater than account", ), ], ) def test_tenant_gt( tenant_1: Tenant, tenant_2: Tenant, expected: bool, description: str ) -> None: """Test __gt__ operation.""" assert (tenant_1 > tenant_2) == expected, description @pytest.mark.parametrize( "tenant_1, tenant_2, expected, description", [ ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_1, True, "the same tenant is greater than or equal", ), ( TENANT_ACCOUNT_1, TENANT_ACCOUNT_2, True, "tenant account 1 is greater than or equal to tenant account 2", ), ( TENANT_ACCOUNT_2, TENANT_ACCOUNT_1, False, "tenant account 2 is not greater than or equal to tenant account 1", ), ( TENANT_ACCOUNT_1, TENANT_COMPANY_BRAND, False, "tenant account 1 is not greater than or equal to company brand", ), ( TENANT_COMPANY_BRAND, TENANT_ACCOUNT_1, True, "tenant company brand is greater than or equal to account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT, False, "tenant account 1 is not greater than or equal to subaccount", ), ( TENANT_SUBACCOUNT, TENANT_ACCOUNT_1, True, "tenant subaccount is greater than or equal to account 1", ), ( TENANT_ACCOUNT_1, TENANT_SUBACCOUNT_SAME_UUID_AS_ACCOUNT_1, False, "subaccount with same uuid is not greater than or equal to account", ), ], ) def test_tenant_gte( tenant_1: Tenant, tenant_2: Tenant, expected: bool, description: str ) -> None: """Test __gte__ operation.""" assert (tenant_1 >= tenant_2) == expected, description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing company_brand"), ( { "company_brand": { "tenant_type": "company_brand", "tenant_uuid": "397513ac-da50-4921-aec2-913c08919580", } }, False, { "company_brand": { "tenant_type": "company_brand", "tenant_uuid": "397513ac-da50-4921-aec2-913c08919580", } }, "valid tenant hierarchy ", ), ( { "company_brand": { "tenant_type": "company_brand", "tenant_uuid": "397513ac-da50-4921-aec2-913c08919580", }, "vendor": { "tenant_type": "account", "tenant_uuid": "560ef3a1-c546-4ba3-8226-74aa077dafb9", }, }, False, { "company_brand": { "tenant_type": "company_brand", "tenant_uuid": "397513ac-da50-4921-aec2-913c08919580", }, "vendor": { "tenant_type": "account", "tenant_uuid": "560ef3a1-c546-4ba3-8226-74aa077dafb9", }, }, "valid tenant hierarchy with vendor", ), ( { "company_brand": { "tenant_type": "company_brand", "tenant_uuid": "397513ac-da50-4921-aec2-913c08919580", }, "subaccount": { "tenant_type": "subaccount", "tenant_uuid": "2c03bd86-ba0d-42a6-bcaf-a273861412a8", }, "vendor": { "tenant_type": "account", "tenant_uuid": "560ef3a1-c546-4ba3-8226-74aa077dafb9", }, }, False, { "company_brand": { "tenant_type": "company_brand", "tenant_uuid": "397513ac-da50-4921-aec2-913c08919580", }, "subaccount": { "tenant_type": "subaccount", "tenant_uuid": "2c03bd86-ba0d-42a6-bcaf-a273861412a8", }, "vendor": { "tenant_type": "account", "tenant_uuid": "560ef3a1-c546-4ba3-8226-74aa077dafb9", }, }, "valid tenant hierarchy with subaccount and vendor", ), ], ) def test_tenant_hierarchy( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the TenantHierarchy model.""" if expect_exception: with pytest.raises(Exception): TenantHierarchy.model_validate(payload) else: actual = TenantHierarchy.model_validate(payload) assert actual == TenantHierarchy(**expected) @pytest.mark.parametrize( "description, tenant_hierarchy, expected", [ ( "Valid tenant hierarchy with a parent_company tenant", TenantHierarchy( company_brand=Tenant( tenant_type="company_brand", tenant_uuid=UUID("8cdadb10-73f2-413c-8379-c319a38faf73"), ), parent_company=Tenant( tenant_type="parent_company", tenant_uuid=UUID("babd6f81-00a9-4001-a5a2-45e512a39f93"), ), ), [ "babd6f81-00a9-4001-a5a2-45e512a39f93", "8cdadb10-73f2-413c-8379-c319a38faf73", ], ), ( "Valid tenant hierarchy with a company_brand tenant", TenantHierarchy( company_brand=Tenant( tenant_type="company_brand", tenant_uuid=UUID("8cdadb10-73f2-413c-8379-c319a38faf73"), ) ), ["8cdadb10-73f2-413c-8379-c319a38faf73"], ), ( "Valid tenant hierarchy with no company_brand", TenantHierarchy(company_brand=None), [], ), ], ) def test_tenant_hierarchy_to_array( description: str, tenant_hierarchy: TenantHierarchy, expected: Optional[List[str]], ) -> None: """Test the TenantHierarchy.to_cerbos_array method.""" actual = tenant_hierarchy.to_array() assert actual == expected, description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ( { "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), } }, False, { "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": None, } }, "valid tenant resource attributes", ), ( { "tenant": { "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), }, }, True, None, "missing tenant type", ), ( {}, True, None, "missing tenant key", ), ( { "other": "attributes", "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": None, }, }, False, { "other": "attributes", "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": None, }, }, "Allows attributes in addition to tenant", ), ( { "other": "attributes", "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": ["not_a_uuid"], }, }, True, None, "Hierarchy array must contain valid uuids", ), ( { "other": "attributes", "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": ["8b7276cf-150a-454d-ae2c-afb6e14a4057"], }, }, False, { "other": "attributes", "tenant": { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": ["8b7276cf-150a-454d-ae2c-afb6e14a4057"], }, }, "Hierarchy array is parsed", ), ], ) def test_tenant_with_maybe_hierarchy_resource_attributes( payload: Optional[TenantWithMaybeHierarchy], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the TenantWithMaybeHierarchyResourceAttributes model.""" if expect_exception: with pytest.raises(Exception): TenantWithMaybeHierarchyResourceAttributes.model_validate(payload) else: actual = TenantWithMaybeHierarchyResourceAttributes.model_validate(payload) assert actual == TenantWithMaybeHierarchyResourceAttributes(**expected), ( description ) @pytest.mark.parametrize( "payload, expected_needs_hierarchy", [ ( { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": ["8b7276cf-150a-454d-ae2c-afb6e14a4057"], }, False, ), ( { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), "tenant_hierarchy": [], }, False, ), ( { "tenant_type": "account", "tenant_uuid": UUID("89b79b52-de18-4644-bd2b-bd28fdbeebaa"), }, True, ), ], ) def test_tenant_needs_hierarchy( payload: TenantWithMaybeHierarchy, expected_needs_hierarchy: bool, ) -> None: """Test TenantWithMaybeHierarchy.needs_hierarchy.""" actual = TenantWithMaybeHierarchy.model_validate(payload) assert actual.needs_hierarchy() == expected_needs_hierarchy @pytest.mark.parametrize( "payload, expect_exception, expected", [ pytest.param( {}, True, None, id="Tenant Type and Tenant Id are required", ), pytest.param( { "tenant_type": "not_label_participant", "tenant_id": "89b79b52-de18-4644-bd2b-bd28fdbeebaa", }, True, None, id="Tenant Type is validated", ), pytest.param( { "tenant_type": "account", }, True, None, id="Tenant Id is required", ), pytest.param( { "tenant_id": "111", }, True, None, id="Tenant Type is required", ), pytest.param( { "tenant_type": "account", "tenant_id": 7123, }, False, { "tenant_type": "account", "tenant_id": 7123, }, id="Classic vendor id is supported", ), pytest.param( { "tenant_type": "subaccount", "tenant_id": "12223", }, False, { "tenant_type": "subaccount", "tenant_id": "12223", }, id="Id can be string", ), pytest.param( { "tenant_type": "label_participant", "tenant_id": "89b79b52-de18-4644-bd2b-bd28fdbeebaa", }, False, { "tenant_type": "label_participant", "tenant_id": "89b79b52-de18-4644-bd2b-bd28fdbeebaa", }, id="Label Participant can have an ID even if its still its UUID", ), ], ) def test_id_to_uuid_exchange_tenant_model_validate( payload: Any, expect_exception: bool, expected: Dict[str, Any] ) -> None: """Parametrized testing of IdToUuidExchangeTenant schema.""" if expect_exception: with pytest.raises(Exception): IdToUuidExchangeTenant.model_validate(payload) else: actual = IdToUuidExchangeTenant.model_validate(payload) assert actual == IdToUuidExchangeTenant(**expected) @pytest.mark.parametrize( "payload, expect_exception, expected", [ pytest.param({}, True, None, id="Tenant Type and Tenant UUID are required"), pytest.param( { "tenant_type": "account", "tenant_uuid": "a561344f-87e2-493a-aab9-5dc80294b693", }, False, { "tenant_type": "account", "tenant_uuid": "a561344f-87e2-493a-aab9-5dc80294b693", }, ), ], ) def test_uuid_to_id_exchange_tenant_model_validate( payload: Any, expect_exception: bool, expected: Dict[str, Any] ) -> None: """Validate the UuidToIdExchangeTenant schema. NOTE: This test is sparse because the Tenant schema tests cover valid cases. """ if expect_exception: with pytest.raises(Exception): UuidToIdExchangeTenant.model_validate(payload) else: actual = UuidToIdExchangeTenant.model_validate(payload) assert actual == UuidToIdExchangeTenant(**expected) def test_uuid_to_id_exchange_tenant_supports_container_type_operations( tenant_1_uuid: UUID, ) -> None: """Verify that UuidToIdExchangeTenant supports Python container operations. Smaller test that covers Tenant schema type hashability, comparator, and repr tests. """ tenant_account = UuidToIdExchangeTenant( tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=tenant_1_uuid ) tenant_subaccount = UuidToIdExchangeTenant( tenant_type=TenantType.TENANT_TYPE_SUBACCOUNT, tenant_uuid=tenant_1_uuid ) tenant_company_brand = UuidToIdExchangeTenant( tenant_type=TenantType.TENANT_TYPE_COMPANY_BRAND, tenant_uuid=tenant_1_uuid ) tenant_label_participant = UuidToIdExchangeTenant( tenant_type=TenantType.TENANT_TYPE_LABEL_PARTICIPANT, tenant_uuid=tenant_1_uuid ) # Hashability assert { tenant_account: "tenant_account", tenant_subaccount: "tenant_subaccount", tenant_company_brand: "tenant_company_brand", tenant_label_participant: "tenant_label_participant", }, "Verify that UuidToIdExchangeTenant is hashable." test_item_list = [ tenant_account, tenant_subaccount, tenant_company_brand, tenant_label_participant, ] # comparators assert sorted(test_item_list, reverse=True) == [ tenant_subaccount, tenant_label_participant, tenant_company_brand, tenant_account, ], "Verify that the comparator methods work as expected." # set() operations test_item_list_with_dupes = test_item_list * 2 assert len(test_item_list_with_dupes) == 8, "Sanity check the dupes list." assert len(set(test_item_list_with_dupes)) == 4, "Verify set() can dedupe items." # repr assert [repr(item) for item in test_item_list] == [ "TenantType.TENANT_TYPE_ACCOUNT#a9dd9b42-e53d-11ee-be6d-4a2888760682", "TenantType.TENANT_TYPE_SUBACCOUNT#a9dd9b42-e53d-11ee-be6d-4a2888760682", "TenantType.TENANT_TYPE_COMPANY_BRAND#a9dd9b42-e53d-11ee-be6d-4a2888760682", "TenantType.TENANT_TYPE_LABEL_PARTICIPANT#a9dd9b42-e53d-11ee-be6d-4a2888760682", ], "Verify repr works."