نسخهٔ وب مستقل — پلتفرم نیروی کار هوش مصنوعی
مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت. تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
"""Configuration safety guards.
|
||||
|
||||
A production API booted with a placeholder ``JWT_SECRET`` lets anyone forge a
|
||||
token for any tenant. These tests pin the fail-closed behaviour.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from app.core.config import DEVELOPMENT_CORS_ORIGINS, MIN_SECRET_LENGTH, Settings
|
||||
|
||||
_SAFE = {
|
||||
"app_env": "production",
|
||||
"jwt_secret": "s" * MIN_SECRET_LENGTH,
|
||||
"encryption_key": "k" * 44,
|
||||
"cors_origins": "https://app.example.com",
|
||||
}
|
||||
|
||||
|
||||
def _build(**overrides) -> Settings:
|
||||
return Settings(**{**_SAFE, **overrides})
|
||||
|
||||
|
||||
def test_development_tolerates_placeholder_secrets():
|
||||
"""A fresh clone must run with zero configuration."""
|
||||
settings = Settings(
|
||||
app_env="development", jwt_secret="change-me", encryption_key=""
|
||||
)
|
||||
assert settings.is_production is False
|
||||
|
||||
|
||||
def test_development_cors_allows_both_loopback_spellings():
|
||||
"""``localhost`` and ``127.0.0.1`` are different browser origins.
|
||||
|
||||
Listing only one makes the dev UI fail with an opaque "Disallowed CORS
|
||||
origin" — which is exactly what happened when the frontend was started with
|
||||
``-H 127.0.0.1`` while the API allowed only ``localhost``.
|
||||
"""
|
||||
origins = Settings(app_env="development").cors_origin_list
|
||||
assert "http://localhost:3000" in origins
|
||||
assert "http://127.0.0.1:3000" in origins
|
||||
|
||||
|
||||
def test_production_rejects_the_placeholder_secret():
|
||||
with pytest.raises(ValidationError, match="placeholder"):
|
||||
_build(jwt_secret="change-me")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("secret", ["", "short", "x" * (MIN_SECRET_LENGTH - 1)])
|
||||
def test_production_rejects_a_short_secret(secret: str):
|
||||
with pytest.raises(ValidationError, match="JWT_SECRET"):
|
||||
_build(jwt_secret=secret)
|
||||
|
||||
|
||||
def test_production_requires_an_encryption_key():
|
||||
"""Without it, stored provider credentials cannot be encrypted at rest."""
|
||||
with pytest.raises(ValidationError, match="ENCRYPTION_KEY"):
|
||||
_build(encryption_key="")
|
||||
|
||||
|
||||
def test_production_rejects_wildcard_cors():
|
||||
with pytest.raises(ValidationError, match="CORS_ORIGINS"):
|
||||
_build(cors_origins="*")
|
||||
|
||||
|
||||
def test_production_rejects_the_development_cors_default():
|
||||
"""A production deploy left on the dev allowlist has not been configured."""
|
||||
with pytest.raises(ValidationError, match="development default"):
|
||||
_build(cors_origins=DEVELOPMENT_CORS_ORIGINS)
|
||||
|
||||
|
||||
def test_production_accepts_a_fully_configured_environment():
|
||||
settings = _build()
|
||||
assert settings.is_production is True
|
||||
assert settings.cors_origin_list == ["https://app.example.com"]
|
||||
Reference in New Issue
Block a user