2022-01-28 16:48:22 +00:00
|
|
|
from datetime import datetime
|
2024-07-27 09:31:16 +00:00
|
|
|
from typing import Iterator
|
2022-01-28 16:48:22 +00:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
from starlette import convertors
|
|
|
|
from starlette.convertors import Convertor, register_url_convertor
|
2024-02-04 18:39:34 +00:00
|
|
|
from starlette.requests import Request
|
2022-01-28 16:48:22 +00:00
|
|
|
from starlette.responses import JSONResponse
|
|
|
|
from starlette.routing import Route, Router
|
2024-07-27 09:31:16 +00:00
|
|
|
from tests.types import TestClientFactory
|
2022-01-28 16:48:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="module", autouse=True)
|
2024-02-04 18:39:34 +00:00
|
|
|
def refresh_convertor_types() -> Iterator[None]:
|
2022-01-28 16:48:22 +00:00
|
|
|
convert_types = convertors.CONVERTOR_TYPES.copy()
|
|
|
|
yield
|
|
|
|
convertors.CONVERTOR_TYPES = convert_types
|
|
|
|
|
|
|
|
|
2023-07-23 21:41:50 +00:00
|
|
|
class DateTimeConvertor(Convertor[datetime]):
|
2022-01-28 16:48:22 +00:00
|
|
|
regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?"
|
|
|
|
|
|
|
|
def convert(self, value: str) -> datetime:
|
|
|
|
return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S")
|
|
|
|
|
|
|
|
def to_string(self, value: datetime) -> str:
|
|
|
|
return value.strftime("%Y-%m-%dT%H:%M:%S")
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
def app() -> Router:
|
|
|
|
register_url_convertor("datetime", DateTimeConvertor())
|
|
|
|
|
2024-02-04 18:39:34 +00:00
|
|
|
def datetime_convertor(request: Request) -> JSONResponse:
|
2022-01-28 16:48:22 +00:00
|
|
|
param = request.path_params["param"]
|
|
|
|
assert isinstance(param, datetime)
|
|
|
|
return JSONResponse({"datetime": param.strftime("%Y-%m-%dT%H:%M:%S")})
|
|
|
|
|
|
|
|
return Router(
|
|
|
|
routes=[
|
|
|
|
Route(
|
|
|
|
"/datetime/{param:datetime}",
|
|
|
|
endpoint=datetime_convertor,
|
|
|
|
name="datetime-convertor",
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-09-01 13:11:01 +00:00
|
|
|
def test_datetime_convertor(test_client_factory: TestClientFactory, app: Router) -> None:
|
2022-01-28 16:48:22 +00:00
|
|
|
client = test_client_factory(app)
|
|
|
|
response = client.get("/datetime/2020-01-01T00:00:00")
|
|
|
|
assert response.json() == {"datetime": "2020-01-01T00:00:00"}
|
|
|
|
|
|
|
|
assert (
|
2024-09-01 13:11:01 +00:00
|
|
|
app.url_path_for("datetime-convertor", param=datetime(1996, 1, 22, 23, 0, 0)) == "/datetime/1996-01-22T23:00:00"
|
2022-01-28 16:48:22 +00:00
|
|
|
)
|
2022-12-03 11:16:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("param, status_code", [("1.0", 200), ("1-0", 404)])
|
2024-09-01 13:11:01 +00:00
|
|
|
def test_default_float_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None:
|
2024-02-04 18:39:34 +00:00
|
|
|
def float_convertor(request: Request) -> JSONResponse:
|
2022-12-03 11:16:16 +00:00
|
|
|
param = request.path_params["param"]
|
|
|
|
assert isinstance(param, float)
|
|
|
|
return JSONResponse({"float": param})
|
|
|
|
|
|
|
|
app = Router(routes=[Route("/{param:float}", endpoint=float_convertor)])
|
|
|
|
|
|
|
|
client = test_client_factory(app)
|
|
|
|
response = client.get(f"/{param}")
|
|
|
|
assert response.status_code == status_code
|