Skip to content

Commit

Permalink
Merge pull request #45 from 5monkeys/feature/parented-menu-items
Browse files Browse the repository at this point in the history
Better schema tag support
  • Loading branch information
lundberg committed Nov 21, 2019
2 parents ba90a5a + f1e4f2e commit c0de48d
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 18 deletions.
7 changes: 1 addition & 6 deletions bananas/admin/api/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,7 @@ def get_admin_meta(cls):
)

basename = "{}.{}".format(meta.app_label, meta.basename)
meta.update(
dict(
basename=basename,
)
)
meta.update(dict(basename=basename))
cls._admin_meta = meta

return meta
Expand Down Expand Up @@ -117,7 +113,6 @@ def get_view_name(self, respect_name=True):


class SchemaSerializerMixin(object):

def get_serializer_class(self, status_code: int = None):
serializer_class = super().get_serializer_class()

Expand Down
7 changes: 7 additions & 0 deletions bananas/admin/api/schemas/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def tags(include=None, exclude=None):
def decorator(view):
view.include_tags = include
view.exclude_tags = exclude
return view

return decorator
13 changes: 10 additions & 3 deletions bananas/admin/api/schemas/yasg.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,20 @@ def get_summary(self):
def get_tags(self, operation_keys):
view = self.view
meta = self.view.get_admin_meta()
tags = ["app:{label}".format(label=meta.app_label)]
tags = {"app:{label}".format(label=meta.app_label)}

if self.is_navigation():
tags.append("navigation")
tags.add("navigation")

if issubclass(view.__class__, viewsets.ModelViewSet):
tags.append("crud")
tags.add("crud")

view_method = getattr(view, view.action, None)
if view_method:
include_tags = set(getattr(view_method, "include_tags", None) or [])
exclude_tags = set(getattr(view_method, "exclude_tags", None) or [])
tags |= include_tags
tags -= exclude_tags

return [tag for tag in tags if tag not in meta.exclude_tags]

Expand Down
4 changes: 1 addition & 3 deletions bananas/admin/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ def get_full_name(self, obj):

return full_name

@schema_serializer_method(
serializer_or_field=serializers.CharField()
)
@schema_serializer_method(serializer_or_field=serializers.CharField())
def get_email(self, obj):
return getattr(obj, obj.get_email_field_name(), None)

Expand Down
12 changes: 12 additions & 0 deletions example/example/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from rest_framework.response import Response

from bananas.admin.api.schemas import schema, schema_serializer_method
from bananas.admin.api.schemas.decorators import tags
from bananas.admin.api.views import BananasAPI
from bananas.compat import reverse
from bananas.lazy import lazy_title
Expand Down Expand Up @@ -136,9 +137,20 @@ class AppleViewSet(BananasAPI, viewsets.ModelViewSet):

name = lazy_title(_("apple"))

@tags(exclude=["navigation"])
def list(self, request):
return Response()

@tags(["navigation"])
@action(detail=False)
def red_delicious(self, request):
return Response()

@tags(include=["navigation"])
@action(detail=False)
def granny_smith(self, request):
return Response()

class Admin:
app_label = "fruit"

Expand Down
7 changes: 5 additions & 2 deletions tests/admin_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from rest_framework.response import Response

from bananas.admin.api.mixins import BananasAPI
from bananas.admin.api.schemas.decorators import tags
from bananas.admin.api.views import BananasAdminAPI
from bananas.lazy import lazy_capitalize, lazy_title

Expand All @@ -23,11 +24,12 @@ def list(self, request):

@action(detail=False)
def bar(self, request):
return Response({"bar": "baz"})
return Response({"bar": True})

@tags(include=["navigation"])
@action(detail=False, methods=["get", "post"])
def baz(self, request):
return Response({"bar": "baz"})
return Response({"baz": True})


class HamAPI(BananasAPI, viewsets.ModelViewSet):
Expand All @@ -38,5 +40,6 @@ class HamAPI(BananasAPI, viewsets.ModelViewSet):
def get_queryset(self):
return None

@tags(exclude=["navigation"])
def list(self, request):
pass
26 changes: 22 additions & 4 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,23 @@ def check_valid_schema(self, data):

action = data["paths"]["/tests/ham/"]["get"]
self.assertIn("crud", action["tags"])
self.assertIn("navigation", action["tags"])
self.assertNotIn("navigation", action["tags"])

action = data["paths"]["/bananas/me/"]["get"]
self.assertNotIn("navigation", action["tags"])

action = data["paths"]["/tests/foo/baz/"]
self.assertEqual(action["get"]["operationId"], "tests.foo:baz.read")
self.assertEqual(action["post"]["operationId"], "tests.foo:baz.create")
action = data["paths"]["/tests/foo/"]["get"]
self.assertNotIn("crud", action["tags"])
self.assertIn("navigation", action["tags"])

bar_endpoint = data["paths"]["/tests/foo/bar/"]
self.assertEqual(bar_endpoint["get"]["operationId"], "tests.foo:bar")
self.assertNotIn("navigation", bar_endpoint["get"]["tags"])

baz_endpoint = data["paths"]["/tests/foo/baz/"]
self.assertEqual(baz_endpoint["get"]["operationId"], "tests.foo:baz.read")
self.assertEqual(baz_endpoint["post"]["operationId"], "tests.foo:baz.create")
self.assertIn("navigation", baz_endpoint["get"]["tags"])

def test_login(self):
user = self.create_user()
Expand Down Expand Up @@ -326,3 +335,12 @@ def test_change_password(self):

self.client.login(username=user.username, password="foobar123")
self.assertAuthorized()

def test_tags_decorated_action(self):
self.login_user()
url = compat.reverse("bananas:v1.0:tests.foo-bar")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

data = response.json()
self.assertEqual(data["bar"], True)

0 comments on commit c0de48d

Please sign in to comment.