# -*- coding: utf-8 -*- """只读 Web 服务测试(离线): uv run python tests/test_web_server.py""" import http.client import json import os import sys import tempfile import threading import urllib.parse from pathlib import Path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.stdout.reconfigure(encoding="utf-8") from reaction_board.config import ConfigStore # noqa: E402 from reaction_board.database import Database # noqa: E402 from reaction_board.web.server import create_server # noqa: E402 from tests.web_fixtures import build_db, write_config # noqa: E402 class RunningServer: def __init__(self, tmp: str, *, token: str = "", preview: bool = False): self.config = write_config(tmp, token=token) build_db(tmp) self.db = Database(Path(tmp) / "app.db") self.db.initialize() if preview: self.db.write(lambda conn: conn.execute( "INSERT OR REPLACE INTO kv(k, v) VALUES ('preview:seeded', '1')" )) self.store = ConfigStore(self.config) self.server = create_server( self.store, self.db, port=0, preview=preview, clock=lambda: 1_793_459_000, ) self.port = self.server.server_address[1] self.thread = threading.Thread(target=self.server.serve_forever, daemon=True) self.thread.start() def request(self, path: str, *, method: str = "GET", headers=None, body=None): conn = http.client.HTTPConnection("127.0.0.1", self.port, timeout=5) conn.request(method, path, body=body, headers=headers or {}) response = conn.getresponse() payload = response.read() result = response.status, dict(response.getheaders()), payload conn.close() return result def json(self, path: str, **kwargs): status, headers, payload = self.request(path, **kwargs) return status, headers, json.loads(payload.decode("utf-8")) def close(self): self.server.shutdown() self.server.server_close() self.db.close() def test_readonly_routes_and_static(): with tempfile.TemporaryDirectory() as tmp: running = RunningServer(tmp) try: status, _, health = running.json("/api/health") assert status == 200 and health["ok"] is True assert health["data"]["preview"] is False status, _, overview = running.json("/api/overview") assert status == 200 and overview["ok"] is True assert overview["data"]["data_date"] == "2026-10-31" status, headers, payload = running.request("/") assert status == 200 assert "text/html" in headers["Content-Type"] assert b"