test_generics.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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, UniqueTogetherModel
  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_patch(self):
  74. """
  75. Test that PATCH request partially updates all submitted resources.
  76. """
  77. obj1 = SimpleModel.objects.create(contents='hello world', number=1)
  78. obj2 = SimpleModel.objects.create(contents='hello mars', number=2)
  79. response = self.view(self.request.patch(
  80. '',
  81. json.dumps([
  82. {'contents': 'foo', 'id': obj1.pk},
  83. {'contents': 'bar', 'id': obj2.pk},
  84. ]),
  85. content_type='application/json',
  86. ))
  87. self.assertEqual(response.status_code, status.HTTP_200_OK)
  88. self.assertEqual(SimpleModel.objects.count(), 2)
  89. self.assertEqual(
  90. list(SimpleModel.objects.all().values_list('id', 'contents', 'number')),
  91. [
  92. (obj1.pk, 'foo', 1),
  93. (obj2.pk, 'bar', 2),
  94. ]
  95. )
  96. def test_delete_not_filtered(self):
  97. """
  98. Test that DELETE is not allowed when results are not filtered.
  99. """
  100. SimpleModel.objects.create(contents='hello world', number=1)
  101. SimpleModel.objects.create(contents='hello mars', number=10)
  102. response = self.view(self.request.delete(''))
  103. self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
  104. def test_delete_filtered(self):
  105. """
  106. Test that DELETE removes all filtered resources.
  107. """
  108. SimpleModel.objects.create(contents='hello world', number=1)
  109. SimpleModel.objects.create(contents='hello mars', number=10)
  110. response = FilteredBulkAPIView.as_view()(self.request.delete(''))
  111. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
  112. self.assertEqual(SimpleModel.objects.count(), 1)
  113. self.assertEqual(SimpleModel.objects.get().contents, 'hello world')
  114. def test_options(self):
  115. """
  116. Test that OPTIONS request is successful on bulk view.
  117. """
  118. response = self.view(self.request.options(''))
  119. self.assertEqual(response.status_code, status.HTTP_200_OK)
  120. class TestBulkAPIViewSet(TestCase):
  121. """
  122. Integration class testing that viewset requests are correctly
  123. routed via bulk router and that expected status code is returned.
  124. """
  125. def setUp(self):
  126. super(TestBulkAPIViewSet, self).setUp()
  127. self.url = reverse('api:simple-list')
  128. def test_get_single(self):
  129. """
  130. Test that we are still able to query single resource
  131. """
  132. response = self.client.get(self.url)
  133. self.assertEqual(response.status_code, status.HTTP_200_OK)
  134. def test_get(self):
  135. """
  136. Test that GET returns 200
  137. """
  138. obj = SimpleModel.objects.create(contents='hello world', number=7)
  139. response = self.client.get(reverse('api:simple-detail', args=[obj.pk]))
  140. self.assertEqual(response.status_code, status.HTTP_200_OK)
  141. def test_post_single(self):
  142. """
  143. Test that POST with single resource returns 201
  144. """
  145. response = self.client.post(
  146. self.url,
  147. data=json.dumps({
  148. 'contents': 'hello world',
  149. 'number': 1,
  150. }),
  151. content_type='application/json',
  152. )
  153. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  154. def test_post_bulk(self):
  155. """
  156. Test that POST with multiple resources returns 201
  157. """
  158. response = self.client.post(
  159. self.url,
  160. data=json.dumps([
  161. {
  162. 'contents': 'hello world',
  163. 'number': 1,
  164. },
  165. {
  166. 'contents': 'hello mars',
  167. 'number': 2,
  168. },
  169. ]),
  170. content_type='application/json',
  171. )
  172. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  173. def test_put(self):
  174. """
  175. Test that PUT with multiple resources returns 200
  176. """
  177. obj1 = SimpleModel.objects.create(contents='hello world', number=7)
  178. obj2 = SimpleModel.objects.create(contents='hello mars', number=10)
  179. response = self.client.put(
  180. self.url,
  181. data=json.dumps([
  182. {
  183. 'contents': 'foo',
  184. 'number': 1,
  185. 'id': obj1.pk,
  186. },
  187. {
  188. 'contents': 'bar',
  189. 'number': 2,
  190. 'id': obj2.pk,
  191. },
  192. ]),
  193. content_type='application/json',
  194. )
  195. self.assertEqual(response.status_code, status.HTTP_200_OK)
  196. def test_patch(self):
  197. """
  198. Test that PATCH with multiple partial resources returns 200
  199. """
  200. obj1 = SimpleModel.objects.create(contents='hello world', number=7)
  201. obj2 = SimpleModel.objects.create(contents='hello mars', number=10)
  202. response = self.client.patch(
  203. self.url,
  204. data=json.dumps([
  205. {
  206. 'contents': 'foo',
  207. 'id': obj1.pk,
  208. },
  209. {
  210. 'contents': 'bar',
  211. 'id': obj2.pk,
  212. },
  213. ]),
  214. content_type='application/json',
  215. )
  216. self.assertEqual(response.status_code, status.HTTP_200_OK)
  217. def test_patch_unique_together(self):
  218. """
  219. Test that PATCH with multiple partial resources returns 200
  220. even on model with unique together columns
  221. """
  222. obj1 = UniqueTogetherModel.objects.create(foo=1, bar=2)
  223. obj2 = UniqueTogetherModel.objects.create(foo=3, bar=4)
  224. response = self.client.patch(
  225. reverse('api:unique-together-list'),
  226. data=json.dumps([
  227. {'foo': 5, 'id': obj1.pk},
  228. {'foo': 6, 'id': obj2.pk},
  229. ]),
  230. content_type='application/json',
  231. )
  232. self.assertEqual(response.status_code, status.HTTP_200_OK)
  233. def test_delete(self):
  234. """
  235. Test that PATCH with multiple partial resources returns 200
  236. """
  237. SimpleModel.objects.create(contents='hello world', number=7)
  238. SimpleModel.objects.create(contents='hello mars', number=10)
  239. response = self.client.delete(self.url)
  240. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)