示例#1
0
def test_app_run():
    app = Baguette()

    running = threading.Event()

    async def set_running():
        running.set()

    def do_request():
        if not running.wait(10.0):
            raise TimeoutError("App hasn't started after 10s")

        requests.get("http://127.0.0.1:8080")

    request_thread = threading.Thread(target=do_request)
    request_thread.start()

    app.run(
        host="127.0.0.1",
        port=8080,
        debug=True,
        limit_max_requests=1,  # end after one request
        callback_notify=set_running,
        timeout_notify=1,  # set the running event every second
    )

    request_thread.join()
示例#2
0
async def test_error_middleware(
    path: str,
    method: str,
    body: str,
    expected_response_body: str,
    expected_response_status_code: int,
):
    app = Baguette(error_include_description=False)

    @app.route("/")
    async def index(request):
        return await request.body()

    @app.route("/user/<user_id:int>")
    async def user(user_id: int):
        return str(user_id)

    @app.route("/notimplemented")
    async def notimplemented():
        raise NotImplemented()  # noqa: F901

    @app.route("/error")
    async def error():
        raise Exception()

    request = create_test_request(path=path, method=method, body=body)
    response = await app.handle_request(request)
    assert response.body == expected_response_body
    assert response.status_code == expected_response_status_code
示例#3
0
def create_test_request(
    path: str = "/",
    method: str = "GET",
    headers={
        "server": "baguette",
        "content-type": "text/plain; charset=utf-8"
    },
    querystring: str = "a=b",
    body: str = "",
    json=None,
):
    request = Request(
        Baguette(),
        create_http_scope(
            path=path,
            method=method,
            headers=headers,
            querystring=querystring,
        ),
        Receive(),
    )
    request._body = body
    if json is not None:
        request._json = json

    return request
示例#4
0
async def test_app_call_error():
    app = Baguette()

    scope = {"type": "nonexistent"}
    receive = Receive()
    send = Send()

    with pytest.raises(NotImplementedError):
        await app(scope, receive, send)
示例#5
0
async def test_default_headers_middleware(headers, expected_headers):
    app = Baguette(default_headers={"server": "baguette"})

    @app.route("/")
    async def index(request):
        return Response(body="", headers=request.headers)

    request = create_test_request(headers=headers)
    response = await app.handle_request(request)
    assert response.headers == expected_headers
示例#6
0
async def test_app_add_remove_middleware():
    app = Baguette()

    @app.route("/short")
    async def short():
        return ""

    @app.route("/long")
    async def long():
        await asyncio.sleep(0.2)
        return ""

    assert len(app.middlewares) == 2
    app.add_middleware(TimingMiddleware)
    assert len(app.middlewares) == 3

    request = create_test_request(path="/short")
    response = await app.handle_request(request)
    assert "X-time" in response.headers
    short_time = float(response.headers["X-time"])

    request = create_test_request(path="/long")
    response = await app.handle_request(request)
    assert "X-time" in response.headers
    long_time = float(response.headers["X-time"])

    assert short_time < long_time

    app.remove_middleware(TimingMiddleware)
    assert len(app.middlewares) == 2
示例#7
0
async def test_app_call(scope, receive: Receive, expected_sent_values: list):
    app = Baguette()

    @app.route("/")
    async def index(request):
        return PlainTextResponse(await request.body())

    send = Send()
    await app(scope, receive, send)

    assert len(expected_sent_values) == len(send.values)
    for message in send.values:
        assert message == expected_sent_values.pop(0)
示例#8
0
def test_app_route(setup, expected_attributes: dict):
    app = Baguette()

    handler = setup(app)

    router = app.router.routes.pop()
    while (not router.handler_is_class and router.handler != handler) or (
            router.handler_is_class
            and not isinstance(router.handler, handler)):
        router = app.router.routes.pop()

    for name, value in expected_attributes.items():
        assert getattr(router, name) == value
示例#9
0
async def test_app_render():
    app = Baguette(templates_directory="tests/templates")

    @app.route("/template")
    async def template():
        return await render(
            "index.html",
            paragraphs=["1st paragraph", "2nd paragraph"],
        )

    app = TestClient(app)

    response: HTMLResponse = await app.get("/template")
    assert strip(response.body) == strip(expected_html)
示例#10
0
def test_create_app():
    app = Baguette()
    assert app.debug is False
    assert isinstance(app.router, Router)
    assert isinstance(app.default_headers, Headers)
    assert app.error_response_type == "plain"
    assert app.error_include_description is True

    app = Baguette(
        debug=True,
        default_headers={"server": "baguette"},
        error_response_type="json",
        error_include_description=False,
    )
    assert app.debug is True
    assert isinstance(app.router, Router)
    assert isinstance(app.default_headers, Headers)
    assert app.default_headers["server"] == "baguette"
    assert app.error_response_type == "json"
    assert app.error_include_description is True  # True because debug=True

    with pytest.raises(ValueError):
        Baguette(error_response_type="nonexistent")
示例#11
0
def create_view():
    class TestView(View):
        async def get(self, request):
            return "GET"

        async def post(self, request):
            return "POST"

        async def put(self, request):
            return "PUT"

        async def delete(self, request):
            return "DELETE"

    return TestView(Baguette())
示例#12
0
async def test_app_static(path, file_path, mimetype):
    app = TestClient(Baguette(static_directory="tests/static"))

    response: FileResponse = await app.get(path)

    path = pathlib.Path(file_path).resolve(strict=True)
    async with aiofiles.open(path, "rb") as f:
        content_length = len(await f.read())

    assert isinstance(response, FileResponse)
    assert response.file_path == path
    assert response.mimetype == mimetype
    assert response.headers["content-type"] == mimetype
    assert response.file_size == content_length
    assert int(response.headers["content-length"]) == content_length
示例#13
0
async def test_app_middleware():
    app = Baguette()

    @app.route("/short")
    async def short():
        return ""

    @app.route("/long")
    async def long():
        await asyncio.sleep(0.2)
        return ""

    assert len(app.middlewares) == 2

    @app.middleware()
    class TimingMiddleware(Middleware):
        async def __call__(self, request: Request):
            start_time = time.perf_counter()
            response = await self.next(request)
            response.headers["X-time"] = str(time.perf_counter() - start_time)
            return response

    assert len(app.middlewares) == 3

    @app.middleware()
    async def timing_middleware(next_middleware, request: Request):
        start_time = time.time()
        response = await next_middleware(request)
        process_time = time.time() - start_time
        response.headers["X-time"] = str(process_time)
        return response

    assert len(app.middlewares) == 4

    request = create_test_request(path="/short")
    response = await app.handle_request(request)
    assert "X-time" in response.headers
    short_time = float(response.headers["X-time"])

    request = create_test_request(path="/long")
    response = await app.handle_request(request)
    assert "X-time" in response.headers
    long_time = float(response.headers["X-time"])

    assert short_time < long_time

    app.remove_middleware(timing_middleware)
    app.remove_middleware(TimingMiddleware)
    assert len(app.middlewares) == 2
示例#14
0
async def test_view_create():
    class TestView(View):
        async def get(self, request):
            return "GET"

        async def post(self, request):
            return "POST"

        async def put(self, request):
            return "PUT"

        async def delete(self, request):
            return "DELETE"

        async def nonexistent_method(self, request):
            return "NONEXISTENT"

    view = TestView(Baguette())
    assert view.methods == ["GET", "POST", "PUT", "DELETE"]
    assert await view.get(None) == "GET"
    assert await view.post(None) == "POST"
    assert await view.put(None) == "PUT"
    assert await view.delete(None) == "DELETE"
    assert await view.nonexistent_method(None) == "NONEXISTENT"