Example #1
0
async def test_session_middleware_with_encryptor(app, mock_receive, mock_send):
    app.middlewares.append(
        SessionMiddleware("LOREM_IPSUM",
                          encryptor=FernetEncryptor(Fernet.generate_key())))

    @app.router.get("/")
    def home(request: Request):
        session = request.session

        assert isinstance(session, Session)
        session["foo"] = "Some value"

        return text("Hello, World")

    @app.router.get("/second")
    def second(request: Request):
        session = request.session

        assert "foo" in session
        assert session["foo"] == "Some value"

        return text("Hello, World")

    await app.start()

    await app(
        get_example_scope(
            "GET",
            "/",
        ),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200

    session_set_cookie = response.headers.get_single(b"Set-Cookie")
    assert session_set_cookie is not None

    cookie = parse_cookie(session_set_cookie)

    await app(
        get_example_scope(
            "GET",
            "/second",
            [
                [b"cookie", b"session=" + cookie.value.encode()],
            ],
        ),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200

    session_set_cookie = response.headers.get_first(b"Set-Cookie")
    assert session_set_cookie is None
Example #2
0
async def test_session_middleware_handling_of_expired_signature(
        app, mock_receive, mock_send):
    app.middlewares.append(SessionMiddleware("LOREM_IPSUM", session_max_age=1))

    @app.router.get("/")
    def home(request: Request):
        session = request.session

        assert isinstance(session, Session)
        session["foo"] = "Some value"

        return text("Hello, World")

    @app.router.get("/second")
    def second(request: Request):
        session = request.session

        assert "foo" not in session

        return text("Hello, World")

    await app.start()

    await app(
        get_example_scope(
            "GET",
            "/",
        ),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200

    session_set_cookie = response.headers.get_single(b"Set-Cookie")
    assert session_set_cookie is not None

    cookie = parse_cookie(session_set_cookie)

    time.sleep(2)

    await app(
        get_example_scope(
            "GET",
            "/second",
            [
                [b"cookie", b"session=" + cookie.value.encode()],
            ],
        ),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200

    session_set_cookie = response.headers.get_first(b"Set-Cookie")
    assert session_set_cookie is None
async def test_pretty_json_response_in_controller(obj: Any,
                                                  values: Dict[str, Any], app,
                                                  mock_receive, mock_send):
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        @get("/")
        def greet(self):
            return self.pretty_json(obj)

    await app.start()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    raw = await response.text()
    assert response.status == 200

    content_type = response.headers.get_single(b"content-type")
    assert content_type == b"application/json"

    raw = await response.text()
    data = await response.json()
    for name, value in values.items():
        assert data.get(name) == value
        if isinstance(value, str):
            assert f'    "{name}": "{value}"' in raw
        else:
            assert f'    "{name}": ' in raw
async def test_created_response_with_value(app, mock_receive, mock_send):
    @app.router.get("/")
    async def home():
        return created(
            Foo(UUID("726807b3-5a82-4a59-8bed-65639d3529ba"), "example",
                False),
            location="https://foo.org/foo/726807b3-5a82-4a59-8bed-65639d3529ba",
        )

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 201
    location = response.headers.get_single(b"location")
    assert location == b"https://foo.org/foo/726807b3-5a82-4a59-8bed-65639d3529ba"
    content = await app.response.json()
    assert content.get("id") == "726807b3-5a82-4a59-8bed-65639d3529ba"
    assert content.get("name") == "example"
    assert content.get("ufo") is False
async def test_status_method_response_in_controller(method, expected_status,
                                                    app, mock_receive,
                                                    mock_send):
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    method_name = method.__name__

    class Home(Controller):
        @get("/")
        def greet(self):
            controller_method = getattr(Home, method_name, None)
            return controller_method(self, "Everything's good")

    controller_method = getattr(Home, method_name, None)
    assert callable(controller_method)

    await app.start()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    assert app.response.status == expected_status
    content = await app.response.text()
    assert content == "Everything's good"
async def test_redirect_method_in_controller(method, expected_status, app,
                                             mock_receive, mock_send):
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    method_name = method.__name__

    class Home(Controller):
        @get("/")
        def greet(self):
            controller_method = getattr(Home, method_name, None)
            return controller_method(self, "https://foo.org/somewhere")

    controller_method = getattr(Home, method_name, None)
    assert callable(controller_method)

    await app.start()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == expected_status
    location = response.headers.get_single(b"location")
    assert location == b"https://foo.org/somewhere"
async def test_file_response_from_bytes_io(app, mock_receive, mock_send):
    bytes_io: Optional[BytesIO] = None

    @app.router.get("/")
    async def home():
        nonlocal bytes_io
        bytes_io = BytesIO()
        bytes_io.write("Żywią i bronią".encode("utf-8"))
        return file(bytes_io, "text/plain; charset=utf-8", file_name="foo.txt")

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    assert response.headers.get_single(
        b"content-type") == b"text/plain; charset=utf-8"
    assert (response.headers.get_single(b"content-disposition") ==
            b'attachment; filename="foo.txt"')

    assert bytes_io is not None
    assert bytes_io.closed  # type: ignore
async def test_file_response_from_fs_with_filename(app, mock_receive,
                                                   mock_send):
    file_path = get_file_path("example.config", "files2")

    @app.router.get("/")
    async def home():
        return file(file_path,
                    "text/plain; charset=utf-8",
                    file_name="foo.xml")

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    assert response.headers.get_single(
        b"content-type") == b"text/plain; charset=utf-8"
    assert (response.headers.get_single(b"content-disposition") ==
            b'attachment; filename="foo.xml"')

    text = await response.text()
    with open(file_path, mode="rt", encoding="utf8") as f:
        contents = f.read()
        assert contents == text
async def test_status_method_without_body_response_in_controller(
        method, expected_status, app, mock_receive, mock_send):
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    method_name = method.__name__

    class Home(Controller):
        @get("/")
        def greet(self):
            controller_method = getattr(Home, method_name, None)
            return controller_method(self)

    controller_method = getattr(Home, method_name, None)
    assert callable(controller_method)

    await app.start()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == expected_status
    assert response.has_body() is False
async def test_file_response_from_byte_array(app, mock_receive, mock_send):
    value = bytearray()
    value.extend(b"Hello!\n")
    value.extend(b"World!\n\n")
    value.extend(b"...")
    expected_result = bytes(value).decode("utf8")

    @app.router.get("/")
    async def home():
        return file(
            value,
            "text/plain",
            file_name="example.txt",
            content_disposition=ContentDispositionType.INLINE,
        )

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    assert response.headers.get_single(b"content-type") == b"text/plain"
    assert (response.headers.get_single(b"content-disposition") ==
            b'inline; filename="example.txt"')

    text = await response.text()
    assert text == expected_result
async def test_file_response_from_generator_inline_with_name(
        app, mock_receive, mock_send):
    @app.router.get("/")
    async def home():
        return file(
            get_example_css,
            "text/css",
            file_name="home.css",
            content_disposition=ContentDispositionType.INLINE,
        )

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    assert response.headers.get_single(b"content-type") == b"text/css"
    assert (response.headers.get_single(b"content-disposition") ==
            b'inline; filename="home.css"')

    text = await response.text()
    assert text == await read_from_asynciterable(get_example_css)
async def test_pretty_json_response(obj: Any, values: Dict[str, Any], app,
                                    mock_receive, mock_send):
    @app.router.get("/")
    async def home():
        return pretty_json(obj)

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200

    content_type = response.headers.get_single(b"content-type")
    assert content_type == b"application/json"

    raw = await response.text()
    data = await response.json()
    for name, value in values.items():
        assert data.get(name) == value
        if isinstance(value, str):
            assert f'    "{name}": "{value}"' in raw
        else:
            assert f'    "{name}": ' in raw
async def _view_scenario(app: FakeApplication, expected_text, url="/"):
    app.build_services()
    app.normalize_handlers()
    await app(get_example_scope("GET", url), MockReceive(), MockSend())
    text = await app.response.text()
    assert text == expected_text
    assert app.response.status == 200
Example #14
0
async def test_serve_files_with_custom_files_handler(app, mock_receive,
                                                     mock_send):
    file_path = files2_index_path

    with open(file_path, mode="rt") as actual_file:
        expected_body = actual_file.read()

    class CustomFilesHandler(FilesHandler):
        def __init__(self) -> None:
            self.calls = []

        def open(self, file_path: str, mode: str = "rb") -> FileContext:
            self.calls.append(file_path)
            return super().open(file_path, mode)

    app.files_handler = CustomFilesHandler()

    folder_path = get_folder_path("files2")
    app.serve_files(folder_path, discovery=True)

    await app.start()

    scope = get_example_scope("GET", "/index.html", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    body = await response.text()
    assert body == expected_body

    assert app.files_handler.calls[0] == file_path
Example #15
0
async def test_serve_files_discovery(folder_name: str, app, mock_receive,
                                     mock_send):
    folder_path = get_folder_path(folder_name)
    app.serve_files(folder_path, discovery=True)
    extensions = get_default_extensions()

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    body = await response.text()

    folder = Path(folder_path)
    for item in folder.iterdir():
        if item.is_dir():
            assert f"/{item.name}" in body
            continue

        file_extension = get_file_extension(str(item))
        if file_extension in extensions:
            assert f"/{item.name}" in body
        else:
            assert item.name not in body
Example #16
0
async def test_static_files_support_authentication_by_route(
    app, mock_receive, mock_send
):
    app.use_authentication().add(MockNotAuthHandler())

    app.use_authorization().add(
        AdminsPolicy()
    ).default_policy += AuthenticatedRequirement()

    @app.router.get("/")
    async def home():
        return None

    app.serve_files(get_folder_path("files"), allow_anonymous=False)
    app.serve_files(get_folder_path("files2"), allow_anonymous=True, root_path="/login")

    await app.start()

    await app(get_example_scope("GET", "/"), mock_receive(), mock_send)

    assert app.response.status == 401

    await app(get_example_scope("GET", "/lorem-ipsum.txt"), mock_receive(), mock_send)

    assert app.response.status == 401

    await app(get_example_scope("GET", "/login/index.html"), mock_receive(), mock_send)

    assert app.response.status == 200
    content = await app.response.text()
    assert (
        content
        == """<!DOCTYPE html>
<html>
  <head>
    <title>Example.</title>
    <link rel="stylesheet" type="text/css" href="/styles/main.css" />
  </head>
  <body>
    <h1>Lorem ipsum</h1>
    <p>Dolor sit amet.</p>
    <script src="/scripts/main.js"></script>
  </body>
</html>
"""
    )
Example #17
0
async def test_can_serve_files_with_relative_paths(files2_index_contents, app,
                                                   mock_receive, mock_send):
    folder_path = get_folder_path("files2")
    app.serve_files(folder_path, discovery=True)

    await app.start()

    scope = get_example_scope("GET", "/styles/../index.html", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    body = await response.read()
    assert body == files2_index_contents

    scope = get_example_scope("GET", "/styles/fonts/../../index.html", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    body = await response.read()
    assert body == files2_index_contents

    scope = get_example_scope("GET", "/styles/../does-not-exist.html", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 404
Example #18
0
async def test_static_files_support_authentication(app, mock_receive, mock_send):
    app.use_authentication().add(MockNotAuthHandler())

    app.use_authorization().add(
        AdminsPolicy()
    ).default_policy += AuthenticatedRequirement()

    @app.router.get("/")
    async def home():
        return None

    app.serve_files(get_folder_path("files"), allow_anonymous=False)

    await app.start()

    await app(get_example_scope("GET", "/"), mock_receive(), mock_send)

    assert app.response.status == 401

    await app(get_example_scope("GET", "/lorem-ipsum.txt"), mock_receive(), mock_send)

    assert app.response.status == 401
Example #19
0
async def test_authorization_default_requires_authenticated_user(
    app, mock_receive, mock_send
):
    app.use_authentication().add(MockNotAuthHandler())

    app.use_authorization()

    @app.router.get("/")
    async def home():
        return None

    @auth()
    @app.router.get("/admin")
    async def admin():
        return None

    app.prepare()
    await app(get_example_scope("GET", "/"), mock_receive(), mock_send)
    assert app.response.status == 204

    await app(get_example_scope("GET", "/admin"), mock_receive(), mock_send)
    assert app.response.status == 401
Example #20
0
async def test_authorization_default_allows_anonymous(app, mock_receive, mock_send):
    app.use_authentication().add(MockAuthHandler())

    app.use_authorization().add(AdminsPolicy())

    @app.router.get("/")
    async def home():
        return None

    app.prepare()
    await app(get_example_scope("GET", "/"), mock_receive(), mock_send)

    assert app.response.status == 204
Example #21
0
async def test_authorization_unauthorized_error(app, mock_receive, mock_send):
    app.use_authentication().add(MockAuthHandler())

    app.use_authorization().add(AdminsPolicy())

    @auth("admin")
    @app.router.get("/")
    async def home():
        return None

    app.prepare()
    await app(get_example_scope("GET", "/"), mock_receive(), mock_send)

    assert app.response.status == 401
Example #22
0
async def test_serve_files_no_discovery(app, mock_receive, mock_send):
    # Note the folder files3 does not contain an index.html page
    app.serve_files(get_folder_path("files3"))

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 404
Example #23
0
async def test_serve_files_can_disable_index_html_by_default(
        app, mock_receive, mock_send):
    app.serve_files(get_folder_path("files2"), index_document=None)

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 404
Example #24
0
async def test_authorization_policy_success(app, mock_receive, mock_send):
    admin = Identity({"id": "001", "name": "Charlie Brown", "role": "admin"}, "JWT")

    app.use_authentication().add(MockAuthHandler(admin))

    app.use_authorization().add(AdminsPolicy())

    @auth("admin")
    @app.router.get("/")
    async def home():
        return None

    app.prepare()
    await app(get_example_scope("GET", "/"), mock_receive(), mock_send)

    assert app.response.status == 204
Example #25
0
async def test_serve_files_serves_index_html_by_default(
        files2_index_contents, app, mock_receive, mock_send):
    app.serve_files(get_folder_path("files2"))

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 200
    assert files2_index_contents == await response.read()
Example #26
0
async def test_cannot_serve_files_with_unhandled_extension(
        app, mock_receive, mock_send):
    folder_path = get_folder_path("files2")
    app.serve_files(folder_path, discovery=True, extensions={".py"})

    await app.start()

    scope = get_example_scope("GET", "/example.config", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 404
Example #27
0
async def test_cannot_serve_files_outside_static_folder(
        app, mock_receive, mock_send):
    folder_path = get_folder_path("files")
    app.serve_files(folder_path, discovery=True, extensions={".py"})

    await app.start()

    scope = get_example_scope("GET", "../test_files_serving.py", [])
    await app(
        scope,
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 404
async def test_status_code_response_with_empty_body(status: int, app,
                                                    mock_receive, mock_send):
    @app.router.get("/")
    async def home():
        return status_code(status)

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    assert app.response.status == status
    content = await app.response.text()
    assert content == ""
async def test_status_method_response_empty_body(method, expected_status, app,
                                                 mock_receive, mock_send):
    @app.router.get("/")
    async def home():
        return method()

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    assert app.response.status == expected_status
    content = await app.response.text()
    assert content == ""
async def test_created_response_with_empty_body(app, mock_receive, mock_send):
    @app.router.get("/")
    async def home():
        return created(location="https://foo.org/foo/001")

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        mock_receive(),
        mock_send,
    )

    response = app.response
    assert response.status == 201
    location = response.headers.get_single(b"location")
    assert location == b"https://foo.org/foo/001"