test_generics.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. from __future__ import unicode_literals, print_function
  2. import json
  3. from django.core.urlresolvers import reverse
  4. from django.test import TestCase
  5. from django.test.client import RequestFactory
  6. from rest_framework import status
  7. from .simple_app.models import SimpleModel
  8. from .simple_app.views import FilteredBulkAPIView, SimpleBulkAPIView
  9. class TestBulkAPIView(TestCase):
  10. def setUp(self):
  11. super(TestBulkAPIView, self).setUp()
  12. self.view = SimpleBulkAPIView.as_view()
  13. self.request = RequestFactory()
  14. def test_get(self):
  15. """
  16. Test that GET request is successful on bulk view.
  17. """
  18. response = self.view(self.request.get(''))
  19. self.assertEqual(response.status_code, status.HTTP_200_OK)
  20. def test_post_single(self):
  21. """
  22. Test that POST request with single resource only creates a single resource.
  23. """
  24. response = self.view(self.request.post(
  25. '',
  26. json.dumps({'contents': 'hello world', 'number': 1}),
  27. content_type='application/json',
  28. ))
  29. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  30. self.assertEqual(SimpleModel.objects.count(), 1)
  31. self.assertEqual(SimpleModel.objects.get().contents, 'hello world')
  32. def test_post_bulk(self):
  33. """
  34. Test that POST request with multiple resources creates all posted resources.
  35. """
  36. response = self.view(self.request.post(
  37. '',
  38. json.dumps([
  39. {'contents': 'hello world', 'number': 1},
  40. {'contents': 'hello mars', 'number': 2},
  41. ]),
  42. content_type='application/json',
  43. ))
  44. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  45. self.assertEqual(SimpleModel.objects.count(), 2)
  46. self.assertEqual(list(SimpleModel.objects.all().values_list('contents', flat=True)), [
  47. 'hello world',
  48. 'hello mars',
  49. ])
  50. def test_put(self):
  51. """
  52. Test that PUT request updates all submitted resources.
  53. """
  54. obj1 = SimpleModel.objects.create(contents='hello world', number=1)
  55. obj2 = SimpleModel.objects.create(contents='hello mars', number=2)
  56. response = self.view(self.request.put(
  57. '',
  58. json.dumps([
  59. {'contents': 'foo', 'number': 3, 'id': obj1.pk},
  60. {'contents': 'bar', 'number': 4, 'id': obj2.pk},
  61. ]),
  62. content_type='application/json',
  63. ))
  64. self.assertEqual(response.status_code, status.HTTP_200_OK)
  65. self.assertEqual(SimpleModel.objects.count(), 2)
  66. self.assertEqual(
  67. list(SimpleModel.objects.all().values_list('id', 'contents', 'number')),
  68. [
  69. (obj1.pk, 'foo', 3),
  70. (obj2.pk, 'bar', 4),
  71. ]
  72. )
  73. def test_put_without_update_key(self):
  74. """
  75. Test that PUT request updates all submitted resources.
  76. """
  77. response = self.view(self.request.put(
  78. '',
  79. json.dumps([
  80. {'contents': 'foo', 'number': 3},
  81. {'contents': 'rainbows', 'number': 4}, # multiple objects without id
  82. {'contents': 'bar', 'number': 4, 'id': 555}, # non-existing id
  83. ]),
  84. content_type='application/json',
  85. ))
  86. self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
  87. def test_patch(self):
  88. """
  89. Test that PATCH request partially updates all submitted resources.
  90. """
  91. obj1 = SimpleModel.objects.create(contents='hello world', number=1)
  92. obj2 = SimpleModel.objects.create(contents='hello mars', number=2)
  93. response = self.view(self.request.patch(
  94. '',
  95. json.dumps([
  96. {'contents': 'foo', 'id': obj1.pk},
  97. {'contents': 'bar', 'id': obj2.pk},
  98. ]),
  99. content_type='application/json',
  100. ))
  101. self.assertEqual(response.status_code, status.HTTP_200_OK)
  102. self.assertEqual(SimpleModel.objects.count(), 2)
  103. self.assertEqual(
  104. list(SimpleModel.objects.all().values_list('id', 'contents', 'number')),
  105. [
  106. (obj1.pk, 'foo', 1),
  107. (obj2.pk, 'bar', 2),
  108. ]
  109. )
  110. def test_delete_not_filtered(self):
  111. """
  112. Test that DELETE is not allowed when results are not filtered.
  113. """
  114. SimpleModel.objects.create(contents='hello world', number=1)
  115. SimpleModel.objects.create(contents='hello mars', number=10)
  116. response = self.view(self.request.delete(''))
  117. self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
  118. def test_delete_filtered(self):
  119. """
  120. Test that DELETE removes all filtered resources.
  121. """
  122. SimpleModel.objects.create(contents='hello world', number=1)
  123. SimpleModel.objects.create(contents='hello mars', number=10)
  124. response = FilteredBulkAPIView.as_view()(self.request.delete(''))
  125. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
  126. self.assertEqual(SimpleModel.objects.count(), 1)
  127. self.assertEqual(SimpleModel.objects.get().contents, 'hello world')
  128. def test_options(self):
  129. """
  130. Test that OPTIONS request is successful on bulk view.
  131. """
  132. response = self.view(self.request.options(''))
  133. self.assertEqual(response.status_code, status.HTTP_200_OK)
  134. class TestBulkAPIViewSet(TestCase):
  135. """
  136. Integration class testing that viewset requests are correctly
  137. routed via bulk router and that expected status code is returned.
  138. """
  139. def setUp(self):
  140. super(TestBulkAPIViewSet, self).setUp()
  141. self.url = reverse('api:simple-list')
  142. def test_get_single(self):
  143. """
  144. Test that we are still able to query single resource
  145. """
  146. response = self.client.get(self.url)
  147. self.assertEqual(response.status_code, status.HTTP_200_OK)
  148. def test_get(self):
  149. """
  150. Test that GET returns 200
  151. """
  152. obj = SimpleModel.objects.create(contents='hello world', number=7)
  153. response = self.client.get(reverse('api:simple-detail', args=[obj.pk]))
  154. self.assertEqual(response.status_code, status.HTTP_200_OK)
  155. def test_post_single(self):
  156. """
  157. Test that POST with single resource returns 201
  158. """
  159. response = self.client.post(
  160. self.url,
  161. data=json.dumps({
  162. 'contents': 'hello world',
  163. 'number': 1,
  164. }),
  165. content_type='application/json',
  166. )
  167. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  168. def test_post_bulk(self):
  169. """
  170. Test that POST with multiple resources returns 201
  171. """
  172. response = self.client.post(
  173. self.url,
  174. data=json.dumps([
  175. {
  176. 'contents': 'hello world',
  177. 'number': 1,
  178. },
  179. {
  180. 'contents': 'hello mars',
  181. 'number': 2,
  182. },
  183. ]),
  184. content_type='application/json',
  185. )
  186. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  187. def test_put(self):
  188. """
  189. Test that PUT with multiple resources returns 200
  190. """
  191. obj1 = SimpleModel.objects.create(contents='hello world', number=7)
  192. obj2 = SimpleModel.objects.create(contents='hello mars', number=10)
  193. response = self.client.put(
  194. self.url,
  195. data=json.dumps([
  196. {
  197. 'contents': 'foo',
  198. 'number': 1,
  199. 'id': obj1.pk,
  200. },
  201. {
  202. 'contents': 'bar',
  203. 'number': 2,
  204. 'id': obj2.pk,
  205. },
  206. ]),
  207. content_type='application/json',
  208. )
  209. self.assertEqual(response.status_code, status.HTTP_200_OK)
  210. def test_patch(self):
  211. """
  212. Test that PATCH with multiple partial resources returns 200
  213. """
  214. obj1 = SimpleModel.objects.create(contents='hello world', number=7)
  215. obj2 = SimpleModel.objects.create(contents='hello mars', number=10)
  216. response = self.client.patch(
  217. self.url,
  218. data=json.dumps([
  219. {
  220. 'contents': 'foo',
  221. 'id': obj1.pk,
  222. },
  223. {
  224. 'contents': 'bar',
  225. 'id': obj2.pk,
  226. },
  227. ]),
  228. content_type='application/json',
  229. )
  230. self.assertEqual(response.status_code, status.HTTP_200_OK)
  231. def test_delete(self):
  232. """
  233. Test that PATCH with multiple partial resources returns 200
  234. """
  235. SimpleModel.objects.create(contents='hello world', number=7)
  236. SimpleModel.objects.create(contents='hello mars', number=10)
  237. response = self.client.delete(self.url)
  238. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)