Phase 2 and 3 of the platform rework. - Neutral request/response contract: external_id, metadata, X-AI-Key, run_id in the response; client-specific fields removed. - AI profile is a revision table: saving creates an inactive revision, activation is separate, try-run does not store a run. One chat-completions gateway serves AIHub and OpenAI-compatible profiles. - Add between and in rule operators. - Contracts moved to contracts/lead-scoring/ with a score-response fixture. - Admin Web updated for revisions, runs and the neutral fixture. - Consolidate tests; remove rewrite_architect.md and the stale handoff doc; rewrite spec, CONTEXT and ARCHITECTURE for the current design. Not verified: live AIHub/OpenAI behavior, Omni/EMS integration.
46 lines
1.6 KiB
Python
46 lines
1.6 KiB
Python
import pytest
|
|
from pydantic import SecretStr, ValidationError
|
|
|
|
from ai_platform.infrastructure.config.settings import Settings
|
|
from ai_platform.lead_scoring.domain.safe_http_url import safe_http_url
|
|
|
|
DB = "postgresql+asyncpg://test:test@localhost/ai_platform_test"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("url", "environment", "allowed"),
|
|
[
|
|
("https://aihub.example/v1", "production", True),
|
|
("http://localhost:8317/v1", "development", True),
|
|
("http://localhost:8317/v1", "production", False),
|
|
("http://remote.example/v1", "development", False),
|
|
("https://user:pass@example.com", "production", False),
|
|
("https://example.com/v1?token=x", "production", False),
|
|
("ftp://example.com", "production", False),
|
|
(" https://example.com", "production", False),
|
|
(None, "production", False),
|
|
],
|
|
)
|
|
def test_safe_http_url(url, environment, allowed):
|
|
assert safe_http_url(url, environment) is allowed
|
|
|
|
|
|
@pytest.mark.usefixtures("isolated_settings")
|
|
def test_openai_settings_validate_url_and_key():
|
|
ok = Settings(
|
|
database_url=DB,
|
|
environment="production",
|
|
openai_base_url="https://proxy.example/v1",
|
|
openai_api_key=SecretStr("proxy-key"),
|
|
)
|
|
assert "proxy-key" not in repr(ok)
|
|
for url, key in (
|
|
("http://localhost:8317", None),
|
|
(None, SecretStr("key")),
|
|
("https://proxy.example/v1", SecretStr("k\r\nX: y")),
|
|
):
|
|
with pytest.raises(ValidationError):
|
|
Settings(
|
|
database_url=DB, environment="production", openai_base_url=url, openai_api_key=key
|
|
)
|