From de9456e3d7567fd882941a602559aec5748b96a2 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Thu, 18 Mar 2021 18:48:29 +0100 Subject: [PATCH] import log api --- cookbook/serializer.py | 29 ++++++-- cookbook/tests/api/test_api_import_log.py | 86 +++++++++++++++++++++++ cookbook/urls.py | 1 + cookbook/views/api.py | 13 +++- 4 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 cookbook/tests/api/test_api_import_log.py diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 57ddb1432..916460a0e 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -13,7 +13,7 @@ from cookbook.models import (Comment, CookLog, Food, Ingredient, Keyword, RecipeBook, RecipeBookEntry, RecipeImport, ShareLink, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Step, Storage, Sync, SyncLog, - Unit, UserPreference, ViewLog, SupermarketCategory, Supermarket, SupermarketCategoryRelation) + Unit, UserPreference, ViewLog, SupermarketCategory, Supermarket, SupermarketCategoryRelation, ImportLog) from cookbook.templatetags.custom_tags import markdown @@ -160,6 +160,7 @@ class KeywordSerializer(UniqueFieldsMixin, serializers.ModelSerializer): return obj class Meta: + list_serializer_class = SpaceFilterSerializer model = Keyword fields = ('id', 'name', 'icon', 'label', 'description', 'created_at', 'updated_at') @@ -424,7 +425,7 @@ class ShareLinkSerializer(SpacedModelSerializer): class CookLogSerializer(serializers.ModelSerializer): - def create(self, validated_data): # TODO make mixin + def create(self, validated_data): validated_data['created_by'] = self.context['request'].user validated_data['space'] = self.context['request'].space return super().create(validated_data) @@ -435,10 +436,30 @@ class CookLogSerializer(serializers.ModelSerializer): read_only_fields = ('id', 'created_by') -class ViewLogSerializer(SpacedModelSerializer): +class ViewLogSerializer(serializers.ModelSerializer): + def create(self, validated_data): + validated_data['created_by'] = self.context['request'].user + validated_data['space'] = self.context['request'].space + return super().create(validated_data) + class Meta: model = ViewLog - fields = '__all__' + fields = ('id', 'recipe', 'created_by', 'created_at') + read_only_fields = ('created_by',) + + +class ImportLogSerializer(serializers.ModelSerializer): + keyword = KeywordSerializer(read_only=True) + + def create(self, validated_data): + validated_data['created_by'] = self.context['request'].user + validated_data['space'] = self.context['request'].space + return super().create(validated_data) + + class Meta: + model = ImportLog + fields = ('id', 'type', 'msg', 'running', 'keyword', 'created_by', 'created_at') + read_only_fields = ('created_by',) # Export/Import Serializers diff --git a/cookbook/tests/api/test_api_import_log.py b/cookbook/tests/api/test_api_import_log.py new file mode 100644 index 000000000..427c9a080 --- /dev/null +++ b/cookbook/tests/api/test_api_import_log.py @@ -0,0 +1,86 @@ +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, ViewLog, ImportLog + +LIST_URL = 'api:importlog-list' +DETAIL_URL = 'api:importlog-detail' + + +@pytest.fixture() +def obj_1(space_1, u1_s1, recipe_1_s1): + return ImportLog.objects.create(type='test', created_by=auth.get_user(u1_s1), space=space_1) + + +@pytest.fixture +def obj_2(space_1, u1_s1, recipe_1_s1): + return ImportLog.objects.create(type='test', created_by=auth.get_user(u1_s1), space=space_1) + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 403], + ['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)) == 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( + DETAIL_URL, + args={obj_1.id} + ), + {'msg': 'new'}, + content_type='application/json' + ) + assert r.status_code == arg[1] + + +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 ImportLog.objects.count() == 0 diff --git a/cookbook/urls.py b/cookbook/urls.py index cc5626533..47bf6b593 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -35,6 +35,7 @@ router.register(r'cook-log', api.CookLogViewSet) router.register(r'recipe-book', api.RecipeBookViewSet) router.register(r'recipe-book-entry', api.RecipeBookEntryViewSet) router.register(r'supermarket', api.SupermarketViewSet) +router.register(r'import-log', api.ImportLogViewSet) urlpatterns = [ path('', views.index, name='index'), diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 3db330669..784fb2b7f 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -32,7 +32,7 @@ from cookbook.models import (CookLog, Food, Ingredient, Keyword, MealPlan, MealType, Recipe, RecipeBook, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Step, Storage, Sync, SyncLog, Unit, UserPreference, - ViewLog, RecipeBookEntry, Supermarket) + ViewLog, RecipeBookEntry, Supermarket, ImportLog) from cookbook.provider.dropbox import Dropbox from cookbook.provider.local import Local from cookbook.provider.nextcloud import Nextcloud @@ -47,7 +47,7 @@ from cookbook.serializer import (FoodSerializer, IngredientSerializer, StorageSerializer, SyncLogSerializer, SyncSerializer, UnitSerializer, UserNameSerializer, UserPreferenceSerializer, - ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer, RecipeOverviewSerializer, SupermarketSerializer) + ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer, RecipeOverviewSerializer, SupermarketSerializer, ImportLogSerializer) from recipes.settings import DEMO @@ -393,6 +393,15 @@ class CookLogViewSet(viewsets.ModelViewSet): return self.queryset +class ImportLogViewSet(viewsets.ModelViewSet): + queryset = ImportLog.objects + serializer_class = ImportLogSerializer + permission_classes = [CustomIsUser] + + def get_queryset(self): + return self.queryset.filter(space=self.request.space).all() + + # -------------- non django rest api views -------------------- def get_recipe_provider(recipe):