Skip to content

Commit f9eb277

Browse files
leo-naekasliverc
andauthored
Fixed invalid relationship pointer in error object (#1070)
Co-authored-by: Oliver Sauder <[email protected]>
1 parent e49af3f commit f9eb277

File tree

4 files changed

+116
-6
lines changed

4 files changed

+116
-6
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
Note that in line with [Django REST framework policy](https://www.django-rest-framework.org/topics/release-notes/),
99
any parts of the framework not mentioned in the documentation should generally be considered private API, and may be subject to change.
1010

11+
## [Unreleased]
12+
13+
### Fixed
14+
15+
* Fixed invalid relationship pointer in error objects when field naming formatting is used.
16+
1117
## [5.0.0] - 2022-01-03
1218

1319
This release is not backwards compatible. For easy migration best upgrade first to version

example/tests/__snapshots__/test_errors.ambr

+54-2
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,66 @@
4747
]),
4848
})
4949
# ---
50-
# name: test_relationship_errors_has_correct_pointers
50+
# name: test_relationship_errors_has_correct_pointers_with_camelize
5151
dict({
5252
'errors': list([
5353
dict({
5454
'code': 'incorrect_type',
5555
'detail': 'Incorrect type. Expected resource identifier object, received str.',
5656
'source': dict({
57-
'pointer': '/data/relationships/author',
57+
'pointer': '/data/relationships/authors',
58+
}),
59+
'status': '400',
60+
}),
61+
dict({
62+
'code': 'incorrect_type',
63+
'detail': 'Incorrect type. Expected resource identifier object, received str.',
64+
'source': dict({
65+
'pointer': '/data/relationships/mainAuthor',
66+
}),
67+
'status': '400',
68+
}),
69+
]),
70+
})
71+
# ---
72+
# name: test_relationship_errors_has_correct_pointers_with_dasherize
73+
dict({
74+
'errors': list([
75+
dict({
76+
'code': 'incorrect_type',
77+
'detail': 'Incorrect type. Expected resource identifier object, received str.',
78+
'source': dict({
79+
'pointer': '/data/relationships/authors',
80+
}),
81+
'status': '400',
82+
}),
83+
dict({
84+
'code': 'incorrect_type',
85+
'detail': 'Incorrect type. Expected resource identifier object, received str.',
86+
'source': dict({
87+
'pointer': '/data/relationships/main-author',
88+
}),
89+
'status': '400',
90+
}),
91+
]),
92+
})
93+
# ---
94+
# name: test_relationship_errors_has_correct_pointers_with_no_formatting
95+
dict({
96+
'errors': list([
97+
dict({
98+
'code': 'incorrect_type',
99+
'detail': 'Incorrect type. Expected resource identifier object, received str.',
100+
'source': dict({
101+
'pointer': '/data/relationships/authors',
102+
}),
103+
'status': '400',
104+
}),
105+
dict({
106+
'code': 'incorrect_type',
107+
'detail': 'Incorrect type. Expected resource identifier object, received str.',
108+
'source': dict({
109+
'pointer': '/data/relationships/main_author',
58110
}),
59111
'status': '400',
60112
}),

example/tests/test_errors.py

+53-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ class EntrySerializer(serializers.Serializer):
3030
comment = CommentSerializer(required=False)
3131
headline = serializers.CharField(allow_null=True, required=True)
3232
body_text = serializers.CharField()
33-
author = serializers.ResourceRelatedField(
33+
main_author = serializers.ResourceRelatedField(
3434
queryset=Author.objects.all(), required=False
3535
)
36+
authors = serializers.ResourceRelatedField(
37+
queryset=Author.objects.all(), required=False, many=True
38+
)
3639

3740
def validate(self, attrs):
3841
body_text = attrs["body_text"]
@@ -195,7 +198,31 @@ def test_many_third_level_dict_errors(client, some_blog, snapshot):
195198
assert snapshot == perform_error_test(client, data)
196199

197200

198-
def test_relationship_errors_has_correct_pointers(client, some_blog, snapshot):
201+
def test_relationship_errors_has_correct_pointers_with_camelize(
202+
client, some_blog, snapshot
203+
):
204+
data = {
205+
"data": {
206+
"type": "entries",
207+
"attributes": {
208+
"blog": some_blog.pk,
209+
"bodyText": "body_text",
210+
"headline": "headline",
211+
},
212+
"relationships": {
213+
"mainAuthor": {"data": {"id": "INVALID_ID", "type": "authors"}},
214+
"authors": {"data": [{"id": "INVALID_ID", "type": "authors"}]},
215+
},
216+
}
217+
}
218+
219+
assert snapshot == perform_error_test(client, data)
220+
221+
222+
@override_settings(JSON_API_FORMAT_FIELD_NAMES="dasherize")
223+
def test_relationship_errors_has_correct_pointers_with_dasherize(
224+
client, some_blog, snapshot
225+
):
199226
data = {
200227
"data": {
201228
"type": "entries",
@@ -205,7 +232,30 @@ def test_relationship_errors_has_correct_pointers(client, some_blog, snapshot):
205232
"headline": "headline",
206233
},
207234
"relationships": {
208-
"author": {"data": {"id": "INVALID_ID", "type": "authors"}}
235+
"main-author": {"data": {"id": "INVALID_ID", "type": "authors"}},
236+
"authors": {"data": [{"id": "INVALID_ID", "type": "authors"}]},
237+
},
238+
}
239+
}
240+
241+
assert snapshot == perform_error_test(client, data)
242+
243+
244+
@override_settings(JSON_API_FORMAT_FIELD_NAMES=None)
245+
def test_relationship_errors_has_correct_pointers_with_no_formatting(
246+
client, some_blog, snapshot
247+
):
248+
data = {
249+
"data": {
250+
"type": "entries",
251+
"attributes": {
252+
"blog": some_blog.pk,
253+
"body_text": "body_text",
254+
"headline": "headline",
255+
},
256+
"relationships": {
257+
"main_author": {"data": {"id": "INVALID_ID", "type": "authors"}},
258+
"authors": {"data": [{"id": "INVALID_ID", "type": "authors"}]},
209259
},
210260
}
211261
}

rest_framework_json_api/utils.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,9 @@ def format_drf_errors(response, context, exc):
380380
serializer = context["view"].get_serializer()
381381
fields = get_serializer_fields(serializer) or dict()
382382
relationship_fields = [
383-
name for name, field in fields.items() if is_relationship_field(field)
383+
format_field_name(name)
384+
for name, field in fields.items()
385+
if is_relationship_field(field)
384386
]
385387

386388
for field, error in response.data.items():

0 commit comments

Comments
 (0)