Skip to content

Commit 4b55db6

Browse files
committed
Add unit tests for the graph client
1 parent c9c9d2a commit 4b55db6

File tree

3 files changed

+118
-20
lines changed

3 files changed

+118
-20
lines changed

msgraphcore/graph_client.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@
1010

1111
class GraphClient:
1212
"""Constructs a custom HTTPClient to be used for requests against Microsoft Graph"""
13+
__instance = None
14+
15+
def __new__(cls, *args, **kwargs):
16+
if not GraphClient.__instance:
17+
GraphClient.__instance = object.__new__(cls)
18+
return GraphClient.__instance
19+
1320
def __init__(self, **kwargs):
1421
"""
1522
Class constructor that accepts a session object and kwargs to
1623
be passed to the HTTPClientFactory
1724
"""
18-
self.graph_session = get_graph_session(**kwargs)
25+
self.graph_session = self.get_graph_session(**kwargs)
1926

2027
@middleware_control.get_middleware_options
2128
def get(self, url: str, **kwargs):
@@ -76,25 +83,23 @@ def _graph_url(self, url: str) -> str:
7683
"""
7784
return self.graph_session.base_url + url if (url[0] == '/') else url
7885

86+
@staticmethod
87+
def get_graph_session(**kwargs):
88+
"""Method to always return a single instance of a HTTP Client"""
7989

80-
_INSTANCE = None
81-
82-
83-
def get_graph_session(**kwargs):
84-
"""Method to always return a single instance of a HTTP Client"""
85-
86-
global _INSTANCE
90+
session = None
8791

88-
credential = kwargs.get('credential')
89-
middleware = kwargs.get('middleware')
92+
credential = kwargs.get('credential')
93+
middleware = kwargs.get('middleware')
9094

91-
if credential and middleware:
92-
raise Exception("Invalid parameters! Both TokenCredential and middleware cannot be passed")
93-
if not credential and not middleware:
94-
raise ValueError("Invalid parameters!. Missing TokenCredential or middleware")
95-
if _INSTANCE is None:
95+
if credential and middleware:
96+
raise Exception(
97+
"Invalid parameters! Both TokenCredential and middleware cannot be passed"
98+
)
99+
if not credential and not middleware:
100+
raise ValueError("Invalid parameters!. Missing TokenCredential or middleware")
96101
if credential:
97-
_INSTANCE = HTTPClientFactory(**kwargs).create_with_default_middleware(credential)
102+
session = HTTPClientFactory(**kwargs).create_with_default_middleware(credential)
98103
elif middleware:
99-
_INSTANCE = HTTPClientFactory(**kwargs).create_with_custom_middleware(middleware)
100-
return _INSTANCE
104+
session = HTTPClientFactory(**kwargs).create_with_custom_middleware(middleware)
105+
return session

tests/unit/test_client_factory.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import ssl
2-
31
import pytest
42
from requests import Session
53
from requests.adapters import HTTPAdapter

tests/unit/test_graph_client.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import pytest
2+
import responses
3+
from requests import Session
4+
from requests.adapters import HTTPAdapter
5+
6+
from msgraphcore.constants import CONNECTION_TIMEOUT, REQUEST_TIMEOUT
7+
from msgraphcore.enums import APIVersion, NationalClouds
8+
from msgraphcore.graph_client import GraphClient
9+
from msgraphcore.middleware.authorization import AuthorizationHandler
10+
from msgraphcore.middleware.middleware import BaseMiddleware, MiddlewarePipeline
11+
12+
13+
def test_graph_client_with_default_middleware():
14+
"""
15+
Test creating a graph client with default middleware works as expected
16+
"""
17+
credential = _CustomTokenCredential()
18+
client = GraphClient(credential=credential)
19+
20+
assert isinstance(client.graph_session, Session)
21+
assert isinstance(client.graph_session.get_adapter('https://'), HTTPAdapter)
22+
assert client.graph_session.base_url == NationalClouds.Global + '/' + APIVersion.v1
23+
24+
25+
def test_graph_client_with_custom_middleware():
26+
"""
27+
Test creating a graph client with custom middleware works as expected
28+
"""
29+
credential = _CustomTokenCredential()
30+
middleware = [
31+
AuthorizationHandler(credential),
32+
]
33+
client = GraphClient(middleware=middleware)
34+
35+
assert isinstance(client.graph_session, Session)
36+
assert isinstance(client.graph_session.get_adapter('https://'), HTTPAdapter)
37+
assert client.graph_session.base_url == NationalClouds.Global + '/' + APIVersion.v1
38+
39+
40+
def test_graph_client_with_custom_configuration():
41+
"""
42+
Test creating a graph client with custom middleware works as expected
43+
"""
44+
credential = _CustomTokenCredential()
45+
client = GraphClient(
46+
credential=credential, api_version=APIVersion.beta, cloud=NationalClouds.China
47+
)
48+
49+
assert client.graph_session.base_url == NationalClouds.China + '/' + APIVersion.beta
50+
51+
52+
def test_graph_client_uses_same_session():
53+
"""
54+
Test graph client is a singleton class and uses the same session
55+
"""
56+
credential = _CustomTokenCredential()
57+
client = GraphClient(credential=credential)
58+
59+
client2 = GraphClient(credential=credential)
60+
assert client is client2
61+
62+
63+
@responses.activate
64+
def test_graph_client_builds_graph_urls():
65+
"""
66+
Test that the graph client builds full urls if supplied with partial
67+
"""
68+
credential = _CustomTokenCredential()
69+
client = GraphClient(credential=credential)
70+
graph_url = client.graph_session.base_url + '/me'
71+
72+
responses.add(responses.GET, graph_url, status=200)
73+
74+
client.get('/me')
75+
assert graph_url == responses.calls[0].request.url
76+
77+
78+
@responses.activate
79+
def test_does_not_build_graph_urls_for_full_urls():
80+
"""
81+
Test that the graph client builds full urls if supplied with partial
82+
"""
83+
other_url = 'https://microsoft.com/'
84+
responses.add(responses.GET, other_url, status=200)
85+
86+
credential = _CustomTokenCredential()
87+
client = GraphClient(credential=credential)
88+
client.get(other_url)
89+
request_url = responses.calls[0].request.url
90+
assert other_url == request_url
91+
92+
93+
class _CustomTokenCredential:
94+
def get_token(self, scopes):
95+
return ['{token:https://graph.microsoft.com/}']

0 commit comments

Comments
 (0)