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.

test_availability.py 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import datetime
  2. from decimal import Decimal as D
  3. from django.test import TestCase
  4. from oscar.apps.offer import models
  5. from oscar.core.compat import get_user_model
  6. from oscar.test.factories import (
  7. OrderDiscountFactory, UserFactory, create_order)
  8. User = get_user_model()
  9. class TestAPerUserConditionalOffer(TestCase):
  10. def setUp(self):
  11. self.offer = models.ConditionalOffer(max_user_applications=1)
  12. self.user = UserFactory()
  13. def test_is_available_with_no_applications(self):
  14. self.assertTrue(self.offer.is_available())
  15. def test_max_applications_is_correct_when_no_applications(self):
  16. self.assertEqual(1, self.offer.get_max_applications(self.user))
  17. def test_max_applications_is_correct_when_equal_applications(self):
  18. order = create_order(user=self.user)
  19. OrderDiscountFactory(
  20. order=order, offer_id=self.offer.id, frequency=1)
  21. self.assertEqual(0, self.offer.get_max_applications(self.user))
  22. def test_max_applications_is_correct_when_more_applications(self):
  23. order = create_order(user=self.user)
  24. OrderDiscountFactory(
  25. order=order, offer_id=self.offer.id, frequency=5)
  26. self.assertEqual(0, self.offer.get_max_applications(self.user))
  27. class TestADateBasedConditionalOffer(TestCase):
  28. def setUp(self):
  29. self.start = datetime.date(2011, 1, 1)
  30. self.end = datetime.date(2011, 2, 1)
  31. self.offer = models.ConditionalOffer(start_datetime=self.start,
  32. end_datetime=self.end)
  33. def test_is_available_during_date_range(self):
  34. test = datetime.date(2011, 1, 10)
  35. self.assertTrue(self.offer.is_available(test_date=test))
  36. def test_is_inactive_before_date_range(self):
  37. test = datetime.date(2010, 3, 10)
  38. self.assertFalse(self.offer.is_available(test_date=test))
  39. def test_is_inactive_after_date_range(self):
  40. test = datetime.date(2011, 3, 10)
  41. self.assertFalse(self.offer.is_available(test_date=test))
  42. def test_is_active_on_end_datetime(self):
  43. self.assertTrue(self.offer.is_available(test_date=self.end))
  44. def test_active_on_null_end_datetime(self):
  45. # null end_datetime means offer should never expire
  46. offer = models.ConditionalOffer(start_datetime=self.start,
  47. end_datetime=None)
  48. test = datetime.date(2017, 3, 10)
  49. self.assertTrue(offer.is_available(test_date=test))
  50. def test_active_on_null_start_datetime(self):
  51. # null start_datetime means offer is active from the beginning of time
  52. offer = models.ConditionalOffer(start_datetime=None,
  53. end_datetime=self.end)
  54. test = datetime.date(2000, 3, 10)
  55. self.assertTrue(offer.is_available(test_date=test))
  56. def test_active_on_null_start_and_end_datetime(self):
  57. # null datetimes - offer is always available
  58. offer = models.ConditionalOffer(start_datetime=None, end_datetime=None)
  59. test = datetime.date(2017, 3, 10)
  60. self.assertTrue(offer.is_available(test_date=test))
  61. class TestAConsumptionFrequencyBasedConditionalOffer(TestCase):
  62. def setUp(self):
  63. self.offer = models.ConditionalOffer(max_global_applications=4)
  64. def test_is_available_with_no_applications(self):
  65. self.assertTrue(self.offer.is_available())
  66. def test_is_available_with_fewer_applications_than_max(self):
  67. self.offer.num_applications = 3
  68. self.assertTrue(self.offer.is_available())
  69. def test_is_inactive_with_equal_applications_to_max(self):
  70. self.offer.num_applications = 4
  71. self.assertFalse(self.offer.is_available())
  72. def test_is_inactive_with_more_applications_than_max(self):
  73. self.offer.num_applications = 4
  74. self.assertFalse(self.offer.is_available())
  75. def test_restricts_number_of_applications_correctly_with_no_applications(self):
  76. self.assertEqual(4, self.offer.get_max_applications())
  77. def test_restricts_number_of_applications_correctly_with_fewer_applications_than_max(self):
  78. self.offer.num_applications = 3
  79. self.assertEqual(1, self.offer.get_max_applications())
  80. def test_restricts_number_of_applications_correctly_with_more_applications_than_max(self):
  81. self.offer.num_applications = 5
  82. self.assertEqual(0, self.offer.get_max_applications())
  83. class TestCappedDiscountConditionalOffer(TestCase):
  84. def setUp(self):
  85. self.offer = models.ConditionalOffer(
  86. max_discount=D('100.00'),
  87. total_discount=D('0.00'))
  88. def test_is_available_when_below_threshold(self):
  89. self.assertTrue(self.offer.is_available())
  90. def test_is_inactive_when_on_threshold(self):
  91. self.offer.total_discount = self.offer.max_discount
  92. self.assertFalse(self.offer.is_available())
  93. def test_is_inactive_when_above_threshold(self):
  94. self.offer.total_discount = self.offer.max_discount + D('10.00')
  95. self.assertFalse(self.offer.is_available())
  96. class TestASuspendedOffer(TestCase):
  97. def setUp(self):
  98. self.offer = models.ConditionalOffer(
  99. status=models.ConditionalOffer.SUSPENDED)
  100. def test_is_unavailable(self):
  101. self.assertFalse(self.offer.is_available())
  102. def test_lists_suspension_as_an_availability_restriction(self):
  103. restrictions = self.offer.availability_restrictions()
  104. self.assertEqual(1, len(restrictions))