From 6defe78137c0ec34c00abd025408c6602768043d Mon Sep 17 00:00:00 2001 From: Lukas Erlacher Date: Mon, 8 Jan 2018 16:22:00 +1100 Subject: [PATCH] Improve serializer bad relationship error Fixes a possible string formatting error in the error clause --- sqlalchemy_jsonapi/serializer.py | 14 +++++++--- .../tests/test_collection_post.py | 27 ++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/sqlalchemy_jsonapi/serializer.py b/sqlalchemy_jsonapi/serializer.py index 95d6b67..8379eac 100644 --- a/sqlalchemy_jsonapi/serializer.py +++ b/sqlalchemy_jsonapi/serializer.py @@ -47,6 +47,12 @@ class Permissions(Enum): EDIT = 102 DELETE = 103 +class MissingKey: + def __init__(self, elem): + self.elem = elem + + def __repr__(self): + return '<{} elem={}>'.format(self.__class__.__name__, self.elem) ALL_PERMISSIONS = { Permissions.VIEW, Permissions.CREATE, Permissions.EDIT, Permissions.DELETE @@ -980,15 +986,15 @@ def post_collection(self, session, data, api_type): data['data'].setdefault('attributes', {}) data_keys = set(map(( - lambda x: resource.__jsonapi_map_to_py__.get(x, None)), + lambda x: resource.__jsonapi_map_to_py__.get(x, MissingKey(x))), data['data'].get('relationships', {}).keys())) model_keys = set(resource.__mapper__.relationships.keys()) if not data_keys <= model_keys: + data_keys = set([key.elem if isinstance(key, MissingKey) else key for key in data_keys]) # pragma: no cover raise BadRequestError( - '{} not relationships for {}'.format( - ', '.join(list(data_keys - - model_keys)), model.__jsonapi_type__)) + '{} not relationships for {}'.format( + ', '.join([repr(key) for key in list(data_keys - model_keys)]), model.__jsonapi_type__)) attrs_to_ignore = {'__mapper__', 'id'} diff --git a/sqlalchemy_jsonapi/tests/test_collection_post.py b/sqlalchemy_jsonapi/tests/test_collection_post.py index e904fc5..bd76607 100644 --- a/sqlalchemy_jsonapi/tests/test_collection_post.py +++ b/sqlalchemy_jsonapi/tests/test_collection_post.py @@ -2,7 +2,7 @@ from sqlalchemy_jsonapi.errors import ( InvalidTypeForEndpointError, MissingTypeError, PermissionDeniedError, - ValidationError, MissingContentTypeError) + ValidationError, MissingContentTypeError, BadRequestError) from faker import Faker fake = Faker() @@ -183,3 +183,28 @@ def test_409_for_wrong_field_name(client): '/api/users/', data=json.dumps(payload), content_type='application/vnd.api+json').validate( 409, ValidationError) + + +def test_400_for_unknown_relationship_type(user, client): + payload = { + 'data': { + 'type': 'blog-posts', + 'attributes': { + 'title': 'Some title', + 'content': 'Hello, World!', + 'is-published': True + }, + 'relationships': { + 'bogon': { + 'data': { + 'type': 'users', + 'id': str(user.id) + } + } + } + } + } + client.post( + '/api/blog-posts/', data=json.dumps(payload), + content_type='application/vnd.api+json').validate( + 400, BadRequestError)