Permalink
Browse files

Added checking for phone numbers as well as a unit testing framework.

  • Loading branch information...
1 parent 0072972 commit d8e72b5b1f65d01f6161eef3f4acdc5f55a208d2 @chrismeyer chrismeyer committed Jun 23, 2010
Showing with 59 additions and 1 deletion.
  1. +3 −1 main.py
  2. +56 −0 utils.py
View
@@ -10,7 +10,7 @@
from datetime import datetime, timedelta
from models import Event, Feedback, ROOM_OPTIONS, GUESTS_PER_STAFF, PENDING_LIFETIME
-from utils import dojo, username, human_username, set_cookie, local_today
+from utils import dojo, username, human_username, set_cookie, local_today, is_phone_valid
from notices import *
class ExpireCron(webapp.RequestHandler):
@@ -164,6 +164,8 @@ def post(self):
self.request.get('end_time_ampm')), "%m/%d/%Y %I:%M %p")
if (end_time-start_time).days < 0:
raise ValueError("End time must be after start time")
+ if ( not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
+ raise ValueError( "Phone number does not appear to be valid" )
else:
event = Event(
name = self.request.get('name'),
View
@@ -1,7 +1,9 @@
from google.appengine.api import urlfetch, memcache
from django.utils import simplejson
from datetime import datetime
+import re
import pytz
+import unittest
LOCAL_TZ = 'America/Los_Angeles'
@@ -38,3 +40,57 @@ def local_today():
utc_now = pytz.utc.localize(datetime.utcnow())
local_now = utc_now.astimezone(pytz.timezone(LOCAL_TZ))
return datetime(*local_now.timetuple()[:3])
+
+def get_phone_parts( in_phone, international_okay=False ):
+ '''Return the different parts of a phone number: area code, trunk, number, extension, and optionally international code'''
+ phone_pattern = '((\d{3})\D*)?(\d{3})\D*(\d{4})(\D+(\d+))?$'
+ if international_okay:
+ phone_pattern = '(\+?\d{1-3})?\D*' + phone_pattern
+ phone_re = re.compile( '^' + phone_pattern )
+ try:
+ seg = phone_re.search( in_phone ).groups()
+ except AttributeError:
+ return [ None, None, None, None, None ]
+ if international_okay:
+ return [ seg[ 2 ], seg[ 3 ], seg[ 4 ], seg[ 6 ], seg[ 0 ] ]
+ else:
+ return [ seg[ 1 ], seg[ 2 ], seg[ 3 ], seg[ 5 ] ]
+
+def is_phone_valid( in_phone, area_code_required=True, international_okay=True ):
+ '''Check to make sure a given phone number is valid'''
+ parts = get_phone_parts( in_phone, international_okay )
+ out = True
+ if area_code_required and ( parts[ 0 ] == None or len( parts[ 0 ] ) != 3 ):
+ out = False
+ if parts[ 1 ] == None or parts[ 2 ] == None or len( parts[ 1 ] ) != 3 or len( parts[ 2 ] ) != 4:
+ out = False
+ return out
+
+
+
+class TestInput( unittest.TestCase ):
+ '''Unit tests to make sure the above functions are operating properly'''
+ def setUp( self ):
+ pass
+
+ def test_phone( self ):
+ self.assertFalse( is_phone_valid( "898-7925" ) )
+ self.assertFalse( is_phone_valid( "898-7925 x1234" ) )
+ self.assertFalse( is_phone_valid( "8985-7925" ) )
+ self.assertFalse( is_phone_valid( "8987925" ) )
+ self.assertTrue( is_phone_valid( "(650) 898-7925" ) )
+ self.assertTrue( is_phone_valid( "(650) 898-7925 x1234" ) )
+ self.assertTrue( is_phone_valid( "6508987925" ) )
+ self.assertFalse( is_phone_valid( "65089879251234" ) )
+ self.assertFalse( is_phone_valid( "89879251234" ) )
+ self.assertTrue( is_phone_valid( "6508987925x1234" ) )
+ self.assertFalse( is_phone_valid( "89879251234" ) )
+ self.assertFalse( is_phone_valid( "your mom" ) )
+
+ def test_phone_international( self ):
+ # TODO: Tests for this
+ pass
+
+# If this file is executed by itself, do the unit tests defined in the Test classes
+if ( __name__ == "__main__" ):
+ unittest.main()

0 comments on commit d8e72b5

Please sign in to comment.