File: test_convertors.py

package info (click to toggle)
starlette 1.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,104 kB
  • sloc: python: 13,266; sh: 35; javascript: 32; makefile: 6
file content (96 lines) | stat: -rw-r--r-- 3,264 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from collections.abc import Iterator
from datetime import datetime
from uuid import UUID

import pytest

from starlette import convertors
from starlette.convertors import Convertor, register_url_convertor
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route, Router
from tests.types import TestClientFactory


@pytest.fixture(scope="module", autouse=True)
def refresh_convertor_types() -> Iterator[None]:
    convert_types = convertors.CONVERTOR_TYPES.copy()
    yield
    convertors.CONVERTOR_TYPES = convert_types


class DateTimeConvertor(Convertor[datetime]):
    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())

    def datetime_convertor(request: Request) -> JSONResponse:
        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",
            )
        ]
    )


def test_datetime_convertor(test_client_factory: TestClientFactory, app: Router) -> None:
    client = test_client_factory(app)
    response = client.get("/datetime/2020-01-01T00:00:00")
    assert response.json() == {"datetime": "2020-01-01T00:00:00"}

    assert (
        app.url_path_for("datetime-convertor", param=datetime(1996, 1, 22, 23, 0, 0)) == "/datetime/1996-01-22T23:00:00"
    )


@pytest.mark.parametrize("param, status_code", [("1.0", 200), ("1-0", 404)])
def test_default_float_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None:
    def float_convertor(request: Request) -> JSONResponse:
        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


@pytest.mark.parametrize(
    "param, status_code",
    [
        ("00000000-aaaa-ffff-9999-000000000000", 200),
        ("00000000aaaaffff9999000000000000", 200),
        ("00000000-AAAA-FFFF-9999-000000000000", 200),
        ("00000000AAAAFFFF9999000000000000", 200),
        ("not-a-uuid", 404),
    ],
)
def test_default_uuid_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None:
    def uuid_convertor(request: Request) -> JSONResponse:
        param = request.path_params["param"]
        assert isinstance(param, UUID)
        return JSONResponse("ok")

    app = Router(routes=[Route("/{param:uuid}", endpoint=uuid_convertor)])

    client = test_client_factory(app)
    response = client.get(f"/{param}")
    assert response.status_code == status_code