Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions tests/test_openapi_websocket_exclusion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Regression test: WebSocket routes used to show up in /openapi.json as an
empty, spec-invalid Path Item Object ({}) -- PathItem has no "websocket"
field, so setattr(path_item, "websocket", op) silently created a dangling
attribute to_dict() never serialized, and the path stayed in the schema
with no operations at all.
"""

import asyncio

from velocix import TestClient, Velocix
from velocix.websocket.connection import WebSocket


def _run(coro):
return asyncio.run(coro)


def test_websocket_route_excluded_from_openapi_schema():
app = Velocix()

@app.get("/posts")
async def list_posts():
return {"posts": []}

@app.websocket("/ws/posts/{post_id}")
async def watch_post(websocket: WebSocket):
await websocket.accept()
await websocket.close()

async def scenario():
async with TestClient(app) as client:
schema = (await client.get("/openapi.json")).json()
paths = schema.get("paths", {})
assert "/posts" in paths
assert "get" in paths["/posts"]
assert "/ws/posts/{post_id}" not in paths

_run(scenario())
6 changes: 6 additions & 0 deletions velocix/core/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,12 @@ async def openapi_handler(request: Request) -> Response:
# missing from the docs entirely or, once hit, showed up
# under the literal ID that happened to hit them first.
for method, path, handler, _name in self.router._registered:
if method == "WEBSOCKET":
# OpenAPI 3.x has no operation concept for
# WebSocket routes; PathItem has no matching
# field, so this always produced an empty (and
# spec-invalid) {} entry.
continue
if getattr(handler, "__route_include_in_schema__", True) is False:
continue
if path in (self.openapi_url, self.docs_url, self.redoc_url):
Expand Down
Loading