Skip to content

Commit 854a8e0

Browse files
committed
More tests for RelationshipView
1 parent 610469d commit 854a8e0

File tree

4 files changed

+139
-20
lines changed

4 files changed

+139
-20
lines changed

example/models.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ def __str__(self):
5454
class Comment(BaseModel):
5555
entry = models.ForeignKey(Entry)
5656
body = models.TextField()
57-
author = models.ForeignKey(Author)
57+
author = models.ForeignKey(
58+
Author,
59+
null=True,
60+
blank=True
61+
)
5862

5963
def __str__(self):
6064
return self.body

example/tests/test_views.py

Lines changed: 113 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,82 @@
1+
import json
2+
13
from django.utils import timezone
24
from rest_framework.reverse import reverse
3-
from rest_framework.test import APITestCase, APIRequestFactory
4-
import json
55

6-
from rest_framework_json_api.utils import format_relation_name
6+
from rest_framework.test import APITestCase
77

8-
from example.models import Blog, Entry
9-
from example.views import EntryRelationshipView, BlogRelationshipView
8+
from rest_framework_json_api.utils import format_relation_name
9+
from example.models import Blog, Entry, Comment, Author
1010

1111

1212
class TestRelationshipView(APITestCase):
1313
def setUp(self):
14+
self.author = Author.objects.create(name='Super powerful superhero', email='i.am@lost.com')
1415
self.blog = Blog.objects.create(name='Some Blog', tagline="It's a blog")
1516
self.other_blog = Blog.objects.create(name='Other blog', tagline="It's another blog")
16-
self.entry = Entry.objects.create(
17+
self.first_entry = Entry.objects.create(
1718
blog=self.blog,
18-
headline='headline',
19-
body_text='body_text',
19+
headline='headline one',
20+
body_text='body_text two',
2021
pub_date=timezone.now(),
2122
mod_date=timezone.now(),
2223
n_comments=0,
2324
n_pingbacks=0,
2425
rating=3
2526
)
27+
self.second_entry = Entry.objects.create(
28+
blog=self.blog,
29+
headline='headline two',
30+
body_text='body_text one',
31+
pub_date=timezone.now(),
32+
mod_date=timezone.now(),
33+
n_comments=0,
34+
n_pingbacks=0,
35+
rating=1
36+
)
37+
self.first_comment = Comment.objects.create(entry=self.first_entry, body="This entry is cool", author=None)
38+
self.second_comment = Comment.objects.create(
39+
entry=self.second_entry,
40+
body="This entry is not cool",
41+
author=self.author
42+
)
2643

2744
def test_get_entry_relationship_blog(self):
28-
url = reverse('entry-relationships', kwargs={'pk': self.entry.id, 'related_field': 'blog'})
45+
url = reverse('entry-relationships', kwargs={'pk': self.first_entry.id, 'related_field': 'blog'})
2946
response = self.client.get(url)
30-
expected_data = {'type': format_relation_name('Blog'), 'id': str(self.entry.blog.id)}
47+
expected_data = {'type': format_relation_name('Blog'), 'id': str(self.first_entry.blog.id)}
3148

3249
assert response.data == expected_data
3350

3451
def test_get_entry_relationship_invalid_field(self):
35-
response = self.client.get('/entries/{}/relationships/invalid_field'.format(self.entry.id))
52+
response = self.client.get('/entries/{}/relationships/invalid_field'.format(self.first_entry.id))
3653

3754
assert response.status_code == 404
3855

3956
def test_get_blog_relationship_entry_set(self):
4057
response = self.client.get('/blogs/{}/relationships/entry_set'.format(self.blog.id))
4158

4259
def test_put_entry_relationship_blog_returns_405(self):
43-
url = '/entries/{}/relationships/blog'.format(self.entry.id)
60+
url = '/entries/{}/relationships/blog'.format(self.first_entry.id)
4461
response = self.client.put(url, data={})
4562
assert response.status_code == 405
4663

64+
def test_patch_invalid_entry_relationship_blog_returns_400(self):
65+
url = '/entries/{}/relationships/blog'.format(self.first_entry.id)
66+
response = self.client.patch(url,
67+
data=json.dumps({'data': {'invalid': ''}}),
68+
content_type='application/vnd.api+json')
69+
assert response.status_code == 400
70+
71+
def test_get_empty_to_one_relationship(self):
72+
url = '/comments/{}/relationships/author'.format(self.first_entry.id)
73+
response = self.client.get(url)
74+
expected_data = None
75+
76+
assert response.data == expected_data
77+
4778
def test_patch_to_one_relationship(self):
48-
url = '/entries/{}/relationships/blog'.format(self.entry.id)
79+
url = '/entries/{}/relationships/blog'.format(self.first_entry.id)
4980
request_data = {
5081
'data': {'type': format_relation_name('Blog'), 'id': str(self.other_blog.id)}
5182
}
@@ -54,3 +85,72 @@ def test_patch_to_one_relationship(self):
5485

5586
response = self.client.get(url)
5687
assert response.data == request_data['data']
88+
89+
def test_patch_to_many_relationship(self):
90+
url = '/blogs/{}/relationships/entry_set'.format(self.first_entry.id)
91+
request_data = {
92+
'data': [{'type': format_relation_name('Entry'), 'id': str(self.first_entry.id)}, ]
93+
}
94+
response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
95+
assert response.status_code == 200, response.content.decode()
96+
97+
response = self.client.get(url)
98+
assert response.data == request_data['data']
99+
100+
def test_post_to_one_relationship_should_fail(self):
101+
url = '/entries/{}/relationships/blog'.format(self.first_entry.id)
102+
request_data = {
103+
'data': {'type': format_relation_name('Blog'), 'id': str(self.other_blog.id)}
104+
}
105+
response = self.client.post(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
106+
assert response.status_code == 405, response.content.decode()
107+
108+
def test_post_to_many_relationship_with_no_change(self):
109+
url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id)
110+
request_data = {
111+
'data': [{'type': format_relation_name('Comment'), 'id': str(self.first_comment.id)}, ]
112+
}
113+
response = self.client.post(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
114+
assert response.status_code == 204, response.content.decode()
115+
116+
def test_post_to_many_relationship_with_change(self):
117+
url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id)
118+
request_data = {
119+
'data': [{'type': format_relation_name('Comment'), 'id': str(self.second_comment.id)}, ]
120+
}
121+
response = self.client.post(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
122+
assert response.status_code == 200, response.content.decode()
123+
124+
assert request_data['data'][0] in response.data
125+
126+
def test_delete_to_one_relationship_should_fail(self):
127+
url = '/entries/{}/relationships/blog'.format(self.first_entry.id)
128+
request_data = {
129+
'data': {'type': format_relation_name('Blog'), 'id': str(self.other_blog.id)}
130+
}
131+
response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
132+
assert response.status_code == 405, response.content.decode()
133+
134+
def test_delete_to_many_relationship_with_no_change(self):
135+
url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id)
136+
request_data = {
137+
'data': [{'type': format_relation_name('Comment'), 'id': str(self.second_comment.id)}, ]
138+
}
139+
response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
140+
assert response.status_code == 204, response.content.decode()
141+
142+
def test_delete_one_to_many_relationship_with_not_null_constraint(self):
143+
url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id)
144+
request_data = {
145+
'data': [{'type': format_relation_name('Comment'), 'id': str(self.first_comment.id)}, ]
146+
}
147+
response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
148+
assert response.status_code == 409, response.content.decode()
149+
150+
def test_delete_to_many_relationship_with_change(self):
151+
url = '/authors/{}/relationships/comment_set'.format(self.author.id)
152+
request_data = {
153+
'data': [{'type': format_relation_name('Comment'), 'id': str(self.second_comment.id)}, ]
154+
}
155+
response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json')
156+
assert response.status_code == 200, response.content.decode()

example/urls_test.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from django.conf.urls import include, url
22
from rest_framework import routers
33

4-
from example.views import BlogViewSet, EntryViewSet, AuthorViewSet, EntryRelationshipView, BlogRelationshipView
4+
from example.views import BlogViewSet, EntryViewSet, AuthorViewSet, EntryRelationshipView, BlogRelationshipView, \
5+
CommentRelationshipView, AuthorRelationshipView
56
from .api.resources.identity import Identity, GenericIdentity
67

78
router = routers.DefaultRouter(trailing_slash=False)
@@ -27,5 +28,11 @@
2728
url(r'^blogs/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)',
2829
BlogRelationshipView.as_view(),
2930
name='blog-relationships'),
31+
url(r'^comments/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)',
32+
CommentRelationshipView.as_view(),
33+
name='comment-relationships'),
34+
url(r'^authors/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)',
35+
AuthorRelationshipView.as_view(),
36+
name='author-relationships'),
3037
]
3138

example/views.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
11
from rest_framework import viewsets
2+
23
from rest_framework_json_api.views import RelationshipView
3-
from example.models import Blog, Entry, Author
4+
from example.models import Blog, Entry, Author, Comment
45
from example.serializers import BlogSerializer, EntrySerializer, AuthorSerializer
56

67

78
class BlogViewSet(viewsets.ModelViewSet):
8-
99
queryset = Blog.objects.all()
1010
serializer_class = BlogSerializer
1111

12-
class EntryViewSet(viewsets.ModelViewSet):
1312

13+
class EntryViewSet(viewsets.ModelViewSet):
1414
queryset = Entry.objects.all()
1515
serializer_class = EntrySerializer
1616
resource_name = 'posts'
1717

18-
class AuthorViewSet(viewsets.ModelViewSet):
1918

19+
class AuthorViewSet(viewsets.ModelViewSet):
2020
queryset = Author.objects.all()
2121
serializer_class = AuthorSerializer
2222

2323

24-
2524
class EntryRelationshipView(RelationshipView):
2625
queryset = Entry.objects
2726

27+
2828
class BlogRelationshipView(RelationshipView):
2929
queryset = Blog.objects
30+
31+
32+
class CommentRelationshipView(RelationshipView):
33+
queryset = Comment.objects
34+
35+
36+
class AuthorRelationshipView(RelationshipView):
37+
queryset = Author.objects

0 commit comments

Comments
 (0)