f2a1847557
- Test KBSettings has enable_semantic_segmentation field with bool type - Test default value is True - Test environment variable override (KB_ENABLE_SEMANTIC_SEGMENTATION) - Test boolean string parsing (true/false, yes/no, 1/0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
217 lines
8.0 KiB
Python
217 lines
8.0 KiB
Python
"""Tests for configuration management module
|
|
|
|
Tests for KBSettings and get_settings function using pydantic-settings.
|
|
"""
|
|
|
|
import os
|
|
import pytest
|
|
from pathlib import Path
|
|
from unittest.mock import patch, MagicMock
|
|
from pydantic import ValidationError as PydanticValidationError
|
|
|
|
from kb_workflow.pipeline.config import KBSettings, get_settings
|
|
|
|
|
|
class TestKBSettings:
|
|
"""Tests for KBSettings class"""
|
|
|
|
def test_kbsettings_has_base_path_field(self):
|
|
"""Test KBSettings has base_path field"""
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive"
|
|
)
|
|
assert settings.base_path == "/tmp/kb"
|
|
|
|
def test_kbsettings_has_archive_path_field(self):
|
|
"""Test KBSettings has archive_path field"""
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive"
|
|
)
|
|
assert settings.archive_path == "/tmp/archive"
|
|
|
|
def test_kbsettings_optional_fields_can_be_empty(self):
|
|
"""Test optional fields accept empty string when explicitly set"""
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive",
|
|
git_root="",
|
|
git_user="",
|
|
git_email=""
|
|
)
|
|
assert settings.git_root == ""
|
|
assert settings.git_user == ""
|
|
assert settings.git_email == ""
|
|
|
|
def test_kbsettings_hf_token_is_secret(self):
|
|
"""Test hf_token is SecretStr type"""
|
|
from pydantic import SecretStr
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive",
|
|
hf_token="secret_token"
|
|
)
|
|
assert isinstance(settings.hf_token, SecretStr)
|
|
|
|
def test_kbsettings_zhihu_cookie_is_secret(self):
|
|
"""Test zhihu_cookie is SecretStr type"""
|
|
from pydantic import SecretStr
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive",
|
|
zhihu_cookie="secret_cookie"
|
|
)
|
|
assert isinstance(settings.zhihu_cookie, SecretStr)
|
|
|
|
def test_kbsettings_missing_base_path_raises_error(self):
|
|
"""Test missing base_path raises ValidationError"""
|
|
# Clear env vars that might provide values
|
|
with patch.dict(os.environ, {}, clear=True):
|
|
with pytest.raises(PydanticValidationError) as exc_info:
|
|
KBSettings(archive_path="/tmp/archive", _env_file=None)
|
|
assert "base_path" in str(exc_info.value).lower()
|
|
|
|
def test_kbsettings_missing_archive_path_raises_error(self):
|
|
"""Test missing archive_path raises ValidationError"""
|
|
# Clear env vars that might provide values
|
|
with patch.dict(os.environ, {}, clear=True):
|
|
with pytest.raises(PydanticValidationError) as exc_info:
|
|
KBSettings(base_path="/tmp/kb", _env_file=None)
|
|
assert "archive_path" in str(exc_info.value).lower()
|
|
|
|
def test_kbsettings_can_set_optional_fields(self):
|
|
"""Test optional fields can be set"""
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive",
|
|
git_root="/tmp/repo",
|
|
git_user="testuser",
|
|
git_email="test@example.com"
|
|
)
|
|
assert settings.git_root == "/tmp/repo"
|
|
assert settings.git_user == "testuser"
|
|
assert settings.git_email == "test@example.com"
|
|
|
|
|
|
class TestGetSettings:
|
|
"""Tests for get_settings function"""
|
|
|
|
def test_get_settings_returns_kbsettings(self):
|
|
"""Test get_settings returns KBSettings instance"""
|
|
with patch.dict(os.environ, {
|
|
"KB_BASE_PATH": "/tmp/kb",
|
|
"KB_ARCHIVE_PATH": "/tmp/archive"
|
|
}, clear=False):
|
|
# Clear cache before test
|
|
get_settings.cache_clear()
|
|
settings = get_settings()
|
|
assert isinstance(settings, KBSettings)
|
|
|
|
def test_get_settings_returns_singleton(self):
|
|
"""Test get_settings returns same instance (cached)"""
|
|
with patch.dict(os.environ, {
|
|
"KB_BASE_PATH": "/tmp/kb",
|
|
"KB_ARCHIVE_PATH": "/tmp/archive"
|
|
}, clear=False):
|
|
# Clear cache before test
|
|
get_settings.cache_clear()
|
|
settings1 = get_settings()
|
|
settings2 = get_settings()
|
|
assert settings1 is settings2
|
|
|
|
def test_get_settings_uses_env_vars_with_prefix(self):
|
|
"""Test get_settings reads from KB_ prefixed env vars"""
|
|
with patch.dict(os.environ, {
|
|
"KB_BASE_PATH": "/custom/kb",
|
|
"KB_ARCHIVE_PATH": "/custom/archive"
|
|
}, clear=False):
|
|
# Clear cache before test
|
|
get_settings.cache_clear()
|
|
settings = get_settings()
|
|
assert settings.base_path == "/custom/kb"
|
|
assert settings.archive_path == "/custom/archive"
|
|
|
|
|
|
class TestKBSettingsEnvFile:
|
|
"""Tests for KBSettings env file loading"""
|
|
|
|
def test_kbsettings_model_config_has_env_file(self):
|
|
"""Test KBSettings model_config has env_file setting"""
|
|
assert hasattr(KBSettings, "model_config")
|
|
assert "env_file" in KBSettings.model_config
|
|
|
|
def test_kbsettings_model_config_has_env_prefix(self):
|
|
"""Test KBSettings model_config has env_prefix setting"""
|
|
assert KBSettings.model_config.get("env_prefix") == "KB_"
|
|
|
|
def test_kbsettings_model_config_ignores_extra(self):
|
|
"""Test KBSettings model_config ignores extra fields"""
|
|
assert KBSettings.model_config.get("extra") == "ignore"
|
|
|
|
|
|
class TestEnableSemanticSegmentationField:
|
|
"""Tests for enable_semantic_segmentation field (CONFIG-01)"""
|
|
|
|
def test_kbsettings_has_enable_semantic_segmentation_field(self):
|
|
"""Test KBSettings has enable_semantic_segmentation field"""
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive"
|
|
)
|
|
assert hasattr(settings, "enable_semantic_segmentation"), \
|
|
"KBSettings should have enable_semantic_segmentation field"
|
|
assert isinstance(settings.enable_semantic_segmentation, bool), \
|
|
"enable_semantic_segmentation should be bool type"
|
|
|
|
def test_enable_semantic_segmentation_default_value(self):
|
|
"""Test default value is True"""
|
|
with patch.dict(os.environ, {}, clear=True):
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive",
|
|
_env_file=None
|
|
)
|
|
assert settings.enable_semantic_segmentation is True, \
|
|
"enable_semantic_segmentation should default to True"
|
|
|
|
def test_enable_semantic_segmentation_from_env(self):
|
|
"""Test KB_ENABLE_SEMANTIC_SEGMENTATION env var is respected"""
|
|
with patch.dict(os.environ, {
|
|
"KB_ENABLE_SEMANTIC_SEGMENTATION": "false"
|
|
}, clear=False):
|
|
get_settings.cache_clear()
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive"
|
|
)
|
|
assert settings.enable_semantic_segmentation is False, \
|
|
"enable_semantic_segmentation should be False when env var is 'false'"
|
|
|
|
def test_enable_semantic_segmentation_boolean_parsing(self):
|
|
"""Test boolean string parsing (true/false, yes/no, 1/0)"""
|
|
test_cases = [
|
|
("true", True),
|
|
("True", True),
|
|
("TRUE", True),
|
|
("yes", True),
|
|
("1", True),
|
|
("false", False),
|
|
("False", False),
|
|
("FALSE", False),
|
|
("no", False),
|
|
("0", False),
|
|
]
|
|
|
|
for env_value, expected in test_cases:
|
|
with patch.dict(os.environ, {
|
|
"KB_ENABLE_SEMANTIC_SEGMENTATION": env_value
|
|
}, clear=False):
|
|
get_settings.cache_clear()
|
|
settings = KBSettings(
|
|
base_path="/tmp/kb",
|
|
archive_path="/tmp/archive"
|
|
)
|
|
assert settings.enable_semantic_segmentation is expected, \
|
|
f"Failed for env_value={env_value}, expected={expected}"
|