google-adk 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. google/adk/agents/run_config.py +4 -0
  2. google/adk/auth/auth_preprocessor.py +19 -16
  3. google/adk/cli/agent_graph.py +31 -5
  4. google/adk/cli/browser/index.html +1 -1
  5. google/adk/cli/browser/{main-XUU6OGCC.js → main-CU22TRPI.js} +30 -30
  6. google/adk/cli/cli.py +8 -8
  7. google/adk/cli/cli_deploy.py +2 -4
  8. google/adk/cli/cli_tools_click.py +57 -12
  9. google/adk/cli/fast_api.py +19 -9
  10. google/adk/flows/llm_flows/contents.py +21 -1
  11. google/adk/flows/llm_flows/functions.py +3 -1
  12. google/adk/models/google_llm.py +0 -1
  13. google/adk/runners.py +13 -2
  14. google/adk/version.py +1 -1
  15. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/METADATA +4 -2
  16. google_adk-0.0.4.dist-info/RECORD +175 -0
  17. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/WHEEL +1 -1
  18. google/adk/cli/media_streamer/__init__.py +0 -19
  19. google/adk/cli/media_streamer/index.html +0 -228
  20. google/adk/tests/__init__.py +0 -14
  21. google/adk/tests/integration/.env.example +0 -10
  22. google/adk/tests/integration/__init__.py +0 -18
  23. google/adk/tests/integration/conftest.py +0 -119
  24. google/adk/tests/integration/fixture/__init__.py +0 -14
  25. google/adk/tests/integration/fixture/agent_with_config/__init__.py +0 -15
  26. google/adk/tests/integration/fixture/agent_with_config/agent.py +0 -88
  27. google/adk/tests/integration/fixture/callback_agent/__init__.py +0 -15
  28. google/adk/tests/integration/fixture/callback_agent/agent.py +0 -105
  29. google/adk/tests/integration/fixture/context_update_test/OWNERS +0 -1
  30. google/adk/tests/integration/fixture/context_update_test/__init__.py +0 -15
  31. google/adk/tests/integration/fixture/context_update_test/agent.py +0 -43
  32. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +0 -582
  33. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +0 -15
  34. google/adk/tests/integration/fixture/context_variable_agent/agent.py +0 -115
  35. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +0 -15
  36. google/adk/tests/integration/fixture/customer_support_ma/agent.py +0 -172
  37. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +0 -15
  38. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +0 -338
  39. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +0 -69
  40. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +0 -6
  41. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +0 -15
  42. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +0 -182
  43. google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +0 -243
  44. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +0 -190
  45. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +0 -15
  46. google/adk/tests/integration/fixture/hello_world_agent/agent.py +0 -95
  47. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +0 -24
  48. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +0 -6
  49. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +0 -15
  50. google/adk/tests/integration/fixture/home_automation_agent/agent.py +0 -304
  51. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +0 -5
  52. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +0 -5
  53. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +0 -5
  54. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +0 -18
  55. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +0 -17
  56. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +0 -6
  57. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +0 -18
  58. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +0 -17
  59. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +0 -5
  60. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +0 -5
  61. google/adk/tests/integration/fixture/tool_agent/__init__.py +0 -15
  62. google/adk/tests/integration/fixture/tool_agent/agent.py +0 -218
  63. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  64. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +0 -15
  65. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +0 -110
  66. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +0 -13
  67. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +0 -5
  68. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +0 -13
  69. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +0 -5
  70. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +0 -7
  71. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +0 -19
  72. google/adk/tests/integration/models/__init__.py +0 -14
  73. google/adk/tests/integration/models/test_google_llm.py +0 -65
  74. google/adk/tests/integration/test_callback.py +0 -70
  75. google/adk/tests/integration/test_context_variable.py +0 -67
  76. google/adk/tests/integration/test_evalute_agent_in_fixture.py +0 -76
  77. google/adk/tests/integration/test_multi_agent.py +0 -28
  78. google/adk/tests/integration/test_multi_turn.py +0 -42
  79. google/adk/tests/integration/test_single_agent.py +0 -23
  80. google/adk/tests/integration/test_sub_agent.py +0 -26
  81. google/adk/tests/integration/test_system_instruction.py +0 -177
  82. google/adk/tests/integration/test_tools.py +0 -287
  83. google/adk/tests/integration/test_with_test_file.py +0 -34
  84. google/adk/tests/integration/tools/__init__.py +0 -14
  85. google/adk/tests/integration/utils/__init__.py +0 -16
  86. google/adk/tests/integration/utils/asserts.py +0 -75
  87. google/adk/tests/integration/utils/test_runner.py +0 -97
  88. google/adk/tests/unittests/__init__.py +0 -14
  89. google/adk/tests/unittests/agents/__init__.py +0 -14
  90. google/adk/tests/unittests/agents/test_base_agent.py +0 -407
  91. google/adk/tests/unittests/agents/test_langgraph_agent.py +0 -191
  92. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +0 -138
  93. google/adk/tests/unittests/agents/test_llm_agent_fields.py +0 -231
  94. google/adk/tests/unittests/agents/test_loop_agent.py +0 -136
  95. google/adk/tests/unittests/agents/test_parallel_agent.py +0 -92
  96. google/adk/tests/unittests/agents/test_sequential_agent.py +0 -114
  97. google/adk/tests/unittests/artifacts/__init__.py +0 -14
  98. google/adk/tests/unittests/artifacts/test_artifact_service.py +0 -276
  99. google/adk/tests/unittests/auth/test_auth_handler.py +0 -575
  100. google/adk/tests/unittests/conftest.py +0 -73
  101. google/adk/tests/unittests/fast_api/__init__.py +0 -14
  102. google/adk/tests/unittests/fast_api/test_fast_api.py +0 -269
  103. google/adk/tests/unittests/flows/__init__.py +0 -14
  104. google/adk/tests/unittests/flows/llm_flows/__init__.py +0 -14
  105. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +0 -142
  106. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +0 -311
  107. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +0 -244
  108. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +0 -346
  109. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +0 -93
  110. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +0 -258
  111. google/adk/tests/unittests/flows/llm_flows/test_identity.py +0 -66
  112. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +0 -164
  113. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +0 -142
  114. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +0 -46
  115. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +0 -269
  116. google/adk/tests/unittests/models/__init__.py +0 -14
  117. google/adk/tests/unittests/models/test_google_llm.py +0 -224
  118. google/adk/tests/unittests/models/test_litellm.py +0 -804
  119. google/adk/tests/unittests/models/test_models.py +0 -60
  120. google/adk/tests/unittests/sessions/__init__.py +0 -14
  121. google/adk/tests/unittests/sessions/test_session_service.py +0 -227
  122. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +0 -246
  123. google/adk/tests/unittests/streaming/__init__.py +0 -14
  124. google/adk/tests/unittests/streaming/test_streaming.py +0 -50
  125. google/adk/tests/unittests/tools/__init__.py +0 -14
  126. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +0 -499
  127. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +0 -204
  128. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +0 -600
  129. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +0 -630
  130. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +0 -345
  131. google/adk/tests/unittests/tools/google_api_tool/__init__.py +0 -13
  132. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +0 -657
  133. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +0 -145
  134. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +0 -68
  135. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +0 -153
  136. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +0 -196
  137. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +0 -573
  138. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +0 -436
  139. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +0 -1367
  140. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +0 -628
  141. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +0 -139
  142. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +0 -406
  143. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +0 -966
  144. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +0 -201
  145. google/adk/tests/unittests/tools/retrieval/__init__.py +0 -14
  146. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +0 -147
  147. google/adk/tests/unittests/tools/test_agent_tool.py +0 -167
  148. google/adk/tests/unittests/tools/test_base_tool.py +0 -141
  149. google/adk/tests/unittests/tools/test_build_function_declaration.py +0 -277
  150. google/adk/tests/unittests/utils.py +0 -304
  151. google_adk-0.0.2.dist-info/RECORD +0 -308
  152. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/entry_points.txt +0 -0
  153. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info/licenses}/LICENSE +0 -0
@@ -1,145 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- """Unit tests for AutoAuthCredentialExchanger."""
16
-
17
- from typing import Dict
18
- from typing import Optional
19
- from typing import Type
20
- from unittest.mock import MagicMock
21
-
22
- from google.adk.auth.auth_credential import AuthCredential
23
- from google.adk.auth.auth_credential import AuthCredentialTypes
24
- from google.adk.auth.auth_schemes import AuthScheme
25
- from google.adk.tools.openapi_tool.auth.credential_exchangers.auto_auth_credential_exchanger import AutoAuthCredentialExchanger
26
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import BaseAuthCredentialExchanger
27
- from google.adk.tools.openapi_tool.auth.credential_exchangers.oauth2_exchanger import OAuth2CredentialExchanger
28
- from google.adk.tools.openapi_tool.auth.credential_exchangers.service_account_exchanger import ServiceAccountCredentialExchanger
29
- import pytest
30
-
31
-
32
- class MockCredentialExchanger(BaseAuthCredentialExchanger):
33
- """Mock credential exchanger for testing."""
34
-
35
- def exchange_credential(
36
- self,
37
- auth_scheme: AuthScheme,
38
- auth_credential: Optional[AuthCredential] = None,
39
- ) -> AuthCredential:
40
- """Mock exchange credential method."""
41
- return auth_credential
42
-
43
-
44
- @pytest.fixture
45
- def auto_exchanger():
46
- """Fixture for creating an AutoAuthCredentialExchanger instance."""
47
- return AutoAuthCredentialExchanger()
48
-
49
-
50
- @pytest.fixture
51
- def auth_scheme():
52
- """Fixture for creating a mock AuthScheme instance."""
53
- scheme = MagicMock(spec=AuthScheme)
54
- return scheme
55
-
56
-
57
- def test_init_with_custom_exchangers():
58
- """Test initialization with custom exchangers."""
59
- custom_exchangers: Dict[str, Type[BaseAuthCredentialExchanger]] = {
60
- AuthCredentialTypes.API_KEY: MockCredentialExchanger
61
- }
62
-
63
- auto_exchanger = AutoAuthCredentialExchanger(
64
- custom_exchangers=custom_exchangers
65
- )
66
-
67
- assert (
68
- auto_exchanger.exchangers[AuthCredentialTypes.API_KEY]
69
- == MockCredentialExchanger
70
- )
71
- assert (
72
- auto_exchanger.exchangers[AuthCredentialTypes.OPEN_ID_CONNECT]
73
- == OAuth2CredentialExchanger
74
- )
75
-
76
-
77
- def test_exchange_credential_no_auth_credential(auto_exchanger, auth_scheme):
78
- """Test exchange_credential with no auth_credential."""
79
-
80
- assert auto_exchanger.exchange_credential(auth_scheme, None) is None
81
-
82
-
83
- def test_exchange_credential_no_exchange(auto_exchanger, auth_scheme):
84
- """Test exchange_credential with NoExchangeCredentialExchanger."""
85
- auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
86
-
87
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
88
-
89
- assert result == auth_credential
90
-
91
-
92
- def test_exchange_credential_open_id_connect(auto_exchanger, auth_scheme):
93
- """Test exchange_credential with OpenID Connect scheme."""
94
- auth_credential = AuthCredential(
95
- auth_type=AuthCredentialTypes.OPEN_ID_CONNECT
96
- )
97
- mock_exchanger = MagicMock(spec=OAuth2CredentialExchanger)
98
- mock_exchanger.exchange_credential.return_value = "exchanged_credential"
99
- auto_exchanger.exchangers[AuthCredentialTypes.OPEN_ID_CONNECT] = (
100
- lambda: mock_exchanger
101
- )
102
-
103
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
104
-
105
- assert result == "exchanged_credential"
106
- mock_exchanger.exchange_credential.assert_called_once_with(
107
- auth_scheme, auth_credential
108
- )
109
-
110
-
111
- def test_exchange_credential_service_account(auto_exchanger, auth_scheme):
112
- """Test exchange_credential with Service Account scheme."""
113
- auth_credential = AuthCredential(
114
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT
115
- )
116
- mock_exchanger = MagicMock(spec=ServiceAccountCredentialExchanger)
117
- mock_exchanger.exchange_credential.return_value = "exchanged_credential_sa"
118
- auto_exchanger.exchangers[AuthCredentialTypes.SERVICE_ACCOUNT] = (
119
- lambda: mock_exchanger
120
- )
121
-
122
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
123
-
124
- assert result == "exchanged_credential_sa"
125
- mock_exchanger.exchange_credential.assert_called_once_with(
126
- auth_scheme, auth_credential
127
- )
128
-
129
-
130
- def test_exchange_credential_custom_exchanger(auto_exchanger, auth_scheme):
131
- """Test that exchange_credential calls the correct (custom) exchanger."""
132
- # Use a custom exchanger via the initialization
133
- mock_exchanger = MagicMock(spec=MockCredentialExchanger)
134
- mock_exchanger.exchange_credential.return_value = "custom_credential"
135
- auto_exchanger.exchangers[AuthCredentialTypes.API_KEY] = (
136
- lambda: mock_exchanger
137
- )
138
- auth_credential = AuthCredential(auth_type=AuthCredentialTypes.API_KEY)
139
-
140
- result = auto_exchanger.exchange_credential(auth_scheme, auth_credential)
141
-
142
- assert result == "custom_credential"
143
- mock_exchanger.exchange_credential.assert_called_once_with(
144
- auth_scheme, auth_credential
145
- )
@@ -1,68 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- """Tests for the BaseAuthCredentialExchanger class."""
16
-
17
- from typing import Optional
18
- from unittest.mock import MagicMock
19
-
20
- from google.adk.auth.auth_credential import AuthCredential
21
- from google.adk.auth.auth_credential import AuthCredentialTypes
22
- from google.adk.auth.auth_schemes import AuthScheme
23
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
24
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import BaseAuthCredentialExchanger
25
- import pytest
26
-
27
-
28
- class MockAuthCredentialExchanger(BaseAuthCredentialExchanger):
29
-
30
- def exchange_credential(
31
- self,
32
- auth_scheme: AuthScheme,
33
- auth_credential: Optional[AuthCredential] = None,
34
- ) -> AuthCredential:
35
- return AuthCredential(token="some-token")
36
-
37
-
38
- class TestBaseAuthCredentialExchanger:
39
- """Tests for the BaseAuthCredentialExchanger class."""
40
-
41
- @pytest.fixture
42
- def base_exchanger(self):
43
- return BaseAuthCredentialExchanger()
44
-
45
- @pytest.fixture
46
- def auth_scheme(self):
47
- scheme = MagicMock(spec=AuthScheme)
48
- scheme.type = "apiKey"
49
- scheme.name = "x-api-key"
50
- return scheme
51
-
52
- def test_exchange_credential_not_implemented(
53
- self, base_exchanger, auth_scheme
54
- ):
55
- auth_credential = AuthCredential(
56
- auth_type=AuthCredentialTypes.API_KEY, token="some-token"
57
- )
58
- with pytest.raises(NotImplementedError) as exc_info:
59
- base_exchanger.exchange_credential(auth_scheme, auth_credential)
60
- assert "Subclasses must implement exchange_credential." in str(
61
- exc_info.value
62
- )
63
-
64
- def test_auth_credential_missing_error(self):
65
- error_message = "Test missing credential"
66
- error = AuthCredentialMissingError(error_message)
67
- # assert error.message == error_message
68
- assert str(error) == error_message
@@ -1,153 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- """Tests for OAuth2CredentialExchanger."""
16
-
17
- import copy
18
- from unittest.mock import MagicMock
19
-
20
- from google.adk.auth.auth_credential import AuthCredential
21
- from google.adk.auth.auth_credential import AuthCredentialTypes
22
- from google.adk.auth.auth_credential import OAuth2Auth
23
- from google.adk.auth.auth_schemes import AuthSchemeType
24
- from google.adk.auth.auth_schemes import OpenIdConnectWithConfig
25
- from google.adk.tools.openapi_tool.auth.credential_exchangers import OAuth2CredentialExchanger
26
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
27
- import pytest
28
-
29
-
30
- @pytest.fixture
31
- def oauth2_exchanger():
32
- return OAuth2CredentialExchanger()
33
-
34
-
35
- @pytest.fixture
36
- def auth_scheme():
37
- openid_config = OpenIdConnectWithConfig(
38
- type_=AuthSchemeType.openIdConnect,
39
- authorization_endpoint="https://example.com/auth",
40
- token_endpoint="https://example.com/token",
41
- scopes=["openid", "profile"],
42
- )
43
- return openid_config
44
-
45
-
46
- def test_check_scheme_credential_type_success(oauth2_exchanger, auth_scheme):
47
- auth_credential = AuthCredential(
48
- auth_type=AuthCredentialTypes.OAUTH2,
49
- oauth2=OAuth2Auth(
50
- client_id="test_client",
51
- client_secret="test_secret",
52
- redirect_uri="http://localhost:8080",
53
- ),
54
- )
55
- # Check that the method does not raise an exception
56
- oauth2_exchanger._check_scheme_credential_type(auth_scheme, auth_credential)
57
-
58
-
59
- def test_check_scheme_credential_type_missing_credential(
60
- oauth2_exchanger, auth_scheme
61
- ):
62
- # Test case: auth_credential is None
63
- with pytest.raises(ValueError) as exc_info:
64
- oauth2_exchanger._check_scheme_credential_type(auth_scheme, None)
65
- assert "auth_credential is empty" in str(exc_info.value)
66
-
67
-
68
- def test_check_scheme_credential_type_invalid_scheme_type(
69
- oauth2_exchanger, auth_scheme: OpenIdConnectWithConfig
70
- ):
71
- """Test case: Invalid AuthSchemeType."""
72
- # Test case: Invalid AuthSchemeType
73
- invalid_scheme = copy.deepcopy(auth_scheme)
74
- invalid_scheme.type_ = AuthSchemeType.apiKey
75
- auth_credential = AuthCredential(
76
- auth_type=AuthCredentialTypes.OAUTH2,
77
- oauth2=OAuth2Auth(
78
- client_id="test_client",
79
- client_secret="test_secret",
80
- redirect_uri="http://localhost:8080",
81
- ),
82
- )
83
- with pytest.raises(ValueError) as exc_info:
84
- oauth2_exchanger._check_scheme_credential_type(
85
- invalid_scheme, auth_credential
86
- )
87
- assert "Invalid security scheme" in str(exc_info.value)
88
-
89
-
90
- def test_check_scheme_credential_type_missing_openid_connect(
91
- oauth2_exchanger, auth_scheme
92
- ):
93
- auth_credential = AuthCredential(
94
- auth_type=AuthCredentialTypes.OAUTH2,
95
- )
96
- with pytest.raises(ValueError) as exc_info:
97
- oauth2_exchanger._check_scheme_credential_type(auth_scheme, auth_credential)
98
- assert "auth_credential is not configured with oauth2" in str(exc_info.value)
99
-
100
-
101
- def test_generate_auth_token_success(
102
- oauth2_exchanger, auth_scheme, monkeypatch
103
- ):
104
- """Test case: Successful generation of access token."""
105
- # Test case: Successful generation of access token
106
- auth_credential = AuthCredential(
107
- auth_type=AuthCredentialTypes.OAUTH2,
108
- oauth2=OAuth2Auth(
109
- client_id="test_client",
110
- client_secret="test_secret",
111
- redirect_uri="http://localhost:8080",
112
- auth_response_uri="https://example.com/callback?code=test_code",
113
- token={"access_token": "test_access_token"},
114
- ),
115
- )
116
- updated_credential = oauth2_exchanger.generate_auth_token(auth_credential)
117
-
118
- assert updated_credential.auth_type == AuthCredentialTypes.HTTP
119
- assert updated_credential.http.scheme == "bearer"
120
- assert updated_credential.http.credentials.token == "test_access_token"
121
-
122
-
123
- def test_exchange_credential_generate_auth_token(
124
- oauth2_exchanger, auth_scheme, monkeypatch
125
- ):
126
- """Test exchange_credential when auth_response_uri is present."""
127
- auth_credential = AuthCredential(
128
- auth_type=AuthCredentialTypes.OAUTH2,
129
- oauth2=OAuth2Auth(
130
- client_id="test_client",
131
- client_secret="test_secret",
132
- redirect_uri="http://localhost:8080",
133
- auth_response_uri="https://example.com/callback?code=test_code",
134
- token={"access_token": "test_access_token"},
135
- ),
136
- )
137
-
138
- updated_credential = oauth2_exchanger.exchange_credential(
139
- auth_scheme, auth_credential
140
- )
141
-
142
- assert updated_credential.auth_type == AuthCredentialTypes.HTTP
143
- assert updated_credential.http.scheme == "bearer"
144
- assert updated_credential.http.credentials.token == "test_access_token"
145
-
146
-
147
- def test_exchange_credential_auth_missing(oauth2_exchanger, auth_scheme):
148
- """Test exchange_credential when auth_credential is missing."""
149
- with pytest.raises(ValueError) as exc_info:
150
- oauth2_exchanger.exchange_credential(auth_scheme, None)
151
- assert "auth_credential is empty. Please create AuthCredential using" in str(
152
- exc_info.value
153
- )
@@ -1,196 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- """Unit tests for the service account credential exchanger."""
16
-
17
- from unittest.mock import MagicMock
18
-
19
- from google.adk.auth.auth_credential import AuthCredential
20
- from google.adk.auth.auth_credential import AuthCredentialTypes
21
- from google.adk.auth.auth_credential import ServiceAccount
22
- from google.adk.auth.auth_credential import ServiceAccountCredential
23
- from google.adk.auth.auth_schemes import AuthScheme
24
- from google.adk.auth.auth_schemes import AuthSchemeType
25
- from google.adk.tools.openapi_tool.auth.credential_exchangers.base_credential_exchanger import AuthCredentialMissingError
26
- from google.adk.tools.openapi_tool.auth.credential_exchangers.service_account_exchanger import ServiceAccountCredentialExchanger
27
- import google.auth
28
- import pytest
29
-
30
-
31
- @pytest.fixture
32
- def service_account_exchanger():
33
- return ServiceAccountCredentialExchanger()
34
-
35
-
36
- @pytest.fixture
37
- def auth_scheme():
38
- scheme = MagicMock(spec=AuthScheme)
39
- scheme.type_ = AuthSchemeType.oauth2
40
- scheme.description = "Google Service Account"
41
- return scheme
42
-
43
-
44
- def test_exchange_credential_success(
45
- service_account_exchanger, auth_scheme, monkeypatch
46
- ):
47
- """Test successful exchange of service account credentials."""
48
- mock_credentials = MagicMock()
49
- mock_credentials.token = "mock_access_token"
50
-
51
- # Mock the from_service_account_info method
52
- mock_from_service_account_info = MagicMock(return_value=mock_credentials)
53
- target_path = (
54
- "google.adk.tools.openapi_tool.auth.credential_exchangers."
55
- "service_account_exchanger.service_account.Credentials."
56
- "from_service_account_info"
57
- )
58
- monkeypatch.setattr(
59
- target_path,
60
- mock_from_service_account_info,
61
- )
62
-
63
- # Mock the refresh method
64
- mock_credentials.refresh = MagicMock()
65
-
66
- # Create a valid AuthCredential with service account info
67
- auth_credential = AuthCredential(
68
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
69
- service_account=ServiceAccount(
70
- service_account_credential=ServiceAccountCredential(
71
- type_="service_account",
72
- project_id="your_project_id",
73
- private_key_id="your_private_key_id",
74
- private_key="-----BEGIN PRIVATE KEY-----...",
75
- client_email="...@....iam.gserviceaccount.com",
76
- client_id="your_client_id",
77
- auth_uri="https://accounts.google.com/o/oauth2/auth",
78
- token_uri="https://oauth2.googleapis.com/token",
79
- auth_provider_x509_cert_url=(
80
- "https://www.googleapis.com/oauth2/v1/certs"
81
- ),
82
- client_x509_cert_url=(
83
- "https://www.googleapis.com/robot/v1/metadata/x509/..."
84
- ),
85
- universe_domain="googleapis.com",
86
- ),
87
- scopes=["https://www.googleapis.com/auth/cloud-platform"],
88
- ),
89
- )
90
-
91
- result = service_account_exchanger.exchange_credential(
92
- auth_scheme, auth_credential
93
- )
94
-
95
- assert result.auth_type == AuthCredentialTypes.HTTP
96
- assert result.http.scheme == "bearer"
97
- assert result.http.credentials.token == "mock_access_token"
98
- mock_from_service_account_info.assert_called_once()
99
- mock_credentials.refresh.assert_called_once()
100
-
101
-
102
- def test_exchange_credential_use_default_credential_success(
103
- service_account_exchanger, auth_scheme, monkeypatch
104
- ):
105
- """Test successful exchange of service account credentials using default credential."""
106
- mock_credentials = MagicMock()
107
- mock_credentials.token = "mock_access_token"
108
- mock_google_auth_default = MagicMock(
109
- return_value=(mock_credentials, "test_project")
110
- )
111
- monkeypatch.setattr(google.auth, "default", mock_google_auth_default)
112
-
113
- auth_credential = AuthCredential(
114
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
115
- service_account=ServiceAccount(
116
- use_default_credential=True,
117
- scopes=["https://www.googleapis.com/auth/cloud-platform"],
118
- ),
119
- )
120
-
121
- result = service_account_exchanger.exchange_credential(
122
- auth_scheme, auth_credential
123
- )
124
-
125
- assert result.auth_type == AuthCredentialTypes.HTTP
126
- assert result.http.scheme == "bearer"
127
- assert result.http.credentials.token == "mock_access_token"
128
- mock_google_auth_default.assert_called_once()
129
- mock_credentials.refresh.assert_called_once()
130
-
131
-
132
- def test_exchange_credential_missing_auth_credential(
133
- service_account_exchanger, auth_scheme
134
- ):
135
- """Test missing auth credential during exchange."""
136
- with pytest.raises(AuthCredentialMissingError) as exc_info:
137
- service_account_exchanger.exchange_credential(auth_scheme, None)
138
- assert "Service account credentials are missing" in str(exc_info.value)
139
-
140
-
141
- def test_exchange_credential_missing_service_account_info(
142
- service_account_exchanger, auth_scheme
143
- ):
144
- """Test missing service account info during exchange."""
145
- auth_credential = AuthCredential(
146
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
147
- )
148
- with pytest.raises(AuthCredentialMissingError) as exc_info:
149
- service_account_exchanger.exchange_credential(auth_scheme, auth_credential)
150
- assert "Service account credentials are missing" in str(exc_info.value)
151
-
152
-
153
- def test_exchange_credential_exchange_failure(
154
- service_account_exchanger, auth_scheme, monkeypatch
155
- ):
156
- """Test failure during service account token exchange."""
157
- mock_from_service_account_info = MagicMock(
158
- side_effect=Exception("Failed to load credentials")
159
- )
160
- target_path = (
161
- "google.adk.tools.openapi_tool.auth.credential_exchangers."
162
- "service_account_exchanger.service_account.Credentials."
163
- "from_service_account_info"
164
- )
165
- monkeypatch.setattr(
166
- target_path,
167
- mock_from_service_account_info,
168
- )
169
-
170
- auth_credential = AuthCredential(
171
- auth_type=AuthCredentialTypes.SERVICE_ACCOUNT,
172
- service_account=ServiceAccount(
173
- service_account_credential=ServiceAccountCredential(
174
- type_="service_account",
175
- project_id="your_project_id",
176
- private_key_id="your_private_key_id",
177
- private_key="-----BEGIN PRIVATE KEY-----...",
178
- client_email="...@....iam.gserviceaccount.com",
179
- client_id="your_client_id",
180
- auth_uri="https://accounts.google.com/o/oauth2/auth",
181
- token_uri="https://oauth2.googleapis.com/token",
182
- auth_provider_x509_cert_url=(
183
- "https://www.googleapis.com/oauth2/v1/certs"
184
- ),
185
- client_x509_cert_url=(
186
- "https://www.googleapis.com/robot/v1/metadata/x509/..."
187
- ),
188
- universe_domain="googleapis.com",
189
- ),
190
- scopes=["https://www.googleapis.com/auth/cloud-platform"],
191
- ),
192
- )
193
- with pytest.raises(AuthCredentialMissingError) as exc_info:
194
- service_account_exchanger.exchange_credential(auth_scheme, auth_credential)
195
- assert "Failed to exchange service account token" in str(exc_info.value)
196
- mock_from_service_account_info.assert_called_once()