diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 4abb415a..90d7b5b1 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -40,7 +40,8 @@ class UserNameSerializer(serializers.ModelSerializer): class UserPreferenceSerializer(serializers.ModelSerializer): class Meta: model = UserPreference - fields = '__all__' + fields = ('user', 'theme', 'nav_color', 'default_unit', 'default_page', 'search_style', 'show_recent', + 'plan_share', 'ingredient_decimals', 'comments') read_only_fields = ['user'] @@ -58,7 +59,7 @@ class StorageSerializer(serializers.ModelSerializer): class SyncSerializer(serializers.ModelSerializer): class Meta: model = Sync - fields = '__all__' + fields = ('storage', 'path', 'active', 'last_checked', 'created_at', 'updated_at') class SyncLogSerializer(serializers.ModelSerializer): diff --git a/cookbook/tests/api/test_api_sync.py b/cookbook/tests/api/test_api_sync.py new file mode 100644 index 00000000..92024d6e --- /dev/null +++ b/cookbook/tests/api/test_api_sync.py @@ -0,0 +1,53 @@ +import json + +from django.contrib import auth +from django.db.models import ProtectedError +from django.urls import reverse + +from cookbook.models import Storage, Sync +from cookbook.tests.views.test_views import TestViews + + +class TestApiSync(TestViews): + + def setUp(self): + super(TestApiSync, self).setUp() + self.storage = Storage.objects.create( + name='Test Storage', + username='test', + password='password', + token='token', + url='url', + created_by=auth.get_user(self.admin_client_1) + ) + + self.sync = Sync.objects.create( + storage=self.storage, + path='path' + ) + + def test_sync_list(self): + # verify view permissions are applied accordingly + self.batch_requests([(self.anonymous_client, 403), (self.guest_client_1, 403), (self.user_client_1, 403), (self.admin_client_1, 200), (self.superuser_client, 200)], + reverse('api:sync-list')) + + # verify sync is returned + r = self.admin_client_1.get(reverse('api:sync-list')) + self.assertEqual(r.status_code, 200) + response = json.loads(r.content) + self.assertEqual(len(response), 1) + storage_response = response[0] + self.assertEqual(storage_response['path'], self.sync.path) + + def test_sync_update(self): + # can update sync as admin + r = self.admin_client_1.patch(reverse('api:sync-detail', args={self.sync.id}), {'path': 'new'}, content_type='application/json') + response = json.loads(r.content) + self.assertEqual(r.status_code, 200) + self.assertEqual(response['path'], 'new') + + def test_storage_delete(self): + # can delete sync as admin + r = self.admin_client_1.delete(reverse('api:sync-detail', args={self.sync.id})) + self.assertEqual(r.status_code, 204) + self.assertEqual(Sync.objects.count(), 0) diff --git a/cookbook/urls.py b/cookbook/urls.py index c20fcb7b..895c4254 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -12,6 +12,7 @@ router = routers.DefaultRouter() router.register(r'user-name', api.UserNameViewSet, basename='username') router.register(r'user-preference', api.UserPreferenceViewSet) router.register(r'storage', api.StorageViewSet) +router.register(r'sync', api.SyncViewSet) router.register(r'unit', api.UnitViewSet) router.register(r'food', api.FoodViewSet) diff --git a/cookbook/views/api.py b/cookbook/views/api.py index f7062abc..1d0f5df8 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -27,7 +27,7 @@ from cookbook.models import Recipe, Sync, Storage, CookLog, MealPlan, MealType, from cookbook.provider.dropbox import Dropbox from cookbook.provider.nextcloud import Nextcloud from cookbook.serializer import MealPlanSerializer, MealTypeSerializer, RecipeSerializer, ViewLogSerializer, UserNameSerializer, UserPreferenceSerializer, RecipeBookSerializer, IngredientSerializer, FoodSerializer, StepSerializer, \ - KeywordSerializer, RecipeImageSerializer, StorageSerializer + KeywordSerializer, RecipeImageSerializer, StorageSerializer, SyncSerializer class UserNameViewSet(viewsets.ReadOnlyModelViewSet): @@ -77,6 +77,12 @@ class StorageViewSet(viewsets.ModelViewSet): permission_classes = [CustomIsAdmin, ] +class SyncViewSet(viewsets.ModelViewSet): + queryset = Sync.objects.all() + serializer_class = SyncSerializer + permission_classes = [CustomIsAdmin, ] + + class RecipeBookViewSet(RetrieveModelMixin, UpdateModelMixin, ListModelMixin, viewsets.GenericViewSet): queryset = RecipeBook.objects.all() serializer_class = RecipeBookSerializer