import email.parser
from django.core.urlresolvers import reverse
-from rest_framework.serializers import HyperlinkedModelSerializer
+from rest_framework.exceptions import ValidationError
from rest_framework.generics import ListAPIView
from rest_framework.generics import RetrieveUpdateAPIView
+from rest_framework.serializers import ChoiceField
+from rest_framework.serializers import HyperlinkedModelSerializer
from rest_framework.serializers import SerializerMethodField
from patchwork.api.base import PatchworkPermission
+from patchwork.api.base import STATE_CHOICES
from patchwork.models import Patch
+from patchwork.models import State
+
+
+class StateField(ChoiceField):
+ """Avoid the need for a state endpoint."""
+
+ def __init__(self, *args, **kwargs):
+ kwargs['choices'] = STATE_CHOICES
+ super(StateField, self).__init__(*args, **kwargs)
+
+ def to_internal_value(self, data):
+ data = ' '.join(data.split('-'))
+ try:
+ return State.objects.get(name__iexact=data)
+ except State.DoesNotExist:
+ raise ValidationError('Invalid state. Expected one of: %s ' %
+ ', '.join(STATE_CHOICES))
+
+ def to_representation(self, obj):
+ return '-'.join(obj.name.lower().split())
class PatchListSerializer(HyperlinkedModelSerializer):
mbox = SerializerMethodField()
- state = SerializerMethodField()
+ state = StateField()
tags = SerializerMethodField()
check = SerializerMethodField()
checks = SerializerMethodField()
- def get_state(self, instance):
- return instance.state.name
-
def get_mbox(self, instance):
request = self.context.get('request')
return request.build_absolute_uri(instance.get_mbox_url())
from patchwork.tests.utils import create_patch
from patchwork.tests.utils import create_person
from patchwork.tests.utils import create_project
+from patchwork.tests.utils import create_state
from patchwork.tests.utils import create_user
if settings.ENABLE_REST_API:
# A maintainer can update
project = create_project()
patch = create_patch(project=project)
+ state = create_state()
user = create_maintainer(project)
self.client.force_authenticate(user=user)
+ self.assertNotEqual(Patch.objects.get(id=patch.id).state, state)
resp = self.client.patch(self.api_url(patch.id),
- {'state': 2})
+ {'state': state.name})
self.assertEqual(status.HTTP_200_OK, resp.status_code)
+ self.assertEqual(Patch.objects.get(id=patch.id).state, state)
# A normal user can't
user = create_user()
self.client.force_authenticate(user=user)
resp = self.client.patch(self.api_url(patch.id),
- {'state': 2})
+ {'state': state.name})
self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
def test_delete(self):