"""Tests for impersonation Pydantic schemas.""" import datetime from typing import Any import freezegun import pytest from owsclient.m2m.impersonation import ClientCredentials, OAuthToken def test_oauth_token_create(valid_oauth_token_data: dict[str, Any]) -> None: """Test OAuthToken schema with valid data.""" token = OAuthToken.model_validate(valid_oauth_token_data) assert token.access_token == valid_oauth_token_data["access_token"] assert token.expires_in == valid_oauth_token_data["expires_in"] assert token.token_type == valid_oauth_token_data["token_type"] @pytest.mark.parametrize( "invalid_access_token", [ pytest.param("", id="Empty string not allowed"), pytest.param(" ", id="Whitespace-only string not allowed"), ], ) def test_oauth_token_invalid_access_token(invalid_access_token: str) -> None: """Test OAuthToken schema with invalid access tokens.""" with pytest.raises(ValueError): OAuthToken.model_validate( { "access_token": invalid_access_token, "expires_in": 3600, "token_type": "Bearer", } ) @pytest.mark.parametrize( "invalid_expires_in", [ pytest.param(0, id="Zero not allowed"), pytest.param(-1, id="Negative value not allowed"), pytest.param(-3600, id="Large negative value not allowed"), ], ) def test_oauth_token_invalid_expires_in(invalid_expires_in: int) -> None: """Test OAuthToken schema with invalid expires_in values.""" with pytest.raises(ValueError): OAuthToken.model_validate( { "access_token": "valid_token", "expires_in": invalid_expires_in, "token_type": "Bearer", } ) @pytest.mark.parametrize( "invalid_token_type", [ pytest.param("", id="Empty string not allowed"), pytest.param(" ", id="Whitespace-only string not allowed"), ], ) def test_oauth_token_invalid_token_type(invalid_token_type: str) -> None: """Test OAuthToken schema with invalid token types.""" with pytest.raises(ValueError): OAuthToken.model_validate( { "access_token": "valid_token", "expires_in": 3600, "token_type": invalid_token_type, } ) def test_oauth_token_whitespace_stripping() -> None: """Test that whitespace is stripped from string fields.""" token = OAuthToken.model_validate( { "access_token": " token_with_spaces ", "expires_in": 3600, "token_type": " Bearer ", } ) assert token.access_token == "token_with_spaces" assert token.token_type == "Bearer" @freezegun.freeze_time("2024-01-15 12:00:00") def test_oauth_token_convert_to_m2m_token() -> None: """Test conversion from OAuthToken to M2MToken.""" oauth_token = OAuthToken.model_validate( { "access_token": "test_access_token", "expires_in": 3600, "token_type": "Bearer", } ) m2m_token = oauth_token.convert_to_m2m_token() assert m2m_token.token == "test_access_token" expected_expires_at = datetime.datetime(2024, 1, 15, 13, 0, 0, tzinfo=datetime.UTC) assert m2m_token.expires_at == expected_expires_at def test_client_credentials_create( valid_client_credentials_data: dict[str, Any], ) -> None: """Test ClientCredentials schema with valid data.""" credentials = ClientCredentials.model_validate(valid_client_credentials_data) assert credentials.audience == valid_client_credentials_data["audience"] assert credentials.client_id == valid_client_credentials_data["client_id"] assert credentials.client_secret == valid_client_credentials_data["client_secret"] assert credentials.grant_type == valid_client_credentials_data["grant_type"] def test_client_credentials_default_grant_type() -> None: """Test ClientCredentials schema with default grant_type.""" credentials = ClientCredentials.model_validate( { "audience": "https://api.example.com", "client_id": "test_client_id", "client_secret": "test_client_secret", } ) assert credentials.grant_type == "client_credentials" @pytest.mark.parametrize( "data", [ pytest.param( { "client_id": "test_client_id", "client_secret": "test_client_secret", "grant_type": "client_credentials", }, id="Missing audience not allowed", ), pytest.param( { "audience": "https://api.example.com", "client_secret": "test_client_secret", "grant_type": "client_credentials", }, id="Missing client_id not allowed", ), pytest.param( { "audience": "https://api.example.com", "client_id": "test_client_id", "grant_type": "client_credentials", }, id="Missing client_secret not allowed", ), pytest.param( { "audience": "https://api.example.com", "client_id": "test_client_id", "client_secret": "test_client_secret", "grant_type": "", }, id="Empty string for grant_type not allowed", ), ], ) def test_client_credentials_invalid_empty_fields(data: dict[str, Any]) -> None: """Test ClientCredentials schema with missing required fields.""" with pytest.raises(ValueError): ClientCredentials.model_validate(data)