26
26
from test_shared_cache_credential import get_account_event , populated_cache
27
27
28
28
29
+ def test_supported ():
30
+ """the cache is supported on Linux, macOS, Windows, so this should pass unless you're developing on e.g. FreeBSD"""
31
+ assert SharedTokenCacheCredential .supported ()
32
+
33
+
29
34
@pytest .mark .asyncio
30
35
async def test_no_scopes ():
31
36
"""The credential should raise when get_token is called with no scopes"""
@@ -37,39 +42,53 @@ async def test_no_scopes():
37
42
38
43
@pytest .mark .asyncio
39
44
async def test_close ():
40
- transport = AsyncMockTransport ()
45
+ async def send (* _ , ** __ ):
46
+ return mock_response (json_payload = build_aad_response (access_token = "**" ))
47
+
48
+ transport = AsyncMockTransport (send = send )
41
49
credential = SharedTokenCacheCredential (
42
50
_cache = populated_cache (get_account_event ("test@user" , "uid" , "utid" )), transport = transport
43
51
)
44
52
53
+ # the credential doesn't open a transport session before one is needed, so we send a request
54
+ await credential .get_token ("scope" )
55
+
45
56
await credential .close ()
46
57
47
58
assert transport .__aexit__ .call_count == 1
48
59
49
60
50
61
@pytest .mark .asyncio
51
62
async def test_context_manager ():
52
- transport = AsyncMockTransport ()
63
+ async def send (* _ , ** __ ):
64
+ return mock_response (json_payload = build_aad_response (access_token = "**" ))
65
+
66
+ transport = AsyncMockTransport (send = send )
53
67
credential = SharedTokenCacheCredential (
54
68
_cache = populated_cache (get_account_event ("test@user" , "uid" , "utid" )), transport = transport
55
69
)
56
70
71
+ # async with before initialization: credential should call aexit but not aenter
57
72
async with credential :
58
- assert transport . __aenter__ . call_count == 1
73
+ await credential . get_token ( "scope" )
59
74
60
- assert transport .__aenter__ .call_count == 1
75
+ assert transport .__aenter__ .call_count == 0
61
76
assert transport .__aexit__ .call_count == 1
62
77
78
+ # async with after initialization: credential should call aenter and aexit
79
+ async with credential :
80
+ await credential .get_token ("scope" )
81
+ assert transport .__aenter__ .call_count == 1
82
+ assert transport .__aexit__ .call_count == 2
83
+
63
84
64
85
@pytest .mark .asyncio
65
86
async def test_context_manager_no_cache ():
66
87
"""the credential shouldn't open/close sessions when instantiated in an environment with no cache"""
67
88
68
89
transport = AsyncMockTransport ()
69
90
70
- with patch (
71
- "azure.identity._internal.shared_token_cache.load_user_cache" , Mock (side_effect = NotImplementedError )
72
- ):
91
+ with patch ("azure.identity._internal.shared_token_cache.load_user_cache" , Mock (side_effect = NotImplementedError )):
73
92
credential = SharedTokenCacheCredential (transport = transport )
74
93
75
94
async with credential :
@@ -666,14 +685,20 @@ async def test_auth_record_multiple_accounts_for_username():
666
685
assert token .token == expected_access_token
667
686
668
687
669
- def test_authentication_record_authenticating_tenant ():
688
+ @pytest .mark .asyncio
689
+ async def test_authentication_record_authenticating_tenant ():
670
690
"""when given a record and 'tenant_id', the credential should authenticate in the latter"""
671
691
672
692
expected_tenant_id = "tenant-id"
673
693
record = AuthenticationRecord ("not- " + expected_tenant_id , "..." , "..." , "..." , "..." )
674
694
675
695
with patch .object (SharedTokenCacheCredential , "_get_auth_client" ) as get_auth_client :
676
- SharedTokenCacheCredential (authentication_record = record , _cache = TokenCache (), tenant_id = expected_tenant_id )
696
+ credential = SharedTokenCacheCredential (
697
+ authentication_record = record , _cache = TokenCache (), tenant_id = expected_tenant_id
698
+ )
699
+ with pytest .raises (CredentialUnavailableError ):
700
+ # this raises because the cache is empty
701
+ await credential .get_token ("scope" )
677
702
678
703
assert get_auth_client .call_count == 1
679
704
_ , kwargs = get_auth_client .call_args
@@ -713,3 +738,20 @@ async def test_allow_unencrypted_cache():
713
738
714
739
msal_extensions_patch .stop ()
715
740
platform_patch .stop ()
741
+
742
+
743
+ @pytest .mark .asyncio
744
+ async def test_initialization ():
745
+ """the credential should attempt to load the cache only once, when it's first needed"""
746
+
747
+ with patch ("azure.identity._internal.persistent_cache._load_persistent_cache" ) as mock_cache_loader :
748
+ mock_cache_loader .side_effect = Exception ("it didn't work" )
749
+
750
+ credential = SharedTokenCacheCredential ()
751
+ assert mock_cache_loader .call_count == 0
752
+
753
+ for _ in range (2 ):
754
+ with pytest .raises (CredentialUnavailableError ):
755
+ await credential .get_token ("scope" )
756
+ assert mock_cache_loader .call_count == 1
757
+
0 commit comments