From 3e163613228a8518196300ba9823b9b4328edbd5 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Thu, 9 Jul 2020 22:00:14 +0200 Subject: [PATCH] added keyword api tests --- cookbook/serializer.py | 2 +- cookbook/tests/api/test_api_keyword.py | 57 ++++++++++++++++++++++++++ cookbook/urls.py | 2 +- cookbook/views/api.py | 48 +++++++++++----------- 4 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 cookbook/tests/api/test_api_keyword.py diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 224a54760..41fdef1fc 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -81,7 +81,7 @@ class KeywordSerializer(UniqueFieldsMixin, serializers.ModelSerializer): class Meta: model = Keyword - fields = ('id', 'name', 'icon', 'label', 'description', 'created_by', 'created_at', 'updated_at') + fields = ('id', 'name', 'icon', 'label', 'description', 'created_at', 'updated_at') read_only_fields = ('id',) diff --git a/cookbook/tests/api/test_api_keyword.py b/cookbook/tests/api/test_api_keyword.py new file mode 100644 index 000000000..6865f214d --- /dev/null +++ b/cookbook/tests/api/test_api_keyword.py @@ -0,0 +1,57 @@ +import json + +from django.contrib import auth +from django.db.models import ProtectedError +from django.urls import reverse + +from cookbook.models import Storage, Sync, Keyword +from cookbook.tests.views.test_views import TestViews + + +class TestApiKeyword(TestViews): + + def setUp(self): + super(TestApiKeyword, self).setUp() + self.keyword_1 = Keyword.objects.create( + name='meat' + ) + self.keyword_2 = Keyword.objects.create( + name='veggies' + ) + + def test_keyword_list(self): + # verify view permissions are applied accordingly + self.batch_requests([(self.anonymous_client, 403), (self.guest_client_1, 403), (self.user_client_1, 200), (self.admin_client_1, 200), (self.superuser_client, 200)], + reverse('api:keyword-list')) + + # verify storage is returned + r = self.user_client_1.get(reverse('api:keyword-list')) + self.assertEqual(r.status_code, 200) + response = json.loads(r.content) + self.assertEqual(len(response), 2) + self.assertEqual(response[0]['name'], self.keyword_1.name) + + r = self.user_client_1.get(f'{reverse("api:keyword-list")}?limit=1') + response = json.loads(r.content) + self.assertEqual(len(response), 1) + + r = self.user_client_1.get(f'{reverse("api:keyword-list")}?query=chicken') + response = json.loads(r.content) + self.assertEqual(len(response), 0) + + r = self.user_client_1.get(f'{reverse("api:keyword-list")}?query=MEAT') + response = json.loads(r.content) + self.assertEqual(len(response), 1) + + def test_keyword_update(self): + # can update storage as admin + r = self.admin_client_1.patch(reverse('api:keyword-detail', args={self.keyword_1.id}), {'name': 'new'}, content_type='application/json') + response = json.loads(r.content) + self.assertEqual(r.status_code, 200) + self.assertEqual(response['name'], 'new') + + def test_keyword_delete(self): + # can delete storage as admin + r = self.admin_client_1.delete(reverse('api:keyword-detail', args={self.keyword_1.id})) + self.assertEqual(r.status_code, 204) + self.assertEqual(Keyword.objects.count(), 1) diff --git a/cookbook/urls.py b/cookbook/urls.py index aa1291b38..e267057ee 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -14,12 +14,12 @@ router.register(r'user-preference', api.UserPreferenceViewSet) router.register(r'storage', api.StorageViewSet) router.register(r'sync', api.SyncViewSet) router.register(r'sync-log', api.SyncLogViewSet) +router.register(r'keyword', api.KeywordViewSet) router.register(r'unit', api.UnitViewSet) router.register(r'food', api.FoodViewSet) router.register(r'step', api.StepViewSet) router.register(r'recipe', api.RecipeViewSet) -router.register(r'keyword', api.KeywordViewSet) router.register(r'ingredient', api.IngredientViewSet) router.register(r'meal-plan', api.MealPlanViewSet) router.register(r'meal-type', api.MealTypeViewSet) diff --git a/cookbook/views/api.py b/cookbook/views/api.py index d048eca93..13a9addaf 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -89,6 +89,30 @@ class SyncLogViewSet(viewsets.ReadOnlyModelViewSet): permission_classes = [CustomIsAdmin, ] +class KeywordViewSet(viewsets.ModelViewSet): + """ + list: + optional parameters + + - **query**: search keywords for a string contained in the keyword name (case in-sensitive) + - **limit**: limits the amount of returned results + """ + queryset = Keyword.objects.all() + serializer_class = KeywordSerializer + permission_classes = [CustomIsUser] + + def get_queryset(self): # TODO create standard filter/limit mixin + queryset = Keyword.objects.all() + query = self.request.query_params.get('query', None) + if query is not None: + queryset = queryset.filter(name__icontains=query) + + limit = self.request.query_params.get('limit', None) + if limit is not None: + queryset = queryset[:int(limit)] + return queryset + + class RecipeBookViewSet(RetrieveModelMixin, UpdateModelMixin, ListModelMixin, viewsets.GenericViewSet): queryset = RecipeBook.objects.all() serializer_class = RecipeBookSerializer @@ -233,30 +257,6 @@ class RecipeViewSet(viewsets.ModelViewSet): return Response(serializer.errors, 400) -class KeywordViewSet(viewsets.ModelViewSet): - """ - list: - optional parameters - - - **query**: search keywords for a string contained in the keyword name (case in-sensitive) - - **limit**: limits the amount of returned results - """ - queryset = Keyword.objects.all() - serializer_class = KeywordSerializer - permission_classes = [CustomIsUser] - - def get_queryset(self): # TODO create standard filter/limit mixin - queryset = Keyword.objects.all() - query = self.request.query_params.get('query', None) - if query is not None: - queryset = queryset.filter(name__icontains=query) - - limit = self.request.query_params.get('limit', None) - if limit is not None: - queryset = queryset[:int(limit)] - return queryset - - class ViewLogViewSet(viewsets.ModelViewSet): queryset = ViewLog.objects.all() serializer_class = ViewLogSerializer