Exemple #1
0
async def test_controller_parameter_name_match():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Example(Controller):
        @get("/")
        async def from_query(self, example: str):
            assert isinstance(self, Example)
            assert isinstance(example, str)
            return text(example)

        @get("/{example}")
        async def from_route(self, example: str):
            assert isinstance(self, Example)
            assert isinstance(example, str)
            return text(example)

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())

    assert app.response.status == 400
    body = await app.response.text()
    assert body == "Bad Request: Missing query parameter `example`"

    await app(get_example_scope("GET", "/foo"), MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert body == "foo"
async def test_handler_through_controller_owned_text_method():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    # noinspection PyUnusedLocal
    class Home(Controller):

        def greet(self):
            return 'Hello World'

        @get('/')
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return self.text(self.greet())

        @get('/foo')
        async def foo(self):
            assert isinstance(self, Home)
            return self.text('foo')

    app.setup_controllers()
    await app(get_example_scope('GET', '/'), MockReceive(), MockSend())

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

    await app(get_example_scope('GET', '/foo'), MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert body == 'foo'
Exemple #3
0
async def test_controller_with_base_route_as_string_attribute():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):

        route = "/home"

        def greet(self):
            return "Hello World"

        @get()
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())
    assert app.response.status == 404

    await app(get_example_scope("GET", "/home"), MockReceive(), MockSend())
    assert app.response.status == 200
    body = await app.response.text()
    assert body == "Hello World"

    await app(get_example_scope("GET", "/home/"), MockReceive(), MockSend())
    assert app.response.status == 200
    body = await app.response.text()
    assert body == "Hello World"
Exemple #4
0
async def test_many_controllers(value):
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Settings:
        def __init__(self, greetings: str):
            self.greetings = greetings

    class Home(Controller):
        def __init__(self, settings: Settings):
            self.settings = settings

        def greet(self):
            return self.settings.greetings

        @get("/")
        async def index(self, request: Request):
            return text(self.greet())

    class Foo(Controller):
        @get("/foo")
        async def foo(self, request: Request):
            return text("foo")

    app.services.add_instance(Settings(value))

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())

    body = await app.response.text()
    assert body == value
    assert app.response.status == 200
Exemple #5
0
async def test_controllers_with_duplicate_routes_throw(first_pattern,
                                                       second_pattern):
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class A(Controller):
        @get(first_pattern)
        async def index(self, request: Request):
            ...

    class B(Controller):
        @get(second_pattern)
        async def index(self, request: Request):
            ...

    with pytest.raises(RouteDuplicate) as context:
        app.use_controllers()

    error = context.value
    assert "Cannot register route pattern `" + ensure_str(
        first_pattern) + "` for `GET` more than once." in str(error)
    assert ("This pattern is already registered for handler "
            "test_controllers_with_duplicate_routes_throw.<locals>.A.index."
            in str(error))
async def test_controller_with_base_route_as_string_attribute():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    # noinspection PyUnusedLocal
    class Home(Controller):
        
        route = '/home'

        def greet(self):
            return 'Hello World'

        @get()
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

    app.setup_controllers()
    await app(get_example_scope('GET', '/'), MockReceive(), MockSend())
    assert app.response.status == 404

    await app(get_example_scope('GET', '/home'), MockReceive(), MockSend())
    assert app.response.status == 200
    body = await app.response.text()
    assert body == 'Hello World'

    await app(get_example_scope('GET', '/home/'), MockReceive(), MockSend())
    assert app.response.status == 200
    body = await app.response.text()
    assert body == 'Hello World'
async def test_controller_return_file():
    file_path = get_file_path("example.config", "files2")

    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Example(Controller):
        @get("/")
        async def home(self):
            return self.file(file_path, "text/plain; charset=utf-8")

    app.setup_controllers()

    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"

    text = await response.text()
    with open(file_path, mode="rt", encoding="utf8") as f:
        contents = f.read()
        assert contents == text
Exemple #8
0
async def test_handler_through_controller_owned_text_method():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        def greet(self):
            return "Hello World"

        @get("/")
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return self.text(self.greet())

        @get("/foo")
        async def foo(self):
            assert isinstance(self, Home)
            return self.text("foo")

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())

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

    await app(get_example_scope("GET", "/foo"), MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert body == "foo"
Exemple #9
0
async def test_controller_with_base_route_as_class_method_fragments():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Api(Controller):
        @classmethod
        def route(cls):
            return "/api/" + cls.__name__.lower()

    class Home(Api):
        def greet(self):
            return "Hello World"

        @get()
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

    class Health(Api):
        @get()
        def alive(self):
            return text("Good")

    app.setup_controllers()
    await app(get_example_scope("GET", "/api/home"), MockReceive(), MockSend())
    assert app.response.status == 200
    body = await app.response.text()
    assert body == "Hello World"

    for value in {"/api/Health", "/api/health"}:
        await app(get_example_scope("GET", value), MockReceive(), MockSend())
        assert app.response.status == 200
        body = await app.response.text()
        assert body == "Good"
async def test_controller_with_dependency(value):
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Settings:

        def __init__(self, greetings: str):
            self.greetings = greetings

    # noinspection PyUnusedLocal
    class Home(Controller):

        def __init__(self, settings: Settings):
            assert isinstance(settings, Settings)
            self.settings = settings

        def greet(self):
            return self.settings.greetings

        @get('/')
        async def index(self, request: Request):
            return text(self.greet())

    app.services.add_instance(Settings(value))

    app.setup_controllers()
    await app(get_example_scope('GET', '/'), MockReceive(), MockSend())

    body = await app.response.text()
    assert body == value
    assert app.response.status == 200
async def test_controller_specific_view_name_async_no_model():
    app, _ = get_app(True)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Lorem(Controller):
        @get()
        async def index(self):
            return await self.view_async("nomodel")

    app.setup_controllers()
    await _home_scenario(app, expected_text=nomodel_text)
async def test_controller_conventional_view_name_async(home_model):
    app, _ = get_app(True)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Lorem(Controller):
        @get()
        async def index(self):
            return await self.view_async(model=home_model)

    app.setup_controllers()
    await _home_scenario(app)
async def test_handler_catch_all_through_controller(path_one, path_two):
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        def greet(self):
            return "Hello World"

        @get(path_one)
        async def catch_all(self, filepath: str):
            assert isinstance(self, Home)
            assert isinstance(filepath, str)
            return text(filepath)

        @get(path_two)
        async def catch_all_under_example(self, filepath: str):
            assert isinstance(self, Home)
            assert isinstance(filepath, str)
            return text(f"Example: {filepath}")

        @get("/foo")
        async def foo(self):
            assert isinstance(self, Home)
            return text("foo")

    app.setup_controllers()
    await app(get_example_scope("GET", "/hello.js"), MockReceive(), MockSend())

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

    await app(get_example_scope("GET", "/scripts/a/b/c/hello.js"),
              MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert body == "scripts/a/b/c/hello.js"

    await app(get_example_scope("GET", "/example/a/b/c/hello.js"),
              MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert body == "Example: a/b/c/hello.js"

    await app(get_example_scope("GET", "/foo"), MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert body == "foo"
async def test_controller_specific_view_name(home_model, specific_text):
    app, _ = get_app(False)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Lorem(Controller):
        @get()
        def index(self):
            return self.view("specific", home_model)

    app.setup_controllers()

    await _home_scenario(app, expected_text=specific_text)
Exemple #15
0
async def test_controller_specific_view_name_async(home_model, specific_text):
    app, _ = get_app(True)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    # noinspection PyUnusedLocal
    class Lorem(Controller):
        @get()
        async def index(self):
            return await self.view_async('specific', model=home_model)

    app.setup_controllers()
    await _home_scenario(app, expected_text=specific_text)
async def test_controller_conventional_view_name_no_model(home_model):
    app, _ = get_app(False)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Lorem(Controller):
        @get(...)
        def nomodel(self):
            return self.view()

    app.setup_controllers()

    await _home_scenario(app, "/nomodel", expected_text=nomodel_text)
Exemple #17
0
async def test_controller_conventional_view_name_no_model(home_model):
    app, _ = get_app(False)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    # noinspection PyUnusedLocal
    class Lorem(Controller):
        @get(...)
        def nomodel(self):
            return self.view()

    app.setup_controllers()

    await _home_scenario(app, '/nomodel')
async def test_handler_through_controller_default_type():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        @get("/")
        async def index(self) -> Foo:
            return Foo("Hello", 5.5)

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())

    assert app.response.status == 200
    data = await app.response.json()
    assert data == {"name": "Hello", "value": 5.5}
Exemple #19
0
async def test_application_raises_for_controllers_for_invalid_services():
    app = FakeApplication(services=Services())
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        def greet(self):
            return "Hello World"

        @get()
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

    with pytest.raises(RequiresServiceContainerError):
        app.setup_controllers()
async def test_handler_through_controller_default_str():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        @get("/")
        async def index(self) -> str:
            return "Hello World"

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())

    assert app.response.status == 200
    data = await app.response.text()
    assert data == "Hello World"
Exemple #21
0
async def test_api_controller_with_version():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get
    post = app.controllers_router.post
    delete = app.controllers_router.delete
    patch = app.controllers_router.patch

    class Cat(ApiController):
        @classmethod
        def version(cls) -> Optional[str]:
            return "v1"

        @get(":cat_id")
        def get_cat(self, cat_id: str):
            return text("1")

        @patch()
        def update_cat(self):
            return text("2")

        @post()
        def create_cat(self):
            return text("3")

        @delete(":cat_id")
        def delete_cat(self):
            return text("4")

    app.setup_controllers()

    expected_result = {
        ("GET", "/api/v1/cat/100"): "1",
        ("PATCH", "/api/v1/cat"): "2",
        ("POST", "/api/v1/cat"): "3",
        ("DELETE", "/api/v1/cat/100"): "4",
    }

    for key, value in expected_result.items():
        method, pattern = key
        await app(get_example_scope(method, pattern), MockReceive(),
                  MockSend())

        assert app.response.status == 200
        body = await app.response.text()
        assert body == value
async def test_controller_model_interop(model_fixture):
    app, _ = get_app(False)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Lorem(Controller):
        @get()
        def index(self):
            return self.view("hello", model_fixture())

    app.setup_controllers()

    await _view_scenario(
        app,
        expected_text='<div style="margin: 10em 2em;">\n  <h1>Hello, World!!</h1>\n\n'
        + '  <ul>\n    \n      <li><a href="https://github.com/Neoteroi/'
        + 'BlackSheep">Check this out!</a></li>\n    \n  </ul>\n</div>',
    )
async def test_controller_supports_on_response():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    k = 0

    # noinspection PyUnusedLocal
    class Home(Controller):

        def greet(self):
            return 'Hello World'

        async def on_response(self, response: Response):
            nonlocal k
            k += 1
            assert isinstance(response, Response)
            if response.content.body == b'Hello World':
                assert k < 10
            else:
                assert k >= 10
            return await super().on_response(response)

        @get('/')
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

        @get('/foo')
        async def foo(self):
            assert isinstance(self, Home)
            return text('foo')

    app.setup_controllers()

    for j in range(1, 10):
        await app(get_example_scope('GET', '/'), MockReceive(), MockSend())
        assert app.response.status == 200
        assert k == j

    for j in range(10, 20):
        await app(get_example_scope('GET', '/foo'), MockReceive(), MockSend())
        assert app.response.status == 200
        assert k == j
async def test_api_controller_with_version():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get
    post = app.controllers_router.post
    delete = app.controllers_router.delete
    patch = app.controllers_router.patch

    # noinspection PyUnusedLocal
    class Cat(ApiController):

        @classmethod
        def version(cls) -> Optional[str]:
            return 'v1'

        @get(':cat_id')
        def get_cat(self, cat_id: str): return text('1')

        @patch()
        def update_cat(self): return text('2')

        @post()
        def create_cat(self): return text('3')

        @delete(':cat_id')
        def delete_cat(self): return text('4')

    app.setup_controllers()

    expected_result = {
        ('GET', '/api/v1/cat/100'): '1',
        ('PATCH', '/api/v1/cat'): '2',
        ('POST', '/api/v1/cat'): '3',
        ('DELETE', '/api/v1/cat/100'): '4',
    }

    for key, value in expected_result.items():
        method, pattern = key
        await app(get_example_scope(method, pattern), MockReceive(), MockSend())

        assert app.response.status == 200
        body = await app.response.text()
        assert body == value
Exemple #25
0
async def test_application_raises_for_invalid_route_class_attribute():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):

        route = False

        def greet(self):
            return "Hello World"

        @get()
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

    with pytest.raises(RuntimeError):
        app.setup_controllers()
async def test_controller_conventional_view_name_sub_function(home_model):
    app, _ = get_app(False)
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Lorem(Controller):
        def ufo(self, model):
            return self.foo(model)

        def foo(self, model):
            return self.view(model=model)

        @get()
        def index(self):
            return self.ufo(home_model)

    app.setup_controllers()

    await _home_scenario(app)
async def test_controller_with_duplicate_route_with_base_route_throw(first_pattern, second_pattern):
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    # NB: this test creates ambiguity between the full route of a controller handler,
    # and another handler

    # noinspection PyUnusedLocal
    class A(Controller):

        route = 'home'

        @get(first_pattern)
        async def index(self, request: Request): ...

    @app.route(second_pattern)
    async def home(): ...

    with pytest.raises(RouteDuplicate):
        app.use_controllers()
async def test_controller_with_base_route_as_class_method_fragments():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Api(Controller):

        @classmethod
        def route(cls):
            return '/api/' + cls.__name__.lower()

    # noinspection PyUnusedLocal
    class Home(Api):

        def greet(self):
            return 'Hello World'

        @get()
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

    # noinspection PyUnusedLocal
    class Health(Api):

        @get()
        def alive(self):
            return text('Good')

    app.setup_controllers()
    await app(get_example_scope('GET', '/api/home'), MockReceive(), MockSend())
    assert app.response.status == 200
    body = await app.response.text()
    assert body == 'Hello World'

    for value in {'/api/Health', '/api/health'}:
        await app(get_example_scope('GET', value), MockReceive(), MockSend())
        assert app.response.status == 200
        body = await app.response.text()
        assert body == 'Good'
Exemple #29
0
async def test_controller_supports_on_request():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    k = 0

    class Home(Controller):
        def greet(self):
            return "Hello World"

        async def on_request(self, request: Request):
            nonlocal k
            k += 1
            assert isinstance(request, Request)
            assert request.url.path == b"/" if k < 10 else b"/foo"
            return await super().on_request(request)

        @get("/")
        async def index(self, request: Request):
            assert isinstance(self, Home)
            return text(self.greet())

        @get("/foo")
        async def foo(self):
            assert isinstance(self, Home)
            return text("foo")

    app.setup_controllers()

    for j in range(1, 10):
        await app(get_example_scope("GET", "/"), MockReceive(), MockSend())
        assert app.response.status == 200
        assert k == j

    for j in range(10, 20):
        await app(get_example_scope("GET", "/foo"), MockReceive(), MockSend())
        assert app.response.status == 200
        assert k == j
async def test_handler_through_controller_owned_html_method():
    app = FakeApplication()
    app.controllers_router = RoutesRegistry()
    get = app.controllers_router.get

    class Home(Controller):
        @get("/")
        async def index(self):
            assert isinstance(self, Home)
            return self.html("""
                <h1>Title</h1>
                <p>Lorem ipsum</p>
                """)

    app.setup_controllers()
    await app(get_example_scope("GET", "/"), MockReceive(), MockSend())

    assert app.response.status == 200
    body = await app.response.text()
    assert "<h1>Title</h1>" in body
    assert "<p>Lorem ipsum</p>" in body
    assert app.response.content_type() == b"text/html; charset=utf-8"