# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for the ParameterManagerClient.""" import json from unittest.mock import MagicMock from unittest.mock import patch from google.api_core.gapic_v1 import client_info from google.oauth2.credentials import Credentials import pytest pytest.importorskip("google.cloud.parametermanager_v1") from google.adk.integrations.parameter_manager.parameter_client import ParameterManagerClient from google.adk.integrations.parameter_manager.parameter_client import USER_AGENT class TestParameterManagerClient: """Tests for the ParameterManagerClient class.""" @patch("google.cloud.parametermanager_v1.ParameterManagerClient") @patch( "google.adk.integrations.parameter_manager.parameter_client.default_service_credential" ) def test_init_with_default_credentials( self, mock_default_service_credential, mock_pm_client_class ): """Test initialization with default credentials.""" # Setup mock_credentials = MagicMock() mock_default_service_credential.return_value = ( mock_credentials, "test-project", ) # Execute client = ParameterManagerClient() # Verify mock_default_service_credential.assert_called_once_with( scopes=["https://www.googleapis.com/auth/cloud-platform"] ) mock_pm_client_class.assert_called_once() call_kwargs = mock_pm_client_class.call_args.kwargs assert call_kwargs["credentials"] == mock_credentials assert call_kwargs["client_options"] is None assert call_kwargs["client_info"].user_agent == USER_AGENT assert client._credentials == mock_credentials assert client._client == mock_pm_client_class.return_value @patch("google.cloud.parametermanager_v1.ParameterManagerClient") @patch("google.oauth2.service_account.Credentials.from_service_account_info") def test_init_with_service_account_json( self, mock_from_service_account_info, mock_pm_client_class ): """Test initialization with service account JSON.""" # Setup mock_credentials = MagicMock() mock_from_service_account_info.return_value = mock_credentials service_account_json = json.dumps({ "type": "service_account", "project_id": "test-project", "private_key_id": "key-id", "private_key": "private-key", "client_email": "test@example.com", }) # Execute client = ParameterManagerClient(service_account_json=service_account_json) # Verify mock_from_service_account_info.assert_called_once_with( json.loads(service_account_json) ) mock_pm_client_class.assert_called_once() call_kwargs = mock_pm_client_class.call_args.kwargs assert call_kwargs["credentials"] == mock_credentials assert call_kwargs["client_options"] is None assert call_kwargs["client_info"].user_agent == USER_AGENT assert client._credentials == mock_credentials assert client._client == mock_pm_client_class.return_value @patch("google.cloud.parametermanager_v1.ParameterManagerClient") def test_init_with_auth_token(self, mock_pm_client_class): """Test initialization with auth token.""" auth_token = "test-token" client = ParameterManagerClient(auth_token=auth_token) mock_pm_client_class.assert_called_once() call_kwargs = mock_pm_client_class.call_args.kwargs assert isinstance(call_kwargs["credentials"], Credentials) assert call_kwargs["credentials"].token == auth_token assert call_kwargs["client_options"] is None assert call_kwargs["client_info"].user_agent == USER_AGENT assert isinstance(client._credentials, Credentials) assert client._credentials.token == auth_token assert client._client == mock_pm_client_class.return_value @patch("google.cloud.parametermanager_v1.ParameterManagerClient") @patch( "google.adk.integrations.parameter_manager.parameter_client.default_service_credential" ) @patch( "google.adk.integrations.parameter_manager.parameter_client.get_api_endpoint" ) def test_init_with_location( self, mock_get_api_endpoint, mock_default_service_credential, mock_pm_client_class, ): """Test initialization with a specific location.""" # Setup mock_credentials = MagicMock() mock_default_service_credential.return_value = ( mock_credentials, "test-project", ) location = "us-central1" mock_get_api_endpoint.return_value = "resolved-endpoint" # Execute ParameterManagerClient(location=location) # Verify mock_pm_client_class.assert_called_once() call_kwargs = mock_pm_client_class.call_args.kwargs assert call_kwargs["credentials"] == mock_credentials assert call_kwargs["client_options"] == { "api_endpoint": "resolved-endpoint" } assert call_kwargs["client_info"].user_agent == USER_AGENT mock_get_api_endpoint.assert_called_once_with( location, "parametermanager.{location}.rep.googleapis.com", "parametermanager.{location}.rep.mtls.googleapis.com", ) @patch( "google.adk.integrations.parameter_manager.parameter_client.default_service_credential" ) def test_init_with_default_credentials_error( self, mock_default_service_credential ): """Test initialization with default credentials that fails.""" # Setup mock_default_service_credential.side_effect = Exception("Auth error") # Execute and verify with pytest.raises( ValueError, match="error occurred while trying to use default credentials", ): ParameterManagerClient() def test_init_with_invalid_service_account_json(self): """Test initialization with invalid service account JSON.""" # Execute and verify with pytest.raises(ValueError, match="Invalid service account JSON"): ParameterManagerClient(service_account_json="invalid-json") def test_init_with_both_service_account_json_and_auth_token(self): """Test initialization rejects conflicting credential inputs.""" with pytest.raises( ValueError, match=( "Must provide either 'service_account_json' or 'auth_token', not" " both." ), ): ParameterManagerClient( service_account_json=json.dumps({"type": "service_account"}), auth_token="test-token", ) @patch("google.cloud.parametermanager_v1.ParameterManagerClient") @patch( "google.adk.integrations.parameter_manager.parameter_client.default_service_credential" ) def test_get_parameter( self, mock_default_service_credential, mock_pm_client_class ): """Test getting a parameter.""" # Setup mock_credentials = MagicMock() mock_default_service_credential.return_value = ( mock_credentials, "test-project", ) mock_client = MagicMock() mock_pm_client_class.return_value = mock_client mock_response = MagicMock() mock_response.rendered_payload.decode.return_value = "parameter-value" mock_client.render_parameter_version.return_value = mock_response # Execute client = ParameterManagerClient() result = client.get_parameter( "projects/test-project/locations/global/parameters/test-param/versions/latest" ) # Verify assert result == "parameter-value" mock_response.rendered_payload.decode.assert_called_once_with("UTF-8") # Verify render_parameter_version was called with correct request object call_kwargs = mock_client.render_parameter_version.call_args.kwargs assert ( call_kwargs["request"].name == "projects/test-project/locations/global/parameters/test-param/versions/latest" ) mock_response.rendered_payload.decode.assert_called_once_with("UTF-8") @patch("google.cloud.parametermanager_v1.ParameterManagerClient") @patch( "google.adk.integrations.parameter_manager.parameter_client.default_service_credential" ) def test_get_parameter_error( self, mock_default_service_credential, mock_pm_client_class ): """Test getting a parameter that fails.""" # Setup mock_credentials = MagicMock() mock_default_service_credential.return_value = ( mock_credentials, "test-project", ) mock_client = MagicMock() mock_pm_client_class.return_value = mock_client mock_client.render_parameter_version.side_effect = Exception("API error") # Execute and verify client = ParameterManagerClient() with pytest.raises(Exception, match="API error"): client.get_parameter( "projects/test-project/locations/global/parameters/test-param/versions/latest" )