Commit 47c725d3 by Ivan Ivic

[SOL-2173] Add Backend Validation for End Datetime and Start Datetime

parent 8cd1c75f
......@@ -186,13 +186,13 @@ class CouponMixin(object):
code=code,
course_seat_types=course_seat_types,
email_domains=email_domains,
end_datetime=datetime.date(2020, 1, 1),
end_datetime=datetime.datetime(2020, 1, 1),
max_uses=max_uses,
note=note,
partner=partner,
price=price,
quantity=quantity,
start_datetime=datetime.date(2015, 1, 1),
start_datetime=datetime.datetime(2015, 1, 1),
title=title,
voucher_type=voucher_type
)
......
......@@ -2,7 +2,6 @@ from __future__ import unicode_literals
import logging
import dateutil.parser
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import IntegrityError, transaction
......@@ -154,13 +153,13 @@ class CouponViewSet(EdxOrderPlacementMixin, viewsets.ModelViewSet):
code=code,
course_seat_types=course_seat_types,
email_domains=request.data.get('email_domains'),
end_datetime=dateutil.parser.parse(request.data.get('end_datetime')),
end_datetime=request.data.get('end_datetime'),
max_uses=max_uses,
note=request.data.get('note'),
partner=partner,
price=request.data.get('price'),
quantity=request.data.get('quantity'),
start_datetime=dateutil.parser.parse(request.data.get('start_datetime')),
start_datetime=request.data.get('start_datetime'),
title=request.data.get('title'),
voucher_type=voucher_type
)
......
......@@ -545,7 +545,8 @@ class VoucherAddMessagesViewTests(TestCase):
def test_voucher_expired_error_msg(self):
""" Verify correct error message is returned when voucher has expired. """
end_datetime = datetime.datetime.now() - datetime.timedelta(days=1)
factories.VoucherFactory(code=COUPON_CODE, end_datetime=end_datetime)
start_datetime = datetime.datetime.now() - datetime.timedelta(days=2)
factories.VoucherFactory(code=COUPON_CODE, end_datetime=end_datetime, start_datetime=start_datetime)
self.assertMessage(_("Coupon code '{code}' has expired.").format(code=COUPON_CODE))
def test_voucher_added_to_basket_msg(self):
......
......@@ -388,10 +388,10 @@ class EnrollmentFulfillmentModuleTests(CourseCatalogTestMixin, FulfillmentTestMi
benefit_value=100.00,
catalog=catalog,
coupon=coupon,
end_datetime=datetime.datetime.now(),
end_datetime=datetime.datetime.now() + datetime.timedelta(days=30),
name="Test Voucher",
quantity=10,
start_datetime=datetime.datetime.now() + datetime.timedelta(days=30),
start_datetime=datetime.datetime.now(),
voucher_type=Voucher.SINGLE_USE
)
voucher = vouchers[0]
......
import datetime
import logging
from django.core.exceptions import ValidationError
......@@ -29,6 +30,11 @@ class Voucher(AbstractVoucher):
super(Voucher, self).save(*args, **kwargs) # pylint: disable=bad-super-call
def clean(self):
self.clean_code()
self.clean_datetimes()
super(Voucher, self).clean() # pylint: disable=bad-super-call
def clean_code(self):
if not self.code:
logger.exception('Failed to create Voucher. Voucher code must be set.')
raise ValidationError(_('Voucher code must be set.'))
......@@ -36,5 +42,15 @@ class Voucher(AbstractVoucher):
logger.exception('Failed to create Voucher. Voucher code must contain only alphanumeric characters.')
raise ValidationError(_('Voucher code must contain only alphanumeric characters.'))
def clean_datetimes(self):
if not (self.end_datetime and self.start_datetime):
logger.exception('Failed to create Voucher. Voucher start and end datetime fields must be set.')
raise ValidationError(_('Voucher start and end datetime fields must be set.'))
if not (isinstance(self.end_datetime, datetime.datetime) and
isinstance(self.start_datetime, datetime.datetime)):
logger.exception('Failed to create Voucher. Voucher start and end datetime fields must be type datetime.')
raise ValidationError(_('Voucher start and end datetime fields must be type datetime.'))
from oscar.apps.voucher.models import * # noqa pylint: disable=wildcard-import,unused-wildcard-import,wrong-import-position
import datetime
import ddt
from django.core.exceptions import ValidationError
from django.utils.timezone import now
......@@ -9,25 +10,51 @@ from ecommerce.tests.testcases import TestCase
Voucher = get_model('voucher', 'Voucher')
@ddt.ddt
class VoucherTests(TestCase):
def test_create_voucher(self):
""" Verify voucher is created. """
data = {
def setUp(self):
super(VoucherTests, self).setUp()
self.data = {
'code': 'TESTCODE',
'start_datetime': str(now() - datetime.timedelta(days=1)),
'end_datetime': str(now() + datetime.timedelta(days=1))
'end_datetime': now() + datetime.timedelta(days=1),
'start_datetime': now() - datetime.timedelta(days=1)
}
voucher = Voucher.objects.create(**data)
self.assertEqual(voucher.code, data['code'])
self.assertEqual(voucher.start_datetime, data['start_datetime'])
self.assertEqual(voucher.end_datetime, data['end_datetime'])
def test_create_voucher(self):
""" Verify voucher is created. """
voucher = Voucher.objects.create(**self.data)
self.assertEqual(voucher.code, self.data['code'])
self.assertEqual(voucher.start_datetime, self.data['start_datetime'])
self.assertEqual(voucher.end_datetime, self.data['end_datetime'])
def test_no_code_raises_exception(self):
""" Verify creating voucher without code set raises exception. """
del self.data['code']
with self.assertRaises(ValidationError):
Voucher.objects.create()
Voucher.objects.create(**self.data)
def test_wrong_code_data_raises_exception(self):
""" Verify creating voucher with code value that contains spaces (non alphanumeric value) raises exception. """
self.data['code'] = 'Only alphanumeric without spaces'
with self.assertRaises(ValidationError):
Voucher.objects.create(**self.data)
@ddt.data('end_datetime', 'start_datetime')
def test_no_datetime_set_raises_exception(self, key):
""" Verify creating voucher without start/end datetime set raises exception. """
del self.data[key]
with self.assertRaises(ValidationError):
Voucher.objects.create(**self.data)
@ddt.data('end_datetime', 'start_datetime')
def test_incorrect_datetime_value_raises_exception(self, key):
""" Verify creating voucher with incorrect start/end datetime value raises exception. """
self.data[key] = 'incorrect value'
with self.assertRaises(ValidationError):
Voucher.objects.create(**self.data)
def test_start_datetime_after_end_datetime(self):
""" Verify creating voucher with start datetime set after end datetime raises exception. """
self.data['start_datetime'] = self.data['end_datetime'] + datetime.timedelta(days=1)
with self.assertRaises(ValidationError):
Voucher.objects.create(code='Only alphanumeric without spaces')
Voucher.objects.create(**self.data)
......@@ -6,6 +6,7 @@ import hashlib
import logging
import uuid
import dateutil.parser
from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import ValidationError
......@@ -367,6 +368,26 @@ def _create_new_voucher(code, coupon, end_datetime, name, offer, start_datetime,
raise ValidationError(_('Voucher can not be created when code is set in enrollment coupon.'))
voucher_code = code or _generate_code_string(settings.VOUCHER_CODE_LENGTH)
if not end_datetime:
logger.exception('Failed to create Voucher. Voucher end datetime field must be set.')
raise ValidationError(_('Voucher end datetime field must be set.'))
elif not isinstance(end_datetime, datetime.datetime):
try:
end_datetime = dateutil.parser.parse(end_datetime)
except (AttributeError, ValueError):
logger.exception('Failed to create Voucher. Voucher end datetime value [%s] is invalid.', end_datetime)
raise ValidationError(_('Voucher end datetime value [{date}] is invalid.'.format(date=end_datetime)))
if not start_datetime:
logger.exception('Failed to create Voucher. Voucher start datetime field must be set.')
raise ValidationError(_('Voucher start datetime field must be set.'))
elif not isinstance(start_datetime, datetime.datetime):
try:
start_datetime = dateutil.parser.parse(start_datetime)
except (AttributeError, ValueError):
logger.exception('Failed to create Voucher. Voucher start datetime value [%s] is invalid.', start_datetime)
raise ValidationError(_('Voucher start datetime value [{date}] is invalid.'.format(date=start_datetime)))
voucher = Voucher.objects.create(
name=name,
code=voucher_code,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment