Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

shipping_tests.py 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. from decimal import Decimal as D
  2. from django.test import TestCase
  3. from oscar.apps.shipping.methods import Free, FixedPrice
  4. from oscar.apps.shipping.models import OrderAndItemCharges, WeightBased
  5. from oscar.apps.shipping import Scales
  6. from oscar.apps.basket.models import Basket
  7. from oscar.core.compat import get_user_model
  8. from oscar.test.factories import create_product
  9. User = get_user_model()
  10. class FreeTest(TestCase):
  11. def setUp(self):
  12. self.method = Free()
  13. def test_shipping_is_free_for_empty_basket(self):
  14. basket = Basket()
  15. self.method.set_basket(basket)
  16. self.assertEquals(D('0.00'), self.method.basket_charge_incl_tax())
  17. self.assertEquals(D('0.00'), self.method.basket_charge_excl_tax())
  18. def test_shipping_is_free_for_nonempty_basket(self):
  19. basket = Basket()
  20. basket.add_product(create_product())
  21. self.method.set_basket(basket)
  22. self.assertEquals(D('0.00'), self.method.basket_charge_incl_tax())
  23. self.assertEquals(D('0.00'), self.method.basket_charge_excl_tax())
  24. class FixedPriceTest(TestCase):
  25. def test_fixed_price_shipping_charges_for_empty_basket(self):
  26. method = FixedPrice(D('10.00'), D('10.00'))
  27. basket = Basket()
  28. method.set_basket(basket)
  29. self.assertEquals(D('10.00'), method.basket_charge_incl_tax())
  30. self.assertEquals(D('10.00'), method.basket_charge_excl_tax())
  31. def test_fixed_price_shipping_assumes_no_tax(self):
  32. method = FixedPrice(D('10.00'))
  33. basket = Basket()
  34. method.set_basket(basket)
  35. self.assertEquals(D('10.00'), method.basket_charge_excl_tax())
  36. def test_different_values(self):
  37. shipping_values = ['1.00', '5.00', '10.00', '12.00']
  38. for value in shipping_values:
  39. basket = Basket()
  40. method = FixedPrice(D(value))
  41. method.set_basket(basket)
  42. self.assertEquals(D(value), method.basket_charge_excl_tax())
  43. class OrderAndItemChargesTests(TestCase):
  44. def setUp(self):
  45. self.method = OrderAndItemCharges(price_per_order=D('5.00'), price_per_item=D('1.00'))
  46. self.basket = Basket.objects.create()
  47. self.method.set_basket(self.basket)
  48. def test_order_level_charge_for_empty_basket(self):
  49. self.assertEquals(D('5.00'), self.method.basket_charge_incl_tax())
  50. def test_single_item_basket(self):
  51. p = create_product()
  52. self.basket.add_product(p)
  53. self.assertEquals(D('5.00') + D('1.00'), self.method.basket_charge_incl_tax())
  54. def test_multi_item_basket(self):
  55. p = create_product()
  56. self.basket.add_product(p, 7)
  57. self.assertEquals(D('5.00') + 7*D('1.00'), self.method.basket_charge_incl_tax())
  58. class ZeroFreeThresholdTest(TestCase):
  59. def setUp(self):
  60. self.method = OrderAndItemCharges(price_per_order=D('10.00'), free_shipping_threshold=D('0.00'))
  61. self.basket = Basket.objects.create()
  62. self.method.set_basket(self.basket)
  63. def test_free_shipping_with_empty_basket(self):
  64. self.assertEquals(D('0.00'), self.method.basket_charge_incl_tax())
  65. def test_free_shipping_with_nonempty_basket(self):
  66. p = create_product(D('5.00'))
  67. self.basket.add_product(p)
  68. self.assertEquals(D('0.00'), self.method.basket_charge_incl_tax())
  69. class NonZeroFreeThresholdTest(TestCase):
  70. def setUp(self):
  71. self.method = OrderAndItemCharges(price_per_order=D('10.00'), free_shipping_threshold=D('20.00'))
  72. self.basket = Basket.objects.create()
  73. self.method.set_basket(self.basket)
  74. def test_basket_below_threshold(self):
  75. p = create_product(D('5.00'))
  76. self.basket.add_product(p)
  77. self.assertEquals(D('10.00'), self.method.basket_charge_incl_tax())
  78. def test_basket_on_threshold(self):
  79. p = create_product(D('5.00'))
  80. self.basket.add_product(p, 4)
  81. self.assertEquals(D('0.00'), self.method.basket_charge_incl_tax())
  82. def test_basket_above_threshold(self):
  83. p = create_product(D('5.00'))
  84. self.basket.add_product(p, 8)
  85. self.assertEquals(D('0.00'), self.method.basket_charge_incl_tax())
  86. class ScalesTests(TestCase):
  87. def test_simple_weight_calculation(self):
  88. scales = Scales(attribute_code='weight')
  89. p = create_product(attributes={'weight': '1'})
  90. self.assertEqual(1, scales.weigh_product(p))
  91. def test_default_weight_is_used_when_attribute_is_missing(self):
  92. scales = Scales(attribute_code='weight', default_weight=0.5)
  93. p = create_product()
  94. self.assertEqual(0.5, scales.weigh_product(p))
  95. def test_exception_is_raised_when_attribute_is_missing(self):
  96. scales = Scales(attribute_code='weight')
  97. p = create_product()
  98. with self.assertRaises(ValueError):
  99. scales.weigh_product(p)
  100. def test_weight_calculation_of_empty_basket(self):
  101. basket = Basket()
  102. scales = Scales(attribute_code='weight')
  103. self.assertEquals(0, scales.weigh_basket(basket))
  104. def test_weight_calculation_of_basket(self):
  105. basket = Basket()
  106. basket.add_product(create_product(attributes={'weight': '1'}))
  107. basket.add_product(create_product(attributes={'weight': '2'}))
  108. scales = Scales(attribute_code='weight')
  109. self.assertEquals(1+2, scales.weigh_basket(basket))
  110. def test_weight_calculation_of_basket_with_line_quantity(self):
  111. basket = Basket()
  112. basket.add_product(create_product(
  113. attributes={'weight': '1'}), quantity=3)
  114. basket.add_product(create_product(
  115. attributes={'weight': '2'}), quantity=4)
  116. scales = Scales(attribute_code='weight')
  117. self.assertEquals(1*3+2*4, scales.weigh_basket(basket))
  118. class WeightBasedMethodTests(TestCase):
  119. def setUp(self):
  120. self.standard = WeightBased.objects.create(name='Standard')
  121. self.express = WeightBased.objects.create(name='Express')
  122. def tearDown(self):
  123. self.standard.delete()
  124. self.express.delete()
  125. def test_get_band_for_lower_weight(self):
  126. band = self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  127. fetched_band = self.standard.get_band_for_weight(0.5)
  128. self.assertEqual(band.id, fetched_band.id)
  129. def test_get_band_for_higher_weight(self):
  130. self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  131. fetched_band = self.standard.get_band_for_weight(1.5)
  132. self.assertIsNone(fetched_band)
  133. def test_get_band_for_matching_weight(self):
  134. band = self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  135. fetched_band = self.standard.get_band_for_weight(1)
  136. self.assertEqual(band.id, fetched_band.id)
  137. def test_weight_to_is_upper_bound(self):
  138. band = self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  139. self.assertEqual(1, band.weight_to)
  140. def test_weight_from_for_single_band(self):
  141. band = self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  142. self.assertEqual(0, band.weight_from)
  143. def test_weight_from_for_multiple_bands(self):
  144. self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  145. band = self.standard.objects.create(upper_limit=2, charge=D('8.00'))
  146. self.assertEqual(1, band.weight_from)
  147. def test_weight_from_for_multiple_bands(self):
  148. self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  149. band = self.express.bands.create(upper_limit=2, charge=D('8.00'))
  150. self.assertEqual(0, band.weight_from)
  151. def test_get_band_for_series_of_bands(self):
  152. self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  153. self.standard.bands.create(upper_limit=2, charge=D('8.00'))
  154. self.standard.bands.create(upper_limit=3, charge=D('12.00'))
  155. self.assertEqual(D('4.00'), self.standard.get_band_for_weight(0.5).charge)
  156. self.assertEqual(D('8.00'), self.standard.get_band_for_weight(1.5).charge)
  157. self.assertEqual(D('12.00'), self.standard.get_band_for_weight(2.5).charge)
  158. def test_get_band_for_series_of_bands_from_different_methods(self):
  159. self.express.bands.create(upper_limit=2, charge=D('8.00'))
  160. self.standard.bands.create(upper_limit=1, charge=D('4.00'))
  161. self.standard.bands.create(upper_limit=3, charge=D('12.00'))
  162. self.assertEqual(D('12.00'), self.standard.get_band_for_weight(2.5).charge)
  163. def test_for_smoke_with_basket_charge(self):
  164. basket = Basket()
  165. self.standard.set_basket(basket)
  166. charge = self.standard.basket_charge_incl_tax()
  167. self.assertEqual(D('0.00'), charge)
  168. class OfferDiscountTest(TestCase):
  169. """
  170. Should test a discounted shipping method against a non-discounted one.
  171. So far only checks if the is_discounted field is present on all
  172. methods
  173. """
  174. def setUp(self):
  175. self.non_discount_methods = [
  176. Free(),
  177. FixedPrice(D('10.00'), D('10.00')),
  178. OrderAndItemCharges(price_per_order=D('5.00'), price_per_item=D('1.00'))]
  179. self.discount_methods = []
  180. def test_is_discounted_present_and_reasonable(self):
  181. for method in self.non_discount_methods + self.discount_methods:
  182. self.assertTrue(hasattr(method, 'is_discounted'))
  183. for method in self.non_discount_methods:
  184. self.assertFalse(method.is_discounted)
  185. for method in self.discount_methods:
  186. self.assertTrue(method.is_discounted)