Exemple #1
0
async def test_file_response_from_bytes_io():
    app = FakeApplication()
    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", "/", []),
        MockReceive(),
        MockSend(),
    )

    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
Exemple #2
0
async def test_pretty_json_response(obj: Any, values: Dict[str, Any]):
    app = FakeApplication()

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

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    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 test_serve_files_with_custom_files_handler():
    app = FakeApplication()
    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(ServeFilesOptions(folder_path, discovery=True))

    await app.start()

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

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

    assert app.files_handler.calls[0] == file_path
Exemple #4
0
async def test_status_method_response_in_controller(method, expected_status):
    app = FakeApplication()
    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", "/", []),
        MockReceive(),
        MockSend(),
    )

    assert app.response.status == expected_status
    content = await app.response.text()
    assert content == "Everything's good"
Exemple #5
0
async def test_file_response_from_fs_with_filename():
    app = FakeApplication()
    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", "/", []),
        MockReceive(),
        MockSend(),
    )

    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
Exemple #6
0
async def test_redirect_method_in_controller(method, expected_status):
    app = FakeApplication()
    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", "/", []),
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == expected_status
    location = response.headers.get_single(b"location")
    assert location == b"https://foo.org/somewhere"
Exemple #7
0
async def test_pretty_json_response_in_controller(obj: Any, values: Dict[str, Any]):
    app = FakeApplication()
    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", "/", []),
        MockReceive(),
        MockSend(),
    )

    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
Exemple #8
0
async def test_file_response_from_generator_inline_with_name():
    app = FakeApplication()

    @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", "/", []),
        MockReceive(),
        MockSend(),
    )

    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)
Exemple #9
0
async def test_status_method_without_body_response_in_controller(
    method, expected_status
):
    app = FakeApplication()
    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", "/", []),
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == expected_status
    assert response.has_body() is False
async def test_serve_files_discovery(folder_name: str):
    app = FakeApplication()

    folder_path = get_folder_path(folder_name)
    options = ServeFilesOptions(folder_path, discovery=True)
    app.serve_files(options)

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

    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 options.extensions:
            assert f"/{item.name}" in body
        else:
            assert item.name not in body
Exemple #11
0
async def test_created_response_with_value():
    app = FakeApplication()

    @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", "/", []),
        MockReceive(),
        MockSend(),
    )

    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_can_serve_files_with_relative_paths(files2_index_contents):
    app = FakeApplication()
    folder_path = get_folder_path("files2")
    options = ServeFilesOptions(folder_path, discovery=True)
    app.serve_files(options)

    await app.start()

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

    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,
        MockReceive(),
        MockSend(),
    )

    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,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 404
Exemple #13
0
async def test_serve_files_can_disable_index_html_by_default():
    app = FakeApplication()

    app.serve_files(get_folder_path("files2"), index_document=None)

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 404
async def test_serve_files_serves_index_html_by_default(files2_index_contents):
    app = FakeApplication()

    app.serve_files(ServeFilesOptions(get_folder_path("files2")))

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 200
    assert files2_index_contents == await response.read()
async def test_serve_files_no_discovery():
    app = FakeApplication()

    # Note the folder files3 does not contain an index.html page
    app.serve_files(ServeFilesOptions(get_folder_path("files3")))

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 404
Exemple #16
0
async def test_cannot_serve_files_with_unhandled_extension():
    app = FakeApplication()

    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,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 404
Exemple #17
0
async def test_cannot_serve_files_outside_static_folder():
    app = FakeApplication()

    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,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 404
Exemple #18
0
async def test_status_code_response_with_empty_body(status: int):
    app = FakeApplication()

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

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    assert app.response.status == status
    content = await app.response.text()
    assert content == ""
Exemple #19
0
async def test_status_method_response_empty_body(method, expected_status):
    app = FakeApplication()

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

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    assert app.response.status == expected_status
    content = await app.response.text()
    assert content == ""
Exemple #20
0
async def test_no_body_method(method, expected_status):
    app = FakeApplication()

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

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == expected_status
    assert response.has_body() is False
Exemple #21
0
async def test_serve_files_deprecated_serve_files_options(files2_index_contents):
    app = FakeApplication()

    with pytest.deprecated_call():
        app.serve_files(ServeFilesOptions(get_folder_path("files2")))  # type: ignore

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 200
    assert files2_index_contents == await response.read()
Exemple #22
0
async def test_serve_files_fallback_document(files2_index_contents: bytes):
    """Feature used to serve SPAs that use HTML5 History API"""
    app = FakeApplication()

    app.serve_files(get_folder_path("files2"), fallback_document="index.html")

    await app.start()

    for path in {"/", "/one", "/one/two", "/one/two/anything.txt"}:
        scope = get_example_scope("GET", path, [])
        await app(
            scope,
            MockReceive(),
            MockSend(),
        )

        response = app.response
        assert response.status == 200
        assert await response.read() == files2_index_contents
Exemple #23
0
async def test_redirect_method_bytes_location(method, expected_status):
    app = FakeApplication()

    @app.router.get("/")
    async def home():
        return method(b"https://foo.org/somewhere")

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == expected_status
    location = response.headers.get_single(b"location")
    assert location == b"https://foo.org/somewhere"
Exemple #24
0
async def test_status_code_response_with_object(status: int):
    app = FakeApplication()

    @app.router.get("/")
    async def home():
        return status_code(status, Foo(uuid4(), "foo", True))

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    assert app.response.status == status
    content = await app.response.json()
    assert content.get("name") == "foo"
    assert content.get("ufo") is True
Exemple #25
0
async def test_created_response_with_empty_body():
    app = FakeApplication()

    @app.router.get("/")
    async def home():
        return created(location="https://foo.org/foo/001")

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    response = app.response
    assert response.status == 201
    location = response.headers.get_single(b"location")
    assert location == b"https://foo.org/foo/001"
Exemple #26
0
async def test_status_code_response_with_text_in_controller(status: int):
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        @get("/")
        def greet(self):
            return self.status_code(status, "Everything's good")

    await app.start()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    assert app.response.status == status
    content = await app.response.text()
    assert content == "Everything's good"
Exemple #27
0
async def test_serve_files_custom_index_page():
    app = FakeApplication()

    # Note the folder files3 does not contain an index.html page
    app.serve_files(get_folder_path("files3"), index_document="lorem-ipsum.txt")

    await app.start()

    scope = get_example_scope("GET", "/", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

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

    with open(get_file_path("lorem-ipsum.txt", "files3"), mode="rt") as actual_file:
        content = actual_file.read()
        assert content == await response.text()
async def test_serve_files_discovery_subfolder():
    app = FakeApplication()

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

    await app.start()

    scope = get_example_scope("GET", "/scripts", [])
    await app(
        scope,
        MockReceive(),
        MockSend(),
    )

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

    folder = Path(folder_path) / "scripts"
    for item in folder.iterdir():
        assert f"/{item.name}" in body
Exemple #29
0
async def test_file_response_from_generator():
    app = FakeApplication()

    @app.router.get("/")
    async def home():
        return file(get_example_css, "text/css")

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

    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"attachment"

    text = await response.text()
    assert text == await read_from_asynciterable(get_example_css)
Exemple #30
0
async def test_html_response_with_status(content, status):
    app = FakeApplication()

    @app.router.get("/")
    async def home():
        return html(content, status)

    app.normalize_handlers()

    await app(
        get_example_scope("GET", "/", []),
        MockReceive(),
        MockSend(),
    )

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

    content_type = response.headers.get_single(b"content-type")
    assert content_type == b"text/html; charset=utf-8"

    body = await response.text()
    assert body == content