Skip to content

Commit 2c59670

Browse files
committed
bumped up test coverage
1 parent 09143b3 commit 2c59670

File tree

10 files changed

+129
-14
lines changed

10 files changed

+129
-14
lines changed

ellar/core/middleware/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from starlette.middleware.httpsredirect import (
77
HTTPSRedirectMiddleware as HTTPSRedirectMiddleware,
88
)
9+
from starlette.middleware.sessions import SessionMiddleware as SessionMiddleware
910
from starlette.middleware.trustedhost import (
1011
TrustedHostMiddleware as TrustedHostMiddleware,
1112
)
@@ -29,4 +30,5 @@
2930
"WSGIMiddleware",
3031
"RequestVersioningMiddleware",
3132
"RequestServiceProviderMiddleware",
33+
"SessionMiddleware",
3234
]

ellar/core/modules/ref.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,13 @@ def routers(self) -> t.Sequence[t.Union[BaseRoute, ModuleMount, Mount]]:
218218
def routes(self) -> t.List[BaseRoute]:
219219
if not self._flatten_routes:
220220
for router in self._routers:
221-
if isinstance(router, ModuleMount):
222-
# TODO: Allow users to choose whether to run flatten route of group routes together
223-
# router.build_child_routes()
224-
self._flatten_routes.append(router)
225-
continue
221+
# if isinstance(router, ModuleMount):
222+
# # TODO: Allow users to choose whether to run flatten route of group routes together
223+
# # router.build_child_routes()
224+
# self._flatten_routes.append(router)
225+
# continue
226+
# if isinstance(router, BaseRoute):
227+
# self._flatten_routes.append(router)
226228
if isinstance(router, BaseRoute):
227229
self._flatten_routes.append(router)
228230
return self._flatten_routes

ellar/core/routing/controller/base.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ def _get_controller_instance(self, ctx: IExecutionContext) -> ControllerBase:
1313
controller_type: t.Optional[t.Type[ControllerBase]] = reflect.get_metadata(
1414
CONTROLLER_CLASS_KEY, self.endpoint
1515
)
16-
if not controller_type and issubclass(controller_type, ControllerBase): # type: ignore
16+
if not controller_type or (
17+
controller_type and not issubclass(controller_type, ControllerBase)
18+
):
1719
raise RuntimeError("Controller Type was not found")
1820

1921
service_provider = ctx.get_service_provider()

ellar/core/routing/route.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def __init__(
4444
path: str,
4545
methods: t.List[str],
4646
endpoint: t.Callable,
47-
response: t.Mapping[int, t.Type],
47+
response: t.Mapping[int, t.Union[t.Type, t.Any]],
4848
name: t.Optional[str] = None,
4949
include_in_schema: bool = True,
5050
) -> None:

ellar/core/routing/websocket/route.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,3 @@ def _load_model(self) -> None:
144144
"`WsBody` should only be used when "
145145
"`use_extra_handler` flag is set to True in WsRoute"
146146
)
147-
148-
def __hash__(self) -> t.Any:
149-
return self.endpoint

tests/test_common/test_decorators/test_controller.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
from ellar.core import ControllerBase
1+
import pytest
22

33
from ellar.common import Controller, set_metadata
44
from ellar.constants import CONTROLLER_METADATA, GUARDS_KEY, NOT_SET, VERSIONING_KEY
5+
from ellar.core import ControllerBase
6+
from ellar.core.exceptions import ImproperConfiguration
57
from ellar.reflect import reflect
68

79

@@ -109,3 +111,14 @@ def test_controller_set_metadata_decorator_works():
109111
)
110112
== "Something"
111113
)
114+
115+
116+
def test_controller_decorator_fails_as_a_function_decorator():
117+
def controller_function():
118+
pass # pragma: no cover
119+
120+
with pytest.raises(
121+
ImproperConfiguration,
122+
match=f"Controller is a class decorator - {controller_function}",
123+
):
124+
Controller("/some-prefix")(controller_function)

tests/test_controller/test_controller_inheritance.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from ellar.common import Controller, get, ws_route
44
from ellar.constants import CONTROLLER_CLASS_KEY
5+
from ellar.core import AppFactory
56
from ellar.core.routing.router.module import controller_router_factory
67
from ellar.reflect import reflect
78

@@ -49,3 +50,40 @@ def endpoint_once(self):
4950

5051
with pytest.raises(Exception, match=r"Operation must have a single control type."):
5152
controller_router_factory(AnotherSampleController)
53+
54+
55+
def test_controller_raise_exception_for_controller_operation_without_controller_class(
56+
test_client_factory,
57+
):
58+
@Controller("/abcd")
59+
class Another2SampleController:
60+
@get("/test")
61+
def endpoint_once(self):
62+
pass
63+
64+
app = AppFactory.create_app(controllers=(Another2SampleController,))
65+
reflect.delete_metadata(
66+
CONTROLLER_CLASS_KEY, Another2SampleController.endpoint_once
67+
)
68+
client = test_client_factory(app)
69+
with pytest.raises(RuntimeError, match=r"Controller Type was not found"):
70+
client.get("/abcd/test")
71+
72+
73+
def test_controller_raise_exception_for_controller_operation_for_invalid_type(
74+
test_client_factory,
75+
):
76+
@Controller("/abcd")
77+
class Another3SampleController:
78+
@get("/test")
79+
def endpoint_once(self):
80+
pass
81+
82+
reflect.delete_metadata(
83+
CONTROLLER_CLASS_KEY, Another3SampleController.endpoint_once
84+
)
85+
app = AppFactory.create_app(controllers=(Another3SampleController,))
86+
87+
client = test_client_factory(app)
88+
with pytest.raises(RuntimeError, match=r"Controller Type was not found"):
89+
client.get("/abcd/test")

tests/test_response/test_route_response_model.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,25 @@
33
import pytest
44
from starlette.responses import JSONResponse
55

6+
from ellar.constants import RESPONSE_OVERRIDE_KEY
7+
from ellar.core.exceptions import ImproperConfiguration
68
from ellar.core.response.model import (
79
EmptyAPIResponseModel,
810
JSONResponseModel,
911
ResponseModel,
1012
RouteResponseExecution,
1113
RouteResponseModel,
1214
)
15+
from ellar.core.routing import RouteOperation
16+
from ellar.reflect import reflect
1317

1418
from ..schema import BlogObjectDTO, NoteSchemaDC
1519

1620

21+
def endpoint_sample():
22+
pass # pragma: no cover
23+
24+
1725
class JsonApiResponse(JSONResponse):
1826
media_type = "application/vnd.api+json"
1927

@@ -101,3 +109,17 @@ def test_route_response_model(
101109
def test_route_response_model_exception(inputs):
102110
with pytest.raises(RouteResponseExecution):
103111
RouteResponseModel(route_responses=inputs)
112+
113+
114+
def test_invalid_response_override_definition():
115+
reflect.define_metadata(
116+
RESPONSE_OVERRIDE_KEY, {EmptyAPIResponseModel()}, endpoint_sample
117+
)
118+
with pytest.raises(ImproperConfiguration) as ex:
119+
RouteOperation(
120+
path="/",
121+
methods=["get"],
122+
endpoint=endpoint_sample,
123+
response={200: EmptyAPIResponseModel()},
124+
)
125+
assert "`RESPONSE_OVERRIDE` is must be of type `Dict`" in str(ex)

tests/test_routing/test_route_endpoint_params.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,45 @@
55
from starlette.responses import Response as StarletteResponse
66
from starlette.websockets import WebSocket as StarletteWebSocket
77

8-
from ellar.common import Context, Http, Req, Res, Ws
9-
from ellar.core import ExecutionContext, TestClientFactory
8+
from ellar.common import Context, Host, Http, Provide, Req, Res, Session, Ws
9+
from ellar.core import Config, ExecutionContext, TestClientFactory
1010
from ellar.core.connection import (
1111
HTTPConnection as EllarHTTPConnection,
1212
Request as EllarRequest,
1313
WebSocket as EllarWebSocket,
1414
)
1515
from ellar.core.context import IExecutionContext
16+
from ellar.core.middleware import Middleware, SessionMiddleware
1617
from ellar.core.routing import ModuleRouter
18+
from ellar.helper.importer import get_class_import
1719

1820
router = ModuleRouter()
1921

2022

23+
class SampleConfig:
24+
SECRET_KEY: str = "ellar_cf303596-e51a-441a-ba67-5da42dbffb07"
25+
26+
MIDDLEWARE = [Middleware(SessionMiddleware, secret_key=SECRET_KEY)]
27+
28+
29+
config_path = get_class_import(SampleConfig)
30+
31+
2132
@router.get("/starlette-request")
2233
def get_requests(request: StarletteRequest, req=Req()):
2334
assert isinstance(request, EllarRequest) # True
2435
assert isinstance(req, EllarRequest)
2536
return req == request
2637

2738

39+
@router.get("/others")
40+
def get_requests(session=Session(), host=Host(), config=Provide(Config)):
41+
assert isinstance(config, Config) # True
42+
assert host == "testclient"
43+
assert isinstance(session, dict) and len(session) == 0
44+
return True
45+
46+
2847
@router.get("/ellar-context")
2948
def get_requests(context_1: IExecutionContext, context_2=Context()):
3049
assert isinstance(context_1, ExecutionContext)
@@ -54,7 +73,7 @@ async def get_websockets(websocket: StarletteWebSocket, ws=Ws()):
5473
await ws.close()
5574

5675

57-
tm = TestClientFactory.create_test_module(routers=[router])
76+
tm = TestClientFactory.create_test_module(routers=[router], config_module=config_path)
5877
client = tm.get_client()
5978

6079

@@ -82,6 +101,12 @@ def test_get_response():
82101
assert response.json() is True
83102

84103

104+
def test_other_route_function_parameter():
105+
response = client.get("/others")
106+
assert response.status_code == 200
107+
assert response.json() is True
108+
109+
85110
def test_get_websocket():
86111
with client.websocket_connect("/starlette-websocket") as session:
87112
data = session.receive_json()

tests/test_websocket_handler.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from ellar.common import ModuleRouter, WsBody
55
from ellar.core import TestClientFactory
6+
from ellar.core.exceptions import ImproperConfiguration
67

78
from .schema import Item
89

@@ -92,3 +93,16 @@ def test_plain_websocket_route():
9293
websocket.send_text("Ellar")
9394
message = websocket.receive_json()
9495
assert message == {"message": "Thanks. Ellar"}
96+
97+
98+
def test_websocket_setup_fails_when_using_body_without_handler():
99+
with pytest.raises(
100+
ImproperConfiguration,
101+
match=r"`WsBody` should only be used when `use_extra_handler` flag is set to True in WsRoute",
102+
):
103+
104+
@router.ws_route("/ws-with-handler", use_extra_handler=False)
105+
async def websocket_with_handler(
106+
websocket: WebSocket, query: str, data: Item = WsBody()
107+
):
108+
pass

0 commit comments

Comments
 (0)