mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-16 17:01:40 -06:00
2bb55590bf
Delete the entire turnstone/mq/ package (broker, bridge, protocol, client) and turnstone/sim/ package. Remove Redis as a dependency. Channel gateway and console now communicate with server nodes via direct HTTP (httpx + httpx-sse) instead of Redis pub/sub and queues. Single-node deployments work with zero infrastructure beyond the database. Key changes: - Channel adapters use httpx POST for create/send/approve/close and httpx-sse for per-workstream event streaming - Console collector discovers nodes via services table instead of Redis SCAN - Console scheduler dispatches tasks via HTTP POST with DB-based leader election - Server registers in services table with 30s heartbeat - Server accepts optional ws_id in create request (for Phase 2 console-generated routing) - SDK events gain IntentVerdictEvent and OutputWarningEvent types - All docs, examples, bootstrap wizard updated 63 files changed, -5968 net lines (Redis transport fully removed)
121 lines
3.7 KiB
Python
121 lines
3.7 KiB
Python
"""Integration tests for API versioning and OpenAPI/docs endpoints."""
|
|
|
|
import queue
|
|
import threading
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
|
|
class TestServerVersioning:
|
|
"""Test /v1/ routes and OpenAPI endpoints on the server."""
|
|
|
|
@pytest.fixture()
|
|
def client(self):
|
|
from starlette.testclient import TestClient
|
|
|
|
from turnstone.core.auth import AuthConfig
|
|
from turnstone.server import create_app
|
|
|
|
mock_mgr = MagicMock()
|
|
mock_mgr.list_all.return_value = []
|
|
mock_mgr.max_workstreams = 10
|
|
app = create_app(
|
|
workstreams=mock_mgr,
|
|
global_queue=queue.Queue(),
|
|
global_listeners=[],
|
|
global_listeners_lock=threading.Lock(),
|
|
skip_permissions=False,
|
|
auth_config=AuthConfig(),
|
|
)
|
|
client = TestClient(app, raise_server_exceptions=False)
|
|
yield client
|
|
client.close()
|
|
|
|
def test_v1_workstreams(self, client):
|
|
resp = client.get("/v1/api/workstreams")
|
|
assert resp.status_code == 200
|
|
assert "workstreams" in resp.json()
|
|
|
|
def test_unversioned_api_404(self, client):
|
|
resp = client.get("/api/workstreams")
|
|
assert resp.status_code == 404
|
|
|
|
def test_openapi_json(self, client):
|
|
resp = client.get("/openapi.json")
|
|
assert resp.status_code == 200
|
|
spec = resp.json()
|
|
assert spec["openapi"] == "3.1.0"
|
|
assert "/v1/api/send" in spec["paths"]
|
|
|
|
def test_docs_page(self, client):
|
|
resp = client.get("/docs")
|
|
assert resp.status_code == 200
|
|
assert "swagger-ui" in resp.text.lower()
|
|
|
|
def test_health_unversioned(self, client):
|
|
resp = client.get("/health")
|
|
assert resp.status_code == 200
|
|
assert "status" in resp.json()
|
|
|
|
def test_shared_static_unversioned(self, client):
|
|
resp = client.get("/shared/base.css")
|
|
assert resp.status_code == 200
|
|
|
|
|
|
class TestConsoleVersioning:
|
|
"""Test /v1/ routes and OpenAPI endpoints on the console."""
|
|
|
|
@pytest.fixture()
|
|
def client(self):
|
|
from starlette.testclient import TestClient
|
|
|
|
from turnstone.console.collector import ClusterCollector
|
|
from turnstone.console.server import _load_static, create_app
|
|
from turnstone.core.auth import AuthConfig
|
|
|
|
_load_static()
|
|
collector = MagicMock(spec=ClusterCollector)
|
|
collector.get_overview.return_value = {
|
|
"nodes": 0,
|
|
"workstreams": 0,
|
|
"states": {},
|
|
"aggregate": {},
|
|
}
|
|
app = create_app(
|
|
collector=collector,
|
|
auth_config=AuthConfig(),
|
|
)
|
|
client = TestClient(app, raise_server_exceptions=False)
|
|
yield client
|
|
client.close()
|
|
|
|
def test_v1_cluster_overview(self, client):
|
|
resp = client.get("/v1/api/cluster/overview")
|
|
assert resp.status_code == 200
|
|
|
|
def test_unversioned_api_404(self, client):
|
|
resp = client.get("/api/cluster/overview")
|
|
assert resp.status_code == 404
|
|
|
|
def test_openapi_json(self, client):
|
|
resp = client.get("/openapi.json")
|
|
assert resp.status_code == 200
|
|
spec = resp.json()
|
|
assert spec["openapi"] == "3.1.0"
|
|
assert "/v1/api/cluster/overview" in spec["paths"]
|
|
|
|
def test_docs_page(self, client):
|
|
resp = client.get("/docs")
|
|
assert resp.status_code == 200
|
|
assert "swagger-ui" in resp.text.lower()
|
|
|
|
def test_health_unversioned(self, client):
|
|
resp = client.get("/health")
|
|
assert resp.status_code == 200
|
|
|
|
def test_console_app_js_uses_v1_paths(self, client):
|
|
resp = client.get("/static/app.js")
|
|
body = resp.text
|
|
assert "/v1/api/cluster" in body
|