Spaces:
Paused
Paused
| import asyncio | |
| import os | |
| from unittest.mock import AsyncMock, MagicMock, patch | |
| import pytest | |
| from browser_utils.initialization import auth | |
| def mock_context(): | |
| context = AsyncMock() | |
| context.storage_state = AsyncMock() | |
| return context | |
| def mock_loop(): | |
| loop = MagicMock() | |
| future = asyncio.Future() | |
| future.set_result("test_result") | |
| loop.run_in_executor.return_value = future | |
| return loop | |
| # ==================== _save_auth_state Tests ==================== | |
| async def test_save_auth_state_success(mock_context, tmp_path): | |
| """Test _save_auth_state saves auth correctly with auto-generated filename.""" | |
| with ( | |
| patch("browser_utils.initialization.auth.SAVED_AUTH_DIR", str(tmp_path)), | |
| patch("browser_utils.initialization.auth.print"), | |
| patch("browser_utils.initialization.auth.logger"), | |
| ): | |
| await auth._save_auth_state(mock_context, "test_auth") | |
| mock_context.storage_state.assert_called_once() | |
| kwargs = mock_context.storage_state.call_args[1] | |
| assert kwargs["path"].endswith("test_auth.json") | |
| assert str(tmp_path) in kwargs["path"] | |
| async def test_save_auth_state_adds_json_extension(mock_context, tmp_path): | |
| """Test _save_auth_state adds .json extension if missing.""" | |
| with ( | |
| patch("browser_utils.initialization.auth.SAVED_AUTH_DIR", str(tmp_path)), | |
| patch("browser_utils.initialization.auth.print"), | |
| patch("browser_utils.initialization.auth.logger"), | |
| ): | |
| await auth._save_auth_state(mock_context, "my_profile") | |
| kwargs = mock_context.storage_state.call_args[1] | |
| assert kwargs["path"].endswith("my_profile.json") | |
| async def test_save_auth_state_preserves_json_extension(mock_context, tmp_path): | |
| """Test _save_auth_state preserves .json if already present.""" | |
| with ( | |
| patch("browser_utils.initialization.auth.SAVED_AUTH_DIR", str(tmp_path)), | |
| patch("browser_utils.initialization.auth.print"), | |
| patch("browser_utils.initialization.auth.logger"), | |
| ): | |
| await auth._save_auth_state(mock_context, "already.json") | |
| kwargs = mock_context.storage_state.call_args[1] | |
| assert kwargs["path"].endswith("already.json") | |
| assert not kwargs["path"].endswith("already.json.json") | |
| async def test_save_auth_state_exception(mock_context, tmp_path): | |
| """Test _save_auth_state catches and logs exceptions.""" | |
| mock_context.storage_state.side_effect = Exception("Storage failed") | |
| with ( | |
| patch("browser_utils.initialization.auth.SAVED_AUTH_DIR", str(tmp_path)), | |
| patch("browser_utils.initialization.auth.print"), | |
| patch("browser_utils.initialization.auth.logger") as mock_logger, | |
| ): | |
| # Should not raise | |
| await auth._save_auth_state(mock_context, "test_auth") | |
| mock_logger.error.assert_called() | |
| async def test_save_auth_state_cancelled_error(mock_context, tmp_path): | |
| """Test _save_auth_state re-raises CancelledError.""" | |
| mock_context.storage_state.side_effect = asyncio.CancelledError() | |
| with ( | |
| patch("browser_utils.initialization.auth.SAVED_AUTH_DIR", str(tmp_path)), | |
| patch("browser_utils.initialization.auth.print"), | |
| ): | |
| with pytest.raises(asyncio.CancelledError): | |
| await auth._save_auth_state(mock_context, "test_auth") | |
| # ==================== wait_for_model_list_and_handle_auth_save Tests ==================== | |
| async def test_wait_for_model_list_success(mock_context, mock_loop, tmp_path): | |
| """Test wait_for_model_list calls _save_auth_state on success.""" | |
| import server | |
| server.model_list_fetch_event.set() | |
| with ( | |
| patch("browser_utils.initialization.auth._save_auth_state") as mock_save, | |
| patch("browser_utils.initialization.auth.logger"), | |
| ): | |
| await auth.wait_for_model_list_and_handle_auth_save( | |
| mock_context, "normal", mock_loop | |
| ) | |
| mock_save.assert_called_once() | |
| # Should be called with auto-generated filename | |
| args = mock_save.call_args[0] | |
| assert args[0] == mock_context | |
| assert args[1].startswith("auth_auto_") | |
| async def test_wait_for_model_list_timeout(mock_context, mock_loop): | |
| """Test wait_for_model_list handles timeout and still saves.""" | |
| import server | |
| server.model_list_fetch_event.clear() | |
| original_wait_for = asyncio.wait_for | |
| async def side_effect(coro, timeout): | |
| if timeout == 30.0: | |
| raise asyncio.TimeoutError() | |
| return await original_wait_for(coro, timeout) | |
| with ( | |
| patch("asyncio.wait_for", side_effect=side_effect), | |
| patch("browser_utils.initialization.auth._save_auth_state") as mock_save, | |
| patch("browser_utils.initialization.auth.logger"), | |
| ): | |
| await auth.wait_for_model_list_and_handle_auth_save( | |
| mock_context, "normal", mock_loop | |
| ) | |
| mock_save.assert_called_once() | |
| async def test_wait_for_model_list_with_env_filename(mock_context, mock_loop): | |
| """Test wait_for_model_list uses SAVE_AUTH_FILENAME env var.""" | |
| import server | |
| server.model_list_fetch_event.set() | |
| with ( | |
| patch.dict(os.environ, {"SAVE_AUTH_FILENAME": "env_auth"}), | |
| patch("browser_utils.initialization.auth._save_auth_state") as mock_save, | |
| patch("browser_utils.initialization.auth.logger"), | |
| ): | |
| await auth.wait_for_model_list_and_handle_auth_save( | |
| mock_context, "normal", mock_loop | |
| ) | |
| mock_save.assert_called_with(mock_context, "env_auth") | |