"""Test check_resources.""" import uuid from typing import Any, Dict, Union from unittest.mock import AsyncMock, MagicMock, call, patch import pytest from pdp.constants.constants import TenantType from pdp.fastapi.schemas.check_resources import CheckResourcesRequest from pdp.fastapi.schemas.identity import CheckResourceAction, Resource from pdp.fastapi.schemas.tenant import ( IdExchangeTenantHierarchy, IdToUuidExchangeTenant, Tenant, ) @pytest.mark.parametrize( "payload, expect_exception, expected", [ ({}, True, None), ({"resources": []}, True, None), ({"resources": [{"resource": {}}]}, True, None), ({"resources": [{"resource": {}, "action": "delete"}]}, True, None), ( { "resources": [ { "resource": { "resource_id": 123, "resource_type": "identity", }, "action": "view", } ] }, False, { "resources": [ { "resource": { "resource_id": "123", "resource_type": "identity", "attributes": {}, }, "action": "view", } ] }, ), ], ) def test_check_resources_request_model_validate( payload: Any, expect_exception: bool, expected: Dict[str, Any] ) -> None: """Parametrized testing of CheckResourcesRequest schema.""" if expect_exception: with pytest.raises(Exception): CheckResourcesRequest.model_validate(payload) else: actual = CheckResourcesRequest.model_validate(payload) assert actual == CheckResourcesRequest(**expected) @patch("pdp.fastapi.schemas.check_resources.IdToUuidExchangeTenantProxy") @patch("pdp.fastapi.schemas.check_resources.RedisConnector") @patch("pdp.fastapi.schemas.check_resources.OwsAccountClient") async def test_check_resources_request_update_with_id_to_uuid_exchange( mock_ows_account_client: MagicMock, mock_redis_connector: MagicMock, mock_proxy: MagicMock, ) -> None: """Test CheckResourcesRequest update_with_id_to_uuid_exchange.""" company_brand_uuid = uuid.uuid4() tenant_id_789_exchange = IdExchangeTenantHierarchy( tenant_id=789, tenant_type=TenantType.TENANT_TYPE_ACCOUNT, tenant_uuid=uuid.uuid4(), company_brand=Tenant( tenant_type=TenantType.TENANT_TYPE_COMPANY_BRAND, tenant_uuid=company_brand_uuid, ), ) def mock_get_tenant_exchange( tenant_type: TenantType, tenant_id: Union[int, str] ) -> Union[IdExchangeTenantHierarchy | None]: if tenant_type == TenantType.TENANT_TYPE_ACCOUNT and tenant_id == 789: return tenant_id_789_exchange return None mock_proxy.return_value.gather_tenant_exchange = AsyncMock() mock_proxy.return_value.get_tenant_exchange = MagicMock( side_effect=mock_get_tenant_exchange ) check_resources_request = CheckResourcesRequest( resources=[ CheckResourceAction( action="nothing to update", resource=Resource(resource_id=1, resource_type="no changes after"), ), CheckResourceAction( action="proxy returned no exchange", resource=Resource( resource_id=2, resource_type="no changes after", attributes={ "id_to_uuid_exchange_tenant": { "tenant_id": 123, "tenant_type": "subaccount", } }, ), ), CheckResourceAction( action="proxy returned an exchange", resource=Resource( resource_id=3, resource_type="expect changes after", attributes={ "id_to_uuid_exchange_tenant": { "tenant_id": 789, "tenant_type": "account", } }, ), ), CheckResourceAction( action="proxy overwrites provided tenant", resource=Resource( resource_id=4, resource_type="expect changes after", attributes={ "id_to_uuid_exchange_tenant": { "tenant_id": 789, "tenant_type": "account", }, "tenant": { "tenant_uuid": str(uuid.uuid4()), "tenant_type": "label_participant", "tenant_hierarchy": [str(uuid.uuid4()), str(uuid.uuid4())], }, }, ), ), ] ) await check_resources_request.update_with_id_to_uuid_exchange( redis_connector=mock_redis_connector, ows_account_client=mock_ows_account_client, ) mock_proxy.assert_called_once_with( tenants=[ IdToUuidExchangeTenant( tenant_id=123, tenant_type=TenantType.TENANT_TYPE_SUBACCOUNT, ), IdToUuidExchangeTenant( tenant_id=789, tenant_type=TenantType.TENANT_TYPE_ACCOUNT, ), IdToUuidExchangeTenant( tenant_id=789, tenant_type=TenantType.TENANT_TYPE_ACCOUNT, ), ], redis_connector=mock_redis_connector, ows_account_client=mock_ows_account_client, ) mock_proxy.return_value.gather_tenant_exchange.assert_called_once() mock_proxy.return_value.get_tenant_exchange.assert_has_calls( [ call(TenantType.TENANT_TYPE_SUBACCOUNT, 123), call(TenantType.TENANT_TYPE_ACCOUNT, 789), call(TenantType.TENANT_TYPE_ACCOUNT, 789), ] ) assert check_resources_request == CheckResourcesRequest( resources=[ CheckResourceAction( action="nothing to update", resource=Resource(resource_id=1, resource_type="no changes after"), ), CheckResourceAction( action="proxy returned no exchange", resource=Resource( resource_id=2, resource_type="no changes after", attributes={ "id_to_uuid_exchange_tenant": { "tenant_id": 123, "tenant_type": "subaccount", } }, ), ), CheckResourceAction( action="proxy returned an exchange", resource=Resource( resource_id=3, resource_type="expect changes after", attributes={ "id_to_uuid_exchange_tenant": { "tenant_id": 789, "tenant_type": "account", }, "tenant": { "tenant_uuid": str(tenant_id_789_exchange.tenant_uuid), "tenant_type": "account", "tenant_hierarchy": [str(company_brand_uuid)], }, }, ), ), CheckResourceAction( action="proxy overwrites provided tenant", resource=Resource( resource_id=4, resource_type="expect changes after", attributes={ "id_to_uuid_exchange_tenant": { "tenant_id": 789, "tenant_type": "account", }, "tenant": { "tenant_uuid": str(tenant_id_789_exchange.tenant_uuid), "tenant_type": "account", "tenant_hierarchy": [str(company_brand_uuid)], }, }, ), ), ] )