test_settings.py
1 """ 2 Unit tests for settings.py Config class and environment variable handling. 3 """ 4 5 import os 6 import tempfile 7 8 import pytest 9 import yaml 10 11 from settings import Config 12 13 14 @pytest.mark.unit 15 def test_config_defaults(): 16 """Test Config has correct default values.""" 17 cfg = Config() 18 assert cfg.max_concurrency == 8 19 assert cfg.rule_timeout_s == 30 20 assert cfg.rulesets == [] 21 assert cfg.enabled_rules == [] 22 23 24 @pytest.mark.unit 25 def test_config_from_dict(): 26 """Test Config can be created from dict.""" 27 cfg = Config( 28 max_concurrency=16, 29 rule_timeout_s=60, 30 rulesets=["test-ruleset"], 31 enabled_rules=["D-SCHEMA-03"] 32 ) 33 assert cfg.max_concurrency == 16 34 assert cfg.rule_timeout_s == 60 35 assert cfg.rulesets == ["test-ruleset"] 36 assert cfg.enabled_rules == ["D-SCHEMA-03"] 37 38 39 @pytest.mark.unit 40 def test_apply_env_overrides_max_concurrency(monkeypatch): 41 """Test apply_env_overrides with max_concurrency override.""" 42 monkeypatch.setenv("CURATOR_MAX_CONCURRENCY", "16") 43 cfg = Config() 44 cfg.apply_env_overrides() 45 assert cfg.max_concurrency == 16 46 47 48 @pytest.mark.unit 49 def test_apply_env_overrides_rule_timeout(monkeypatch): 50 """Test apply_env_overrides with rule_timeout_s override.""" 51 monkeypatch.setenv("CURATOR_RULE_TIMEOUT_S", "60") 52 cfg = Config() 53 cfg.apply_env_overrides() 54 assert cfg.rule_timeout_s == 60 55 56 57 @pytest.mark.unit 58 def test_apply_env_overrides_rulesets(monkeypatch): 59 """Test apply_env_overrides with rulesets override.""" 60 monkeypatch.setenv("CURATOR_RULESETS", "ruleset1, ruleset2, ruleset3") 61 cfg = Config() 62 cfg.apply_env_overrides() 63 assert cfg.rulesets == ["ruleset1", "ruleset2", "ruleset3"] 64 65 66 @pytest.mark.unit 67 def test_apply_env_overrides_enabled_rules(monkeypatch): 68 """Test apply_env_overrides with enabled_rules override.""" 69 monkeypatch.setenv("CURATOR_ENABLED_RULES", "D-SCHEMA-03, P-QUALITY-01") 70 cfg = Config() 71 cfg.apply_env_overrides() 72 assert cfg.enabled_rules == ["D-SCHEMA-03", "P-QUALITY-01"] 73 74 75 @pytest.mark.unit 76 def test_apply_env_overrides_all(monkeypatch): 77 """Test apply_env_overrides with all variables set.""" 78 monkeypatch.setenv("CURATOR_MAX_CONCURRENCY", "32") 79 monkeypatch.setenv("CURATOR_RULE_TIMEOUT_S", "120") 80 monkeypatch.setenv("CURATOR_RULESETS", "rs1, rs2") 81 monkeypatch.setenv("CURATOR_ENABLED_RULES", "D-FILES-01, P-QUALITY-01") 82 83 cfg = Config() 84 cfg.apply_env_overrides() 85 86 assert cfg.max_concurrency == 32 87 assert cfg.rule_timeout_s == 120 88 assert cfg.rulesets == ["rs1", "rs2"] 89 assert cfg.enabled_rules == ["D-FILES-01", "P-QUALITY-01"] 90 91 92 @pytest.mark.unit 93 def test_config_from_yaml_file(): 94 """Test Config can be loaded from YAML file.""" 95 with tempfile.NamedTemporaryFile(mode='w', suffix='.yml', delete=False) as f: 96 yaml.dump({ 97 "max_concurrency": 12, 98 "rule_timeout_s": 45, 99 "rulesets": ["test-ruleset"], 100 "enabled_rules": ["D-SCHEMA-03"] 101 }, f) 102 temp_path = f.name 103 104 try: 105 with open(temp_path) as f: 106 cfg = Config.model_validate(yaml.safe_load(f)) 107 108 assert cfg.max_concurrency == 12 109 assert cfg.rule_timeout_s == 45 110 assert cfg.rulesets == ["test-ruleset"] 111 assert cfg.enabled_rules == ["D-SCHEMA-03"] 112 finally: 113 os.unlink(temp_path) 114 115 116 @pytest.mark.unit 117 def test_config_forbids_extra_fields(): 118 """Test Config raises error on extra fields (extra='forbid').""" 119 with pytest.raises(Exception, match="unknown_field"): # Pydantic validation error 120 Config(max_concurrency=8, unknown_field="value") 121 122 123 @pytest.mark.unit 124 def test_apply_env_overrides_empty_lists(monkeypatch): 125 """Test apply_env_overrides handles empty comma-separated strings.""" 126 monkeypatch.setenv("CURATOR_RULESETS", "") 127 monkeypatch.setenv("CURATOR_ENABLED_RULES", " , , ") 128 129 cfg = Config() 130 cfg.apply_env_overrides() 131 132 assert cfg.rulesets == [] 133 assert cfg.enabled_rules == []