2626from test_shared_cache_credential import get_account_event , populated_cache
2727
2828
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+
2934@pytest .mark .asyncio
3035async def test_no_scopes ():
3136 """The credential should raise when get_token is called with no scopes"""
@@ -37,39 +42,53 @@ async def test_no_scopes():
3742
3843@pytest .mark .asyncio
3944async 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 )
4149 credential = SharedTokenCacheCredential (
4250 _cache = populated_cache (get_account_event ("test@user" , "uid" , "utid" )), transport = transport
4351 )
4452
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+
4556 await credential .close ()
4657
4758 assert transport .__aexit__ .call_count == 1
4859
4960
5061@pytest .mark .asyncio
5162async 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 )
5367 credential = SharedTokenCacheCredential (
5468 _cache = populated_cache (get_account_event ("test@user" , "uid" , "utid" )), transport = transport
5569 )
5670
71+ # async with before initialization: credential should call aexit but not aenter
5772 async with credential :
58- assert transport . __aenter__ . call_count == 1
73+ await credential . get_token ( "scope" )
5974
60- assert transport .__aenter__ .call_count == 1
75+ assert transport .__aenter__ .call_count == 0
6176 assert transport .__aexit__ .call_count == 1
6277
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+
6384
6485@pytest .mark .asyncio
6586async def test_context_manager_no_cache ():
6687 """the credential shouldn't open/close sessions when instantiated in an environment with no cache"""
6788
6889 transport = AsyncMockTransport ()
6990
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 )):
7392 credential = SharedTokenCacheCredential (transport = transport )
7493
7594 async with credential :
@@ -666,14 +685,20 @@ async def test_auth_record_multiple_accounts_for_username():
666685 assert token .token == expected_access_token
667686
668687
669- def test_authentication_record_authenticating_tenant ():
688+ @pytest .mark .asyncio
689+ async def test_authentication_record_authenticating_tenant ():
670690 """when given a record and 'tenant_id', the credential should authenticate in the latter"""
671691
672692 expected_tenant_id = "tenant-id"
673693 record = AuthenticationRecord ("not- " + expected_tenant_id , "..." , "..." , "..." , "..." )
674694
675695 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" )
677702
678703 assert get_auth_client .call_count == 1
679704 _ , kwargs = get_auth_client .call_args
@@ -713,3 +738,20 @@ async def test_allow_unencrypted_cache():
713738
714739 msal_extensions_patch .stop ()
715740 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