104 lines
3.8 KiB
Python
104 lines
3.8 KiB
Python
"""Jev 감정 공급자 설정 계약."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import unittest
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
from pydantic import SecretStr, ValidationError
|
|
|
|
from .config import Settings
|
|
from . import main
|
|
|
|
|
|
class JevSettingsTest(unittest.TestCase):
|
|
def test_defaults_keep_legacy_provider(self) -> None:
|
|
with patch.dict(
|
|
os.environ,
|
|
{
|
|
"VIGNETTE_CLIENT_AFFECT_PROVIDER": "legacy",
|
|
"TYPESAFE_API_KEY": "",
|
|
"OPENROUTER_API_KEY": "",
|
|
},
|
|
clear=False,
|
|
):
|
|
configured = Settings(_env_file=None)
|
|
|
|
self.assertEqual("legacy", configured.client_affect_provider)
|
|
self.assertEqual("openrouter", configured.jev_provider)
|
|
self.assertEqual("~typesafe/jev-latest", configured.jev_model)
|
|
self.assertEqual(1.2, configured.jev_timeout_seconds)
|
|
self.assertEqual(0.65, configured.jev_min_confidence)
|
|
|
|
def test_default_openrouter_jev_requires_its_own_key(self) -> None:
|
|
with self.assertRaisesRegex(ValidationError, "OPENROUTER_API_KEY"):
|
|
Settings(
|
|
_env_file=None,
|
|
client_affect_provider="jev",
|
|
typesafe_api_key=SecretStr("typesafe-only-key"),
|
|
openrouter_api_key=SecretStr(""),
|
|
)
|
|
|
|
def test_explicit_typesafe_jev_requires_typesafe_key(self) -> None:
|
|
with self.assertRaisesRegex(ValidationError, "TYPESAFE_API_KEY"):
|
|
Settings(
|
|
_env_file=None,
|
|
client_affect_provider="jev",
|
|
jev_provider="typesafe",
|
|
openrouter_api_key=SecretStr("openrouter-only-key"),
|
|
typesafe_api_key=SecretStr(""),
|
|
)
|
|
|
|
def test_jev_environment_aliases_and_limits_apply(self) -> None:
|
|
with patch.dict(
|
|
os.environ,
|
|
{
|
|
"VIGNETTE_CLIENT_AFFECT_PROVIDER": "jev",
|
|
"VIGNETTE_JEV_PROVIDER": "openrouter",
|
|
"OPENROUTER_API_KEY": "unit-test-openrouter-key",
|
|
"VIGNETTE_JEV_MODEL": "~typesafe/jev-latest",
|
|
"VIGNETTE_JEV_TIMEOUT_SECONDS": "0.4",
|
|
"VIGNETTE_JEV_MIN_CONFIDENCE": "0.8",
|
|
},
|
|
clear=False,
|
|
):
|
|
configured = Settings(_env_file=None)
|
|
|
|
self.assertEqual("jev", configured.client_affect_provider)
|
|
self.assertEqual("openrouter", configured.jev_provider)
|
|
self.assertEqual(
|
|
"unit-test-openrouter-key",
|
|
configured.openrouter_api_key.get_secret_value(),
|
|
)
|
|
self.assertEqual(0.4, configured.jev_timeout_seconds)
|
|
self.assertEqual(0.8, configured.jev_min_confidence)
|
|
|
|
def test_timeout_bounds_are_enforced(self) -> None:
|
|
with self.assertRaises(ValidationError):
|
|
Settings(_env_file=None, jev_timeout_seconds=0.09)
|
|
with self.assertRaises(ValidationError):
|
|
Settings(_env_file=None, jev_timeout_seconds=10.1)
|
|
|
|
|
|
class JevHealthStatusTest(unittest.IsolatedAsyncioTestCase):
|
|
async def test_health_exposes_configuration_without_claiming_live_readiness(self) -> None:
|
|
with (
|
|
patch.object(main, "healthcheck", AsyncMock(return_value=True)),
|
|
patch.object(
|
|
main.engine_client,
|
|
"health_detail",
|
|
AsyncMock(return_value={"ok": True}),
|
|
),
|
|
):
|
|
response = await main.health()
|
|
|
|
self.assertEqual(main.settings.client_affect_provider, response["client_affect_provider"])
|
|
self.assertEqual(main.settings.jev_model, response["jev"]["model"])
|
|
self.assertEqual(main.settings.jev_provider, response["jev"]["provider"])
|
|
self.assertIn("configured", response["jev"])
|
|
self.assertFalse(response["jev"]["live_verified"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|