Skip to content

Commit f6884b0

Browse files
committed
Fixed test and increase cov to 100%
1 parent 4798e84 commit f6884b0

File tree

7 files changed

+154
-77
lines changed

7 files changed

+154
-77
lines changed

ninja_extra/ordering.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def __init__(
178178
self.as_view = wraps(view_func)(orderator_view)
179179

180180
@property
181-
def view_func_has_kwargs(self) -> bool:
181+
def view_func_has_kwargs(self) -> bool: # pragma: no cover
182182
return self.orderator.pass_parameter is not None
183183

184184
def get_view_function(self) -> Callable:

ninja_extra/pagination.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def __init__(
207207
self.as_view = wraps(view_func)(paginator_view)
208208

209209
@property
210-
def view_func_has_kwargs(self) -> bool:
210+
def view_func_has_kwargs(self) -> bool: # pragma: no cover
211211
return self.paginator.pass_parameter is not None
212212

213213
def get_view_function(self) -> Callable:

ninja_extra/searching.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def __init__(
190190
self.as_view = wraps(view_func)(searcherator_view)
191191

192192
@property
193-
def view_func_has_kwargs(self) -> bool:
193+
def view_func_has_kwargs(self) -> bool: # pragma: no cover
194194
return self.searcherator.pass_parameter is not None
195195

196196
def get_view_function(self) -> Callable:

tests/test_controller.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
testing,
1515
)
1616
from ninja_extra.controllers import ControllerBase, RouteContext, RouteFunction
17-
from ninja_extra.controllers.base import APIController, get_route_functions
17+
from ninja_extra.controllers.base import (
18+
APIController,
19+
MissingAPIControllerDecoratorException,
20+
get_route_functions,
21+
)
1822
from ninja_extra.controllers.response import Detail, Id, Ok
23+
from ninja_extra.helper import get_route_function
1924
from ninja_extra.permissions.common import AllowAny
2025

2126
from .schemas import UserSchema
@@ -76,23 +81,32 @@ class DisableAutoImportController:
7681

7782
class TestAPIController:
7883
def test_api_controller_as_decorator(self):
79-
api_controller_instance = api_controller(
80-
"prefix", tags="new_tag", auth=FakeAuth()
84+
controller_type = api_controller("prefix", tags="new_tag", auth=FakeAuth())(
85+
type("Any", (), {})
8186
)
87+
api_controller_instance = controller_type.get_api_controller()
8288

8389
assert not api_controller_instance.has_auth_async
8490
assert not api_controller_instance._prefix_has_route_param
8591
assert api_controller_instance.prefix == "prefix"
8692
assert api_controller_instance.tags == ["new_tag"]
8793
assert api_controller_instance.permission_classes == [AllowAny]
8894

89-
api_controller_instance = api_controller()
95+
controller_type = api_controller()(controller_type)
96+
api_controller_instance = controller_type.get_api_controller()
9097
assert api_controller_instance.prefix == ""
91-
assert api_controller_instance.tags is None
98+
assert api_controller_instance.tags == ["any"]
9299
assert "abc" in SomeController.__module__
93100
assert "tests.test_controller" in Some2Controller.__module__
94101
assert Some2Controller.get_api_controller()
95102

103+
def test_controller_get_api_controller_raise_exception(self):
104+
class BController(ControllerBase):
105+
pass
106+
107+
with pytest.raises(MissingAPIControllerDecoratorException):
108+
BController.get_api_controller()
109+
96110
def test_api_controller_prefix_with_parameter(self):
97111
@api_controller("/{int:organisation_id}")
98112
class UsersController:
@@ -130,7 +144,9 @@ def test_controller_should_have_path_operation_list(self):
130144
_api_controller = SomeControllerWithRoute.get_api_controller()
131145
assert len(_api_controller._path_operations) == 7
132146

133-
route_function: RouteFunction = SomeControllerWithRoute.example
147+
route_function: RouteFunction = get_route_function(
148+
SomeControllerWithRoute().example
149+
)
134150
path_view = _api_controller._path_operations.get(str(route_function))
135151
assert path_view, "route doesn't exist in controller"
136152
assert len(path_view.operations) == 1
@@ -144,18 +160,16 @@ def test_get_route_function_should_return_instance_route_definitions(self):
144160
assert isinstance(route_definition, RouteFunction)
145161

146162
def test_compute_api_route_function_works(self):
147-
_api_controller = api_controller()
148-
163+
@api_controller()
149164
class AnyClassTypeWithRoute:
150165
@http_get("/example")
151166
def example(self):
152167
pass
153168

154-
_api_controller(AnyClassTypeWithRoute)
155-
assert len(_api_controller.path_operations) == 1
156-
path_view = _api_controller.path_operations.get(
157-
str(AnyClassTypeWithRoute.example)
158-
)
169+
api_controller_instance = AnyClassTypeWithRoute.get_api_controller()
170+
assert len(api_controller_instance.path_operations) == 1
171+
route_function = get_route_function(AnyClassTypeWithRoute().example)
172+
path_view = api_controller_instance.path_operations.get(str(route_function))
159173
assert path_view
160174

161175
@pytest.mark.django_db
@@ -207,29 +221,32 @@ def test_controller_base_get_object_or_none_works(self):
207221

208222
@pytest.mark.skipif(django.VERSION < (3, 1), reason="requires django 3.1 or higher")
209223
def test_async_controller():
210-
api_controller_instance = api_controller(
224+
api_controller_decorator = api_controller(
211225
"prefix", tags="any_Tag", auth=AsyncFakeAuth()
212226
)
213-
assert api_controller_instance.has_auth_async
214227

215228
with pytest.raises(Exception) as ex:
216229

217-
@api_controller_instance
230+
@api_controller_decorator
218231
class NonAsyncRouteInControllerWithAsyncAuth:
219232
@http_get("/example")
220233
def example(self):
221234
pass
222235

223236
assert "NonAsyncRouteInControllerWithAsyncAuth" in str(ex) and "example" in str(ex)
224237

225-
@api_controller_instance
238+
@api_controller_decorator
226239
class AsyncRouteInControllerWithAsyncAuth:
227240
@http_get("/example")
228241
async def example(self):
229242
pass
230243

244+
example_route_function = get_route_function(
245+
AsyncRouteInControllerWithAsyncAuth().example
246+
)
247+
assert AsyncRouteInControllerWithAsyncAuth.get_api_controller().has_auth_async
231248
assert isinstance(
232-
AsyncRouteInControllerWithAsyncAuth.example.operation.auth_callbacks[0],
249+
example_route_function.operation.auth_callbacks[0],
233250
AsyncFakeAuth,
234251
)
235252

@@ -291,9 +308,10 @@ def test_generic_controller_response_in_route_functions_works(self):
291308
)
292309

293310
ok_response = Ok[UserSchema](dict(name="John", age=56))
294-
result = SomeControllerWithRoute.example_with_ok_schema_response(
295-
request=Mock(), user=UserSchema(name="John", age=56)
311+
route_function = get_route_function(
312+
SomeControllerWithRoute().example_with_ok_schema_response
296313
)
314+
result = route_function(request=Mock(), user=UserSchema(name="John", age=56))
297315
assert isinstance(result, tuple)
298316
assert result[1] == ok_response.convert_to_schema()
299317
assert result[0] == ok_response.status_code
@@ -307,17 +325,19 @@ def test_controller_response_in_route_functions_works(self):
307325
assert detail.convert_to_schema().dict() == response.json()
308326

309327
ok_response = Ok("5242")
310-
result = SomeControllerWithRoute.example_with_ok_response(
311-
request=Mock(), ex_id="5242"
328+
route_function = get_route_function(
329+
SomeControllerWithRoute().example_with_ok_response
312330
)
331+
result = route_function(request=Mock(), ex_id="5242")
313332
assert isinstance(result, tuple)
314333
assert result[1] == ok_response.convert_to_schema()
315334
assert result[0] == ok_response.status_code
316335

317336
id_response = Id("5242")
318-
result = SomeControllerWithRoute.example_with_id_response(
319-
request=Mock(), ex_id="5242"
337+
route_function = get_route_function(
338+
SomeControllerWithRoute().example_with_id_response
320339
)
340+
result = route_function(request=Mock(), ex_id="5242")
321341
assert isinstance(result, tuple)
322342
assert result[1] == id_response.convert_to_schema()
323343
assert result[0] == id_response.status_code

tests/test_operation.py

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

44
from ninja_extra import api_controller, route
55
from ninja_extra.controllers import AsyncRouteFunction, RouteFunction
6+
from ninja_extra.helper import get_route_function
67
from ninja_extra.operation import AsyncOperation, Operation
78
from ninja_extra.testing import TestAsyncClient, TestClient
89

@@ -25,7 +26,7 @@ def example_exception(self):
2526
@mock_log_call("info")
2627
def test_route_operation_execution_works(self):
2728
client = TestClient(self.SomeTestController)
28-
response = client.get(str(self.SomeTestController.example))
29+
response = client.get("/example")
2930
assert response.json() == {"message": "example"}
3031

3132
@mock_signal_call("route_context_started")
@@ -34,12 +35,16 @@ def test_route_operation_execution_works(self):
3435
def test_route_operation_execution_should_log_execution(self):
3536
client = TestClient(self.SomeTestController)
3637
with pytest.raises(Exception):
37-
client.get(str(self.SomeTestController.example_exception))
38+
client.get("/example_exception")
3839

3940

4041
@pytest.mark.skipif(django.VERSION < (3, 1), reason="requires django 3.1 or higher")
4142
def test_operation_auth_configs():
42-
api_controller_instance = api_controller("prefix", tags="any_Tag")
43+
@api_controller("prefix", tags="any_Tag")
44+
class AController:
45+
pass
46+
47+
api_controller_instance = AController.get_api_controller()
4348

4449
async def async_endpoint(self, request):
4550
pass
@@ -50,23 +55,26 @@ def sync_endpoint(self, request):
5055
sync_auth_http_get = route.get("/example", auth=[FakeAuth()])
5156
async_auth_http_get = route.get("/example/async", auth=[AsyncFakeAuth()])
5257

53-
route_function = sync_auth_http_get(async_endpoint)
54-
assert isinstance(route_function, AsyncRouteFunction)
55-
async_route_function = async_auth_http_get(async_endpoint)
58+
sync_auth_http_get(async_endpoint)
59+
async_route_function = get_route_function(async_endpoint)
60+
assert isinstance(async_route_function, AsyncRouteFunction)
5661

57-
api_controller_instance._add_operation_from_route_function(route_function)
58-
assert isinstance(route_function.operation, AsyncOperation)
62+
api_controller_instance._add_operation_from_route_function(async_route_function)
63+
assert isinstance(async_route_function.operation, AsyncOperation)
5964
api_controller_instance._add_operation_from_route_function(async_route_function)
6065
assert isinstance(async_route_function.operation, AsyncOperation)
6166

62-
sync_route_function = sync_auth_http_get(sync_endpoint)
67+
sync_auth_http_get(sync_endpoint)
68+
sync_route_function = get_route_function(sync_endpoint)
6369
api_controller_instance._add_operation_from_route_function(sync_route_function)
6470
assert isinstance(sync_route_function.operation, Operation)
6571
assert isinstance(sync_route_function, RouteFunction)
6672

6773
with pytest.raises(Exception) as ex:
74+
new_sync_endpoint = async_auth_http_get(sync_endpoint)
75+
new_sync_route_function = get_route_function(new_sync_endpoint)
6876
api_controller_instance._add_operation_from_route_function(
69-
async_auth_http_get(sync_endpoint)
77+
new_sync_route_function
7078
)
7179
assert "sync_endpoint" in str(ex) and "AsyncFakeAuth" in str(ex)
7280

@@ -91,7 +99,7 @@ async def example_exception(self):
9199
@mock_log_call("info")
92100
async def test_async_route_operation_execution_works(self):
93101
client = TestAsyncClient(self.SomeTestController)
94-
response = await client.get(str(self.SomeTestController.example))
102+
response = await client.get("/example")
95103
assert response.json() == {"message": "example"}
96104

97105
@mock_signal_call("route_context_started")
@@ -100,4 +108,4 @@ async def test_async_route_operation_execution_works(self):
100108
async def test_async_route_operation_execution_should_log_execution(self):
101109
client = TestAsyncClient(self.SomeTestController)
102110
with pytest.raises(Exception):
103-
await client.get(str(self.SomeTestController.example_exception))
111+
await client.get("/example_exception")

tests/test_permissions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ def test_or_true(self):
6969
def test_not_false(self):
7070
composed_perm = ~permissions.IsAuthenticated
7171
assert composed_perm().has_permission(anonymous_request, None) is True
72+
assert (
73+
composed_perm().has_object_permission(anonymous_request, None, None)
74+
is False
75+
)
7276

7377
@pytest.mark.django_db
7478
def test_not_true(self):

0 commit comments

Comments
 (0)