Skip to content

Commit 90d63fd

Browse files
committed
Added tests
1 parent a388d61 commit 90d63fd

File tree

2 files changed

+164
-1
lines changed

2 files changed

+164
-1
lines changed

example/tests/test_relations.py

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
from __future__ import absolute_import
22

3+
from django.test.client import RequestFactory
34
from django.utils import timezone
45
from rest_framework import serializers
6+
from rest_framework.fields import SkipField
7+
from rest_framework.reverse import reverse
58

69
from rest_framework_json_api.exceptions import Conflict
7-
from rest_framework_json_api.relations import ResourceRelatedField
10+
from rest_framework_json_api.relations import (
11+
HyperLinkedRelatedField,
12+
ResourceRelatedField,
13+
SerializerMethodHyperLinkedRelatedField
14+
)
815
from rest_framework_json_api.utils import format_resource_type
916

1017
from . import TestBase
1118
from example.models import Author, Blog, Comment, Entry
1219
from example.serializers import CommentSerializer
20+
from example.views import EntryViewSet
1321

1422

1523
class TestResourceRelatedField(TestBase):
@@ -129,6 +137,117 @@ def test_invalid_resource_id_object(self):
129137
}
130138

131139

140+
class TestHyperLinkedFieldBase(TestBase):
141+
142+
def setUp(self):
143+
super(TestHyperLinkedFieldBase, self).setUp()
144+
self.blog = Blog.objects.create(name='Some Blog', tagline="It's a blog")
145+
self.entry = Entry.objects.create(
146+
blog=self.blog,
147+
headline='headline',
148+
body_text='body_text',
149+
pub_date=timezone.now(),
150+
mod_date=timezone.now(),
151+
n_comments=0,
152+
n_pingbacks=0,
153+
rating=3
154+
)
155+
self.comment = Comment.objects.create(
156+
entry=self.entry,
157+
body='testing one two three',
158+
)
159+
160+
self.request = RequestFactory().get(reverse('entry-detail', kwargs={'pk': self.entry.pk}))
161+
self.view = EntryViewSet(request=self.request, kwargs={'entry_pk': self.entry.id})
162+
163+
164+
class TestHyperLinkedRelatedField(TestHyperLinkedFieldBase):
165+
166+
def test_single_hyperlinked_related_field(self):
167+
field = HyperLinkedRelatedField(
168+
related_link_view_name='entry-blog',
169+
related_link_url_kwarg='entry_pk',
170+
self_link_view_name='entry-relationships',
171+
read_only=True,
172+
)
173+
field._context = {'request': self.request, 'view': self.view}
174+
field.field_name = 'blog'
175+
176+
self.assertRaises(NotImplementedError, field.to_representation, self.entry)
177+
self.assertRaises(SkipField, field.get_attribute, self.entry)
178+
179+
links_expected = {
180+
'self': 'http://testserver/entries/{}/relationships/blog'.format(self.entry.pk),
181+
'related': 'http://testserver/entries/{}/blog'.format(self.entry.pk)
182+
}
183+
got = field.get_links(self.entry)
184+
self.assertEqual(got, links_expected)
185+
186+
def test_many_hyperlinked_related_field(self):
187+
field = HyperLinkedRelatedField(
188+
related_link_view_name='entry-comments',
189+
related_link_url_kwarg='entry_pk',
190+
self_link_view_name='entry-relationships',
191+
read_only=True,
192+
many=True
193+
)
194+
field._context = {'request': self.request, 'view': self.view}
195+
field.field_name = 'comments'
196+
197+
self.assertRaises(NotImplementedError, field.to_representation, self.entry.comments.all())
198+
self.assertRaises(SkipField, field.get_attribute, self.entry)
199+
200+
links_expected = {
201+
'self': 'http://testserver/entries/{}/relationships/comments'.format(self.entry.pk),
202+
'related': 'http://testserver/entries/{}/comments'.format(self.entry.pk)
203+
}
204+
got = field.child_relation.get_links(self.entry)
205+
self.assertEqual(got, links_expected)
206+
207+
208+
class TestSerializerMethodHyperLinkedRelatedField(TestHyperLinkedFieldBase):
209+
210+
def test_single_serializer_method_hyperlinked_related_field(self):
211+
serializer = EntryModelSerializerWithHyperLinks(
212+
instance=self.entry,
213+
context={
214+
'request': self.request,
215+
'view': self.view
216+
}
217+
)
218+
field = serializer.fields['blog']
219+
220+
self.assertRaises(NotImplementedError, field.to_representation, self.entry)
221+
self.assertRaises(SkipField, field.get_attribute, self.entry)
222+
223+
expected = {
224+
'self': 'http://testserver/entries/{}/relationships/blog'.format(self.entry.pk),
225+
'related': 'http://testserver/entries/{}/blog'.format(self.entry.pk)
226+
}
227+
got = field.get_links(self.entry)
228+
self.assertEqual(got, expected)
229+
230+
def test_many_serializer_method_hyperlinked_related_field(self):
231+
serializer = EntryModelSerializerWithHyperLinks(
232+
instance=self.entry,
233+
context={
234+
'request': self.request,
235+
'view': self.view
236+
}
237+
)
238+
field = serializer.fields['comments']
239+
240+
self.assertRaises(NotImplementedError, field.to_representation, self.entry)
241+
self.assertRaises(SkipField, field.get_attribute, self.entry)
242+
243+
expected = {
244+
'self': 'http://testserver/entries/{}/relationships/comments'.format(self.entry.pk),
245+
'related': 'http://testserver/entries/{}/comments'.format(self.entry.pk)
246+
}
247+
got = field.get_links(self.entry)
248+
self.assertEqual(got, expected)
249+
250+
132251
class BlogResourceRelatedField(ResourceRelatedField):
133252
def get_queryset(self):
134253
return Blog.objects
@@ -149,3 +268,32 @@ class EntryModelSerializer(serializers.ModelSerializer):
149268
class Meta:
150269
model = Entry
151270
fields = ('authors', 'comments')
271+
272+
273+
class EntryModelSerializerWithHyperLinks(serializers.ModelSerializer):
274+
blog = SerializerMethodHyperLinkedRelatedField(
275+
related_link_view_name='entry-blog',
276+
related_link_url_kwarg='entry_pk',
277+
self_link_view_name='entry-relationships',
278+
many=True,
279+
read_only=True,
280+
source='get_blog'
281+
)
282+
comments = SerializerMethodHyperLinkedRelatedField(
283+
related_link_view_name='entry-comments',
284+
related_link_url_kwarg='entry_pk',
285+
self_link_view_name='entry-relationships',
286+
many=True,
287+
read_only=True,
288+
source='get_comments'
289+
)
290+
291+
class Meta:
292+
model = Entry
293+
fields = ('blog', 'comments',)
294+
295+
def get_blog(self, obj):
296+
return obj.blog
297+
298+
def get_authors(self, obj):
299+
return obj.comments.all()

example/urls_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,25 @@
3737
GenericIdentity.as_view(), name='user-default'),
3838

3939

40+
url(r'^entries/(?P<entry_pk>[^/.]+)/blog',
41+
BlogViewSet.as_view({'get': 'retrieve'}),
42+
name='entry-blog'
43+
),
44+
url(r'^entries/(?P<entry_pk>[^/.]+)/comments',
45+
CommentViewSet.as_view({'get': 'list'}),
46+
name='entry-comments'
47+
),
4048
url(r'^entries/(?P<entry_pk>[^/.]+)/suggested/',
4149
EntryViewSet.as_view({'get': 'list'}),
4250
name='entry-suggested'
4351
),
52+
url(r'entries/(?P<entry_pk>[^/.]+)/authors',
53+
AuthorViewSet.as_view({'get': 'list'}),
54+
name='entry-authors'),
55+
url(r'entries/(?P<entry_pk>[^/.]+)/featured',
56+
EntryViewSet.as_view({'get': 'retrieve'}),
57+
name='entry-featured'),
58+
4459
url(r'^entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)',
4560
EntryRelationshipView.as_view(),
4661
name='entry-relationships'),

0 commit comments

Comments
 (0)