forked from cardosofelipe/fast-next-template
Implements RAG capabilities with pgvector for semantic search: - Intelligent chunking strategies (code-aware, markdown-aware, text) - Semantic search with vector similarity (HNSW index) - Keyword search with PostgreSQL full-text search - Hybrid search using Reciprocal Rank Fusion (RRF) - Redis caching for embeddings - Collection management (ingest, search, delete, stats) - FastMCP tools: search_knowledge, ingest_content, delete_content, list_collections, get_collection_stats, update_document Testing: - 128 comprehensive tests covering all components - 58% code coverage (database integration tests use mocks) - Passes ruff linting and mypy type checking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
105 lines
3.1 KiB
Python
105 lines
3.1 KiB
Python
"""Tests for configuration module."""
|
|
|
|
import os
|
|
|
|
|
|
class TestSettings:
|
|
"""Tests for Settings class."""
|
|
|
|
def test_default_values(self, settings):
|
|
"""Test default configuration values."""
|
|
assert settings.port == 8002
|
|
assert settings.embedding_dimension == 1536
|
|
assert settings.code_chunk_size == 500
|
|
assert settings.search_default_limit == 10
|
|
|
|
def test_env_prefix(self):
|
|
"""Test environment variable prefix."""
|
|
from config import Settings, reset_settings
|
|
|
|
reset_settings()
|
|
os.environ["KB_PORT"] = "9999"
|
|
|
|
settings = Settings()
|
|
assert settings.port == 9999
|
|
|
|
# Cleanup
|
|
del os.environ["KB_PORT"]
|
|
reset_settings()
|
|
|
|
def test_embedding_settings(self, settings):
|
|
"""Test embedding-related settings."""
|
|
assert settings.embedding_model == "text-embedding-3-large"
|
|
assert settings.embedding_batch_size == 100
|
|
assert settings.embedding_cache_ttl == 86400
|
|
|
|
def test_chunking_settings(self, settings):
|
|
"""Test chunking-related settings."""
|
|
assert settings.code_chunk_size == 500
|
|
assert settings.code_chunk_overlap == 50
|
|
assert settings.markdown_chunk_size == 800
|
|
assert settings.markdown_chunk_overlap == 100
|
|
assert settings.text_chunk_size == 400
|
|
assert settings.text_chunk_overlap == 50
|
|
|
|
def test_search_settings(self, settings):
|
|
"""Test search-related settings."""
|
|
assert settings.search_default_limit == 10
|
|
assert settings.search_max_limit == 100
|
|
assert settings.semantic_threshold == 0.7
|
|
assert settings.hybrid_semantic_weight == 0.7
|
|
assert settings.hybrid_keyword_weight == 0.3
|
|
|
|
|
|
class TestGetSettings:
|
|
"""Tests for get_settings function."""
|
|
|
|
def test_returns_singleton(self):
|
|
"""Test that get_settings returns singleton."""
|
|
from config import get_settings, reset_settings
|
|
|
|
reset_settings()
|
|
settings1 = get_settings()
|
|
settings2 = get_settings()
|
|
assert settings1 is settings2
|
|
|
|
def test_reset_creates_new_instance(self):
|
|
"""Test that reset_settings clears the singleton."""
|
|
from config import get_settings, reset_settings
|
|
|
|
settings1 = get_settings()
|
|
reset_settings()
|
|
settings2 = get_settings()
|
|
assert settings1 is not settings2
|
|
|
|
|
|
class TestIsTestMode:
|
|
"""Tests for is_test_mode function."""
|
|
|
|
def test_returns_true_when_set(self):
|
|
"""Test returns True when IS_TEST is set."""
|
|
from config import is_test_mode
|
|
|
|
old_value = os.environ.get("IS_TEST")
|
|
os.environ["IS_TEST"] = "true"
|
|
|
|
assert is_test_mode() is True
|
|
|
|
if old_value:
|
|
os.environ["IS_TEST"] = old_value
|
|
else:
|
|
del os.environ["IS_TEST"]
|
|
|
|
def test_returns_false_when_not_set(self):
|
|
"""Test returns False when IS_TEST is not set."""
|
|
from config import is_test_mode
|
|
|
|
old_value = os.environ.get("IS_TEST")
|
|
if old_value:
|
|
del os.environ["IS_TEST"]
|
|
|
|
assert is_test_mode() is False
|
|
|
|
if old_value:
|
|
os.environ["IS_TEST"] = old_value
|