Files @ dec0a759ca90
Branch filter:

Location: symposion_app/registrasion/tests/test_voucher.py - annotation

Christopher Neugebauer
Merge branch 'chrisjrn/20161006'
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
cc4249083219
63dfd353c16e
d9e433659d01
875f736d67c5
875f736d67c5
ac10ea4ee895
563355485435
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
eab1deff7776
cc4249083219
d9e433659d01
d9e433659d01
d9e433659d01
eab1deff7776
d9e433659d01
cc4249083219
d9e433659d01
224878a10ce3
224878a10ce3
875f736d67c5
cc4249083219
2f77f5bb23ee
2f77f5bb23ee
d9e433659d01
0d57da8d6f66
0d57da8d6f66
875f736d67c5
d9e433659d01
0d57da8d6f66
d9e433659d01
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
d9e433659d01
d9e433659d01
d9e433659d01
875f736d67c5
d9e433659d01
d9e433659d01
875f736d67c5
d9e433659d01
7b476fd5cb04
d9e433659d01
d9e433659d01
eab1deff7776
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
cc4249083219
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
875f736d67c5
d9e433659d01
d9e433659d01
d9e433659d01
875f736d67c5
d9e433659d01
d9e433659d01
d9e433659d01
d9e433659d01
63dfd353c16e
d9e433659d01
d9e433659d01
eab1deff7776
cc4249083219
d9e433659d01
d9e433659d01
cc4249083219
63dfd353c16e
cc4249083219
8d66ed57150d
cc4249083219
8d66ed57150d
cc4249083219
cc4249083219
8d66ed57150d
8d66ed57150d
cc4249083219
cc4249083219
cc4249083219
eab1deff7776
cc4249083219
2d5cd622c517
2d5cd622c517
2d5cd622c517
eab1deff7776
2d5cd622c517
0d57da8d6f66
0d57da8d6f66
0d57da8d6f66
0d57da8d6f66
2d5cd622c517
2d5cd622c517
2d5cd622c517
eab1deff7776
2d5cd622c517
2d5cd622c517
2f77f5bb23ee
2d5cd622c517
8d07518a9bc6
8d07518a9bc6
2d5cd622c517
2d5cd622c517
cf85af771983
cf85af771983
cf85af771983
cf85af771983
cf85af771983
eab1deff7776
cf85af771983
8ad265a65a08
cf85af771983
563355485435
38cdb8aa6330
8ad265a65a08
cf85af771983
eab1deff7776
cf85af771983
cf85af771983
cf85af771983
6b10a0a7e427
cf85af771983
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
c8c16072ba87
import datetime
import pytz

from decimal import Decimal
from django.core.exceptions import ValidationError
from django.db import IntegrityError
from django.db import transaction

from registrasion.models import conditions
from registrasion.models import inventory
from controller_helpers import TestingCartController
from controller_helpers import TestingInvoiceController

from test_cart import RegistrationCartTestCase

UTC = pytz.timezone('UTC')


class VoucherTestCases(RegistrationCartTestCase):

    def test_apply_voucher(self):
        voucher = self.new_voucher()

        self.set_time(datetime.datetime(2015, 01, 01, tzinfo=UTC))

        cart_1 = TestingCartController.for_user(self.USER_1)
        cart_1.apply_voucher(voucher.code)
        self.assertIn(voucher, cart_1.cart.vouchers.all())

        # Second user should not be able to apply this voucher (it's exhausted)
        cart_2 = TestingCartController.for_user(self.USER_2)
        with self.assertRaises(ValidationError):
            cart_2.apply_voucher(voucher.code)

        # After the reservation duration
        # user 2 should be able to apply voucher
        self.add_timedelta(inventory.Voucher.RESERVATION_DURATION * 2)
        cart_2.apply_voucher(voucher.code)

        cart_2.next_cart()

        # After the reservation duration, even though the voucher has applied,
        # it exceeds the number of vouchers available.
        self.add_timedelta(inventory.Voucher.RESERVATION_DURATION * 2)
        with self.assertRaises(ValidationError):
            cart_1.validate_cart()

    def test_fix_simple_errors_resolves_unavailable_voucher(self):
        self.test_apply_voucher()

        # User has an exhausted voucher leftover from test_apply_voucher
        cart_1 = TestingCartController.for_user(self.USER_1)
        with self.assertRaises(ValidationError):
            cart_1.validate_cart()

        cart_1.fix_simple_errors()
        # This should work now.
        cart_1.validate_cart()

    def test_voucher_enables_item(self):
        voucher = self.new_voucher()

        flag = conditions.VoucherFlag.objects.create(
            description="Voucher condition",
            voucher=voucher,
            condition=conditions.FlagBase.ENABLE_IF_TRUE,
        )
        flag.products.add(self.PROD_1)

        # Adding the product without a voucher will not work
        current_cart = TestingCartController.for_user(self.USER_1)
        with self.assertRaises(ValidationError):
            current_cart.add_to_cart(self.PROD_1, 1)

        # Apply the voucher
        current_cart.apply_voucher(voucher.code)
        current_cart.add_to_cart(self.PROD_1, 1)

    def test_voucher_enables_discount(self):
        voucher = self.new_voucher()

        discount = conditions.VoucherDiscount.objects.create(
            description="VOUCHER RECIPIENT",
            voucher=voucher,
        )
        conditions.DiscountForProduct.objects.create(
            discount=discount,
            product=self.PROD_1,
            percentage=Decimal(100),
            quantity=1
        )

        # Having PROD_1 in place should add a discount
        current_cart = TestingCartController.for_user(self.USER_1)
        current_cart.apply_voucher(voucher.code)
        current_cart.add_to_cart(self.PROD_1, 1)
        self.assertEqual(1, len(current_cart.cart.discountitem_set.all()))

    @transaction.atomic
    def test_voucher_codes_unique(self):
        self.new_voucher(code="VOUCHER")
        with self.assertRaises(IntegrityError):
            self.new_voucher(code="VOUCHER")

    def test_multiple_vouchers_work(self):
        self.new_voucher(code="VOUCHER1")
        self.new_voucher(code="VOUCHER2")

    def test_vouchers_case_insensitive(self):
        voucher = self.new_voucher(code="VOUCHeR")
        current_cart = TestingCartController.for_user(self.USER_1)
        current_cart.apply_voucher(voucher.code.lower())

    def test_voucher_can_only_be_applied_once(self):
        voucher = self.new_voucher(limit=2)
        current_cart = TestingCartController.for_user(self.USER_1)
        current_cart.apply_voucher(voucher.code)
        current_cart.apply_voucher(voucher.code)

        # You can apply the code twice, but it will only add to the cart once.
        self.assertEqual(1, current_cart.cart.vouchers.count())

    def test_voucher_can_only_be_applied_once_across_multiple_carts(self):
        voucher = self.new_voucher(limit=2)
        current_cart = TestingCartController.for_user(self.USER_1)
        current_cart.apply_voucher(voucher.code)

        current_cart.next_cart()

        current_cart = TestingCartController.for_user(self.USER_1)

        with self.assertRaises(ValidationError):
            current_cart.apply_voucher(voucher.code)

        return current_cart

    def test_refund_releases_used_vouchers(self):
        voucher = self.new_voucher(limit=2)
        current_cart = TestingCartController.for_user(self.USER_1)
        current_cart.apply_voucher(voucher.code)
        current_cart.add_to_cart(self.PROD_1, 1)

        inv = TestingInvoiceController.for_cart(current_cart.cart)
        if not inv.invoice.is_paid:
            inv.pay("Hello!", inv.invoice.value)

        current_cart = TestingCartController.for_user(self.USER_1)
        with self.assertRaises(ValidationError):
            current_cart.apply_voucher(voucher.code)

        inv.refund()
        current_cart.apply_voucher(voucher.code)

    def test_fix_simple_errors_does_not_remove_limited_voucher(self):
        voucher = self.new_voucher(code="VOUCHER")
        current_cart = TestingCartController.for_user(self.USER_1)
        current_cart.apply_voucher(voucher.code)

        current_cart.fix_simple_errors()
        self.assertEqual(1, current_cart.cart.vouchers.count())