Extra action detection is too permissive. Add failing test + fix (#7217)

* Add failing test

* Add failing test++

* Make get_extra_action less permissive
This commit is contained in:
Tom Christie 2020-03-05 10:18:22 +00:00 committed by GitHub
parent ddfb9672ae
commit 73f7bf4941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 1 deletions

View File

@ -25,11 +25,12 @@ from django.utils.decorators import classonlymethod
from django.views.decorators.csrf import csrf_exempt
from rest_framework import generics, mixins, views
from rest_framework.decorators import MethodMapper
from rest_framework.reverse import reverse
def _is_extra_action(attr):
return hasattr(attr, 'mapping')
return hasattr(attr, 'mapping') and isinstance(attr.mapping, MethodMapper)
class ViewSetMixin:

View File

@ -81,10 +81,20 @@ class ActionNamesViewSet(GenericViewSet):
raise NotImplementedError
class ThingWithMapping:
def __init__(self):
self.mapping = {}
class ActionViewSetWithMapping(ActionViewSet):
mapper = ThingWithMapping()
router = SimpleRouter()
router.register(r'actions', ActionViewSet)
router.register(r'actions-alt', ActionViewSet, basename='actions-alt')
router.register(r'names', ActionNamesViewSet, basename='names')
router.register(r'mapping', ActionViewSetWithMapping, basename='mapping')
urlpatterns = [
@ -161,6 +171,18 @@ class GetExtraActionsTests(TestCase):
self.assertEqual(actual, expected)
def test_should_only_return_decorated_methods(self):
view = ActionViewSetWithMapping()
actual = [action.__name__ for action in view.get_extra_actions()]
expected = [
'custom_detail_action',
'custom_list_action',
'detail_action',
'list_action',
'unresolvable_detail_action',
]
self.assertEqual(actual, expected)
@override_settings(ROOT_URLCONF='tests.test_viewsets')
class GetExtraActionUrlMapTests(TestCase):