diff --git a/cookbook/serializer.py b/cookbook/serializer.py index e4b7bffe..60a601f0 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -382,7 +382,7 @@ class CookLogSerializer(serializers.ModelSerializer): class Meta: model = CookLog - fields = '__all__' + fields = ('id', 'recipe', 'servings', 'rating', 'created_by', 'created_at') read_only_fields = ('id', 'created_by') diff --git a/cookbook/tests/api/test_api_cook_log.py b/cookbook/tests/api/test_api_cook_log.py deleted file mode 100644 index e69de29b..00000000 diff --git a/cookbook/tests/pytest/api/test_api_cook_log.py b/cookbook/tests/pytest/api/test_api_cook_log.py new file mode 100644 index 00000000..fb2730f1 --- /dev/null +++ b/cookbook/tests/pytest/api/test_api_cook_log.py @@ -0,0 +1,116 @@ +import json + +import pytest +from django.contrib import auth +from django.urls import reverse +from django_scopes import scopes_disabled + +from cookbook.models import Keyword, CookLog + +LIST_URL = 'api:cooklog-list' +DETAIL_URL = 'api:cooklog-detail' + + +@pytest.fixture() +def obj_1(space_1, u1_s1, recipe_1_s1): + return CookLog.objects.create(recipe=recipe_1_s1, created_by=auth.get_user(u1_s1), space=space_1) + + +@pytest.fixture +def obj_2(space_1, u1_s1, recipe_1_s1): + return CookLog.objects.create(recipe=recipe_1_s1, created_by=auth.get_user(u1_s1), space=space_1) + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 200], + ['u1_s1', 200], + ['a1_s1', 200], +]) +def test_list_permission(arg, request): + c = request.getfixturevalue(arg[0]) + assert c.get(reverse(LIST_URL)).status_code == arg[1] + + +def test_list_space(obj_1, obj_2, u1_s1, u1_s2, space_2): + assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 2 + assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 0 + + obj_1.space = space_2 + obj_1.save() + + assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 1 + assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 0 + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 404], + ['u1_s1', 200], + ['a1_s1', 404], + ['g1_s2', 404], + ['u1_s2', 404], + ['a1_s2', 404], +]) +def test_update(arg, request, obj_1): + c = request.getfixturevalue(arg[0]) + r = c.patch( + reverse( + DETAIL_URL, + args={obj_1.id} + ), + {'servings': 2}, + content_type='application/json' + ) + response = json.loads(r.content) + assert r.status_code == arg[1] + if r.status_code == 200: + assert response['servings'] == 2 + + +# TODO disabled until https://github.com/vabene1111/recipes/issues/484 + +# @pytest.mark.parametrize("arg", [ +# ['a_u', 403], +# ['g1_s1', 201], +# ['u1_s1', 201], +# ['a1_s1', 201], +# ]) +# def test_add(arg, request, u1_s2, u2_s1, recipe_1_s1): +# c = request.getfixturevalue(arg[0]) +# r = c.post( +# reverse(LIST_URL), +# {'recipe': recipe_1_s1.id}, +# content_type='application/json' +# ) +# response = json.loads(r.content) +# assert r.status_code == arg[1] +# if r.status_code == 201: +# assert response['recipe'] == recipe_1_s1.id +# r = c.get(reverse(DETAIL_URL, args={response['id']})) +# assert r.status_code == 200 +# r = u2_s1.get(reverse(DETAIL_URL, args={response['id']})) +# assert r.status_code == 404 +# r = u1_s2.get(reverse(DETAIL_URL, args={response['id']})) +# assert r.status_code == 404 + + +def test_delete(u1_s1, u1_s2, obj_1): + r = u1_s2.delete( + reverse( + DETAIL_URL, + args={obj_1.id} + ) + ) + assert r.status_code == 404 + + r = u1_s1.delete( + reverse( + DETAIL_URL, + args={obj_1.id} + ) + ) + + assert r.status_code == 204 + with scopes_disabled(): + assert CookLog.objects.count() == 0 diff --git a/cookbook/tests/pytest/api/test_api_keyword.py b/cookbook/tests/pytest/api/test_api_keyword.py index 07e16cd1..946e04f5 100644 --- a/cookbook/tests/pytest/api/test_api_keyword.py +++ b/cookbook/tests/pytest/api/test_api_keyword.py @@ -1,11 +1,13 @@ import json import pytest +from django.urls import reverse from django_scopes import scopes_disabled from cookbook.models import Keyword -from cookbook.tests.views.test_views import TestViews -from django.urls import reverse + +LIST_URL = 'api:keyword-list' +DETAIL_URL = 'api:keyword-detail' @pytest.fixture() @@ -26,12 +28,23 @@ def obj_2(space_1): ]) def test_list_permission(arg, request): c = request.getfixturevalue(arg[0]) - assert c.get(reverse('api:keyword-list')).status_code == arg[1] + assert c.get(reverse(LIST_URL)).status_code == arg[1] + + +def test_list_space(obj_1, obj_2, u1_s1, u1_s2, space_2): + assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 2 + assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 0 + + obj_1.space = space_2 + obj_1.save() + + assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 1 + assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 1 def test_list_filter(obj_1, obj_2, u1_s1): # verify storage is returned - r = u1_s1.get(reverse('api:keyword-list')) + r = u1_s1.get(reverse(LIST_URL)) assert r.status_code == 200 response = json.loads(r.content) assert len(response) == 2 @@ -60,7 +73,7 @@ def test_update(arg, request, obj_1): c = request.getfixturevalue(arg[0]) r = c.patch( reverse( - 'api:keyword-detail', + DETAIL_URL, args={obj_1.id} ), {'name': 'new'}, @@ -78,10 +91,10 @@ def test_update(arg, request, obj_1): ['u1_s1', 201], ['a1_s1', 201], ]) -def test_keyword_add(arg, request, u1_s2): +def test_add(arg, request, u1_s2): c = request.getfixturevalue(arg[0]) r = c.post( - reverse('api:keyword-list'), + reverse(LIST_URL), {'name': 'test'}, content_type='application/json' ) @@ -89,15 +102,15 @@ def test_keyword_add(arg, request, u1_s2): assert r.status_code == arg[1] if r.status_code == 201: assert response['name'] == 'test' - r = c.get(reverse('api:keyword-detail', args={response['id']})) + r = c.get(reverse(DETAIL_URL, args={response['id']})) assert r.status_code == 200 - r = u1_s2.get(reverse('api:keyword-detail', args={response['id']})) + r = u1_s2.get(reverse(DETAIL_URL, args={response['id']})) assert r.status_code == 404 def test_add_duplicate(u1_s1, u1_s2, obj_1): r = u1_s1.post( - reverse('api:keyword-list'), + reverse(LIST_URL), {'name': obj_1.name}, content_type='application/json' ) @@ -106,7 +119,7 @@ def test_add_duplicate(u1_s1, u1_s2, obj_1): assert response['id'] == obj_1.id r = u1_s2.post( - reverse('api:keyword-list'), + reverse(LIST_URL), {'name': obj_1.name}, content_type='application/json' ) @@ -115,10 +128,10 @@ def test_add_duplicate(u1_s1, u1_s2, obj_1): assert response['id'] != obj_1.id -def test_keyword_delete(u1_s1, u1_s2, obj_1): +def test_delete(u1_s1, u1_s2, obj_1): r = u1_s2.delete( reverse( - 'api:keyword-detail', + DETAIL_URL, args={obj_1.id} ) ) @@ -126,7 +139,7 @@ def test_keyword_delete(u1_s1, u1_s2, obj_1): r = u1_s1.delete( reverse( - 'api:keyword-detail', + DETAIL_URL, args={obj_1.id} ) ) diff --git a/cookbook/tests/pytest/conftest.py b/cookbook/tests/pytest/conftest.py index bb61d5ce..75f0bb38 100644 --- a/cookbook/tests/pytest/conftest.py +++ b/cookbook/tests/pytest/conftest.py @@ -3,10 +3,11 @@ import inspect import uuid import pytest +from django.contrib import auth from django.contrib.auth.models import User, Group from django_scopes import scopes_disabled -from cookbook.models import Space +from cookbook.models import Space, Recipe # hack from https://github.com/raphaelm/django-scopes to disable scopes for all fixtures @@ -37,6 +38,20 @@ def space_2(): return Space.objects.get_or_create(name='space_2')[0] +# ---------------------- OBJECT FIXTURES --------------------- + +@pytest.fixture() +def recipe_1_s1(space_1, u1_s1): + return Recipe.objects.create( + name='recipe_1_s1', + waiting_time=20, + working_time=20, + servings=4, + created_by=auth.get_user(u1_s1), + space=space_1 + ) + + # ---------------------- USER FIXTURES ----------------------- # maybe better with factories but this is very explict so ... diff --git a/cookbook/views/api.py b/cookbook/views/api.py index f3fe2941..fcb02c05 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -382,7 +382,7 @@ class ViewLogViewSet(viewsets.ModelViewSet): permission_classes = [CustomIsOwner] def get_queryset(self): - return CookLog.objects.filter(created_by=self.request.user).filter(space=self.request.user.userpreference.space).all()[:5] + return self.queryset.filter(created_by=self.request.user).filter(space=self.request.user.userpreference.space).all()[:5] class CookLogViewSet(viewsets.ModelViewSet): @@ -391,8 +391,11 @@ class CookLogViewSet(viewsets.ModelViewSet): permission_classes = [CustomIsOwner] def get_queryset(self): - queryset = CookLog.objects.filter(created_by=self.request.user).filter(space=self.request.user.userpreference.space).all()[:5] - return queryset + self.queryset = self.queryset.filter(created_by=self.request.user).filter(space=self.request.user.userpreference.space).all() + if self.request.method == 'GET': + return self.queryset[:5] + else: + return self.queryset # -------------- non django rest api views --------------------