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

test_models.py 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. # -*- coding: utf-8 -*-
  2. from decimal import Decimal as D
  3. from django.test import TestCase
  4. from oscar.apps.basket.models import Basket
  5. from oscar.apps.catalogue.models import Option
  6. from oscar.apps.partner import availability, prices, strategy
  7. from oscar.test import factories
  8. from oscar.test.factories import (
  9. BasketFactory, BasketLineAttributeFactory, OptionFactory, ProductFactory)
  10. class TestANewBasket(TestCase):
  11. def setUp(self):
  12. self.basket = Basket()
  13. self.basket.strategy = strategy.Default()
  14. def test_has_zero_lines(self):
  15. self.assertEqual(0, self.basket.num_lines)
  16. def test_has_zero_items(self):
  17. self.assertEqual(0, self.basket.num_items)
  18. def test_doesnt_contain_vouchers(self):
  19. self.assertFalse(self.basket.contains_a_voucher)
  20. def test_can_be_edited(self):
  21. self.assertTrue(self.basket.can_be_edited)
  22. def test_is_empty(self):
  23. self.assertTrue(self.basket.is_empty)
  24. def test_is_not_submitted(self):
  25. self.assertFalse(self.basket.is_submitted)
  26. def test_has_no_applied_offers(self):
  27. self.assertEqual({}, self.basket.applied_offers())
  28. class TestBasketLine(TestCase):
  29. def test_description(self):
  30. basket = BasketFactory()
  31. product = ProductFactory(title="A product")
  32. basket.add_product(product)
  33. line = basket.lines.first()
  34. self.assertEqual(line.description, "A product")
  35. def test_description_with_attributes(self):
  36. basket = BasketFactory()
  37. product = ProductFactory(title="A product")
  38. basket.add_product(product)
  39. line = basket.lines.first()
  40. BasketLineAttributeFactory(
  41. line=line, value=u'\u2603', option__name='with')
  42. self.assertEqual(line.description, u"A product (with = '\u2603')")
  43. def test_create_line_reference(self):
  44. basket = BasketFactory()
  45. product = ProductFactory(title="A product")
  46. option = OptionFactory(name="product_option", code="product_option")
  47. option_product = ProductFactory(title=u'Asunción')
  48. options = [{'option': option, 'value': option_product}]
  49. basket.add_product(product, options=options)
  50. def test_basket_lines_queryset_is_ordered(self):
  51. # This is needed to make sure a formset is not performing the query
  52. # again with an order_by clause (losing all calculated discounts)
  53. basket = BasketFactory()
  54. product = ProductFactory(title="A product")
  55. another_product = ProductFactory(title="Another product")
  56. basket.add_product(product)
  57. basket.add_product(another_product)
  58. queryset = basket.all_lines()
  59. self.assertTrue(queryset.ordered)
  60. class TestAddingAProductToABasket(TestCase):
  61. def setUp(self):
  62. self.basket = Basket()
  63. self.basket.strategy = strategy.Default()
  64. self.product = factories.create_product()
  65. self.record = factories.create_stockrecord(
  66. currency='GBP',
  67. product=self.product, price_excl_tax=D('10.00'))
  68. self.purchase_info = factories.create_purchase_info(self.record)
  69. self.basket.add(self.product)
  70. def test_creates_a_line(self):
  71. self.assertEqual(1, self.basket.num_lines)
  72. def test_sets_line_prices(self):
  73. line = self.basket.lines.all()[0]
  74. self.assertEqual(line.price_incl_tax, self.purchase_info.price.incl_tax)
  75. self.assertEqual(line.price_excl_tax, self.purchase_info.price.excl_tax)
  76. def test_adding_negative_quantity(self):
  77. self.assertEqual(1, self.basket.num_lines)
  78. self.basket.add(self.product, quantity=4)
  79. self.assertEqual(5, self.basket.line_quantity(self.product, self.record))
  80. self.basket.add(self.product, quantity=-10)
  81. self.assertEqual(0, self.basket.line_quantity(self.product, self.record))
  82. def test_means_another_currency_product_cannot_be_added(self):
  83. product = factories.create_product()
  84. factories.create_stockrecord(
  85. currency='USD', product=product, price_excl_tax=D('20.00'))
  86. with self.assertRaises(ValueError):
  87. self.basket.add(product)
  88. class TestANonEmptyBasket(TestCase):
  89. def setUp(self):
  90. self.basket = Basket()
  91. self.basket.strategy = strategy.Default()
  92. self.product = factories.create_product()
  93. self.record = factories.create_stockrecord(
  94. self.product, price_excl_tax=D('10.00'))
  95. self.purchase_info = factories.create_purchase_info(self.record)
  96. self.basket.add(self.product, 10)
  97. def test_can_be_flushed(self):
  98. self.basket.flush()
  99. self.assertEqual(self.basket.num_items, 0)
  100. def test_returns_correct_product_quantity(self):
  101. self.assertEqual(10, self.basket.product_quantity(
  102. self.product))
  103. def test_returns_correct_line_quantity_for_existing_product_and_stockrecord(self):
  104. self.assertEqual(10, self.basket.line_quantity(
  105. self.product, self.record))
  106. def test_returns_zero_line_quantity_for_alternative_stockrecord(self):
  107. record = factories.create_stockrecord(
  108. self.product, price_excl_tax=D('5.00'))
  109. self.assertEqual(0, self.basket.line_quantity(
  110. self.product, record))
  111. def test_returns_zero_line_quantity_for_missing_product_and_stockrecord(self):
  112. product = factories.create_product()
  113. record = factories.create_stockrecord(
  114. product, price_excl_tax=D('5.00'))
  115. self.assertEqual(0, self.basket.line_quantity(
  116. product, record))
  117. def test_returns_correct_quantity_for_existing_product_and_stockrecord_and_options(self):
  118. product = factories.create_product()
  119. record = factories.create_stockrecord(
  120. product, price_excl_tax=D('5.00'))
  121. option = Option.objects.create(name="Message")
  122. options = [{"option": option, "value": "2"}]
  123. self.basket.add(product, options=options)
  124. self.assertEqual(0, self.basket.line_quantity(
  125. product, record))
  126. self.assertEqual(1, self.basket.line_quantity(
  127. product, record, options))
  128. def test_total_sums_product_totals(self):
  129. product = factories.create_product()
  130. factories.create_stockrecord(
  131. product, price_excl_tax=D('5.00'))
  132. self.basket.add(product, 1)
  133. self.assertEqual(self.basket.total_excl_tax, 105)
  134. def test_basket_prices_calculation_for_unavailable_pricing(self):
  135. new_product = factories.create_product()
  136. factories.create_stockrecord(
  137. new_product, price_excl_tax=D('5.00'))
  138. self.basket.add(new_product, 1)
  139. class UnavailableProductStrategy(strategy.Default):
  140. """ A test strategy that makes a specific product unavailable """
  141. def availability_policy(self, product, stockrecord):
  142. if product == new_product:
  143. return availability.Unavailable()
  144. return super(UnavailableProductStrategy, self).availability_policy(product, stockrecord)
  145. def pricing_policy(self, product, stockrecord):
  146. if product == new_product:
  147. return prices.Unavailable()
  148. return super(UnavailableProductStrategy, self).pricing_policy(product, stockrecord)
  149. self.basket.strategy = UnavailableProductStrategy()
  150. line = self.basket.all_lines()[1]
  151. self.assertEqual(line.get_warning(), u"'D\xf9\uff4d\u03fb\u03d2 title' is no longer available")
  152. self.assertIsNone(line.line_price_excl_tax)
  153. self.assertIsNone(line.line_price_incl_tax)
  154. self.assertIsNone(line.line_price_excl_tax_incl_discounts)
  155. self.assertIsNone(line.line_price_incl_tax_incl_discounts)
  156. self.assertIsNone(line.line_tax)
  157. self.assertEqual(self.basket.total_excl_tax, 100)
  158. self.assertEqual(self.basket.total_incl_tax, 100)
  159. self.assertEqual(self.basket.total_excl_tax_excl_discounts, 100)
  160. self.assertEqual(self.basket.total_incl_tax_excl_discounts, 100)
  161. class TestMergingTwoBaskets(TestCase):
  162. def setUp(self):
  163. self.product = factories.create_product()
  164. self.record = factories.create_stockrecord(
  165. self.product, price_excl_tax=D('10.00'))
  166. self.purchase_info = factories.create_purchase_info(self.record)
  167. self.main_basket = Basket()
  168. self.main_basket.strategy = strategy.Default()
  169. self.main_basket.add(self.product, quantity=2)
  170. self.merge_basket = Basket()
  171. self.merge_basket.strategy = strategy.Default()
  172. self.merge_basket.add(self.product, quantity=1)
  173. self.main_basket.merge(self.merge_basket)
  174. def test_doesnt_sum_quantities(self):
  175. self.assertEqual(1, self.main_basket.num_lines)
  176. def test_changes_status_of_merge_basket(self):
  177. self.assertEqual(Basket.MERGED, self.merge_basket.status)
  178. class TestASubmittedBasket(TestCase):
  179. def setUp(self):
  180. self.basket = Basket()
  181. self.basket.strategy = strategy.Default()
  182. self.basket.submit()
  183. def test_has_correct_status(self):
  184. self.assertTrue(self.basket.is_submitted)
  185. def test_can_be_edited(self):
  186. self.assertFalse(self.basket.can_be_edited)
  187. class TestMergingAVoucherBasket(TestCase):
  188. def test_transfers_vouchers_to_new_basket(self):
  189. baskets = [factories.BasketFactory(), factories.BasketFactory()]
  190. voucher = factories.VoucherFactory()
  191. baskets[0].vouchers.add(voucher)
  192. baskets[1].merge(baskets[0])
  193. self.assertEqual(1, baskets[1].vouchers.all().count())