diff --git a/tests/test_graph_client.py b/tests/test_graph_client.py new file mode 100644 index 0000000..327c10e --- /dev/null +++ b/tests/test_graph_client.py @@ -0,0 +1,74 @@ +# Copyright 2026 Guildhouse Dev +# SPDX-License-Identifier: Apache-2.0 + +"""Tests for the shared Graph API client.""" + +import pytest +from unittest.mock import MagicMock, patch, AsyncMock + +from gsap_broker.intune.graph_client import GraphClient + + +@pytest.fixture +def mock_msal(): + with patch("gsap_broker.intune.graph_client.msal") as m: + app_instance = MagicMock() + app_instance.acquire_token_for_client.return_value = { + "access_token": "test-token-abc" + } + m.ConfidentialClientApplication.return_value = app_instance + yield m + + +@pytest.fixture +def graph(mock_msal): + return GraphClient( + tenant_id="test-tenant", + client_id="test-client", + client_secret="test-secret", + ) + + +@pytest.mark.asyncio +async def test_acquire_token(graph, mock_msal): + token = await graph.acquire_token() + assert token == "test-token-abc" + + +@pytest.mark.asyncio +async def test_acquire_token_error(): + with patch("gsap_broker.intune.graph_client.msal") as m: + app_instance = MagicMock() + app_instance.acquire_token_for_client.return_value = { + "error": "invalid_client", + "error_description": "Bad credentials", + } + m.ConfidentialClientApplication.return_value = app_instance + + graph = GraphClient( + tenant_id="t", client_id="c", client_secret="s" + ) + with pytest.raises(RuntimeError, match="Bad credentials"): + await graph.acquire_token() + + +@pytest.mark.asyncio +async def test_get_includes_auth_header(graph): + """GET request includes Bearer token in Authorization header.""" + import httpx + + with patch("gsap_broker.intune.graph_client.httpx.AsyncClient") as mock_http: + mock_response = MagicMock() + mock_response.json.return_value = {"value": []} + mock_response.raise_for_status = MagicMock() + + ctx_manager = AsyncMock() + ctx_manager.__aenter__.return_value.get = AsyncMock(return_value=mock_response) + mock_http.return_value = ctx_manager + + result = await graph.get("/test/path", params={"$top": "10"}) + + call_args = ctx_manager.__aenter__.return_value.get.call_args + headers = call_args.kwargs.get("headers", {}) + assert headers["Authorization"] == "Bearer test-token-abc" + assert result == {"value": []}