From 528f329ebb5f808e9df63579b57e1eed95a4632d Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Wed, 10 Mar 2021 20:31:00 +0100 Subject: [PATCH] new keyword api test working --- cookbook/tests/pytest/__init__.py | 5 +- cookbook/tests/pytest/api/__init__.py | 5 +- cookbook/tests/pytest/api/test_api_keyword.py | 152 +++++++++++------- cookbook/tests/pytest/conftest.py | 12 ++ cookbook/views/api.py | 15 +- 5 files changed, 125 insertions(+), 64 deletions(-) diff --git a/cookbook/tests/pytest/__init__.py b/cookbook/tests/pytest/__init__.py index 255e8298d..cd8863452 100644 --- a/cookbook/tests/pytest/__init__.py +++ b/cookbook/tests/pytest/__init__.py @@ -1,6 +1,7 @@ from django.test import utils from django_scopes import scopes_disabled -# disables scoping error in all queries used inside the test functions -# fixtures need to have their own scopes_disabled +# disables scoping error in all queries used inside the test FUNCTIONS +# FIXTURES need to have their own scopes_disabled!! +# This is done by hook pytest_fixture_setup in conftest.py for all non yield fixtures utils.setup_databases = scopes_disabled()(utils.setup_databases) diff --git a/cookbook/tests/pytest/api/__init__.py b/cookbook/tests/pytest/api/__init__.py index 255e8298d..cd8863452 100644 --- a/cookbook/tests/pytest/api/__init__.py +++ b/cookbook/tests/pytest/api/__init__.py @@ -1,6 +1,7 @@ from django.test import utils from django_scopes import scopes_disabled -# disables scoping error in all queries used inside the test functions -# fixtures need to have their own scopes_disabled +# disables scoping error in all queries used inside the test FUNCTIONS +# FIXTURES need to have their own scopes_disabled!! +# This is done by hook pytest_fixture_setup in conftest.py for all non yield fixtures utils.setup_databases = scopes_disabled()(utils.setup_databases) diff --git a/cookbook/tests/pytest/api/test_api_keyword.py b/cookbook/tests/pytest/api/test_api_keyword.py index 6f7656ee4..07e16cd12 100644 --- a/cookbook/tests/pytest/api/test_api_keyword.py +++ b/cookbook/tests/pytest/api/test_api_keyword.py @@ -9,13 +9,13 @@ from django.urls import reverse @pytest.fixture() -def keyword_1(): - return Keyword.objects.get_or_create(name='test_1')[0] +def obj_1(space_1): + return Keyword.objects.get_or_create(name='test_1', space=space_1)[0] @pytest.fixture -def keyword_2(): - return Keyword.objects.get_or_create(name='test_2')[0] +def obj_2(space_1): + return Keyword.objects.get_or_create(name='test_2', space=space_1)[0] @pytest.mark.parametrize("arg", [ @@ -29,66 +29,108 @@ def test_list_permission(arg, request): assert c.get(reverse('api:keyword-list')).status_code == arg[1] -def test_list_filter(keyword_1, keyword_2, u1_s1): +def test_list_filter(obj_1, obj_2, u1_s1): # verify storage is returned r = u1_s1.get(reverse('api:keyword-list')) assert r.status_code == 200 response = json.loads(r.content) assert len(response) == 2 - assert response[0]['name'] == keyword_1.name + assert response[0]['name'] == obj_1.name - response = json.loads(u1_s1.get(f'{reverse("api:keyword-list")}?limit=1')) + response = json.loads(u1_s1.get(f'{reverse("api:keyword-list")}?limit=1').content) assert len(response) == 1 - response = json.loads(u1_s1.get(f'{reverse("api:keyword-list")}?query=chicken')) + response = json.loads(u1_s1.get(f'{reverse("api:keyword-list")}?query=chicken').content) assert len(response) == 0 - response = json.loads(u1_s1.get(f'{reverse("api:keyword-list")}?query={keyword_1.name[4:]}')) + response = json.loads(u1_s1.get(f'{reverse("api:keyword-list")}?query={obj_1.name[4:]}').content) assert len(response) == 1 -# -# def test_keyword_update(self): -# r = self.user_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_add(self): -# r = self.user_client_1.post( -# reverse('api:keyword-list'), -# {'name': 'test'}, -# content_type='application/json' -# ) -# response = json.loads(r.content) -# self.assertEqual(r.status_code, 201) -# self.assertEqual(response['name'], 'test') -# -# -# def test_keyword_add_duplicate(self): -# r = self.user_client_1.post( -# reverse('api:keyword-list'), -# {'name': self.keyword_1.name}, -# content_type='application/json' -# ) -# response = json.loads(r.content) -# self.assertEqual(r.status_code, 201) -# self.assertEqual(response['name'], self.keyword_1.name) -# -# -# def test_keyword_delete(self): -# r = self.user_client_1.delete( -# reverse( -# 'api:keyword-detail', -# args={self.keyword_1.id} -# ) -# ) -# self.assertEqual(r.status_code, 204) -# self.assertEqual(Keyword.objects.count(), 1) + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 403], + ['u1_s1', 200], + ['a1_s1', 200], + ['g1_s2', 403], + ['u1_s2', 404], + ['a1_s2', 404], +]) +def test_update(arg, request, obj_1): + c = request.getfixturevalue(arg[0]) + r = c.patch( + reverse( + 'api:keyword-detail', + args={obj_1.id} + ), + {'name': 'new'}, + content_type='application/json' + ) + response = json.loads(r.content) + assert r.status_code == arg[1] + if r.status_code == 200: + assert response['name'] == 'new' + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 403], + ['u1_s1', 201], + ['a1_s1', 201], +]) +def test_keyword_add(arg, request, u1_s2): + c = request.getfixturevalue(arg[0]) + r = c.post( + reverse('api:keyword-list'), + {'name': 'test'}, + content_type='application/json' + ) + response = json.loads(r.content) + 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']})) + assert r.status_code == 200 + r = u1_s2.get(reverse('api:keyword-detail', 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'), + {'name': obj_1.name}, + content_type='application/json' + ) + response = json.loads(r.content) + assert r.status_code == 201 + assert response['id'] == obj_1.id + + r = u1_s2.post( + reverse('api:keyword-list'), + {'name': obj_1.name}, + content_type='application/json' + ) + response = json.loads(r.content) + assert r.status_code == 201 + assert response['id'] != obj_1.id + + +def test_keyword_delete(u1_s1, u1_s2, obj_1): + r = u1_s2.delete( + reverse( + 'api:keyword-detail', + args={obj_1.id} + ) + ) + assert r.status_code == 404 + + r = u1_s1.delete( + reverse( + 'api:keyword-detail', + args={obj_1.id} + ) + ) + + assert r.status_code == 204 + with scopes_disabled(): + assert Keyword.objects.count() == 0 diff --git a/cookbook/tests/pytest/conftest.py b/cookbook/tests/pytest/conftest.py index a424b5834..bb61d5ce4 100644 --- a/cookbook/tests/pytest/conftest.py +++ b/cookbook/tests/pytest/conftest.py @@ -1,4 +1,5 @@ import copy +import inspect import uuid import pytest @@ -8,6 +9,17 @@ from django_scopes import scopes_disabled from cookbook.models import Space +# hack from https://github.com/raphaelm/django-scopes to disable scopes for all fixtures +# does not work on yield fixtures as only one yield can be used per fixture (i think) +@pytest.hookimpl(hookwrapper=True) +def pytest_fixture_setup(fixturedef, request): + if inspect.isgeneratorfunction(fixturedef.func): + yield + else: + with scopes_disabled(): + yield + + @pytest.fixture(autouse=True) def enable_db_access_for_all_tests(db): pass diff --git a/cookbook/views/api.py b/cookbook/views/api.py index d192dbd85..f3fe29419 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -152,7 +152,8 @@ class SupermarketViewSet(viewsets.ModelViewSet, StandardFilterMixin): permission_classes = [CustomIsUser] def get_queryset(self): - return self.queryset.filter(space=self.request.user.userpreference.space) + self.queryset = self.queryset.filter(space=self.request.user.userpreference.space) + return super().get_queryset() class KeywordViewSet(viewsets.ModelViewSet, StandardFilterMixin): @@ -169,7 +170,8 @@ class KeywordViewSet(viewsets.ModelViewSet, StandardFilterMixin): permission_classes = [CustomIsUser] def get_queryset(self): - return self.queryset.filter(space=self.request.user.userpreference.space) + self.queryset = self.queryset.filter(space=self.request.user.userpreference.space) + return super().get_queryset() class UnitViewSet(viewsets.ModelViewSet, StandardFilterMixin): @@ -178,7 +180,8 @@ class UnitViewSet(viewsets.ModelViewSet, StandardFilterMixin): permission_classes = [CustomIsUser] def get_queryset(self): - return self.queryset.filter(space=self.request.user.userpreference.space) + self.queryset = self.queryset.filter(space=self.request.user.userpreference.space) + return super().get_queryset() class FoodViewSet(viewsets.ModelViewSet, StandardFilterMixin): @@ -187,7 +190,8 @@ class FoodViewSet(viewsets.ModelViewSet, StandardFilterMixin): permission_classes = [CustomIsUser] def get_queryset(self): - return self.queryset.filter(space=self.request.user.userpreference.space) + self.queryset = self.queryset.filter(space=self.request.user.userpreference.space) + return super().get_queryset() class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin): @@ -196,7 +200,8 @@ class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin): permission_classes = [CustomIsOwner] def get_queryset(self): - return self.queryset.filter(created_by=self.request.user).filter(space=self.request.user.userpreference.space) + self.queryset = self.queryset.filter(created_by=self.request.user).filter(space=self.request.user.userpreference.space) + return super().get_queryset() class RecipeBookEntryViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet):