import os
+import typing
from pathlib import Path
from unittest import mock
from starlette.applications import Starlette
from starlette.background import BackgroundTask
from starlette.middleware import Middleware
-from starlette.middleware.base import BaseHTTPMiddleware
+from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
+from starlette.requests import Request
+from starlette.responses import Response
from starlette.routing import Route
from starlette.templating import Jinja2Templates
+from starlette.testclient import TestClient
+TestClientFactory = typing.Callable[..., TestClient]
-def test_templates(tmpdir, test_client_factory):
+
+def test_templates(tmpdir: Path, test_client_factory: TestClientFactory) -> None:
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
file.write("<html>Hello, <a href='{{ url_for('homepage') }}'>world</a></html>")
- async def homepage(request):
+ async def homepage(request: Request) -> Response:
return templates.TemplateResponse(request, "index.html")
- app = Starlette(
- debug=True,
- routes=[Route("/", endpoint=homepage)],
- )
+ app = Starlette(debug=True, routes=[Route("/", endpoint=homepage)])
templates = Jinja2Templates(directory=str(tmpdir))
client = test_client_factory(app)
response = client.get("/")
assert response.text == "<html>Hello, <a href='http://testserver/'>world</a></html>"
- assert response.template.name == "index.html"
- assert set(response.context.keys()) == {"request"}
+ assert response.template.name == "index.html" # type: ignore
+ assert set(response.context.keys()) == {"request"} # type: ignore
-def test_calls_context_processors(tmp_path, test_client_factory):
+def test_calls_context_processors(
+ tmp_path: Path, test_client_factory: TestClientFactory
+) -> None:
path = tmp_path / "index.html"
path.write_text("<html>Hello {{ username }}</html>")
- async def homepage(request):
+ async def homepage(request: Request) -> Response:
return templates.TemplateResponse(request, "index.html")
- def hello_world_processor(request):
+ def hello_world_processor(request: Request) -> typing.Dict[str, str]:
return {"username": "World"}
app = Starlette(
client = test_client_factory(app)
response = client.get("/")
assert response.text == "<html>Hello World</html>"
- assert response.template.name == "index.html"
- assert set(response.context.keys()) == {"request", "username"}
+ assert response.template.name == "index.html" # type: ignore
+ assert set(response.context.keys()) == {"request", "username"} # type: ignore
-def test_template_with_middleware(tmpdir, test_client_factory):
+def test_template_with_middleware(
+ tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
file.write("<html>Hello, <a href='{{ url_for('homepage') }}'>world</a></html>")
- async def homepage(request):
+ async def homepage(request: Request) -> Response:
return templates.TemplateResponse(request, "index.html")
class CustomMiddleware(BaseHTTPMiddleware):
- async def dispatch(self, request, call_next):
+ async def dispatch(
+ self, request: Request, call_next: RequestResponseEndpoint
+ ) -> Response:
return await call_next(request)
app = Starlette(
client = test_client_factory(app)
response = client.get("/")
assert response.text == "<html>Hello, <a href='http://testserver/'>world</a></html>"
- assert response.template.name == "index.html"
- assert set(response.context.keys()) == {"request"}
+ assert response.template.name == "index.html" # type: ignore
+ assert set(response.context.keys()) == {"request"} # type: ignore
-def test_templates_with_directories(tmp_path: Path, test_client_factory):
+def test_templates_with_directories(
+ tmp_path: Path, test_client_factory: TestClientFactory
+) -> None:
dir_a = tmp_path.resolve() / "a"
dir_a.mkdir()
template_a = dir_a / "template_a.html"
template_a.write_text("<html><a href='{{ url_for('page_a') }}'></a> a</html>")
- async def page_a(request):
+ async def page_a(request: Request) -> Response:
return templates.TemplateResponse(request, "template_a.html")
dir_b = tmp_path.resolve() / "b"
template_b = dir_b / "template_b.html"
template_b.write_text("<html><a href='{{ url_for('page_b') }}'></a> b</html>")
- async def page_b(request):
+ async def page_b(request: Request) -> Response:
return templates.TemplateResponse(request, "template_b.html")
app = Starlette(
client = test_client_factory(app)
response = client.get("/a")
assert response.text == "<html><a href='http://testserver/a'></a> a</html>"
- assert response.template.name == "template_a.html"
- assert set(response.context.keys()) == {"request"}
+ assert response.template.name == "template_a.html" # type: ignore
+ assert set(response.context.keys()) == {"request"} # type: ignore
response = client.get("/b")
assert response.text == "<html><a href='http://testserver/b'></a> b</html>"
- assert response.template.name == "template_b.html"
- assert set(response.context.keys()) == {"request"}
+ assert response.template.name == "template_b.html" # type: ignore
+ assert set(response.context.keys()) == {"request"} # type: ignore
-def test_templates_require_directory_or_environment():
+def test_templates_require_directory_or_environment() -> None:
with pytest.raises(
AssertionError, match="either 'directory' or 'env' arguments must be passed"
):
Jinja2Templates() # type: ignore[call-overload]
-def test_templates_with_directory(tmpdir):
+def test_templates_with_directory(tmpdir: Path) -> None:
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
file.write("Hello")
assert template.render({}) == "Hello"
-def test_templates_with_environment(tmpdir, test_client_factory):
+def test_templates_with_environment(
+ tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
file.write("<html>Hello, <a href='{{ url_for('homepage') }}'>world</a></html>")
- async def homepage(request):
+ async def homepage(request: Request) -> Response:
return templates.TemplateResponse(request, "index.html")
env = jinja2.Environment(loader=jinja2.FileSystemLoader(str(tmpdir)))
client = test_client_factory(app)
response = client.get("/")
assert response.text == "<html>Hello, <a href='http://testserver/'>world</a></html>"
- assert response.template.name == "index.html"
- assert set(response.context.keys()) == {"request"}
+ assert response.template.name == "index.html" # type: ignore
+ assert set(response.context.keys()) == {"request"} # type: ignore
-def test_templates_with_environment_options_emit_warning(tmpdir):
+def test_templates_with_environment_options_emit_warning(tmpdir: Path) -> None:
with pytest.warns(DeprecationWarning):
Jinja2Templates(str(tmpdir), autoescape=True)
-def test_templates_with_kwargs_only(tmpdir, test_client_factory):
+def test_templates_with_kwargs_only(
+ tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
# MAINTAINERS: remove after 1.0
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
spy = mock.MagicMock()
- def page(request):
+ def page(request: Request) -> Response:
return templates.TemplateResponse(
request=request,
name="index.html",
spy.assert_called()
-def test_templates_with_kwargs_only_requires_request_in_context(tmpdir):
+def test_templates_with_kwargs_only_requires_request_in_context(tmpdir: Path) -> None:
# MAINTAINERS: remove after 1.0
templates = Jinja2Templates(directory=str(tmpdir))
def test_templates_with_kwargs_only_warns_when_no_request_keyword(
- tmpdir, test_client_factory
-):
+ tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
# MAINTAINERS: remove after 1.0
path = os.path.join(tmpdir, "index.html")
templates = Jinja2Templates(directory=str(tmpdir))
- def page(request):
+ def page(request: Request) -> Response:
return templates.TemplateResponse(
name="index.html", context={"request": request}
)
client.get("/")
-def test_templates_with_requires_request_in_context(tmpdir):
+def test_templates_with_requires_request_in_context(tmpdir: Path) -> None:
# MAINTAINERS: remove after 1.0
templates = Jinja2Templates(directory=str(tmpdir))
with pytest.warns(DeprecationWarning):
templates.TemplateResponse("index.html", context={})
-def test_templates_warns_when_first_argument_isnot_request(tmpdir, test_client_factory):
+def test_templates_warns_when_first_argument_isnot_request(
+ tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
# MAINTAINERS: remove after 1.0
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
spy = mock.MagicMock()
- def page(request):
+ def page(request: Request) -> Response:
return templates.TemplateResponse(
"index.html",
{"a": "b", "request": request},
spy.assert_called()
-def test_templates_when_first_argument_is_request(tmpdir, test_client_factory):
+def test_templates_when_first_argument_is_request(
+ tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
# MAINTAINERS: remove after 1.0
path = os.path.join(tmpdir, "index.html")
with open(path, "w") as file:
spy = mock.MagicMock()
- def page(request):
+ def page(request: Request) -> Response:
return templates.TemplateResponse(
request,
"index.html",