Skip to content

Commit

Permalink
Merge 287b085 into 8e32477
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiptoo Magutt committed Feb 6, 2018
2 parents 8e32477 + 287b085 commit eec1055
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions flask_restless/views/resources.py
Expand Up @@ -721,6 +721,8 @@ def patch(self, resource_id):
result = self.serializer.serialize(instance, only=only)
except SerializationException as exception:
return errors_from_serialization_exceptions([exception])
except self.validation_exceptions as exception:
return self._handle_validation_exception(exception)
status = 200
else:
result = dict()
Expand Down
1 change: 1 addition & 0 deletions requirements/test.txt
@@ -1,2 +1,3 @@
-r install.txt
unittest2
marshmallow
23 changes: 23 additions & 0 deletions tests/helpers.py
Expand Up @@ -39,6 +39,7 @@
from sqlalchemy.orm.session import Session as SessionBase
from sqlalchemy.types import CHAR
from sqlalchemy.types import TypeDecorator
from marshmallow import ValidationError

from flask_restless import APIManager
from flask_restless import collection_name
Expand Down Expand Up @@ -118,6 +119,28 @@ def deserialize_many(self, *args, **kw):
"""Immediately raises a :exc:`DeserializationException`."""
raise DeserializationException

class raise_s_validation_error(DefaultSerializer):
"""A serializer that unconditionally raises a validation error when
either :meth:`.serialize` or :meth:`.serialize_many` is called.
This class is useful for tests of validation errors.
"""

def serialize(self, instance, *args, **kw):
"""Immediately raises a :exc:`ValidationError` with
access to the provided `instance` of a SQLAlchemy model.
"""
raise ValidationError(instance)

def serialize_many(self, instances, *args, **kw):
"""Immediately raises a :exc:`ValidationError`.
This function requires `instances` to be non-empty.
"""
raise ValidationError(instances[0])

def isclass(obj):
"""Returns ``True`` if and only if the specified object is a type (or a
Expand Down
30 changes: 30 additions & 0 deletions tests/test_updating.py
Expand Up @@ -41,6 +41,7 @@
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import backref
from sqlalchemy.orm import relationship
from marshmallow import ValidationError

from flask_restless import APIManager
from flask_restless import JSONAPI_MIMETYPE
Expand All @@ -55,6 +56,7 @@
from .helpers import MSIE9_UA
from .helpers import ManagerTestBase
from .helpers import raise_s_exception as raise_exception
from .helpers import raise_s_validation_error as raise_validation_error


class TestUpdating(ManagerTestBase):
Expand Down Expand Up @@ -893,6 +895,34 @@ def test_serialization_exception(self):
check_sole_error(response, 500, ['Failed to serialize', 'type', 'tag',
'ID', '1'])

def test_serialization_validation_error(self):
"""Tests that serialization validation errors are caught when
responding with content.
A representation of the modified resource is returned to the
client when an update causes additional changes in the resource
in ways other than those specified by the client.
"""
tag = self.Tag(id=1)
self.session.add(tag)
self.session.commit()
self.manager.create_api(self.Tag, methods=['PATCH'],
validation_exceptions=[ValidationError],
serializer_class=raise_validation_error)
data = {
'data': {
'type': 'tag',
'id': '1',
'attributes': {
'name': u'foo'
}
}
}
response = self.app.patch('/api/tag/1', data=dumps(data))
assert response.status_code == 400
assert response.status == '400 BAD REQUEST'

def test_dont_assign_to_method(self):
"""Tests that if a certain method is to be included in a
resource, that method is not assigned to when updating the
Expand Down

0 comments on commit eec1055

Please sign in to comment.