2018-10-29 14:46:42 +00:00
|
|
|
import pytest
|
|
|
|
|
|
|
|
from starlette.exceptions import ExceptionMiddleware
|
2018-09-05 09:29:04 +00:00
|
|
|
from starlette.responses import Response
|
2018-10-29 14:46:42 +00:00
|
|
|
from starlette.routing import Mount, NoMatchFound, Route, Router, WebSocketRoute
|
2018-09-05 09:29:04 +00:00
|
|
|
from starlette.testclient import TestClient
|
|
|
|
from starlette.websockets import WebSocket, WebSocketDisconnect
|
2018-06-25 21:23:40 +00:00
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
def homepage(request):
|
2018-06-25 21:26:01 +00:00
|
|
|
return Response("Hello, world", media_type="text/plain")
|
2018-06-25 21:23:40 +00:00
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
def users(request):
|
2018-06-25 21:26:01 +00:00
|
|
|
return Response("All users", media_type="text/plain")
|
2018-06-25 21:23:40 +00:00
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
def user(request):
|
|
|
|
content = "User " + request.path_params["username"]
|
2018-06-25 21:26:01 +00:00
|
|
|
return Response(content, media_type="text/plain")
|
2018-06-25 21:23:40 +00:00
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
def staticfiles(request):
|
2018-06-26 09:09:35 +00:00
|
|
|
return Response("xxxxx", media_type="image/png")
|
|
|
|
|
|
|
|
|
2018-06-25 21:26:01 +00:00
|
|
|
app = Router(
|
|
|
|
[
|
2018-10-29 09:22:45 +00:00
|
|
|
Route("/", endpoint=homepage, methods=["GET"]),
|
|
|
|
Mount(
|
|
|
|
"/users",
|
|
|
|
app=Router(
|
|
|
|
[Route("", endpoint=users), Route("/{username}", endpoint=user)]
|
|
|
|
),
|
2018-06-25 21:26:01 +00:00
|
|
|
),
|
2018-10-29 09:22:45 +00:00
|
|
|
Mount("/static", app=staticfiles),
|
2018-06-25 21:26:01 +00:00
|
|
|
]
|
|
|
|
)
|
2018-06-25 21:23:40 +00:00
|
|
|
|
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
@app.route("/func")
|
|
|
|
def func_homepage(request):
|
|
|
|
return Response("Hello, world!", media_type="text/plain")
|
|
|
|
|
|
|
|
|
2018-10-30 16:08:05 +00:00
|
|
|
@app.route("/func", methods=["POST"])
|
|
|
|
def contact(request):
|
|
|
|
return Response("Hello, POST!", media_type="text/plain")
|
|
|
|
|
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
@app.websocket_route("/ws")
|
|
|
|
async def websocket_endpoint(session):
|
|
|
|
await session.accept()
|
|
|
|
await session.send_text("Hello, world!")
|
|
|
|
await session.close()
|
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
@app.websocket_route("/ws/{room}")
|
|
|
|
async def websocket_params(session):
|
|
|
|
await session.accept()
|
|
|
|
await session.send_text("Hello, %s!" % session.path_params["room"])
|
|
|
|
await session.close()
|
|
|
|
|
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
client = TestClient(app)
|
|
|
|
|
2018-06-25 21:23:40 +00:00
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
def test_router():
|
2018-06-25 21:26:01 +00:00
|
|
|
response = client.get("/")
|
2018-06-25 21:23:40 +00:00
|
|
|
assert response.status_code == 200
|
2018-06-25 21:26:01 +00:00
|
|
|
assert response.text == "Hello, world"
|
2018-06-25 21:23:40 +00:00
|
|
|
|
2018-06-26 09:09:35 +00:00
|
|
|
response = client.post("/")
|
2018-08-30 13:42:39 +00:00
|
|
|
assert response.status_code == 405
|
2018-09-04 10:52:29 +00:00
|
|
|
assert response.text == "Method Not Allowed"
|
2018-06-26 09:09:35 +00:00
|
|
|
|
2018-06-25 21:26:01 +00:00
|
|
|
response = client.get("/foo")
|
2018-06-25 21:23:40 +00:00
|
|
|
assert response.status_code == 404
|
2018-09-04 10:52:29 +00:00
|
|
|
assert response.text == "Not Found"
|
2018-06-25 21:23:40 +00:00
|
|
|
|
2018-06-25 21:26:01 +00:00
|
|
|
response = client.get("/users")
|
2018-06-25 21:23:40 +00:00
|
|
|
assert response.status_code == 200
|
2018-06-25 21:26:01 +00:00
|
|
|
assert response.text == "All users"
|
2018-06-25 21:23:40 +00:00
|
|
|
|
2018-06-25 21:26:01 +00:00
|
|
|
response = client.get("/users/tomchristie")
|
2018-06-25 21:23:40 +00:00
|
|
|
assert response.status_code == 200
|
2018-06-25 21:26:01 +00:00
|
|
|
assert response.text == "User tomchristie"
|
2018-06-26 09:09:35 +00:00
|
|
|
|
|
|
|
response = client.get("/static/123")
|
|
|
|
assert response.status_code == 200
|
|
|
|
assert response.text == "xxxxx"
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
|
2018-10-29 11:14:42 +00:00
|
|
|
def test_url_path_for():
|
|
|
|
assert app.url_path_for("homepage") == "/"
|
|
|
|
assert app.url_path_for("user", username="tomchristie") == "/users/tomchristie"
|
|
|
|
assert app.url_path_for("websocket_endpoint") == "/ws"
|
2018-10-29 09:22:45 +00:00
|
|
|
with pytest.raises(NoMatchFound):
|
2018-10-29 11:14:42 +00:00
|
|
|
assert app.url_path_for("broken")
|
2018-08-17 15:36:48 +00:00
|
|
|
|
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
def test_router_add_route():
|
|
|
|
response = client.get("/func")
|
|
|
|
assert response.status_code == 200
|
|
|
|
assert response.text == "Hello, world!"
|
|
|
|
|
|
|
|
|
2018-10-30 16:08:05 +00:00
|
|
|
def test_router_duplicate_path():
|
|
|
|
response = client.post("/func")
|
|
|
|
assert response.status_code == 200
|
|
|
|
assert response.text == "Hello, POST!"
|
|
|
|
|
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
def test_router_add_websocket_route():
|
|
|
|
with client.websocket_connect("/ws") as session:
|
|
|
|
text = session.receive_text()
|
|
|
|
assert text == "Hello, world!"
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
with client.websocket_connect("/ws/test") as session:
|
|
|
|
text = session.receive_text()
|
|
|
|
assert text == "Hello, test!"
|
|
|
|
|
2018-10-26 09:30:54 +00:00
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
def http_endpoint(request):
|
2018-10-29 11:14:42 +00:00
|
|
|
url = request.url_for("http_endpoint")
|
|
|
|
return Response("URL: %s" % url, media_type="text/plain")
|
2018-08-17 15:36:48 +00:00
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
class WebsocketEndpoint:
|
|
|
|
def __init__(self, scope):
|
|
|
|
self.scope = scope
|
|
|
|
|
|
|
|
async def __call__(self, receive, send):
|
|
|
|
session = WebSocket(scope=self.scope, receive=receive, send=send)
|
2018-08-17 15:36:48 +00:00
|
|
|
await session.accept()
|
2018-10-29 11:14:42 +00:00
|
|
|
await session.send_json({"URL": str(session.url_for("WebsocketEndpoint"))})
|
2018-08-17 15:36:48 +00:00
|
|
|
await session.close()
|
|
|
|
|
|
|
|
|
2018-10-29 09:22:45 +00:00
|
|
|
mixed_protocol_app = Router(
|
|
|
|
routes=[
|
|
|
|
Route("/", endpoint=http_endpoint),
|
|
|
|
WebSocketRoute("/", endpoint=WebsocketEndpoint),
|
|
|
|
]
|
2018-08-17 15:36:48 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def test_protocol_switch():
|
|
|
|
client = TestClient(mixed_protocol_app)
|
|
|
|
|
|
|
|
response = client.get("/")
|
|
|
|
assert response.status_code == 200
|
2018-10-29 11:14:42 +00:00
|
|
|
assert response.text == "URL: http://testserver/"
|
2018-08-17 15:36:48 +00:00
|
|
|
|
2018-08-28 13:45:06 +00:00
|
|
|
with client.websocket_connect("/") as session:
|
2018-10-29 11:14:42 +00:00
|
|
|
assert session.receive_json() == {"URL": "ws://testserver/"}
|
2018-08-28 13:34:18 +00:00
|
|
|
|
|
|
|
with pytest.raises(WebSocketDisconnect):
|
2018-08-28 13:45:06 +00:00
|
|
|
client.websocket_connect("/404")
|