File size: 3,239 Bytes
a5a4bde
 
62a3b20
a5a4bde
62a3b20
a5a4bde
 
 
62a3b20
a5a4bde
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62a3b20
a5a4bde
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62a3b20
 
 
 
 
 
 
 
 
 
 
 
 
a5a4bde
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from pathlib import Path

import pytest
from fastapi.testclient import TestClient
from pydantic import ValidationError

from app.config import Settings
from app.main import create_app
from app.schemas import ChatRequest, ProviderCredentials


def _settings(tmp_path: Path) -> Settings:
    return Settings(
        environment="test",
        service_token="internal-test-token",
        checkpoint_backend="memory",
        artifact_dir=tmp_path / "artifacts",
        checkpoint_db_path=tmp_path / "checkpoints.sqlite",
    )


def test_health_and_models_are_self_describing(tmp_path: Path) -> None:
    with TestClient(create_app(_settings(tmp_path))) as client:
        health = client.get("/health")
        models = client.get("/v1/models")

    assert health.status_code == 200
    assert health.json()["status"] == "ok"
    assert models.status_code == 200
    assert len(models.json()["models"]) >= 14


def test_protected_routes_require_internal_auth(tmp_path: Path) -> None:
    with TestClient(create_app(_settings(tmp_path))) as client:
        response = client.post(
            "/v1/reports",
            headers={"X-User-Id": "user-1"},
            json={"title": "Test", "markdown": "A sufficiently useful report."},
        )
    assert response.status_code == 401


def test_validation_response_never_echoes_provider_key(tmp_path: Path) -> None:
    secret = "tiny"
    with TestClient(create_app(_settings(tmp_path))) as client:
        response = client.post(
            "/v1/chat/stream",
            headers={
                "Authorization": "Bearer internal-test-token",
                "X-User-Id": "user-1",
            },
            json={
                "thread_id": "thread-1",
                "message": "hello",
                "model": "openai/gpt-5.6-luna",
                "credentials": {"api_key": secret},
            },
        )
    assert response.status_code == 422
    assert secret not in response.text


def test_web_search_flag_defaults_on_and_requires_a_real_boolean() -> None:
    payload = {
        "thread_id": "thread-1",
        "message": "hello",
        "model": "openai/gpt-5-nano",
        "credentials": ProviderCredentials(api_key="provider-test-secret"),
    }

    assert ChatRequest(**payload).web_search_enabled is True
    with pytest.raises(ValidationError):
        ChatRequest(**payload, web_search_enabled="false")


def test_report_download_is_isolated_by_user(tmp_path: Path) -> None:
    headers = {
        "Authorization": "Bearer internal-test-token",
        "X-User-Id": "user-1",
    }
    with TestClient(create_app(_settings(tmp_path))) as client:
        created = client.post(
            "/v1/reports",
            headers=headers,
            json={"title": "Test report", "markdown": "# Result\n\nA useful finding."},
        )
        artifact = created.json()["artifact"]
        downloaded = client.get(artifact["download_url"], headers=headers)
        denied = client.get(
            artifact["download_url"],
            headers={**headers, "X-User-Id": "user-2"},
        )

    assert created.status_code == 201
    assert downloaded.status_code == 200
    assert downloaded.content.startswith(b"%PDF-")
    assert denied.status_code == 404