from typing import Any import pytest from unittest.mock import MagicMock, patch from pytest_mock import MockerFixture from artist.connectors import ows_permissions def directly_accessible_vendors_response() -> dict[str, list[dict[str, Any]]]: """Raw ows-permissions /v2/profile/vendors/direct-access response.""" return { "vendors": [ {"vendor_id": "*", "vendor_uuid": "053a1a75-acc5-4cd8-9206-a194335d2afa"}, {"vendor_id": 123, "vendor_uuid": "uuid_123"} ] } @patch('artist.connectors.ows_permissions.g') def test_get_directly_accessible_vendors(mock_g, app_context, mocker): ows_client_get = MagicMock( return_value=MagicMock(json=MagicMock(return_value=directly_accessible_vendors_response()))) mocker.patch.object( ows_permissions, "get_ows_client", return_value=MagicMock(get=ows_client_get) ) request_context = { "authorization": "Bearer some-token", "profile_type": "SomeType", "profile_id": "456" } mock_g.request_context = MagicMock(**request_context) result = ows_permissions.get_directly_accessible_vendors() assert {k: v.model_dump() for k, v in result.items()} == { "*": { "vendor_id": "*", "vendor_uuid": "053a1a75-acc5-4cd8-9206-a194335d2afa" }, "123": { "vendor_id": "123", "vendor_uuid": "uuid_123" } } ows_client_get.assert_called_once_with( "ows-permissions", "/v2/profile/vendors/direct-access", headers={ "Content-Type": "application/json", "Orchard-Profile-Type": "SomeType", "Orchard-Profile-Id": "456" } ) def test_get_single_vendor_id_for_label_profile(mocker: MockerFixture) -> None: """ Test happy path when input is a LabelProfile and ows-permissions returns a single Vendor. """ ows_permissions_response = { "vendors": [ {"vendor_id": 123, "vendor_uuid": "uuid_123"} ] } ows_client_get = MagicMock( return_value=MagicMock(json=MagicMock(return_value=ows_permissions_response))) mocker.patch.object( ows_permissions, "get_ows_client", return_value=MagicMock(get=ows_client_get) ) request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="LabelProfile", profile_id=456 ) result = ows_permissions.get_single_vendor_id_for_label_profile(request_context) assert result == 123 ows_client_get.assert_called_once_with( "ows-permissions", "/v2/profile/self/vendors/direct-access", headers={ "Content-Type": "application/json", "Orchard-Profile-Type": "LabelProfile", "Orchard-Profile-Id": "456" } ) def test_get_single_vendor_id_for_label_profile_with_wrong_profile_type(mocker) -> None: """Test that a non-LabelProfile profile raises a ValueError.""" request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="InsightsProfile", profile_id=456 ) with pytest.raises(ValueError): ows_permissions.get_single_vendor_id_for_label_profile(request_context) def test_get_single_vendor_id_for_label_profile_has_multiple_vendors( mocker: MockerFixture ) -> None: ows_permissions_response = { "vendors": [ {"vendor_id": 123, "vendor_uuid": "uuid_123"}, {"vendor_id": 456, "vendor_uuid": "uuid_456"} ] } ows_client_get = MagicMock( return_value=MagicMock(json=MagicMock(return_value=ows_permissions_response))) mocker.patch.object( ows_permissions, "get_ows_client", return_value=MagicMock(get=ows_client_get) ) request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="LabelProfile", profile_id=456 ) with pytest.raises(ValueError): ows_permissions.get_single_vendor_id_for_label_profile(request_context) def test_get_single_vendor_id_for_label_profile_no_vendors_returns_none( mocker: MockerFixture ) -> None: ows_permissions_response = { "vendors": [] } ows_client_get = MagicMock( return_value=MagicMock(json=MagicMock(return_value=ows_permissions_response))) mocker.patch.object( ows_permissions, "get_ows_client", return_value=MagicMock(get=ows_client_get) ) request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="LabelProfile", profile_id=456 ) result = ows_permissions.get_single_vendor_id_for_label_profile(request_context) assert result is None def test_get_single_subaccount_id_for_label_profile(mocker: MockerFixture) -> None: """ Test happy path when input is a LabelProfile and ows-permissions returns a single Subaccount. """ ows_permissions_response = { "subaccounts": [ {"subaccount_id": 789, "subaccount_uuid": "uuid_789"} ] } ows_client_get = MagicMock( return_value=MagicMock(json=MagicMock(return_value=ows_permissions_response))) mocker.patch.object( ows_permissions, "get_ows_client", return_value=MagicMock(get=ows_client_get) ) request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="LabelProfile", profile_id=456 ) result = ows_permissions.get_subaccount_ids_for_label_profile(request_context) assert result == [789] ows_client_get.assert_called_once_with( "ows-permissions", "/v2/profile/self/subaccounts/direct-access", headers={ "Content-Type": "application/json", "Orchard-Profile-Type": "LabelProfile", "Orchard-Profile-Id": "456" } ) def test_get_single_subaccount_id_for_label_profile_with_wrong_profile_type(mocker) -> None: """Test that a non-LabelProfile profile raises a ValueError.""" request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="InsightsProfile", profile_id=456 ) with pytest.raises(ValueError): ows_permissions.get_subaccount_ids_for_label_profile(request_context) def test_get_subaccount_ids_for_label_profile_returns_multiple_subaccounts(mocker: MockerFixture) -> None: """Test that multiple subaccounts are returned for a LabelProfile when present in the payload.""" ows_permissions_response = { "subaccounts": [ {"subaccount_id": 789, "subaccount_uuid": "uuid_789"}, {"subaccount_id": 101, "subaccount_uuid": "uuid_101"} ] } ows_client_get = MagicMock( return_value=MagicMock(json=MagicMock(return_value=ows_permissions_response))) mocker.patch.object( ows_permissions, "get_ows_client", return_value=MagicMock(get=ows_client_get) ) request_context = MagicMock( spec=ows_permissions.LabelProfile, profile_type="LabelProfile", profile_id=456 ) result = ows_permissions.get_subaccount_ids_for_label_profile(request_context) assert result == [789, 101] ows_client_get.assert_called_once_with( "ows-permissions", "/v2/profile/self/subaccounts/direct-access", headers={ "Content-Type": "application/json", "Orchard-Profile-Type": "LabelProfile", "Orchard-Profile-Id": "456" } )