From d2be3f5468a18036ce796bc1dfdf3eb896277c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=CC=81o=20S?= Date: Tue, 28 Jun 2022 15:22:19 +0200 Subject: [PATCH 1/3] Add failing tests for misformed relationship pointers in error payloads (#1069) --- example/tests/__snapshots__/test_errors.ambr | 56 +++++++++++++++++++- example/tests/test_errors.py | 56 ++++++++++++++++++-- 2 files changed, 107 insertions(+), 5 deletions(-) diff --git a/example/tests/__snapshots__/test_errors.ambr b/example/tests/__snapshots__/test_errors.ambr index 1ef85ab8..fe872b46 100644 --- a/example/tests/__snapshots__/test_errors.ambr +++ b/example/tests/__snapshots__/test_errors.ambr @@ -47,14 +47,66 @@ ]), }) # --- -# name: test_relationship_errors_has_correct_pointers +# name: test_relationship_errors_has_correct_pointers_with_camelize dict({ 'errors': list([ dict({ 'code': 'incorrect_type', 'detail': 'Incorrect type. Expected resource identifier object, received str.', 'source': dict({ - 'pointer': '/data/relationships/author', + 'pointer': '/data/relationships/authors', + }), + 'status': '400', + }), + dict({ + 'code': 'incorrect_type', + 'detail': 'Incorrect type. Expected resource identifier object, received str.', + 'source': dict({ + 'pointer': '/data/relationships/mainAuthor', + }), + 'status': '400', + }), + ]), + }) +# --- +# name: test_relationship_errors_has_correct_pointers_with_dasherize + dict({ + 'errors': list([ + dict({ + 'code': 'incorrect_type', + 'detail': 'Incorrect type. Expected resource identifier object, received str.', + 'source': dict({ + 'pointer': '/data/relationships/authors', + }), + 'status': '400', + }), + dict({ + 'code': 'incorrect_type', + 'detail': 'Incorrect type. Expected resource identifier object, received str.', + 'source': dict({ + 'pointer': '/data/relationships/main-author', + }), + 'status': '400', + }), + ]), + }) +# --- +# name: test_relationship_errors_has_correct_pointers_with_no_formatting + dict({ + 'errors': list([ + dict({ + 'code': 'incorrect_type', + 'detail': 'Incorrect type. Expected resource identifier object, received str.', + 'source': dict({ + 'pointer': '/data/relationships/authors', + }), + 'status': '400', + }), + dict({ + 'code': 'incorrect_type', + 'detail': 'Incorrect type. Expected resource identifier object, received str.', + 'source': dict({ + 'pointer': '/data/relationships/main_author', }), 'status': '400', }), diff --git a/example/tests/test_errors.py b/example/tests/test_errors.py index 2267ec6e..72e742c7 100644 --- a/example/tests/test_errors.py +++ b/example/tests/test_errors.py @@ -30,9 +30,12 @@ class EntrySerializer(serializers.Serializer): comment = CommentSerializer(required=False) headline = serializers.CharField(allow_null=True, required=True) body_text = serializers.CharField() - author = serializers.ResourceRelatedField( + main_author = serializers.ResourceRelatedField( queryset=Author.objects.all(), required=False ) + authors = serializers.ResourceRelatedField( + queryset=Author.objects.all(), required=False, many=True + ) def validate(self, attrs): body_text = attrs["body_text"] @@ -195,7 +198,31 @@ def test_many_third_level_dict_errors(client, some_blog, snapshot): assert snapshot == perform_error_test(client, data) -def test_relationship_errors_has_correct_pointers(client, some_blog, snapshot): +def test_relationship_errors_has_correct_pointers_with_camelize( + client, some_blog, snapshot +): + data = { + "data": { + "type": "entries", + "attributes": { + "blog": some_blog.pk, + "bodyText": "body_text", + "headline": "headline", + }, + "relationships": { + "mainAuthor": {"data": {"id": "INVALID_ID", "type": "authors"}}, + "authors": {"data": [{"id": "INVALID_ID", "type": "authors"}]}, + }, + } + } + + assert snapshot == perform_error_test(client, data) + + +@override_settings(JSON_API_FORMAT_FIELD_NAMES="dasherize") +def test_relationship_errors_has_correct_pointers_with_dasherize( + client, some_blog, snapshot +): data = { "data": { "type": "entries", @@ -205,7 +232,30 @@ def test_relationship_errors_has_correct_pointers(client, some_blog, snapshot): "headline": "headline", }, "relationships": { - "author": {"data": {"id": "INVALID_ID", "type": "authors"}} + "main-author": {"data": {"id": "INVALID_ID", "type": "authors"}}, + "authors": {"data": [{"id": "INVALID_ID", "type": "authors"}]}, + }, + } + } + + assert snapshot == perform_error_test(client, data) + + +@override_settings(JSON_API_FORMAT_FIELD_NAMES=None) +def test_relationship_errors_has_correct_pointers_with_no_formatting( + client, some_blog, snapshot +): + data = { + "data": { + "type": "entries", + "attributes": { + "blog": some_blog.pk, + "body_text": "body_text", + "headline": "headline", + }, + "relationships": { + "main_author": {"data": {"id": "INVALID_ID", "type": "authors"}}, + "authors": {"data": [{"id": "INVALID_ID", "type": "authors"}]}, }, } } From d1e5bd82148468f7ba01fc03c1cfd71fbd253584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=CC=81o=20S?= Date: Tue, 28 Jun 2022 15:26:20 +0200 Subject: [PATCH 2/3] Properly format relationship pointers in error payloads (#1069) --- rest_framework_json_api/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index aba9de5a..8d2dfa73 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -380,7 +380,9 @@ def format_drf_errors(response, context, exc): serializer = context["view"].get_serializer() fields = get_serializer_fields(serializer) or dict() relationship_fields = [ - name for name, field in fields.items() if is_relationship_field(field) + format_field_name(name) + for name, field in fields.items() + if is_relationship_field(field) ] for field, error in response.data.items(): From 3bcc7b59a53d294fa149caf7a2d50725975f4793 Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Wed, 29 Jun 2022 11:59:46 +0200 Subject: [PATCH 3/3] Added CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6b257d4..a1b72009 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Note that in line with [Django REST framework policy](https://www.django-rest-framework.org/topics/release-notes/), any parts of the framework not mentioned in the documentation should generally be considered private API, and may be subject to change. +## [Unreleased] + +### Fixed + +* Fixed invalid relationship pointer in error objects when field naming formatting is used. + ## [5.0.0] - 2022-01-03 This release is not backwards compatible. For easy migration best upgrade first to version pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy