|
From: <sub...@co...> - 2005-11-29 23:05:25
|
Author: rflosi
Date: 2005-11-29 23:04:57 +0000 (Tue, 29 Nov 2005)
New Revision: 1327
Added:
FormEncode/trunk/tests/test_cc_expires.py
Modified:
FormEncode/trunk/formencode/validators.py
Log:
added a CreditCardExpires validator and cooresponding test file; usage is like CreditCardValidator; default field names are: ccExpiresMonth, ccExpiresYear; Currently only supports 4 digit years; errors could be improved if desired
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2005-11-28 09:16:53 UTC (rev 1326)
+++ FormEncode/trunk/formencode/validators.py 2005-11-29 23:04:57 UTC (rev 1327)
@@ -2159,6 +2159,80 @@
('1800', 15)],
}
+class CreditCardExpires(FormValidator):
+ """
+ Checks that credit card expiration date is valid relative to
+ the current date.
+
+ You pass in the name of the field that has the credit card
+ expiration month and the field with the credit card expiration
+ year.
+
+ ::
+
+ >>> ed = CreditCardExpires()
+ >>> ed.to_python({'ccExpiresMonth': '11', 'ccExpiresYear': '2250'})
+ {'ccExpiresYear': '2250', 'ccExpiresMonth': '11'}
+ >>> ed.to_python({'ccExpiresMonth': '10', 'ccExpiresYear': '2005'})
+ Traceback (most recent call last):
+ ...
+ Invalid: ccExpiresMonth: Invalid Expiration Date<br>
+ ccExpiresYear: Invalid Expiration Date
+ """
+
+ validate_partial_form = True
+
+ cc_expires_month_field = 'ccExpiresMonth'
+ cc_expires_year_field = 'ccExpiresYear'
+ __unpackargs__ = ('cc_expires_month_field', 'cc_expires_year_field')
+
+ datetime_module = None
+
+ messages = {
+ 'notANumber': "Please enter numbers only for month and year",
+ 'invalidNumber': "Invalid Expiration Date",
+ }
+
+ def validate_partial(self, field_dict, state):
+ if not field_dict.get(self.cc_expires_month_field, None) \
+ or not field_dict.get(self.cc_expires_year_field, None):
+ return None
+ self.validate_python(field_dict, state)
+
+ def validate_python(self, field_dict, state):
+ errors = self._validateReturn(field_dict, state)
+ if errors:
+ error_list = errors.items()
+ error_list.sort()
+ raise Invalid(
+ '<br>\n'.join(["%s: %s" % (name, value)
+ for name, value in error_list]),
+ field_dict, state, error_dict=errors)
+
+ def _validateReturn(self, field_dict, state):
+ ccExpiresMonth = field_dict[self.cc_expires_month_field].strip()
+ ccExpiresYear = field_dict[self.cc_expires_year_field].strip()
+
+ try:
+ ccExpiresMonth = int(ccExpiresMonth)
+ ccExpiresYear = int(ccExpiresYear)
+ dt_mod = import_datetime(self.datetime_module)
+ now = datetime_now(dt_mod)
+ today = datetime_makedate(dt_mod, now.year, now.month, now.day)
+ next_month = (ccExpiresMonth % 12) + 1
+ if next_month == 1:
+ next_month_year = ccExpiresYear + 1
+ else:
+ next_month_year = ccExpiresYear
+ expires_date = datetime_makedate(dt_mod, next_month_year, next_month, 1)
+ assert expires_date > today
+ except ValueError:
+ return {self.cc_expires_month_field: self.message('notANumber', state),
+ self.cc_expires_year_field: self.message('notANumber', state)}
+ except AssertionError:
+ return {self.cc_expires_month_field: self.message('invalidNumber', state),
+ self.cc_expires_year_field: self.message('invalidNumber', state)}
+
__all__ = []
for name, value in globals().items():
if isinstance(value, type) and issubclass(value, Validator):
Added: FormEncode/trunk/tests/test_cc_expires.py
===================================================================
--- FormEncode/trunk/tests/test_cc_expires.py 2005-11-28 09:16:53 UTC (rev 1326)
+++ FormEncode/trunk/tests/test_cc_expires.py 2005-11-29 23:04:57 UTC (rev 1327)
@@ -0,0 +1,19 @@
+from formencode.validators import CreditCardExpires, Invalid
+
+ed = CreditCardExpires()
+
+def validate(month, year):
+ try:
+ ed.validate_python({'ccExpiresMonth': month,
+ 'ccExpiresYear': year}, None)
+ except Invalid, e:
+ return e.unpack_errors()['ccExpiresMonth']
+
+messages = CreditCardExpires._messages
+
+def test_ed():
+ assert validate('11', '2250') is None
+ assert validate('11', 'test') == messages['notANumber']
+ assert validate('test', '2250') == messages['notANumber']
+ assert validate('10', '2005') == messages['invalidNumber']
+ assert validate('10', '05') == messages['invalidNumber']
|