test: add Graph API client unit tests
Verifies MSAL token acquisition, error handling, and Authorization header inclusion in Graph API requests. Signed-off-by: Tyler King <tking@guildhouse.dev>
This commit is contained in:
parent
e24a87db6f
commit
6cfe5f7d9a
1 changed files with 74 additions and 0 deletions
74
tests/test_graph_client.py
Normal file
74
tests/test_graph_client.py
Normal file
|
|
@ -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": []}
|
||||||
Loading…
Reference in a new issue