"""Tests for CLI routing utilities.""" import os import pytest from basic_memory.cli.commands.routing import force_routing, validate_routing_flags class TestValidateRoutingFlags: """Tests for validate_routing_flags function.""" def test_neither_flag(self): """Should not raise when neither flag is set.""" validate_routing_flags(local=False, cloud=False) def test_local_only(self): """Should not raise when only local is set.""" validate_routing_flags(local=True, cloud=False) def test_cloud_only(self): """Should not raise when only cloud is set.""" validate_routing_flags(local=False, cloud=True) def test_both_flags_raises(self): """Should raise ValueError when both flags are set.""" with pytest.raises(ValueError, match="Cannot specify both --local and --cloud"): validate_routing_flags(local=True, cloud=True) class TestForceRouting: """Tests for force_routing context manager.""" def test_local_sets_env_var(self): """Local flag should set BASIC_MEMORY_FORCE_LOCAL.""" # Ensure env var is not set os.environ.pop("BASIC_MEMORY_FORCE_LOCAL", None) with force_routing(local=True): assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") == "true" # Should be cleaned up after context exits assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") is None def test_cloud_clears_env_var(self): """Cloud flag should clear BASIC_MEMORY_FORCE_LOCAL if set.""" # Set env var os.environ["BASIC_MEMORY_FORCE_LOCAL"] = "true" with force_routing(cloud=True): assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") is None # Should restore original value after context exits assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") == "true" # Cleanup os.environ.pop("BASIC_MEMORY_FORCE_LOCAL", None) def test_neither_flag_no_change(self): """Neither flag should not change env vars.""" os.environ.pop("BASIC_MEMORY_FORCE_LOCAL", None) with force_routing(): # Should not be set assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") is None # Should still not be set assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") is None def test_preserves_original_env_var(self): """Should restore original env var value after context exits.""" original_value = "original" os.environ["BASIC_MEMORY_FORCE_LOCAL"] = original_value with force_routing(local=True): assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") == "true" # Should restore original value assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") == original_value # Cleanup os.environ.pop("BASIC_MEMORY_FORCE_LOCAL", None) def test_both_flags_raises(self): """Should raise ValueError when both flags are set.""" with pytest.raises(ValueError, match="Cannot specify both --local and --cloud"): with force_routing(local=True, cloud=True): pass def test_restores_on_exception(self): """Should restore env vars even when exception is raised.""" os.environ.pop("BASIC_MEMORY_FORCE_LOCAL", None) try: with force_routing(local=True): assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") == "true" raise RuntimeError("Test exception") except RuntimeError: pass # Should be cleaned up even after exception assert os.environ.get("BASIC_MEMORY_FORCE_LOCAL") is None