from django.contrib.auth.models import User
+from rest_framework.relations import HyperlinkedRelatedField
from rest_framework.serializers import HyperlinkedModelSerializer
-from patchwork.models import Project
+from patchwork.models import Person, Project
+
+
+class URLSerializer(HyperlinkedModelSerializer):
+ """Just like parent but puts _url for fields"""
+
+ def to_representation(self, instance):
+ data = super(URLSerializer, self).to_representation(instance)
+ for name, field in self.fields.items():
+ if isinstance(field, HyperlinkedRelatedField) and name != 'url':
+ data[name + '_url'] = data.pop(name)
+ return data
+
+
+class PersonSerializer(URLSerializer):
+ class Meta:
+ model = Person
class UserSerializer(HyperlinkedModelSerializer):
self.assertEqual(1, Project.objects.all().count())
+@unittest.skipUnless(settings.ENABLE_REST_API, 'requires ENABLE_REST_API')
+class TestPersonAPI(APITestCase):
+ fixtures = ['default_states']
+
+ @staticmethod
+ def api_url(item=None):
+ if item is None:
+ return reverse('api_1.0:person-list')
+ return reverse('api_1.0:person-detail', args=[item])
+
+ def test_anonymous_list(self):
+ """The API should reject anonymous users."""
+ resp = self.client.get(self.api_url())
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ def test_authenticated_list(self):
+ """This API requires authenticated users."""
+ user = create_user()
+ self.client.force_authenticate(user=user)
+ resp = self.client.get(self.api_url())
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.assertEqual(1, len(resp.data))
+ self.assertEqual(user.username, resp.data[0]['name'])
+ self.assertEqual(user.email, resp.data[0]['email'])
+ self.assertIn('users/%d/' % user.id, resp.data[0]['user_url'])
+
+ def test_unlinked_user(self):
+ defaults.patch_author_person.save()
+ user = create_user()
+ self.client.force_authenticate(user=user)
+ resp = self.client.get(self.api_url())
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.assertEqual(2, len(resp.data))
+ self.assertEqual(defaults.patch_author_person.name,
+ resp.data[0]['name'])
+ self.assertIsNone(resp.data[0]['user_url'])
+
+ def test_readonly(self):
+ defaults.project.save()
+ user = create_maintainer(defaults.project)
+ user.is_superuser = True
+ user.save()
+ self.client.force_authenticate(user=user)
+
+ resp = self.client.delete(self.api_url(user.id))
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ resp = self.client.patch(self.api_url(user.id),
+ {'email': 'foo@f.com'})
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+ resp = self.client.post(self.api_url(), {'email': 'foo@f.com'})
+ self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+
@unittest.skipUnless(settings.ENABLE_REST_API, 'requires ENABLE_REST_API')
class TestUserAPI(APITestCase):
fixtures = ['default_states']
from django.conf import settings
from patchwork.rest_serializers import (
- ProjectSerializer, UserSerializer)
+ PersonSerializer, ProjectSerializer, UserSerializer)
from rest_framework import permissions
from rest_framework.pagination import PageNumberPagination
serializer_class = UserSerializer
+class PeopleViewSet(PatchworkViewSet):
+ permission_classes = (AuthenticatedReadOnly, )
+ serializer_class = PersonSerializer
+
+ def get_queryset(self):
+ qs = super(PeopleViewSet, self).get_queryset()
+ return qs.select_related('user__username')
+
+
class ProjectViewSet(PatchworkViewSet):
permission_classes = (PatchworkPermission, )
serializer_class = ProjectSerializer
router = DefaultRouter()
+router.register('people', PeopleViewSet, 'person')
router.register('projects', ProjectViewSet, 'project')
router.register('users', UserViewSet, 'user')