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.

guest_checkout_tests.py 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import sys
  2. from django.test.utils import override_settings
  3. from django.core.urlresolvers import reverse
  4. from django.conf import settings
  5. from django.utils.importlib import import_module
  6. import mock
  7. from oscar.test.testcases import WebTestCase
  8. from oscar.test import factories
  9. from . import CheckoutMixin
  10. # Python 3 compat
  11. try:
  12. from imp import reload
  13. except ImportError:
  14. pass
  15. def reload_url_conf():
  16. # Reload URLs to pick up the overridden settings
  17. if settings.ROOT_URLCONF in sys.modules:
  18. reload(sys.modules[settings.ROOT_URLCONF])
  19. import_module(settings.ROOT_URLCONF)
  20. @override_settings(OSCAR_ALLOW_ANON_CHECKOUT=True)
  21. class TestIndexView(CheckoutMixin, WebTestCase):
  22. is_anonymous = True
  23. def setUp(self):
  24. reload_url_conf()
  25. super(TestIndexView, self).setUp()
  26. def test_redirects_customers_with_empty_basket(self):
  27. response = self.get(reverse('checkout:index'))
  28. self.assertRedirectUrlName(response, 'basket:summary')
  29. def test_redirects_customers_with_invalid_basket(self):
  30. # Add product to basket but then remove its stock so it is not
  31. # purchasable.
  32. product = factories.create_product(num_in_stock=1)
  33. self.add_product_to_basket(product)
  34. product.stockrecords.all().update(num_in_stock=0)
  35. response = self.get(reverse('checkout:index'))
  36. self.assertRedirectUrlName(response, 'basket:summary')
  37. @override_settings(OSCAR_ALLOW_ANON_CHECKOUT=True)
  38. class TestShippingAddressView(CheckoutMixin, WebTestCase):
  39. is_anonymous = True
  40. def setUp(self):
  41. reload_url_conf()
  42. super(TestShippingAddressView, self).setUp()
  43. def test_redirects_customers_with_empty_basket(self):
  44. response = self.get(reverse('checkout:shipping-address'))
  45. self.assertRedirectUrlName(response, 'basket:summary')
  46. def test_redirects_customers_who_have_skipped_guest_form(self):
  47. self.add_product_to_basket()
  48. response = self.get(reverse('checkout:shipping-address'))
  49. self.assertRedirectUrlName(response, 'checkout:index')
  50. def test_redirects_customers_whose_basket_doesnt_require_shipping(self):
  51. product = self.create_digital_product()
  52. self.add_product_to_basket(product)
  53. self.enter_guest_details()
  54. response = self.get(reverse('checkout:shipping-address'))
  55. self.assertRedirectUrlName(response, 'checkout:shipping-method')
  56. def test_redirects_customers_with_invalid_basket(self):
  57. # Add product to basket but then remove its stock so it is not
  58. # purchasable.
  59. product = factories.create_product(num_in_stock=1)
  60. self.add_product_to_basket(product)
  61. self.enter_guest_details()
  62. product.stockrecords.all().update(num_in_stock=0)
  63. response = self.get(reverse('checkout:shipping-address'))
  64. self.assertRedirectUrlName(response, 'basket:summary')
  65. @override_settings(OSCAR_ALLOW_ANON_CHECKOUT=True)
  66. class TestShippingMethodView(CheckoutMixin, WebTestCase):
  67. is_anonymous = True
  68. def setUp(self):
  69. reload_url_conf()
  70. super(TestShippingMethodView, self).setUp()
  71. def test_redirects_customers_with_empty_basket(self):
  72. response = self.get(reverse('checkout:shipping-method'))
  73. self.assertRedirectUrlName(response, 'basket:summary')
  74. def test_redirects_customers_with_invalid_basket(self):
  75. product = factories.create_product(num_in_stock=1)
  76. self.add_product_to_basket(product)
  77. self.enter_guest_details()
  78. self.enter_shipping_address()
  79. product.stockrecords.all().update(num_in_stock=0)
  80. response = self.get(reverse('checkout:shipping-method'))
  81. self.assertRedirectUrlName(response, 'basket:summary')
  82. def test_redirects_customers_who_have_skipped_guest_form(self):
  83. self.add_product_to_basket()
  84. response = self.get(reverse('checkout:shipping-method'))
  85. self.assertRedirectUrlName(response, 'checkout:index')
  86. def test_redirects_customers_whose_basket_doesnt_require_shipping(self):
  87. product = self.create_digital_product()
  88. self.add_product_to_basket(product)
  89. self.enter_guest_details()
  90. response = self.get(reverse('checkout:shipping-method'))
  91. self.assertRedirectUrlName(response, 'checkout:payment-method')
  92. def test_redirects_customers_who_have_skipped_shipping_address_form(self):
  93. self.add_product_to_basket()
  94. self.enter_guest_details()
  95. response = self.get(reverse('checkout:shipping-method'))
  96. self.assertRedirectUrlName(response, 'checkout:shipping-address')
  97. @mock.patch('oscar.apps.checkout.views.Repository')
  98. def test_redirects_customers_when_no_shipping_methods_available(self, mock_repo):
  99. self.add_product_to_basket()
  100. self.enter_guest_details()
  101. self.enter_shipping_address()
  102. # Ensure no shipping methods available
  103. instance = mock_repo.return_value
  104. instance.get_shipping_methods.return_value = []
  105. response = self.get(reverse('checkout:shipping-address'))
  106. self.assertIsOk(response)
  107. @mock.patch('oscar.apps.checkout.views.Repository')
  108. def test_redirects_customers_when_only_one_shipping_methods_available(self, mock_repo):
  109. self.add_product_to_basket()
  110. self.enter_guest_details()
  111. self.enter_shipping_address()
  112. # Ensure one shipping method available
  113. method = mock.MagicMock()
  114. method.code = 'm'
  115. instance = mock_repo.return_value
  116. instance.get_shipping_methods.return_value = [method]
  117. response = self.get(reverse('checkout:shipping-method'))
  118. self.assertRedirectUrlName(response, 'checkout:payment-method')
  119. @mock.patch('oscar.apps.checkout.views.Repository')
  120. def test_shows_form_when_multiple_shipping_methods_available(self, mock_repo):
  121. self.add_product_to_basket()
  122. self.enter_guest_details()
  123. self.enter_shipping_address()
  124. # Ensure multiple shipping methods available
  125. method = mock.MagicMock()
  126. method.code = 'm'
  127. instance = mock_repo.return_value
  128. instance.get_shipping_methods.return_value = [method, method]
  129. response = self.get(reverse('checkout:shipping-method'))
  130. self.assertIsOk(response)
  131. @override_settings(OSCAR_ALLOW_ANON_CHECKOUT=True)
  132. class TestPaymentMethodView(CheckoutMixin, WebTestCase):
  133. is_anonymous = True
  134. def setUp(self):
  135. reload_url_conf()
  136. super(TestPaymentMethodView, self).setUp()
  137. def test_redirects_customers_with_empty_basket(self):
  138. response = self.get(reverse('checkout:payment-method'))
  139. self.assertRedirectUrlName(response, 'basket:summary')
  140. def test_redirects_customers_with_invalid_basket(self):
  141. product = factories.create_product(num_in_stock=1)
  142. self.add_product_to_basket(product)
  143. self.enter_guest_details()
  144. self.enter_shipping_address()
  145. product.stockrecords.all().update(num_in_stock=0)
  146. response = self.get(reverse('checkout:payment-method'))
  147. self.assertRedirectUrlName(response, 'basket:summary')
  148. def test_redirects_customers_who_have_skipped_guest_form(self):
  149. self.add_product_to_basket()
  150. response = self.get(reverse('checkout:payment-method'))
  151. self.assertRedirectUrlName(response, 'checkout:index')
  152. def test_redirects_customers_who_have_skipped_shipping_address_form(self):
  153. self.add_product_to_basket()
  154. self.enter_guest_details()
  155. response = self.get(reverse('checkout:payment-method'))
  156. self.assertRedirectUrlName(response, 'checkout:shipping-address')
  157. def test_redirects_customers_who_have_skipped_shipping_method_step(self):
  158. self.add_product_to_basket()
  159. self.enter_guest_details()
  160. self.enter_shipping_address()
  161. response = self.get(reverse('checkout:payment-method'))
  162. self.assertRedirectUrlName(response, 'checkout:shipping-method')
  163. @override_settings(OSCAR_ALLOW_ANON_CHECKOUT=True)
  164. class TestPaymentDetailsView(CheckoutMixin, WebTestCase):
  165. is_anonymous = True
  166. def setUp(self):
  167. reload_url_conf()
  168. super(TestPaymentDetailsView, self).setUp()
  169. def test_redirects_customers_with_empty_basket(self):
  170. response = self.get(reverse('checkout:payment-details'))
  171. self.assertRedirectUrlName(response, 'basket:summary')
  172. def test_redirects_customers_with_invalid_basket(self):
  173. product = factories.create_product(num_in_stock=1)
  174. self.add_product_to_basket(product)
  175. self.enter_guest_details()
  176. self.enter_shipping_address()
  177. product.stockrecords.all().update(num_in_stock=0)
  178. response = self.get(reverse('checkout:payment-details'))
  179. self.assertRedirectUrlName(response, 'basket:summary')
  180. def test_redirects_customers_who_have_skipped_guest_form(self):
  181. self.add_product_to_basket()
  182. response = self.get(reverse('checkout:payment-details'))
  183. self.assertRedirectUrlName(response, 'checkout:index')
  184. def test_redirects_customers_who_have_skipped_shipping_address_form(self):
  185. self.add_product_to_basket()
  186. self.enter_guest_details()
  187. response = self.get(reverse('checkout:payment-details'))
  188. self.assertRedirectUrlName(response, 'checkout:shipping-address')
  189. def test_redirects_customers_who_have_skipped_shipping_method_step(self):
  190. self.add_product_to_basket()
  191. self.enter_guest_details()
  192. self.enter_shipping_address()
  193. response = self.get(reverse('checkout:payment-details'))
  194. self.assertRedirectUrlName(response, 'checkout:shipping-method')
  195. @override_settings(OSCAR_ALLOW_ANON_CHECKOUT=True)
  196. class TestPlacingOrder(CheckoutMixin, WebTestCase):
  197. is_anonymous = True
  198. def setUp(self):
  199. reload_url_conf()
  200. super(TestPlacingOrder, self).setUp()
  201. def test_saves_guest_email_with_order(self):
  202. self.add_product_to_basket()
  203. self.enter_guest_details('hello@egg.com')
  204. self.enter_shipping_address()
  205. page = self.get(reverse('checkout:shipping-method')).follow().follow()
  206. preview = page.click(linkid="view_preview")
  207. thank_you = preview.forms['place-order-form'].submit().follow()
  208. order = thank_you.context['order']
  209. self.assertEqual('hello@egg.com', order.guest_email)