forked from django-json-api/django-rest-framework-json-api
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest_views.py
145 lines (111 loc) · 4.6 KB
/
test_views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import pytest
from django.urls import path, reverse
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_json_api import serializers
from rest_framework_json_api.parsers import JSONParser
from rest_framework_json_api.relations import ResourceRelatedField
from rest_framework_json_api.renderers import JSONRenderer
from rest_framework_json_api.utils import format_link_segment
from rest_framework_json_api.views import ModelViewSet, ReadOnlyModelViewSet
from tests.models import BasicModel
from tests.serializers import BasicModelSerializer
class TestModelViewSet:
@pytest.mark.parametrize(
"format_links",
[
False,
"dasherize",
"camelize",
"capitalize",
"underscore",
],
)
def test_get_related_field_name_handles_formatted_link_segments(
self, settings, format_links, rf
):
settings.JSON_API_FORMAT_RELATED_LINKS = format_links
# use field name which actually gets formatted
related_model_field_name = "related_field_model"
class RelatedFieldNameSerializer(serializers.ModelSerializer):
related_model_field = ResourceRelatedField(queryset=BasicModel.objects)
def __init__(self, *args, **kwargs):
self.related_model_field.field_name = related_model_field_name
super().__init(*args, **kwargs)
class Meta:
model = BasicModel
class RelatedFieldNameView(ModelViewSet):
serializer_class = RelatedFieldNameSerializer
url_segment = format_link_segment(related_model_field_name)
request = rf.get(f"/basic_models/1/{url_segment}")
view = RelatedFieldNameView()
view.setup(request, related_field=url_segment)
assert view.get_related_field_name() == related_model_field_name
class TestReadonlyModelViewSet:
@pytest.mark.parametrize(
"method",
["get", "post", "patch", "delete"],
)
@pytest.mark.parametrize(
"custom_action,action_kwargs",
[("list_action", {}), ("detail_action", {"pk": 1})],
)
def test_custom_action_allows_all_methods(
self, rf, method, custom_action, action_kwargs
):
"""
Test that write methods are allowed on custom list actions.
Even though a read only view only allows reading, custom actions
should be allowed to define other methods which are allowed.
"""
class ReadOnlyModelViewSetWithCustomActions(ReadOnlyModelViewSet):
serializer_class = BasicModelSerializer
queryset = BasicModel.objects.all()
@action(detail=False, methods=["get", "post", "patch", "delete"])
def list_action(self, request):
return Response(status=status.HTTP_204_NO_CONTENT)
@action(detail=True, methods=["get", "post", "patch", "delete"])
def detail_action(self, request, pk):
return Response(status=status.HTTP_204_NO_CONTENT)
view = ReadOnlyModelViewSetWithCustomActions.as_view({method: custom_action})
request = getattr(rf, method)("/", data={})
response = view(request, **action_kwargs)
assert response.status_code == status.HTTP_204_NO_CONTENT
class TestAPIView:
@pytest.mark.urls(__name__)
def test_patch(self, client):
data = {
"data": {
"id": 123,
"type": "custom",
"attributes": {"body": "hello"},
}
}
url = reverse("custom")
response = client.patch(url, data=data)
result = response.json()
assert result["data"]["id"] == str(123)
assert result["data"]["type"] == "custom"
assert result["data"]["attributes"]["body"] == "hello"
class CustomModel:
def __init__(self, response_dict):
for k, v in response_dict.items():
setattr(self, k, v)
@property
def pk(self):
return self.id if hasattr(self, "id") else None
class CustomModelSerializer(serializers.Serializer):
body = serializers.CharField()
id = serializers.IntegerField()
class CustomAPIView(APIView):
parser_classes = [JSONParser]
renderer_classes = [JSONRenderer]
resource_name = "custom"
def patch(self, request, *args, **kwargs):
serializer = CustomModelSerializer(CustomModel(request.data))
return Response(status=status.HTTP_200_OK, data=serializer.data)
urlpatterns = [
path("custom", CustomAPIView.as_view(), name="custom"),
]