@@ -69,9 +69,8 @@ async def test_aget_google_id_token_success_first_call(
69
69
assert auth_methods ._token_cache ["token" ] == MOCK_ID_TOKEN
70
70
assert auth_methods ._token_cache ["expires_at" ] == MOCK_EXPIRY_DATETIME
71
71
72
- @pytest .mark .asyncio
73
72
@patch ("toolbox_core.auth_methods.google.auth.default" )
74
- async def test_aget_google_id_token_success_uses_cache (self , mock_get_token ):
73
+ async def test_aget_google_id_token_success_uses_cache (self , mock_default ):
75
74
"""Tests that subsequent calls use the cached token if valid."""
76
75
# Prime the cache with a valid token
77
76
auth_methods ._token_cache ["token" ] = MOCK_ID_TOKEN
@@ -81,8 +80,8 @@ async def test_aget_google_id_token_success_uses_cache(self, mock_get_token):
81
80
82
81
token = await auth_methods .aget_google_id_token (MOCK_AUDIENCE )
83
82
84
- # The underlying sync function should not be called if cache is valid
85
- mock_get_token .assert_not_called ()
83
+ # The underlying auth function should not be called if cache is valid
84
+ mock_default .assert_not_called ()
86
85
assert token == f"{ auth_methods .BEARER_TOKEN_PREFIX } { MOCK_ID_TOKEN } "
87
86
88
87
@patch ("toolbox_core.auth_methods.id_token.verify_oauth2_token" )
@@ -112,6 +111,23 @@ async def test_aget_google_id_token_refreshes_expired_cache(
112
111
assert token == f"{ auth_methods .BEARER_TOKEN_PREFIX } { MOCK_ID_TOKEN } "
113
112
assert auth_methods ._token_cache ["token" ] == MOCK_ID_TOKEN
114
113
114
+ @patch ("toolbox_core.auth_methods.id_token.fetch_id_token" )
115
+ @patch (
116
+ "toolbox_core.auth_methods.google.auth.default" ,
117
+ return_value = (MagicMock (id_token = None ), MOCK_PROJECT_ID ),
118
+ )
119
+ async def test_aget_raises_if_no_audience_and_no_local_token (
120
+ self , mock_default , mock_fetch
121
+ ):
122
+ """Tests that the async function propagates the missing audience exception."""
123
+ error_msg = "You are not authenticating using User Credentials."
124
+ with pytest .raises (Exception , match = error_msg ):
125
+ # Call without audience to trigger the error path
126
+ await auth_methods .aget_google_id_token ()
127
+
128
+ mock_default .assert_called_once ()
129
+ mock_fetch .assert_not_called ()
130
+
115
131
116
132
class TestSyncAuthMethods :
117
133
"""Tests for synchronous Google ID token fetching."""
@@ -196,3 +212,21 @@ def test_get_google_id_token_validation_failure(
196
212
197
213
# Verify cache is cleared on validation failure
198
214
assert auth_methods ._token_cache ["token" ] is None
215
+
216
+ @patch ("toolbox_core.auth_methods.id_token.fetch_id_token" )
217
+ @patch (
218
+ "toolbox_core.auth_methods.google.auth.default" ,
219
+ # Simulate credentials that DON'T have a pre-existing id_token
220
+ return_value = (MagicMock (id_token = None ), MOCK_PROJECT_ID ),
221
+ )
222
+ def test_get_raises_if_no_audience_and_no_local_token (
223
+ self , mock_default , mock_fetch
224
+ ):
225
+ """Tests exception is raised if audience is required but not provided."""
226
+ error_msg = "You are not authenticating using User Credentials."
227
+ with pytest .raises (Exception , match = error_msg ):
228
+ # Call without an audience to trigger the error path
229
+ auth_methods .get_google_id_token ()
230
+
231
+ mock_default .assert_called_once ()
232
+ mock_fetch .assert_not_called ()
0 commit comments