1616# under the License.
1717
1818import base64
19+ from unittest .mock import MagicMock , patch
1920
2021import pytest
2122import requests
2223from requests_mock import Mocker
23-
2424from pyiceberg .catalog .rest .auth import AuthManagerAdapter , BasicAuthManager , GoogleAuthManager , NoopAuthManager
2525
2626TEST_URI = "https://iceberg-test-catalog/"
@@ -76,16 +76,73 @@ def test_basic_auth_header(rest_mock: Mocker) -> None:
7676 actual_headers = history [0 ].headers
7777 assert actual_headers ["Authorization" ] == expected_header
7878
79- def test_google_auth_header (google_mock : Mocker ) -> None :
80- expected_token = "aaaabbb"
81- expected_header = f"Bearer { expected_token } "
79+
80+ @patch ('google.auth.transport.requests.Request' )
81+ @patch ('google.auth.default' )
82+ def test_google_auth_manager_default_credentials (mock_google_auth_default : MagicMock , mock_google_request : MagicMock , rest_mock : Mocker ) -> None :
83+ """Test GoogleAuthManager with default application credentials."""
84+ mock_credentials = MagicMock ()
85+ mock_credentials .token = "test_token"
86+ mock_google_auth_default .return_value = (mock_credentials , "test_project" )
8287
8388 auth_manager = GoogleAuthManager ()
8489 session = requests .Session ()
8590 session .auth = AuthManagerAdapter (auth_manager )
91+ session .get (TEST_URI )
92+
93+ mock_google_auth_default .assert_called_once_with (scopes = None )
94+ mock_credentials .refresh .assert_called_once_with (mock_google_request .return_value )
95+ history = rest_mock .request_history
96+ assert len (history ) == 1
97+ actual_headers = history [0 ].headers
98+ assert actual_headers ["Authorization" ] == "Bearer test_token"
8699
100+
101+ @patch ('google.auth.transport.requests.Request' )
102+ @patch ('google.auth.load_credentials_from_file' )
103+ def test_google_auth_manager_with_credentials_file (mock_load_creds : MagicMock , mock_google_request : MagicMock , rest_mock : Mocker ) -> None :
104+ """Test GoogleAuthManager with a credentials file path."""
105+ mock_credentials = MagicMock ()
106+ mock_credentials .token = "file_token"
107+ mock_load_creds .return_value = (mock_credentials , "test_project_file" )
108+
109+ auth_manager = GoogleAuthManager (credentials_path = "/fake/path.json" )
110+ session = requests .Session ()
111+ session .auth = AuthManagerAdapter (auth_manager )
87112 session .get (TEST_URI )
88- history = google_mock .request_history
89- assert len (history ) == 2
90- actual_headers = history [1 ].headers
91- assert actual_headers ["Authorization" ] == expected_header
113+
114+ mock_load_creds .assert_called_once_with ("/fake/path.json" , scopes = None )
115+ mock_credentials .refresh .assert_called_once_with (mock_google_request .return_value )
116+ history = rest_mock .request_history
117+ assert len (history ) == 1
118+ actual_headers = history [0 ].headers
119+ assert actual_headers ["Authorization" ] == "Bearer file_token"
120+
121+
122+ @patch ('google.auth.transport.requests.Request' )
123+ @patch ('google.auth.load_credentials_from_file' )
124+ def test_google_auth_manager_with_credentials_file_and_scopes (mock_load_creds : MagicMock , mock_google_request : MagicMock , rest_mock : Mocker ) -> None :
125+ """Test GoogleAuthManager with a credentials file path and scopes."""
126+ mock_credentials = MagicMock ()
127+ mock_credentials .token = "scoped_token"
128+ mock_load_creds .return_value = (mock_credentials , "test_project_scoped" )
129+ scopes = ["https://www.googleapis.com/auth/bigquery" ]
130+
131+ auth_manager = GoogleAuthManager (credentials_path = "/fake/path.json" , scopes = scopes )
132+ session = requests .Session ()
133+ session .auth = AuthManagerAdapter (auth_manager )
134+ session .get (TEST_URI )
135+
136+ mock_load_creds .assert_called_once_with ("/fake/path.json" , scopes = scopes )
137+ mock_credentials .refresh .assert_called_once_with (mock_google_request .return_value )
138+ history = rest_mock .request_history
139+ assert len (history ) == 1
140+ actual_headers = history [0 ].headers
141+ assert actual_headers ["Authorization" ] == "Bearer scoped_token"
142+
143+
144+ def test_google_auth_manager_import_error () -> None :
145+ """Test GoogleAuthManager raises ImportError if google-auth is not installed."""
146+ with patch .dict ('sys.modules' , {'google.auth' : None , 'google.auth.transport.requests' : None }):
147+ with pytest .raises (ImportError , match = "Google Auth libraries not found. Please install 'google-auth'." ):
148+ GoogleAuthManager ()
0 commit comments