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

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