"""Unit tests for the OWS Permissions connector.""" from unittest.mock import MagicMock from uuid import UUID import pytest from pytest_mock import MockerFixture from contributor.api.context import RequestContext from contributor.connectors import ows_permissions @pytest.fixture def mock_ows_client(mocker: MockerFixture) -> MagicMock: """Mock the OWS client.""" return mocker.patch( "contributor.connectors.ows_permissions.datasources.get_ows_client" ) @pytest.fixture def mock_request_context(mocker: MockerFixture) -> MagicMock: """Mock the request context getter.""" return mocker.patch( "contributor.connectors.ows_permissions.context.get_request_context" ) @pytest.fixture def mock_response() -> dict: """Create a mock successful response dict from ows-permissions.""" return { "vendors": [ { "vendor_id": 123, "vendor_uuid": "053a1a75-acc5-4cd8-9206-a194335d2afa", "name": "Test Vendor", } ] } class TestGetDirectlyAccessibleVendors: def test_returns_vendors_with_valid_context( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test get_directly_accessible_vendors with valid request context.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=318696, identity_id="10436b38-5e11-472d-b6a4-bf1ee2b1b438", identity_uuid="10436b38-5e11-472d-b6a4-bf1ee2b1b438", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client result = ows_permissions.get_directly_accessible_vendors() assert result == mock_response mock_client.get.assert_called_once_with( "ows-permissions", path="/v2/profile/self/vendors/direct-access", headers={ "Orchard-Profile-Type": "ContentProfile", "Orchard-Profile-Id": "318696", "Orchard-Identity-Id": "10436b38-5e11-472d-b6a4-bf1ee2b1b438", "Orchard-Identity-Uuid": "10436b38-5e11-472d-b6a4-bf1ee2b1b438", }, ) def test_passes_profile_headers_to_ows_client( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test that profile context fields become Orchard headers.""" mock_request_context.return_value = RequestContext( profile_type="LabelProfile", profile_id=42, identity_id="abc-123", identity_uuid="def-456", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client ows_permissions.get_directly_accessible_vendors() # Verify headers were constructed correctly call_args = mock_client.get.call_args headers = call_args.kwargs["headers"] assert headers["Orchard-Profile-Type"] == "LabelProfile" assert headers["Orchard-Profile-Id"] == "42" assert headers["Orchard-Identity-Id"] == "abc-123" assert headers["Orchard-Identity-Uuid"] == "def-456" def test_omits_missing_context_fields( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test that missing context fields are not included in headers.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=100, identity_id=None, identity_uuid=None, ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client ows_permissions.get_directly_accessible_vendors() call_args = mock_client.get.call_args headers = call_args.kwargs["headers"] assert "Orchard-Profile-Type" in headers assert "Orchard-Profile-Id" in headers assert "Orchard-Identity-Id" not in headers assert "Orchard-Identity-Uuid" not in headers def test_handles_null_request_context( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test get_directly_accessible_vendors when request context is None.""" mock_request_context.return_value = None mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client ows_permissions.get_directly_accessible_vendors() call_args = mock_client.get.call_args headers = call_args.kwargs["headers"] assert headers == {} class TestCanAccessVendor: def test_can_access_vendor_by_id( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test can_access_vendor filters by vendor_id.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=318696, identity_id="test-id", identity_uuid="test-uuid", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client result = ows_permissions.can_access_vendor(vendor_id=123) assert result is True def test_can_access_vendor_by_uuid( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test can_access_vendor filters by vendor_uuid.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=318696, identity_id="test-id", identity_uuid="test-uuid", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client result = ows_permissions.can_access_vendor( vendor_uuid=UUID("053a1a75-acc5-4cd8-9206-a194335d2afa") ) assert result is True def test_can_access_vendor_returns_none_when_no_match( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, mock_response: dict, ) -> None: """Test can_access_vendor returns None when vendor not found.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=318696, identity_id="test-id", identity_uuid="test-uuid", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = mock_response mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client result = ows_permissions.can_access_vendor(vendor_id=999) assert result is False def test_can_access_vendor_by_id_matches_all_access_vendor_id( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, ) -> None: """Test can_access_vendor accepts all-access vendor for vendor_id checks.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=318696, identity_id="test-id", identity_uuid="test-uuid", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = { "vendors": [ { "vendor_id": "*", "vendor_uuid": "11111111-1111-1111-1111-111111111111", "name": "All Access Vendor", } ] } mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client result = ows_permissions.can_access_vendor(vendor_id=999) assert result is True def test_can_access_vendor_by_uuid_matches_all_access_vendor_uuid( self, mock_ows_client: MagicMock, mock_request_context: MagicMock, ) -> None: """Test can_access_vendor accepts all-access vendor for vendor_uuid checks.""" mock_request_context.return_value = RequestContext( profile_type="ContentProfile", profile_id=318696, identity_id="test-id", identity_uuid="test-uuid", ) mock_client = MagicMock() mock_http_response = MagicMock() mock_http_response.json.return_value = { "vendors": [ { "vendor_id": 123, "vendor_uuid": "053a1a75-acc5-4cd8-9206-a194335d2afa", "name": "All Access Vendor", } ] } mock_client.get.return_value = mock_http_response mock_ows_client.return_value = mock_client result = ows_permissions.can_access_vendor( vendor_uuid=UUID("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa") ) assert result is True