sqlalchemy-jsonapi
sqlalchemy-jsonapi copied to clipboard
Post_collection is not raising BadRequestError when payload relationships key's value are not a dictionary
It is very important that the library is able to return some sort of response that let's the user know they submitted an invalid request by raising a BadRequestError and returning a 400 and some sort of description explaining why.
Through testing post_collection, I found that we are not raising a BadRequestError when we send a payload where the relationships key's value are not of type dictionary. For example:
def test_add_resource_when_payload_relationships_keys_value_are_not_type_dict(self):
"""Create a resource when payload relationships key's are not of type dictionary returns 400.
Each relationships key's value must be of type dictionary.
A BadRequestError is raised.
"""
user = models.User(
first='Sally', last='Smith',
password='password', username='SallySmith1')
self.session.add(user)
self.session.commit()
payload = {
'data': {
'attributes': {
'first': 'Sally',
'last': 'Smith',
'username': 'SallySmith1',
'password': 'password',
},
'type': 'users',
'relationships': {
'posts': [{
'data': [{
'type': 'posts',
'id': 1
}]
}]
}
}
}
with self.assertRaises(errors.BadRequestError) as error:
models.serializer.post_collection(
self.session, payload, 'users')
self.assertEqual(
error.exception.detail, 'relationship posts must be an object')
self.assertEqual(error.exception.status_code, 400)
This test fails because there is no check for this in place in post_collection. Thus when I try to run this test a AttributeError occurs. Specifically the AttributeError is occuring because we are failing to check
if not isinstance(data_rel, dict):
raise BadRequestError('relationship {0} must be an object'.format(api_key))
before executing this piece of code in post_collection.
if 'data' not in data_rel.keys():
raise BadRequestError(
'Missing data key in relationship {}'.format(key))
Because we do not have this check, a AttributeError occurs because just prior to this code we have:
data_rel = data['data']['relationships'][api_key]
Thus when trying to do data_rel.keys() when data_rel is actually a list, results in an AttributeError since a 'list' object does not have the attribute 'keys'.
This is an easy fix that would provide an informative error message to users who send badly formatted payloads.