fix: restore green builds and align frontend-backend contracts (P0)
- Isolate Settings tests from .env and process env leakage - Fix analytics metadata test to unwrap psycopg Json wrapper - Remove unused state variables causing frontend build failures - Fix ReviewPage to use /classifications endpoint instead of nonexistent /result - Normalize ReviewPage status enums (failed not error) and access_type values - Align api.ts types with backend response shapes (ReplayPage, AnalyticsData, AgentUsage)
This commit is contained in:
@@ -145,4 +145,11 @@ class TestPostgresAnalyticsRecorder:
|
||||
)
|
||||
call_args = mock_conn.execute.call_args
|
||||
params = call_args[0][1]
|
||||
assert params["metadata"] == {"key": "val"}
|
||||
# PostgresAnalyticsRecorder wraps metadata with psycopg Json() adapter.
|
||||
# Unwrap to compare the inner dict.
|
||||
from psycopg.types.json import Json
|
||||
|
||||
meta = params["metadata"]
|
||||
if isinstance(meta, Json):
|
||||
meta = meta.obj
|
||||
assert meta == {"key": "val"}
|
||||
|
||||
@@ -7,10 +7,41 @@ import pytest
|
||||
from app.config import Settings
|
||||
|
||||
|
||||
def _isolated_settings(**kwargs: object) -> Settings:
|
||||
"""Create a Settings instance that ignores .env files and process env vars.
|
||||
|
||||
pydantic-settings reads from env_file and environment by default, which
|
||||
causes test results to depend on the machine they run on. We override
|
||||
model_config at the class level temporarily so that every test gets
|
||||
deterministic results.
|
||||
"""
|
||||
# Build a throwaway subclass that disables env-file and env-var loading.
|
||||
class _IsolatedSettings(Settings):
|
||||
model_config = Settings.model_config.copy()
|
||||
model_config["env_file"] = None # type: ignore[assignment]
|
||||
model_config["env_ignore_empty"] = True
|
||||
|
||||
# _env_parse_none_str makes pydantic-settings treat missing env vars as
|
||||
# absent rather than empty-string, so required fields will raise.
|
||||
import os
|
||||
|
||||
env_backup = os.environ.copy()
|
||||
# Strip all env vars that Settings knows about so they can't leak in.
|
||||
settings_fields = set(Settings.model_fields)
|
||||
for key in list(os.environ):
|
||||
if key.lower() in settings_fields:
|
||||
del os.environ[key]
|
||||
try:
|
||||
return _IsolatedSettings(**kwargs) # type: ignore[return-value]
|
||||
finally:
|
||||
os.environ.clear()
|
||||
os.environ.update(env_backup)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestSettings:
|
||||
def test_default_values(self) -> None:
|
||||
settings = Settings(
|
||||
settings = _isolated_settings(
|
||||
database_url="postgresql://x:x@localhost/db",
|
||||
anthropic_api_key="key",
|
||||
)
|
||||
@@ -20,7 +51,7 @@ class TestSettings:
|
||||
assert settings.interrupt_ttl_minutes == 30
|
||||
|
||||
def test_custom_values(self) -> None:
|
||||
settings = Settings(
|
||||
settings = _isolated_settings(
|
||||
database_url="postgresql://x:x@localhost/db",
|
||||
llm_provider="openai",
|
||||
llm_model="gpt-4o",
|
||||
@@ -33,18 +64,18 @@ class TestSettings:
|
||||
|
||||
def test_invalid_provider_rejected(self) -> None:
|
||||
with pytest.raises(Exception):
|
||||
Settings(
|
||||
_isolated_settings(
|
||||
database_url="postgresql://x:x@localhost/db",
|
||||
llm_provider="invalid",
|
||||
)
|
||||
|
||||
def test_missing_database_url_rejected(self) -> None:
|
||||
with pytest.raises(Exception):
|
||||
Settings(anthropic_api_key="key")
|
||||
_isolated_settings(anthropic_api_key="key")
|
||||
|
||||
def test_empty_api_key_for_provider_rejected(self) -> None:
|
||||
with pytest.raises(ValueError, match="API key"):
|
||||
Settings(
|
||||
_isolated_settings(
|
||||
database_url="postgresql://x:x@localhost/db",
|
||||
llm_provider="anthropic",
|
||||
anthropic_api_key="",
|
||||
@@ -52,7 +83,7 @@ class TestSettings:
|
||||
|
||||
def test_wrong_provider_key_rejected(self) -> None:
|
||||
with pytest.raises(ValueError, match="API key"):
|
||||
Settings(
|
||||
_isolated_settings(
|
||||
database_url="postgresql://x:x@localhost/db",
|
||||
llm_provider="openai",
|
||||
anthropic_api_key="key",
|
||||
|
||||
Reference in New Issue
Block a user