def test_if_invalid_route_parameter_then_error_response( app, setup, check_status, annotation: typing.Type, string_value: str): setup(app, annotation) client = create_client(app, raise_server_exceptions=False) r = check_status(client, f"/{string_value}") if r is not None: assert "value" in r.json()["detail"]
def test_middleware_called_if_routed_to_sub_app( raw_app, route: str, origin: str, expected: str, expected_body: str ): app = configure( raw_app, cors={"allow_origins": ["example.com", "localhost:8001", "ietf.org"]}, ) @app.route("/") async def index(req, res): res.text = "Hello" sub = App() @sub.route("/") class SubApp: async def get(self, req, res): res.text = "OK" app.mount("/sub", sub) client = create_client(app) res = client.get(route, headers={"origin": origin}) assert res.text == expected_body if not expected: # unknown origin -> no allow-origin header assert "access-control-allow-origin" not in res.headers else: # allowed origin -> allow-origin header" assert "access-control-allow-origin" in res.headers assert res.headers.get("access-control-allow-origin") == expected
def test_if_origin_not_in_allow_origins_then_400(raw_app): app = configure(raw_app, cors={"allow_origins": ["foobar.com"]}) @app.route("/") async def index(req, res): pass client = create_client(app) response = client.options( "/", headers={ "origin": "foobar.com", "access-control-request-method": "GET", }, ) assert response.status_code == 200 response = client.options( "/", headers={ "origin": "example.com", "access-control-request-method": "GET", }, ) assert response.status_code == 400
def test_if_static_dir_is_none_then_no_assets_served(raw_app, tmpdir_factory): static_dir = tmpdir_factory.mktemp("static") _create_asset(static_dir) app = configure(raw_app, static_dir=None) client = create_client(app) assert client.get(f"/static/{FILE_DIR}/{FILE_NAME}").status_code == 404
def test_must_be_configured_to_serve(raw_app): @raw_app.route("/") async def index(req, res): pass with pytest.raises(RuntimeError) as ctx: with create_client(raw_app): pass assert "configure(app)" in str(ctx.value)
def test_assets_are_served_at_static_by_default(raw_app, tmpdir_factory): static_dir = tmpdir_factory.mktemp("static") _create_asset(static_dir) app = configure(raw_app, static_dir=str(static_dir)) client = create_client(app) response = client.get(f"/static/{FILE_DIR}/{FILE_NAME}") assert response.status_code == 200 assert response.text == FILE_CONTENTS
def test_if_host_not_allowed_then_400(raw_app): app = configure(raw_app, allowed_hosts=["example.com"]) client = create_client(app) @app.route("/") async def index(req, res): pass response = client.get("/") assert response.status_code == 400
def test_customize_static_root(raw_app, tmpdir_factory): static_dir = tmpdir_factory.mktemp("static") _create_asset(static_dir) app = configure(raw_app, static_dir=str(static_dir), static_root="assets") client = create_client(app) assert client.get(f"/static/{FILE_DIR}/{FILE_NAME}").status_code == 404 response = client.get(f"/assets/{FILE_DIR}/{FILE_NAME}") assert response.status_code == 200 assert response.text == FILE_CONTENTS
def test_mount_extra_static_files_dirs(raw_app, tmpdir_factory): static_dir = tmpdir_factory.mktemp("staticfiles") _create_asset(static_dir) app = configure(raw_app, static_dir=None) app.mount("assets", static(str(static_dir))) client = create_client(app) response = client.get(f"/assets/{FILE_DIR}/{FILE_NAME}") assert response.status_code == 200 assert response.text == FILE_CONTENTS
def test_if_gzip_enabled_then_response_is_compressed(raw_app): app = configure(raw_app, gzip=True, gzip_min_size=0) @app.route("/") async def index(req, res): pass client = create_client(app) response = client.get("/", headers={"Accept-Encoding": "gzip"}) assert response.status_code == 200 assert response.headers["content-encoding"] == "gzip"
def test_disable_validation_error_handling(raw_app): app = configure(raw_app, handle_typesystem_validation_errors=False) client = create_client(app) @app.route("/todos") class TodoList: async def post(self, req, res): todo = Todo.validate(await req.json()) res.json = dict(todo) with pytest.raises(typesystem.ValidationError): client.post("/todos", json={"title": "Very long string" * 10})
def test_basic(raw_app): def use_foo(app): @app.route("/foo") async def foo(req, res): res.text = "Foo" app = configure(raw_app, plugins=[use_foo]) client = create_client(app) r = client.get("/foo") assert r.status_code == 200 assert r.text == "Foo"
def test_if_hsts_enabled_and_request_is_on_http_then_redirects_to_https( raw_app): app = configure(raw_app, hsts=True) @app.route("/") async def index(req, res): pass client = create_client(app) response = client.get("/", allow_redirects=False) assert 301 <= response.status_code <= 308 assert response.headers["location"] == "https://testserver/"
def test_use_settings(raw_app): @plugin def use_hello(app): hello_message = getattr(settings, "HELLO_MESSAGE") @app.route("/hello") async def foo(req, res): res.text = hello_message app = configure(raw_app, hello_message="Hello, plugins!") client = create_client(app) r = client.get("/hello") assert r.status_code == 200 assert r.text == "Hello, plugins!"
def test_todos(): settings._clear() from todos.asgi import app client = create_client(app) r = client.post("/todos", json={"title": "Make breakfast"}) assert r.status_code == 201 assert r.json() == {"title": "Make breakfast", "done": False} r = client.post( "/todos", json={"title": "Buy cornflakes at the store and make breakfast"}, ) assert r.status_code == 400 assert "title" in r.json()["detail"]
def test_no_allowed_origins_by_default(raw_app): app = configure(raw_app, cors=True) @app.route("/") async def index(req, res): pass client = create_client(app) response = client.options( "/", headers={ "origin": "foobar.com", "access-control-request-method": "GET", }, ) assert response.status_code == 400
def test_redirect_trailing_slash(raw_app, redirect): settings = {} if redirect is not None: settings["redirect_trailing_slash"] = redirect app = configure(raw_app, **settings) client = create_client(app) @app.route("/foo/") async def foo(req, res): pass r = client.get("/foo", allow_redirects=False) if redirect or redirect is None: assert r.status_code == 302 else: assert r.status_code == 404
def test_allow_origin(raw_app, origin: str, allowed: bool): app = configure(raw_app, cors={"allow_origins": ["example.com", "localhost:8001"]}) @app.route("/") async def index(req, res): res.text = "OK" client = create_client(app) r = client.get("/", headers={"origin": origin}) assert r.text == "OK" assert r.status_code == 200 if allowed else 400 if allowed: # allowed origin -> allow-origin header assert "access-control-allow-origin" in r.headers assert r.headers["access-control-allow-origin"] == origin else: # unknown origin -> no allow-origin header assert "access-control-allow-origin" not in r.headers
def test_todos(): settings._clear() from .app import app client = create_client(app) r = client.get("/unseen-todos") assert r.status_code == 200 assert len(r.json()) == 3 r = client.get("/unseen-todos") assert r.status_code == 200 assert len(r.json()) == 0 r = client.post("/todos", json={"content": "test"}) assert r.status_code == 201 r = client.get("/unseen-todos") assert r.status_code == 200 assert len(r.json()) == 1 assert r.json()[0]["content"] == "test"
def test_sessions_enabled_secret_key_present(raw_app, from_env): if from_env: with override_env("SECRET_KEY", "not-so-secret"): app = configure(raw_app, sessions=True) else: app = configure(raw_app, sessions={"secret_key": "not-so-secret"}) @app.route("/set", methods=["post"]) async def set_session(req, res): req.session["data"] = "something" res.text = "Saved" @app.route("/") async def index(req, res): data = req.session["data"] res.text = f"Hello {data}" client = create_client(app) client.post("/set") response = client.get("/") assert "something" in response.text assert "session" in response.cookies
def test_allow_method(raw_app, method, allowed): app = configure( raw_app, cors={ "allow_origins": ["foobar.com"], "allow_methods": ["GET"] }, ) @app.route("/") async def index(req, res): pass client = create_client(app) r = client.options( "/", headers={ "origin": "foobar.com", "access-control-request-method": method, }, ) assert r.status_code == 200 if allowed else 400
def test_custom_error_handler(app: App, exception_cls, success): called = False @app.error_handler(KeyError) async def on_key_error(req, res, exc): nonlocal called res.text = "Oops!" called = True @app.route("/") async def index(req, res): raise exception_cls("foo") client = create_client(app, raise_server_exceptions=False) response = client.get("/") assert called is success if success: assert response.status_code == 200 assert response.text == "Oops!" else: assert response.status_code == 500
def client(): return create_client(app)