test_setup_validator.py
1 """Tests for setup_validator — prerequisites and env checks. 2 3 Covers both happy-path (all files present, vars set) and error cases 4 (missing files, empty vars). All tests use tmp_path to avoid depending 5 on the real project layout. 6 """ 7 8 __all__: list[str] = [] 9 10 from pathlib import Path 11 from unittest.mock import patch 12 13 from services.setup_validator import ( 14 check_prerequisites, 15 validate_env, 16 ) 17 18 # Expected env vars — mirrors the public contract, not the internal data structure. 19 _EXPECTED_ENV_VARS = [ 20 "ANTHROPIC_API_KEY", 21 "OPENAI_API_KEY", 22 "GEMINI_API_KEY", 23 "XAI_API_KEY", 24 "DEEPSEEK_API_KEY", 25 "MISTRAL_API_KEY", 26 "BRIGHTDATA_TOKEN", 27 "NOTION_TOKEN", 28 "NOTION_JOBS_DATABASE_ID", 29 ] 30 31 32 class TestCheckPrerequisites: 33 """Tests for check_prerequisites — file existence checks.""" 34 35 def test_missing_env_file_reported(self, tmp_path: Path) -> None: 36 # .env absent should produce an issue mentioning .env. 37 (tmp_path / "config.toml").touch() 38 with patch.object( 39 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 40 "_PROJECT_ROOT", 41 tmp_path, 42 ): 43 issues = check_prerequisites() 44 assert any(".env" in issue for issue in issues) 45 46 def test_missing_config_toml_reported(self, tmp_path: Path) -> None: 47 # config.toml absent should produce an issue mentioning config.toml. 48 (tmp_path / ".env").touch() 49 with patch.object( 50 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 51 "_PROJECT_ROOT", 52 tmp_path, 53 ): 54 issues = check_prerequisites() 55 assert any("config.toml" in issue for issue in issues) 56 57 def test_all_present_returns_empty(self, tmp_path: Path) -> None: 58 # When all required files exist, no issues should be reported. 59 (tmp_path / ".env").touch() 60 (tmp_path / "config.toml").touch() 61 with patch.object( 62 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 63 "_PROJECT_ROOT", 64 tmp_path, 65 ): 66 issues = check_prerequisites() 67 assert issues == [] 68 69 70 class TestValidateEnv: 71 """Tests for validate_env — env var detection.""" 72 73 def test_returns_all_known_vars(self, tmp_path: Path) -> None: 74 # validate_env must return an entry for every known var, even if .env 75 # is empty. 76 (tmp_path / ".env").touch() 77 with patch.object( 78 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 79 "_PROJECT_ROOT", 80 tmp_path, 81 ): 82 result = validate_env() 83 for var in _EXPECTED_ENV_VARS: 84 assert var in result 85 86 def test_set_var_detected(self, tmp_path: Path) -> None: 87 # A var with a non-empty value should be reported as set. 88 (tmp_path / ".env").write_text("ANTHROPIC_API_KEY=sk-test-123\n") 89 with patch.object( 90 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 91 "_PROJECT_ROOT", 92 tmp_path, 93 ): 94 result = validate_env() 95 assert result["ANTHROPIC_API_KEY"] is True 96 97 def test_empty_var_not_set(self, tmp_path: Path) -> None: 98 # A var with an empty value should be reported as not set. 99 (tmp_path / ".env").write_text("ANTHROPIC_API_KEY=\n") 100 with patch.object( 101 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 102 "_PROJECT_ROOT", 103 tmp_path, 104 ): 105 result = validate_env() 106 assert result["ANTHROPIC_API_KEY"] is False 107 108 def test_missing_env_file_all_false(self, tmp_path: Path) -> None: 109 # When .env doesn't exist, all vars should be reported as not set. 110 with patch.object( 111 __import__("services.setup_validator", fromlist=["_PROJECT_ROOT"]), 112 "_PROJECT_ROOT", 113 tmp_path, 114 ): 115 result = validate_env() 116 assert all(v is False for v in result.values())