import pytest from unittest.mock import MagicMock, patch from ea_chatbot.auth import OIDCClient @pytest.fixture def oidc_config(): return { "client_id": "test_id", "client_secret": "test_secret", "server_metadata_url": "https://example.com/.well-known/openid-configuration", "redirect_uri": "http://localhost:8501" } @pytest.fixture def mock_metadata(): return { "authorization_endpoint": "https://example.com/auth", "token_endpoint": "https://example.com/token", "userinfo_endpoint": "https://example.com/userinfo" } def test_oidc_fetch_metadata(oidc_config, mock_metadata): client = OIDCClient(**oidc_config) with patch("requests.get") as mock_get: mock_response = MagicMock() mock_response.json.return_value = mock_metadata mock_get.return_value = mock_response metadata = client.fetch_metadata() assert metadata == mock_metadata mock_get.assert_called_once_with(oidc_config["server_metadata_url"]) # Second call should use cache client.fetch_metadata() assert mock_get.call_count == 1 def test_oidc_get_login_url(oidc_config, mock_metadata): client = OIDCClient(**oidc_config) client.metadata = mock_metadata with patch.object(client.oauth_session, "create_authorization_url") as mock_create_url: mock_create_url.return_value = ("https://example.com/auth?state=xyz", "xyz") url = client.get_login_url() assert url == "https://example.com/auth?state=xyz" mock_create_url.assert_called_once_with(mock_metadata["authorization_endpoint"]) def test_oidc_get_login_url_missing_endpoint(oidc_config): client = OIDCClient(**oidc_config) client.metadata = {"some_other": "field"} with pytest.raises(ValueError, match="authorization_endpoint not found"): client.get_login_url() def test_oidc_exchange_code_for_token(oidc_config, mock_metadata): client = OIDCClient(**oidc_config) client.metadata = mock_metadata with patch.object(client.oauth_session, "fetch_token") as mock_fetch_token: mock_fetch_token.return_value = {"access_token": "abc"} token = client.exchange_code_for_token("test_code") assert token == {"access_token": "abc"} mock_fetch_token.assert_called_once_with( mock_metadata["token_endpoint"], code="test_code", client_secret=oidc_config["client_secret"] ) def test_oidc_get_user_info(oidc_config, mock_metadata): client = OIDCClient(**oidc_config) client.metadata = mock_metadata with patch.object(client.oauth_session, "get") as mock_get: mock_response = MagicMock() mock_response.json.return_value = {"sub": "user123"} mock_get.return_value = mock_response user_info = client.get_user_info({"access_token": "abc"}) assert user_info == {"sub": "user123"} assert client.oauth_session.token == {"access_token": "abc"} mock_get.assert_called_once_with(mock_metadata["userinfo_endpoint"])