Some checks failed
verify / verify (push) Has been cancelled
The Stage 1 foundation now proves provider contracts with mocks and validates PostgreSQL/pgvector ingestion, approval binding, retrieval, reranking, and idempotency using only synthetic data. Live Bailian validation remains gated on rotating the exposed key. Constraint: The key shown in chat is compromised and cannot be used or committed Rejected: Mark Stage 1 complete from mock and offline results | real three-model smoke is still required Confidence: high Scope-risk: moderate Reversibility: clean Directive: Do not enable real-data ingestion until Stage 3 cloud approval and outbound manifest controls are enforced end to end Tested: make verify; 41 pytest tests; strict mypy; Ruff; Compose config; pinned image build; empty-volume migration; role denial; two idempotent 20-vector seeds; database restart persistence Not-tested: Live Bailian calls require a newly rotated key; React product UI is not implemented
75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.core.config import Settings
|
|
from app.core.secrets import SecretFileError, read_secret_file
|
|
|
|
|
|
def test_secret_file_strips_single_trailing_newline(tmp_path: Path) -> None:
|
|
secret_path = tmp_path / "secret"
|
|
secret_path.write_text("test-only-value\n", encoding="utf-8")
|
|
|
|
assert read_secret_file(secret_path) == "test-only-value"
|
|
|
|
|
|
def test_secret_error_never_contains_secret_value(tmp_path: Path) -> None:
|
|
secret_path = tmp_path / "secret"
|
|
secret_path.write_text("first\nsecond\n", encoding="utf-8")
|
|
|
|
with pytest.raises(SecretFileError) as captured:
|
|
read_secret_file(secret_path)
|
|
|
|
assert "first" not in str(captured.value)
|
|
assert "second" not in str(captured.value)
|
|
|
|
|
|
def test_database_url_reads_password_from_file(tmp_path: Path) -> None:
|
|
password_path = tmp_path / "postgres_password"
|
|
password_path.write_text("local-test-password", encoding="utf-8")
|
|
settings = Settings(postgres_password_file=password_path)
|
|
|
|
url = settings.database_url()
|
|
|
|
assert url.password == "local-test-password"
|
|
assert "local-test-password" not in str(url)
|
|
|
|
|
|
def test_base_urls_drop_trailing_slashes() -> None:
|
|
settings = Settings(
|
|
bailian_openai_base_url="https://example.invalid/compatible-mode/v1/",
|
|
bailian_native_base_url="https://example.invalid/api/v1/",
|
|
bailian_rerank_base_url="https://example.invalid/compatible-api/v1/",
|
|
)
|
|
|
|
assert settings.bailian_openai_base_url.endswith("/v1")
|
|
assert settings.bailian_rerank_base_url.endswith("/v1")
|
|
|
|
|
|
def test_live_endpoints_must_share_one_beijing_workspace(tmp_path: Path) -> None:
|
|
key_path = tmp_path / "key"
|
|
key_path.write_text("test-key-value", encoding="utf-8")
|
|
settings = Settings(
|
|
dashscope_api_key_file=key_path,
|
|
bailian_openai_base_url=(
|
|
"https://workspace-a.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
|
|
),
|
|
bailian_rerank_base_url=(
|
|
"https://workspace-b.cn-beijing.maas.aliyuncs.com/compatible-api/v1"
|
|
),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="same workspace"):
|
|
settings.bailian_api_key()
|
|
|
|
|
|
def test_live_endpoint_rejects_non_bailian_host_before_reading_key(tmp_path: Path) -> None:
|
|
settings = Settings(
|
|
dashscope_api_key_file=tmp_path / "missing",
|
|
bailian_openai_base_url="https://attacker.invalid/compatible-mode/v1",
|
|
bailian_rerank_base_url="https://attacker.invalid/compatible-api/v1",
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="approved Beijing"):
|
|
settings.bailian_api_key()
|