您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

test_views.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. from django.contrib.messages import get_messages
  2. from django.test import TestCase
  3. from django.urls import reverse
  4. from oscar.apps.basket import views
  5. from oscar.core.loading import get_model
  6. from oscar.test import factories
  7. from oscar.test.factories import (
  8. AttributeOptionFactory, AttributeOptionGroupFactory, OptionFactory)
  9. from oscar.test.testcases import WebTestCase
  10. from tests.fixtures import RequestFactory
  11. from tests.functional.checkout import CheckoutMixin
  12. Option = get_model("catalogue", "Option")
  13. class TestVoucherAddView(TestCase):
  14. def test_get(self):
  15. request = RequestFactory().get('/')
  16. view = views.VoucherAddView.as_view()
  17. response = view(request)
  18. self.assertEqual(response.status_code, 302)
  19. def _get_voucher_message(self, request):
  20. return '\n'.join(str(m.message) for m in get_messages(request))
  21. def test_post_valid(self):
  22. voucher = factories.VoucherFactory()
  23. self.assertTrue(voucher.is_active())
  24. data = {
  25. 'code': voucher.code
  26. }
  27. request = RequestFactory().post('/', data=data)
  28. request.basket.save()
  29. view = views.VoucherAddView.as_view()
  30. response = view(request)
  31. self.assertEqual(response.status_code, 302)
  32. voucher = voucher.__class__.objects.get(pk=voucher.pk)
  33. self.assertEqual(voucher.num_basket_additions, 1, msg=self._get_voucher_message(request))
  34. def test_post_valid_from_set(self):
  35. voucherset = factories.VoucherSetFactory()
  36. voucher = voucherset.vouchers.first()
  37. self.assertTrue(voucher.is_active())
  38. data = {
  39. 'code': voucher.code
  40. }
  41. request = RequestFactory().post('/', data=data)
  42. request.basket.save()
  43. view = views.VoucherAddView.as_view()
  44. response = view(request)
  45. self.assertEqual(response.status_code, 302)
  46. voucher = voucher.__class__.objects.get(pk=voucher.pk)
  47. self.assertEqual(voucher.num_basket_additions, 1, msg=self._get_voucher_message(request))
  48. self.assertEqual(voucherset.num_basket_additions, 1)
  49. class TestVoucherRemoveView(TestCase):
  50. def test_post_valid(self):
  51. voucher = factories.VoucherFactory(num_basket_additions=5)
  52. data = {
  53. 'code': voucher.code
  54. }
  55. request = RequestFactory().post('/', data=data)
  56. request.basket.save()
  57. request.basket.vouchers.add(voucher)
  58. view = views.VoucherRemoveView.as_view()
  59. response = view(request, pk=voucher.pk)
  60. self.assertEqual(response.status_code, 302)
  61. voucher = voucher.__class__.objects.get(pk=voucher.pk)
  62. self.assertEqual(voucher.num_basket_additions, 4)
  63. def test_post_with_missing_voucher(self):
  64. """ If the voucher is missing, verify the view queues a message and redirects. """
  65. pk = '12345'
  66. view = views.VoucherRemoveView.as_view()
  67. request = RequestFactory().post('/')
  68. request.basket.save()
  69. response = view(request, pk=pk)
  70. self.assertEqual(response.status_code, 302)
  71. actual = list(get_messages(request))[-1].message
  72. expected = "No voucher found with id '{}'".format(pk)
  73. self.assertEqual(actual, expected)
  74. class TestBasketSummaryView(TestCase):
  75. def setUp(self):
  76. self.url = reverse('basket:summary')
  77. self.country = factories.CountryFactory()
  78. self.user = factories.UserFactory()
  79. def test_default_shipping_address(self):
  80. user_address = factories.UserAddressFactory(
  81. country=self.country, user=self.user, is_default_for_shipping=True
  82. )
  83. request = RequestFactory().get(self.url, user=self.user)
  84. view = views.BasketView(request=request)
  85. self.assertEqual(view.get_default_shipping_address(), user_address)
  86. def test_default_shipping_address_for_anonymous_user(self):
  87. request = RequestFactory().get(self.url)
  88. view = views.BasketView(request=request)
  89. self.assertIsNone(view.get_default_shipping_address())
  90. class TestVoucherViews(CheckoutMixin, WebTestCase):
  91. csrf_checks = False
  92. def setUp(self):
  93. self.voucher = factories.create_voucher()
  94. super().setUp()
  95. def test_add_voucher(self):
  96. """
  97. Checks that voucher can be added to basket through appropriate view.
  98. """
  99. self.add_product_to_basket()
  100. assert self.voucher.basket_set.count() == 0
  101. response = self.post(reverse('basket:vouchers-add'), params={'code': self.voucher.code})
  102. self.assertRedirectsTo(response, 'basket:summary')
  103. assert self.voucher.basket_set.count() == 1
  104. def test_remove_voucher(self):
  105. """
  106. Checks that voucher can be removed from basket through appropriate view.
  107. """
  108. self.add_product_to_basket()
  109. self.add_voucher_to_basket(voucher=self.voucher)
  110. assert self.voucher.basket_set.count() == 1
  111. response = self.post(reverse('basket:vouchers-remove', kwargs={'pk': self.voucher.id}))
  112. self.assertRedirectsTo(response, 'basket:summary')
  113. assert self.voucher.basket_set.count() == 0
  114. class TestOptionAddToBasketView(TestCase):
  115. def setUp(self):
  116. super().setUp()
  117. def setup_options(self, required):
  118. self.product = factories.create_product(num_in_stock=1)
  119. group = AttributeOptionGroupFactory(name="minte")
  120. AttributeOptionFactory(option="henk", group=group)
  121. AttributeOptionFactory(option="klaas", group=group)
  122. self.select = OptionFactory(required=required, code=Option.SELECT, type=Option.SELECT, option_group=group)
  123. self.radio = OptionFactory(required=required, code=Option.RADIO, type=Option.RADIO, option_group=group)
  124. self.multi_select = OptionFactory(
  125. required=required, code=Option.MULTI_SELECT, type=Option.MULTI_SELECT, option_group=group)
  126. self.checkbox = OptionFactory(
  127. required=required, code=Option.CHECKBOX, type=Option.CHECKBOX, option_group=group)
  128. self.product.product_class.options.add(self.select)
  129. self.product.product_class.options.add(self.radio)
  130. self.product.product_class.options.add(self.multi_select)
  131. self.product.product_class.options.add(self.checkbox)
  132. def test_option_visible_required(self):
  133. self.setup_options(True)
  134. url = reverse('catalogue:detail', args=(self.product.slug, self.product.pk))
  135. response = self.client.get(url)
  136. self.assertEqual(response.status_code, 200)
  137. self.assertContains(response, Option.SELECT)
  138. self.assertContains(response, Option.RADIO)
  139. self.assertContains(response, Option.MULTI_SELECT)
  140. self.assertContains(response, Option.CHECKBOX)
  141. def test_option_visible_not_required(self):
  142. self.setup_options(False)
  143. url = reverse('catalogue:detail', args=(self.product.slug, self.product.pk))
  144. response = self.client.get(url)
  145. self.assertEqual(response.status_code, 200)
  146. self.assertContains(response, Option.SELECT)
  147. self.assertContains(response, Option.RADIO)
  148. self.assertContains(response, Option.MULTI_SELECT)
  149. self.assertContains(response, Option.CHECKBOX)
  150. def test_add_to_basket_with_options_required(self):
  151. self.setup_options(True)
  152. url = reverse('basket:add', kwargs={'pk': self.product.pk})
  153. post_params = {
  154. 'product_id': self.product.id,
  155. Option.SELECT: 'klaas',
  156. Option.RADIO: 'henk',
  157. Option.MULTI_SELECT: ['henk', 'klaas'],
  158. Option.CHECKBOX: ['henk'],
  159. 'action': 'add',
  160. 'quantity': 1
  161. }
  162. response = self.client.post(url, post_params, follow=True)
  163. basket = response.context["basket"]
  164. self.assertEqual(basket.all_lines().count(), 1, "One line should have been added to the basket")
  165. line, = basket.all_lines()
  166. self.assertEqual(line.attributes.count(), 4, "One lineattribute shoould have been added to the basket")
  167. checkbox, multi_select, radio, select = line.attributes.order_by("option__code")
  168. self.assertEqual(checkbox.value, ["henk"], "The lineattribute should be saved as json")
  169. self.assertEqual(
  170. checkbox.option, self.checkbox,
  171. "The lineattribute's option should be the option created by the factory"
  172. )
  173. self.assertListEqual(multi_select.value, ["henk", "klaas"], "The lineattribute should be saved as json")
  174. self.assertEqual(
  175. multi_select.option, self.multi_select,
  176. "The lineattribute's option should be the option created by the factory"
  177. )
  178. self.assertEqual(radio.value, "henk", "The lineattribute should be saved as json")
  179. self.assertEqual(
  180. radio.option, self.radio,
  181. "The lineattribute's option should be the option created by the factory"
  182. )
  183. self.assertEqual(select.value, "klaas", "The lineattribute should be saved as json")
  184. self.assertEqual(
  185. select.option, self.select,
  186. "The lineattribute's option should be the option created by the factory"
  187. )
  188. def test_add_to_basket_with_options_not_required(self):
  189. self.setup_options(False)
  190. url = reverse('basket:add', kwargs={'pk': self.product.pk})
  191. post_params = {
  192. 'product_id': self.product.id,
  193. Option.SELECT: 'klaas',
  194. Option.RADIO: 'henk',
  195. Option.MULTI_SELECT: [],
  196. Option.CHECKBOX: ['henk'],
  197. 'action': 'add',
  198. 'quantity': 1
  199. }
  200. response = self.client.post(url, post_params, follow=True)
  201. basket = response.context["basket"]
  202. self.assertEqual(basket.all_lines().count(), 1, "One line should have been added to the basket")
  203. line, = basket.all_lines()
  204. self.assertEqual(line.attributes.count(), 3, "One lineattribute shoould have been added to the basket")
  205. checkbox, radio, select = line.attributes.order_by("option__code")
  206. self.assertEqual(checkbox.value, ["henk"], "The lineattribute should be saved as json")
  207. self.assertEqual(
  208. checkbox.option, self.checkbox,
  209. "The lineattribute's option should be the option created by the factory"
  210. )
  211. self.assertEqual(radio.value, "henk", "The lineattribute should be saved as json")
  212. self.assertEqual(
  213. radio.option, self.radio,
  214. "The lineattribute's option should be the option created by the factory"
  215. )
  216. self.assertEqual(select.value, "klaas", "The lineattribute should be saved as json")
  217. self.assertEqual(
  218. select.option, self.select,
  219. "The lineattribute's option should be the option created by the factory"
  220. )