symposion_app/registrasion/tests/test_cart.py

210 lines
6.8 KiB
Python

import datetime
import pytz
from decimal import Decimal
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ValidationError
from django.test import TestCase
from registrasion import models as rego
from registrasion.controllers.cart import CartController
from patch_datetime import SetTimeMixin
UTC = pytz.timezone('UTC')
class RegistrationCartTestCase(SetTimeMixin, TestCase):
def setUp(self):
super(RegistrationCartTestCase, self).setUp()
@classmethod
def setUpTestData(cls):
cls.USER_1 = User.objects.create_user(
username='testuser',
email='test@example.com',
password='top_secret')
cls.USER_2 = User.objects.create_user(
username='testuser2',
email='test2@example.com',
password='top_secret')
cls.RESERVATION = datetime.timedelta(hours=1)
cls.categories = []
for i in xrange(3):
cat = rego.Category.objects.create(
name="Category " + str(i + 1),
description="This is a test category",
order=i,
render_type=rego.Category.RENDER_TYPE_RADIO,
required=False,
)
cat.save()
cls.categories.append(cat)
cls.CAT_1 = cls.categories[0]
cls.CAT_2 = cls.categories[1]
cls.CAT_3 = cls.categories[2]
cls.products = []
for i in xrange(6):
prod = rego.Product.objects.create(
name="Product 1",
description="This is a test product."
category=cls.categories[i / 2], # 2 products per category
price=Decimal("10.00"),
reservation_duration=cls.RESERVATION,
limit_per_user=10,
order=1,
)
prod.save()
cls.products.append(prod)
cls.PROD_1 = cls.products[0]
cls.PROD_2 = cls.products[1]
cls.PROD_3 = cls.products[2]
cls.PROD_4 = cls.products[3]
cls.PROD_5 = cls.products[4]
cls.PROD_6 = cls.products[5]
cls.PROD_4.price = Decimal("5.00")
cls.PROD_4.save()
@classmethod
def make_ceiling(cls, name, limit=None, start_time=None, end_time=None):
limit_ceiling = rego.TimeOrStockLimitEnablingCondition.objects.create(
description=name,
mandatory=True,
limit=limit,
start_time=start_time,
end_time=end_time
)
limit_ceiling.save()
limit_ceiling.products.add(cls.PROD_1, cls.PROD_2)
limit_ceiling.save()
@classmethod
def make_category_ceiling(
cls, name, limit=None, start_time=None, end_time=None):
limit_ceiling = rego.TimeOrStockLimitEnablingCondition.objects.create(
description=name,
mandatory=True,
limit=limit,
start_time=start_time,
end_time=end_time
)
limit_ceiling.save()
limit_ceiling.categories.add(cls.CAT_1)
limit_ceiling.save()
@classmethod
def make_discount_ceiling(
cls, name, limit=None, start_time=None, end_time=None):
limit_ceiling = rego.TimeOrStockLimitDiscount.objects.create(
description=name,
start_time=start_time,
end_time=end_time,
limit=limit,
)
limit_ceiling.save()
rego.DiscountForProduct.objects.create(
discount=limit_ceiling,
product=cls.PROD_1,
percentage=100,
quantity=10,
).save()
class BasicCartTests(RegistrationCartTestCase):
def test_get_cart(self):
current_cart = CartController.for_user(self.USER_1)
current_cart.cart.active = False
current_cart.cart.save()
old_cart = current_cart
current_cart = CartController.for_user(self.USER_1)
self.assertNotEqual(old_cart.cart, current_cart.cart)
current_cart2 = CartController.for_user(self.USER_1)
self.assertEqual(current_cart.cart, current_cart2.cart)
def test_add_to_cart_collapses_product_items(self):
current_cart = CartController.for_user(self.USER_1)
# Add a product twice
current_cart.add_to_cart(self.PROD_1, 1)
current_cart.add_to_cart(self.PROD_1, 1)
# Count of products for a given user should be collapsed.
items = rego.ProductItem.objects.filter(
cart=current_cart.cart,
product=self.PROD_1)
self.assertEqual(1, len(items))
item = items[0]
self.assertEquals(2, item.quantity)
def test_set_quantity(self):
current_cart = CartController.for_user(self.USER_1)
def get_item():
return rego.ProductItem.objects.get(
cart=current_cart.cart,
product=self.PROD_1)
current_cart.set_quantity(self.PROD_1, 1)
self.assertEqual(1, get_item().quantity)
# Setting the quantity to zero should remove the entry from the cart.
current_cart.set_quantity(self.PROD_1, 0)
with self.assertRaises(ObjectDoesNotExist):
get_item()
current_cart.set_quantity(self.PROD_1, 9)
self.assertEqual(9, get_item().quantity)
with self.assertRaises(ValidationError):
current_cart.set_quantity(self.PROD_1, 11)
self.assertEqual(9, get_item().quantity)
with self.assertRaises(ValidationError):
current_cart.set_quantity(self.PROD_1, -1)
self.assertEqual(9, get_item().quantity)
current_cart.set_quantity(self.PROD_1, 2)
self.assertEqual(2, get_item().quantity)
def test_add_to_cart_product_per_user_limit(self):
current_cart = CartController.for_user(self.USER_1)
# User should be able to add 1 of PROD_1 to the current cart.
current_cart.add_to_cart(self.PROD_1, 1)
# User should be able to add 1 of PROD_1 to the current cart.
current_cart.add_to_cart(self.PROD_1, 1)
# User should not be able to add 10 of PROD_1 to the current cart now,
# because they have a limit of 10.
with self.assertRaises(ValidationError):
current_cart.add_to_cart(self.PROD_1, 10)
current_cart.cart.active = False
current_cart.cart.save()
current_cart = CartController.for_user(self.USER_1)
# User should not be able to add 10 of PROD_1 to the current cart now,
# even though it's a new cart.
with self.assertRaises(ValidationError):
current_cart.add_to_cart(self.PROD_1, 10)
# Second user should not be affected by first user's limits
second_user_cart = CartController.for_user(self.USER_2)
second_user_cart.add_to_cart(self.PROD_1, 10)