You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

testcases.py 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. import json
  2. from http import client as http_client
  3. from django.conf import settings
  4. from django.contrib.messages import INFO
  5. from django.urls import reverse
  6. from django.utils.http import urlencode
  7. from oscar.core.loading import get_class
  8. RelatedFieldWidgetWrapper = get_class('dashboard.widgets',
  9. 'RelatedFieldWidgetWrapper')
  10. class ListViewMixin:
  11. url_name = None
  12. per_page = settings.OSCAR_DASHBOARD_ITEMS_PER_PAGE
  13. def _create_object(self, idx):
  14. raise NotImplementedError
  15. def _get_url(self):
  16. return reverse(self.url_name)
  17. def test_display_pagination_navigation(self):
  18. for idx in range(0, int(1.5 * self.per_page)):
  19. self._create_object(idx)
  20. page = self.get(self._get_url())
  21. # Test the pagination
  22. self.assertContains(page, 'Page 1 of 2')
  23. class ResponseObjectMixin:
  24. url_name = None
  25. def _test_success_response(self):
  26. response = self.response
  27. self.assertEqual(response.status_code, http_client.FOUND)
  28. self.assertRedirectsTo(response, self.success_url_name)
  29. messages = list(response.follow().context['messages'])
  30. self.assertEqual(len(messages), 1)
  31. self.assertEqual(messages[0].level, INFO)
  32. self.assertEqual(messages[0].message, self.success_message)
  33. def _get_url(self):
  34. raise NotImplementedError
  35. class PopUpWindowMixin:
  36. is_popup_testcase = None
  37. @property
  38. def is_popup(self):
  39. return RelatedFieldWidgetWrapper.IS_POPUP_VALUE
  40. @property
  41. def is_popup_var(self):
  42. return RelatedFieldWidgetWrapper.IS_POPUP_VAR
  43. @property
  44. def to_field(self):
  45. return self.model._meta.pk.name
  46. @property
  47. def to_field_var(self):
  48. return RelatedFieldWidgetWrapper.TO_FIELD_VAR
  49. def _test_popup_window_success_response(self):
  50. response = self.response
  51. self.assertEqual(response.status_code, http_client.OK)
  52. self.assertTemplateUsed(response, 'oscar/dashboard/widgets/popup_response.html')
  53. self.assertInContext(response, 'popup_response_data')
  54. self.popup_response_data = json.loads(response.context['popup_response_data'])
  55. def _test_display_regular_window_response(self):
  56. response = self.response
  57. self.assertTrue('is_popup' not in response.context)
  58. self.assertTrue('is_popup_var' not in response.context)
  59. def _get_popup_params(self):
  60. return {
  61. self.is_popup_var: self.is_popup,
  62. }
  63. def _get_popup_url(self, url):
  64. querystring = urlencode(self._get_popup_params())
  65. return '%s?%s' % (url, querystring)
  66. class PopUpWindowCreateUpdateMixin(PopUpWindowMixin):
  67. def _test_display_regular_window_response(self):
  68. super()._test_display_regular_window_response()
  69. response = self.response
  70. self.assertTrue('to_field' not in response.context)
  71. self.assertTrue('to_field_var' not in response.context)
  72. def _test_display_popup_window_response(self):
  73. response = self.response
  74. self.assertInContext(response, 'to_field')
  75. self.assertEqual(response.context['to_field'], self.to_field)
  76. self.assertInContext(response, 'is_popup')
  77. self.assertEqual(response.context['is_popup'], self.is_popup)
  78. self.assertInContext(response, 'to_field_var')
  79. self.assertEqual(response.context['to_field_var'], self.to_field_var)
  80. self.assertInContext(response, 'is_popup_var')
  81. self.assertEqual(response.context['is_popup_var'], self.is_popup_var)
  82. def _get_popup_params(self):
  83. params = super()._get_popup_params()
  84. params.update({self.to_field_var: self.to_field})
  85. return params
  86. class ObjectCreateMixin(ResponseObjectMixin):
  87. model = None
  88. form = None
  89. page_title = None
  90. url_name = None
  91. template_name = None
  92. success_message = None
  93. success_url_name = None
  94. create_check_attr = None
  95. object_check_str = None
  96. def _get_url(self):
  97. return reverse(self.url_name)
  98. def _test_display_create_form_response(self):
  99. response = self.response
  100. self.assertEqual(response.status_code, http_client.OK)
  101. self.assertTemplateUsed(response, self.template_name)
  102. self.assertInContext(response, 'form')
  103. self.assertIsInstance(response.context['form'], self.form)
  104. self.assertTrue(response.context['form'].instance._state.adding)
  105. self.assertInContext(response, 'title')
  106. self.assertEqual(response.context['title'], self.page_title)
  107. def test_display_create_form(self):
  108. self.response = self.get(reverse(self.url_name))
  109. # Test the response
  110. self._test_display_create_form_response()
  111. def _test_creation_of_objects(self):
  112. # Test the creation of an object
  113. self.assertEqual(1, self.model.objects.all().count())
  114. self.obj = self.model.objects.first()
  115. self.assertEqual(
  116. getattr(self.obj, self.create_check_attr), self.object_check_str)
  117. def _get_create_obj_response(self):
  118. raise NotImplementedError
  119. def test_create_object(self):
  120. self.response = self._get_create_obj_response()
  121. # Test the creation of an object
  122. self._test_creation_of_objects()
  123. # Test the response
  124. self._test_success_response()
  125. class PopUpObjectCreateMixin(PopUpWindowCreateUpdateMixin, ObjectCreateMixin):
  126. def _get_url(self):
  127. url = super()._get_url()
  128. if self.is_popup_testcase:
  129. return self._get_popup_url(url)
  130. return url
  131. def test_display_create_form(self):
  132. super().test_display_create_form()
  133. self._test_display_regular_window_response()
  134. def test_display_create_popup_form(self):
  135. self.is_popup_testcase = True
  136. self.url = self._get_url()
  137. self.response = self.get(self._get_url())
  138. # Test the response
  139. self._test_display_create_form_response()
  140. self._test_display_popup_window_response()
  141. def test_create_popup_object(self):
  142. self.is_popup_testcase = True
  143. self.response = self._get_create_obj_response()
  144. # Test the creation of an object
  145. self._test_creation_of_objects()
  146. # Test the response
  147. self._test_create_popup_success_response()
  148. def _test_create_popup_success_response(self):
  149. self._test_popup_window_success_response()
  150. popup_response_data = self.popup_response_data
  151. self.assertTrue('value' in popup_response_data)
  152. self.assertTrue('obj' in popup_response_data)
  153. self.assertFalse('action' in popup_response_data)
  154. response = self.response
  155. messages = list(response.context['messages'])
  156. self.assertEqual(len(messages), 0)
  157. class ObjectUpdateMixin(ResponseObjectMixin):
  158. model = None
  159. form = None
  160. page_title = None
  161. url_name = None
  162. template_name = None
  163. success_message = None
  164. success_url_name = None
  165. create_check_attr = None
  166. object_check_str = None
  167. def _get_url(self):
  168. return reverse(self.url_name, kwargs={'pk': self.obj.pk})
  169. def _get_page_title(self):
  170. raise NotImplementedError
  171. def _create_object_factory(self):
  172. raise NotImplementedError
  173. def setUp(self):
  174. super().setUp()
  175. self.obj = self._create_object_factory()
  176. def _test_display_update_form_response(self):
  177. response = self.response
  178. self.assertEqual(response.status_code, http_client.OK)
  179. self.assertTemplateUsed(response, self.template_name)
  180. self.assertInContext(response, 'form')
  181. self.assertIsInstance(response.context['form'], self.form)
  182. self.assertEqual(response.context['form'].instance, self.obj)
  183. self.assertInContext(response, 'title')
  184. self.assertEqual(response.context['title'], self._get_page_title())
  185. def test_display_update_form(self):
  186. self.response = self.get(self._get_url())
  187. # Test the response
  188. self._test_display_update_form_response()
  189. def _test_update_of_objects(self):
  190. # Test the update of an object
  191. self.obj = self.model.objects.first()
  192. self.assertEqual(
  193. getattr(self.obj, self.create_check_attr), self.object_check_str)
  194. def _get_update_obj_response(self):
  195. raise NotImplementedError
  196. def test_update_object(self):
  197. self.response = self._get_update_obj_response()
  198. # Test the update of an object
  199. self._test_update_of_objects()
  200. # Test the response
  201. self._test_success_response()
  202. class PopUpObjectUpdateMixin(PopUpWindowCreateUpdateMixin, ObjectUpdateMixin):
  203. def _get_url(self):
  204. url = super()._get_url()
  205. if self.is_popup_testcase:
  206. return self._get_popup_url(url)
  207. return url
  208. def test_display_update_form(self):
  209. super().test_display_update_form()
  210. self._test_display_regular_window_response()
  211. def test_display_update_popup_form(self):
  212. self.is_popup_testcase = True
  213. self.url = self._get_url()
  214. self.response = self.get(self._get_url())
  215. # Test the response
  216. self._test_display_update_form_response()
  217. self._test_display_popup_window_response()
  218. def test_update_popup_object(self):
  219. self.is_popup_testcase = True
  220. self.response = self._get_update_obj_response()
  221. # Test the creation of an object
  222. self._test_update_of_objects()
  223. # Test the response
  224. self._test_update_popup_success_response()
  225. def _test_update_popup_success_response(self):
  226. self._test_popup_window_success_response()
  227. popup_response_data = self.popup_response_data
  228. self.assertTrue('action' in popup_response_data)
  229. self.assertEqual(popup_response_data['action'], 'change')
  230. self.assertTrue('value' in popup_response_data)
  231. self.assertTrue('obj' in popup_response_data)
  232. self.assertTrue('new_value' in popup_response_data)
  233. response = self.response
  234. messages = list(response.context['messages'])
  235. self.assertEqual(len(messages), 0)
  236. class ObjectDeleteMixin(ResponseObjectMixin):
  237. model = None
  238. page_title = None
  239. url_name = None
  240. template_name = None
  241. success_message = None
  242. success_url_name = None
  243. delete_dissalowed_possible = None
  244. def _get_url(self):
  245. return reverse(self.url_name, kwargs={'pk': self.obj.pk})
  246. def _get_page_title(self):
  247. raise NotImplementedError
  248. def _create_object_factory(self):
  249. raise NotImplementedError
  250. def setUp(self):
  251. super().setUp()
  252. self.obj = self._create_object_factory()
  253. def _test_display_delete_form_response(self):
  254. response = self.response
  255. self.assertEqual(response.status_code, http_client.OK)
  256. self.assertTemplateUsed(response, self.template_name)
  257. self.assertInContext(response, 'title')
  258. self.assertEqual(response.context['title'], self._get_page_title())
  259. def test_display_delete_form(self):
  260. self.response = self.get(self._get_url())
  261. # Test the response
  262. self._test_display_delete_form_response()
  263. def test_delete_object(self):
  264. self.response = self._get_delete_obj_response()
  265. # Test the deletion of an object
  266. self._test_deletion_of_objects()
  267. # Test the response
  268. self._test_success_response()
  269. def _get_delete_obj_response(self):
  270. raise NotImplementedError
  271. def _test_deletion_of_objects(self):
  272. # Test the deletion of an object
  273. obj_exists = self.model.objects.exists()
  274. self.assertFalse(obj_exists)
  275. def test_display_disallowed_delete(self):
  276. if self.delete_dissalowed_possible:
  277. self.is_disallowed_test = True
  278. self._create_dissalowed_object_factory()
  279. self.response = self.get(self._get_url())
  280. # Test the response
  281. self._test_display_delete_disallowed_response()
  282. def _create_dissalowed_object_factory(self):
  283. raise NotImplementedError
  284. def _test_display_delete_disallowed_response(self):
  285. response = self.response
  286. self.assertInContext(response, 'disallow')
  287. self.assertTrue(response.context['disallow'])
  288. class PopUpObjectDeleteMixin(PopUpWindowMixin, ObjectDeleteMixin):
  289. def _get_url(self):
  290. url = super()._get_url()
  291. if self.is_popup_testcase:
  292. return self._get_popup_url(url)
  293. return url
  294. def test_display_delete_form(self):
  295. super().test_display_delete_form()
  296. self._test_display_regular_window_response()
  297. def test_display_delete_popup_form(self):
  298. self.is_popup_testcase = True
  299. self.url = self._get_url()
  300. self.response = self.get(self._get_url())
  301. # Test the response
  302. self._test_display_delete_form_response()
  303. self._test_display_popup_delete_response()
  304. def _test_display_popup_delete_response(self):
  305. response = self.response
  306. self.assertInContext(response, 'is_popup')
  307. self.assertEqual(response.context['is_popup'], self.is_popup)
  308. self.assertInContext(response, 'is_popup_var')
  309. self.assertEqual(response.context['is_popup_var'], self.is_popup_var)
  310. def test_delete_popup_object(self):
  311. self.is_popup_testcase = True
  312. self.response = self._get_delete_obj_response()
  313. # Test the deletion of an object
  314. self._test_deletion_of_objects()
  315. # Test the response
  316. self._test_delete_popup_success_response()
  317. def _test_delete_popup_success_response(self):
  318. self._test_popup_window_success_response()
  319. popup_response_data = self.popup_response_data
  320. self.assertTrue('action' in popup_response_data)
  321. self.assertEqual(popup_response_data['action'], 'delete')
  322. self.assertTrue('value' in popup_response_data)
  323. response = self.response
  324. messages = list(response.context['messages'])
  325. self.assertEqual(len(messages), 0)
  326. def test_display_disallowed_delete(self):
  327. super().test_display_disallowed_delete()
  328. self._test_display_regular_window_response()
  329. def test_display_disallowed_popup_delete(self):
  330. if self.delete_dissalowed_possible:
  331. self.is_popup_testcase = True
  332. self.is_disallowed_test = True
  333. self._create_dissalowed_object_factory()
  334. self.response = self.get(self._get_url())
  335. # Test the response
  336. self._test_display_popup_delete_response()
  337. self._test_display_delete_disallowed_response()