def test_errors_raised_in_callback_are_handled(api: API, when): class CustomError(Exception): pass @api.error_handler(CustomError) def handle_error(req, res, exception): res.text = "gotcha!" class MiddlewareWithErrors(Middleware): async def before_dispatch(self, req, res): if when == "before": raise CustomError async def after_dispatch(self, req, res): if when == "after": raise CustomError api.add_middleware(MiddlewareWithErrors) @api.route("/") async def index(req, res): pass client = api.build_client(raise_server_exceptions=False) r = client.get("/") assert r.status_code == 200 assert r.text == "gotcha!"
def test_from_obj(api: API): class MyView: async def get(self, req, res): pass api.route("/")(MyView()) assert api.client.get("/").status_code == 200
def test_if_port_env_var_is_set_then_specified_host_is_used(api: API): with env("PORT", "4242"): def run(app, host, **kwargs): assert host == "example.com" api.run(_run=run, host="example.com")
def test_if_port_env_var_is_set_then_host_is_any_and_port_is_env_var(api: API): with env("PORT", "4242"): def run(app, host, port, **kwargs): assert host == "0.0.0.0" assert port == 4242 assert app == api api.run(_run=run)
def test_if_middleware_is_added_then_it_is_called(api: API): with build_middleware() as middleware: api.add_middleware(middleware) @api.route("/") async def index(req, res): pass api.client.get("/")
def test_mount_extra_static_files_dirs(tmpdir_factory): static_dir = tmpdir_factory.mktemp("staticfiles") _create_asset(static_dir) api = API(static_dir=None) api.mount("assets", static(str(static_dir))) response = api.client.get(f"/assets/{FILE_DIR}/{FILE_NAME}") assert response.status_code == 200 assert response.text == FILE_CONTENTS
def test_name_can_be_explicitly_given(api: API): @api.route("/about/{who}", name="about-someone") async def about(req, res, who): pass with pytest.raises(HTTPError): api.url_for(name="about", who="me") url = api.url_for("about-someone", who="me") assert url == "/about/me"
def test_if_prefix_then_routes_mounted_at_prefix(api: API): numbers = Recipe("numbers", prefix="/numbers-yo") @numbers.route("/real") async def real(req, res): pass api.recipe(numbers) assert api.url_for("numbers:real") == "/numbers-yo/real"
def test_callbacks_can_be_sync(api: API): with build_middleware(sync=True) as middleware: api.add_middleware(middleware) @api.route("/") async def index(req, res): pass response = api.client.get("/") assert response.status_code == 200
def test_if_prefix_not_given_then_routes_mounted_at_slash_name(api: API): numbers = Recipe("numbers") @numbers.route("/real") async def real(req, res): pass api.recipe(numbers) assert api.url_for("numbers:real") == "/numbers/real"
def test_only_before_dispatch_is_called_if_method_not_allowed(api: API): with build_middleware(expect_call_after=False) as middleware: api.add_middleware(middleware) @api.route("/") async def index(req, res): pass response = api.client.put("/") assert response.status_code == 405
def test_can_pass_extra_kwargs(api: API): kwargs = {"foo": "bar"} with build_middleware(expect_kwargs=kwargs) as middleware: api.add_middleware(middleware, **kwargs) @api.route("/") async def index(req, res): pass api.client.get("/")
def test_recipe_book(api: API, numbers): api.recipe(numbers) response = api.client.get("/numbers/integers/3.5") assert response.status_code == 200 assert response.json() == {"value": 3} response = api.client.get("/numbers/floats/1") assert response.status_code == 200 assert response.json() == {"value": 1.0}
def test_non_decorator_syntax(api: API): message = None async def setup(): nonlocal message message = "hi" api.on("startup", setup) with api.client: assert message == "hi"
def test_if_asgi_middleware_is_applied(): api = API(enable_gzip=False) api.add_asgi_middleware(GZipMiddleware, minimum_size=0) @api.route("/") async def index(req, res): pass response = api.client.get("/", headers={"Accept-Encoding": "gzip"}) assert response.status_code == 200 assert response.headers["content-encoding"] == "gzip"
def test_builtin_handlers(api: API, handler, check_response): api.add_error_handler(HTTPError, handler) @api.route("/") async def index(req, res): raise HTTPError(403) response = api.client.get("/") assert response.status_code == 403 print(response.text) assert check_response(response)
def test_replace_media_handlers(api: API, foo_type, handle_foo): api.media_handlers = {foo_type: handle_foo} api.media_type = foo_type @api.route("/") async def index(req, res): res.media = "bar" response = api.client.get("/") assert response.status_code == 200 assert response.headers["content-type"] == foo_type assert response.text == handle_foo("bar")
def test_add_and_use_custom_media_handler(api: API, foo_type, handle_foo): api.media_handlers[foo_type] = handle_foo api.media_type = foo_type @api.route("/") async def index(req, res): res.media = "bar" response = api.client.get("/") assert response.status_code == 200 assert response.headers["content-type"] == foo_type assert response.text == handle_foo("bar")
def test_debug_response(api: API, accept: str, content_type: str): api.debug = True @api.route("/") async def index(req, res): raise ValueError("Oops") client = api.build_client(raise_server_exceptions=False) r = client.get("/", headers={"accept": accept}) assert r.status_code == 500 assert r.headers["content-type"] == content_type assert 'raise ValueError("Oops")' in r.text
def test_if_media_type_not_supported_then_setting_it_raises_error(api: API): foo_type = "application/foo" with pytest.raises(UnsupportedMediaType) as ctx: api.media_type = foo_type assert foo_type in str(ctx.value) with pytest.raises(UnsupportedMediaType) as ctx: API(media_type="application/foo") assert foo_type in str(ctx.value)
def test_on_async_function_view(api: API): numbers = Recipe("numbers") with async_function_hooks() as (before, after): @numbers.before(before) @numbers.after(after) @numbers.route("/real") async def real_numbers(req, res): pass api.recipe(numbers) api.client.get("/numbers/real")
def test_on_class_based_view(api: API): numbers = Recipe("numbers") with async_function_hooks() as (before, after): @numbers.before(before) @numbers.route("/real") class RealNumbers: @numbers.after(after) async def get(self, req, res): pass api.recipe(numbers) api.client.get("/numbers/real")
def test_render_sync_template_in_recipe_route(template_file: TemplateWrapper, api: API): numbers = Recipe("numbers") @numbers.route("/sync") def get_numbers_sync(req, res): res.html = numbers.template_sync(template_file.name, **template_file.context) api.recipe(numbers) response = api.client.get("/numbers/sync") assert response.status_code == 200 assert response.text == template_file.rendered
def test_name_is_inferred_from_view_name(api: API): @api.route("/about/{who}") class AboutPerson: async def get(self, req, res, who): pass url = api.url_for("about_person", who="Godzilla") assert url == "/about/Godzilla" @api.route("/about/{who}") async def about_who(req, res, who): pass url = api.url_for("about_who", who="Godzilla") assert url == "/about/Godzilla"
def test_websocket_recipe_route(api: API): chat = Recipe("chat") @chat.websocket_route("/room/{name}", receive_type="json", send_type="text") async def chat_room(ws: WebSocket, name: str): async with ws: message = await ws.receive() await ws.send(f"[{name}]: {message['text']}") api.recipe(chat) with api.client.websocket_connect("/chat/room/test") as client: client.send_json({"text": "Hello"}) assert client.receive_text() == "[test]: Hello"
def test_if_route_exists_then_url_for_returns_full_path(api: API): @api.route("/about/{who}") async def about(req, res, who): pass url = api.url_for("about", who="me") assert url == "/about/me"
def test_on_class_based_views(api: API): @api.route("/about/{who}") class AboutPerson: pass url = api.url_for("about_person", who="Godzilla") assert url == "/about/Godzilla"
def test_if_static_dir_is_none_then_no_assets_served(tmpdir_factory): static_dir = tmpdir_factory.mktemp("static") _create_asset(static_dir) api = API(static_dir=None) assert api.client.get(f"/static/{FILE_DIR}/{FILE_NAME}").status_code == 404
def test_use_namespace(api: API): @api.route("/about", namespace="blog") async def about(req, res): pass url = api.url_for("blog:about") assert url == "/about"
def test_return_response_in_before_hook(api: API): class NopeMiddleware(Middleware): async def before_dispatch(self, req, res): res.text = "Foo" return res api.add_middleware(NopeMiddleware) @api.route("/") async def index(req, res): # Should not be called assert False r = api.client.get("/") assert r.status_code == 200 assert r.text == "Foo"