File size: 3,433 Bytes
aad7814
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
99
100
101
102
103
104
#!/usr/bin/env python3
"""HTTP smoke test for the v2 demo stack. Run while uvicorn is on :8000."""

from __future__ import annotations

import json
import sys
import urllib.error
import urllib.request

BASE = "http://127.0.0.1:8000"
TENANT = "demo-smoke"
PASSWORD = "demo-smoke-pass"


def req(method: str, path: str, *, body: dict | None = None, token: str | None = None) -> tuple[int, bytes]:
    headers = {"Content-Type": "application/json"}
    if token:
        headers["Authorization"] = f"Bearer {token}"
    data = json.dumps(body).encode() if body is not None else None
    request = urllib.request.Request(f"{BASE}{path}", data=data, headers=headers, method=method)
    try:
        with urllib.request.urlopen(request, timeout=120) as resp:
            return resp.status, resp.read()
    except urllib.error.HTTPError as exc:
        return exc.code, exc.read()


def main() -> int:
    print("1. Health")
    code, raw = req("GET", "/health")
    if code != 200:
        print(f"   FAIL health {code}: {raw[:200]}")
        return 1
    health = json.loads(raw)
    print(f"   OK status={health.get('status')} reference={health.get('reference_faiss_count')}")

    print("2. UI")
    code, _ = req("GET", "/v2.html")
    if code != 200:
        print(f"   FAIL v2.html {code}")
        return 1
    print("   OK /v2.html served")

    print("3. Register / login")
    code, raw = req("POST", "/auth/register", body={"tenant_id": TENANT, "password": PASSWORD})
    if code not in (201, 409):
        print(f"   FAIL register {code}: {raw[:200]}")
        return 1
    code, raw = req("POST", "/auth/login", body={"tenant_id": TENANT, "password": PASSWORD})
    if code != 200:
        print(f"   FAIL login {code}: {raw[:200]}")
        return 1
    token = json.loads(raw)["access_token"]
    print("   OK JWT received")

    print("4. Auth me")
    code, raw = req("GET", "/auth/me", token=token)
    if code != 200 or json.loads(raw).get("tenant_id") != TENANT:
        print(f"   FAIL /auth/me {code}")
        return 1
    print("   OK")

    print("5. Schema")
    code, raw = req("GET", "/api/schema", token=token)
    if code != 200:
        print(f"   FAIL schema {code}: {raw[:200]}")
        return 1
    sections = json.loads(raw).get("sections") or []
    print(f"   OK {len(sections)} sections")

    print("6. Reference status")
    code, raw = req("GET", "/api/upload/reference/status", token=token)
    ref = json.loads(raw)
    if code != 200:
        print(f"   FAIL reference status {code}")
        return 1
    print(f"   OK chunks={ref.get('reference_chunk_count')} ready={ref.get('ready_for_generation')}")

    if not ref.get("ready_for_generation"):
        print("   SKIP preview — no reference docs (upload past reports for full test)")
        return 0

    print("7. Preview")
    payload = {
        "raw_notes": "E2: roof tile slipped on south slope",
        "property_type": "semi-detached house",
        "tenure": "freehold",
        "interference_level": "minimum",
    }
    code, raw = req("POST", "/api/report/preview", body=payload, token=token)
    if code != 200:
        print(f"   FAIL preview {code}: {raw[:300]}")
        return 1
    preview = json.loads(raw)
    print(f"   OK mapped={preview.get('sections_mapped')} review={preview.get('sections_needing_review')}")

    print("All smoke checks passed.")
    return 0


if __name__ == "__main__":
    sys.exit(main())