Skip to content

Commit

Permalink
Make sigkey key_id editable
Browse files Browse the repository at this point in the history
This is consistent with other resources where their string primary
identifier can be changed as well (release_id, product_version_id etc).

This change makes it possible to allow PUT requests to update keys. The
original reason to disable it was because key_id was read-only.

A test for creating sigkeys is added to make sure it is not broken.

JIRA: PDC-634, PDC-855, PDC-965
  • Loading branch information
lubomir committed Aug 26, 2015
1 parent d4ac26a commit 48458ab
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 67 deletions.
7 changes: 1 addition & 6 deletions pdc/apps/common/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,6 @@ class Meta:

class SigKeySerializer(StrictSerializerMixin,
serializers.HyperlinkedModelSerializer):
key_id = serializers.CharField(read_only=True)

class Meta:
model = SigKey
fields = ('url', 'name', 'key_id', 'description')
extra_kwargs = {
'url': {'lookup_field': 'key_id'}
}
fields = ('name', 'key_id', 'description')
49 changes: 31 additions & 18 deletions pdc/apps/common/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,30 +337,38 @@ def test_retrieve_sigkey(self):

def test_update_sigkey(self):
url = reverse('sigkey-detail', kwargs={'key_id': '1234adbf'})
response = self.client.put(url, format='json', data={'name': "TEST"})
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
response = self.client.put(url, format='json',
data={'key_id': '1234adbf', 'name': "TEST"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNumChanges([1])
self.assertEqual(response.data['name'], 'TEST')

def test_partial_update_sigkey(self):
url = reverse('sigkey-detail', kwargs={'key_id': '1234adbf'})
response = self.client.patch(url, format='json', data={'name': "TEST"})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['name'], 'TEST')

def test_updating_key_id_fails(self):
def test_can_update_key_id(self):
response = self.client.patch(reverse('sigkey-detail', args=['1234adbf']),
{'key_id': 'cafebabe'},
format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data.get('key_id'), '1234adbf')
self.assertNumChanges([])

def test_bulk_update_fails(self):
response = self.client.put(reverse('sigkey-list'),
{'1234adbf': {'name': 'A',
'description': 'icontains_a'}},
format='json')
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
self.assertNumChanges([])
self.assertEqual(response.data.get('key_id'), 'cafebabe')
self.assertNumChanges([1])
response = self.client.get(reverse('sigkey-detail', args=['1234adbf']))
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
response = self.client.get(reverse('sigkey-detail', args=['cafebabe']))
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_can_bulk_update(self):
data = {'1234adbf': {'name': 'A',
'description': 'icontains_a',
'key_id': '1234adbf'}}
response = self.client.put(reverse('sigkey-list'), data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNumChanges([1])
self.assertDictEqual(dict(response.data), data)

def test_bulk_partial_update(self):
response = self.client.patch(reverse('sigkey-list'),
Expand All @@ -369,16 +377,13 @@ def test_bulk_partial_update(self):
format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNumChanges([2])
base_url_fmt = 'http://testserver/rest_api/v1/sigkeys/%s/'
self.assertDictEqual(dict(response.data),
{'1234adbf': {'key_id': '1234adbf',
'name': 'Key A',
'description': 'icontains_A',
'url': base_url_fmt % '1234adbf'},
'description': 'icontains_A'},
'f2134bca': {'key_id': 'f2134bca',
'name': 'B',
'description': 'icontains b',
'url': base_url_fmt % 'f2134bca'}})
'description': 'icontains b'}})

def test_partial_update_empty(self):
url = reverse('sigkey-detail', kwargs={'key_id': '1234adbf'})
Expand All @@ -390,6 +395,14 @@ def test_delete_sigkey(self):
response = self.client.delete(url, format='json')
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

def test_create_sigkey(self):
url = reverse('sigkey-list')
data = {"key_id": "abcd1234", "name": "test", "description": "test"}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertDictEqual(dict(response.data), data)
self.assertNumChanges([1])


class FilterDocumentingTestCase(TestCase):
def test_result_is_cached(self):
Expand Down
48 changes: 5 additions & 43 deletions pdc/apps/common/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

from rest_framework import viewsets, mixins

from contrib.bulk_operations import bulk_operations

from .models import Arch, SigKey, Label
from . import viewsets as pdc_viewsets
from .serializers import LabelSerializer, ArchSerializer, SigKeySerializer
Expand Down Expand Up @@ -348,54 +346,18 @@ def update(self, request, *args, **kwargs):
__Method__: `PUT`, `PATCH`
PATCH: for partial update
__URL__: $LINK:sigkey-detail:key_id$
__Data__:
%(WRITABLE_SERIALIZER)s
__Response__:
%(SERIALIZER)s
"""

# NOTE: key_id is a read only field and do not allow to update to
# another value, so PATCH is better to take this behavior as the same
# as the XMLRPC API.
if not kwargs.get('partial', False):
return self.http_method_not_allowed(request, *args, **kwargs)
else:
return super(SigKeyViewSet, self).update(request, *args, **kwargs)
All keys are optional for `PATCH` request, but at least one must be
specified.
def bulk_update(self, *args, **kwargs):
"""
### BULK UPDATE
Only partial updating is allowed.
__Method__: PATCH
The data should include a mapping from `key_id` to a change
description. Possible changes are below:
{"name": "new_name"}
or
{"description": "new_description"}
or
{"name": "new_name", "description": "new_description"}
__URL__: $LINK:sigkey-list$
__URL__: $LINK:sigkey-detail:key_id$
__Response__:
The response will again include a mapping from `key_id` to objects
representing the keys. Each key will be shown as follows:
%(SERIALIZER)s
"""
return bulk_operations.bulk_update_impl(self, *args, **kwargs)
return super(SigKeyViewSet, self).update(request, *args, **kwargs)

def create(self, request, *args, **kwargs):
"""
Expand All @@ -408,7 +370,7 @@ def create(self, request, *args, **kwargs):
__Data__:
%(SERIALIZER)s
%(WRITABLE_SERIALIZER)s
__Response__:
Expand Down

0 comments on commit 48458ab

Please sign in to comment.