72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
"""Unit tests: settings defaults & env overrides."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
import pytest
|
|
from pydantic_settings import SettingsError
|
|
|
|
from app.config import Settings
|
|
|
|
|
|
def _settings(**kwargs: Any) -> Settings:
|
|
"""Build Settings without reading a .env file (deterministic tests)."""
|
|
kwargs.setdefault("_env_file", None)
|
|
return Settings(**kwargs) # pyright: ignore[reportCallIssue] (kwarg exists at runtime)
|
|
|
|
|
|
def test_defaults_match_locked_decisions() -> None:
|
|
s = _settings()
|
|
assert s.llm_chat_model == "turbo"
|
|
assert s.llm_embed_model == "embed"
|
|
assert s.embedding_dim == 768
|
|
assert s.llm_base_url.endswith("/v1")
|
|
assert 0 < s.relevance_threshold < 1
|
|
assert s.top_k_chunks >= 1
|
|
assert s.top_n_docs >= 1
|
|
assert len(s.suggestions) >= 3
|
|
|
|
|
|
def test_env_override(monkeypatch) -> None:
|
|
monkeypatch.setenv("BOR_RELEVANCE_THRESHOLD", "0.42")
|
|
monkeypatch.setenv("BOR_LLM_CHAT_MODEL", "juggernaut")
|
|
s = _settings()
|
|
assert s.relevance_threshold == 0.42
|
|
assert s.llm_chat_model == "juggernaut"
|
|
|
|
|
|
def test_suggestions_default_is_three_plus_real_questions() -> None:
|
|
s = _settings()
|
|
assert len(s.suggestions) >= 3
|
|
assert all(isinstance(q, str) and q.strip() for q in s.suggestions)
|
|
# Distinct chips only — duplicates in the onboarding row are noise.
|
|
assert len({q.strip().lower() for q in s.suggestions}) == len(s.suggestions)
|
|
|
|
|
|
def test_suggestions_env_override_is_json_list(monkeypatch) -> None:
|
|
override = [
|
|
"How do I back up with Borg?",
|
|
"How is my K3S cluster set up?",
|
|
"How do I deploy a service?",
|
|
]
|
|
monkeypatch.setenv("BOR_SUGGESTIONS", json.dumps(override))
|
|
s = _settings()
|
|
assert s.suggestions == override
|
|
|
|
|
|
def test_suggestions_malformed_json_fails_loudly(monkeypatch) -> None:
|
|
monkeypatch.setenv("BOR_SUGGESTIONS", "[not valid json")
|
|
with pytest.raises(SettingsError):
|
|
_settings()
|
|
|
|
|
|
def test_effective_api_key_fallback(monkeypatch) -> None:
|
|
monkeypatch.delenv("AIPI_KEY", raising=False)
|
|
s = _settings()
|
|
assert s.effective_api_key == "not-needed"
|
|
|
|
monkeypatch.setenv("AIPI_KEY", "sk-from-env")
|
|
s2 = _settings()
|
|
assert s2.effective_api_key == "sk-from-env"
|