From a6baa45435d9bf6385faecd453619e36fedb4d03 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Thu, 8 May 2008 19:14:39 +0000 Subject: [PATCH] Made signup support yearly subscriptions. --- NEWS | 3 +++ controller/Root.py | 9 ++++++--- controller/Users.py | 17 +++++++++++++---- controller/test/Test_root.py | 15 +++++++++++++++ controller/test/Test_users.py | 30 ++++++++++++++++++++++++++++-- view/Upgrade_page.py | 6 +++--- 6 files changed, 68 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 8405132..ebf848f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +1.3.20: May 8, 2008 + * Made signup support yearly subscriptions. + 1.3.19: May 8, 2008 * Support for yearly subscriptions. diff --git a/controller/Root.py b/controller/Root.py index b2dbc47..cfe086d 100644 --- a/controller/Root.py +++ b/controller/Root.py @@ -2,7 +2,7 @@ import cherrypy from Expose import expose from Expire import strongly_expire -from Validate import validate, Valid_int, Valid_string +from Validate import validate, Valid_int, Valid_string, Valid_bool from Notebooks import Notebooks from Users import Users, grab_user_id from Files import Files @@ -60,9 +60,10 @@ class Root( object ): invite_id = Valid_id( none_okay = True ), after_login = Valid_string( min = 0, max = 1000 ), plan = Valid_int( none_okay = True ), + yearly = Valid_bool( none_okay = True ), user_id = Valid_id( none_okay = True ), ) - def default( self, note_title, invite_id = None, after_login = None, plan = None, user_id = None ): + def default( self, note_title, invite_id = None, after_login = None, plan = None, yearly = False, user_id = None ): """ Convenience method for accessing a note in the main notebook by name rather than by note id. @@ -74,6 +75,8 @@ class Root( object ): @param after_login: URL to redirect to after login (optional, must start with "/") @type plan: int @param plan: rate plan index (optional, defaults to None) + @type yearly: bool + @param yearly: True for yearly plan, False for monthly (optional, defaults to False) @rtype: unicode @return: rendered HTML page """ @@ -88,7 +91,7 @@ class Root( object ): if after_login: return dict( redirect = u"%s/%s?after_login=%s" % ( https_url, note_title, after_login ) ) if plan: - return dict( redirect = u"%s/%s?plan=%s" % ( https_url, note_title, plan ) ) + return dict( redirect = u"%s/%s?plan=%s&yearly=%s" % ( https_url, note_title, plan, yearly ) ) else: return dict( redirect = u"%s/%s" % ( https_url, note_title ) ) diff --git a/controller/Users.py b/controller/Users.py index 7a78f3a..4a490e4 100644 --- a/controller/Users.py +++ b/controller/Users.py @@ -217,8 +217,9 @@ class Users( object ): signup_button = unicode, invite_id = Valid_id( none_okay = True ), rate_plan = Valid_int( none_okay = True ), + yearly = Valid_bool( none_okay = True ), ) - def signup( self, username, password, password_repeat, email_address, signup_button, invite_id = None, rate_plan = None ): + def signup( self, username, password, password_repeat, email_address, signup_button, invite_id = None, rate_plan = None, yearly = False ): """ Create a new User based on the given information. Start that user with their own Notebook and a "welcome to your wiki" Note. For convenience, login the newly created user as well. @@ -238,6 +239,8 @@ class Users( object ): @type rate_plan: int @param rate_plan: index of rate plan to signup for (optional). if greater than zero, redirect to PayPal subscribe page after signup + @type yearly: bool + @param yearly: True for a yearly rate plan, False for monthly (optional, defaults to False ) @rtype: json dict @return: { 'redirect': url, 'authenticated': userdict } @raise Signup_error: passwords don't match or the username is unavailable @@ -292,7 +295,7 @@ class Users( object ): redirect = u"/notebooks/%s" % invite.notebook_id # if there's a requested rate plan, then redirect to the PayPal subscribe page elif rate_plan and rate_plan > 0: - redirect = u"/users/subscribe?rate_plan=%s" % rate_plan + redirect = u"/users/subscribe?rate_plan=%s&yearly=%s" % ( rate_plan, yearly ) # otherwise, just redirect to the newly created notebook else: redirect = u"/notebooks/%s" % notebook.object_id @@ -306,14 +309,17 @@ class Users( object ): @grab_user_id @validate( rate_plan = Valid_int(), + yearly = Valid_bool( none_okay = True ), user_id = Valid_id(), ) - def subscribe( self, rate_plan, user_id ): + def subscribe( self, rate_plan, yearly = False, user_id = None ): """ Submit a subscription form to PayPal, allowing the user to subscribe to the given rate plan. @type rate_plan: int @param rate_plan: index of rate plan to subscribe to + @type yearly: bool + @param yearly: True for a yearly rate plan, False for monthly (optional, defaults to False ) @type user_id: unicode @param user_id: id of current logged-in user @rtype: dict @@ -324,7 +330,10 @@ class Users( object ): raise Signup_error( u"The rate plan is invalid." ) plan = self.__rate_plans[ rate_plan ] - button = plan.get( u"button" ) + if yearly: + button = plan.get( u"yearly_button" ) + else: + button = plan.get( u"button" ) if not button or not button.strip(): raise Signup_error( u"Sorry, that rate plan is not configured for subscriptions. Please contact %s." % \ diff --git a/controller/test/Test_root.py b/controller/test/Test_root.py index 533941e..be7ffb2 100644 --- a/controller/test/Test_root.py +++ b/controller/test/Test_root.py @@ -253,6 +253,21 @@ class Test_root( Test_controller ): assert result[ u"signup_plan" ] == 17 assert result[ u"user" ].object_id == self.anonymous.object_id + def test_default_with_plan_and_yearly( self ): + plan = u"17" + + result = self.http_get( + "/my_note?plan=%s&yearly=True" % plan, + ) + + assert result + assert result[ u"notes" ] + assert len( result[ u"notes" ] ) == 1 + assert result[ u"notes" ][ 0 ].object_id == self.anon_note.object_id + assert result[ u"notebook" ].object_id == self.anon_notebook.object_id + assert result[ u"signup_plan" ] == 17 + assert result[ u"user" ].object_id == self.anonymous.object_id + def test_default_after_login( self ): self.login() diff --git a/controller/test/Test_users.py b/controller/test/Test_users.py index fef267f..eff627c 100644 --- a/controller/test/Test_users.py +++ b/controller/test/Test_users.py @@ -103,7 +103,20 @@ class Test_users( Test_controller ): rate_plan = u"2", ) ) - assert result[ u"redirect" ] == u"/users/subscribe?rate_plan=2" + assert result[ u"redirect" ] == u"/users/subscribe?rate_plan=2&yearly=False" + + def test_signup_with_rate_plan_and_yearly( self ): + result = self.http_post( "/users/signup", dict( + username = self.new_username, + password = self.new_password, + password_repeat = self.new_password, + email_address = self.new_email_address, + signup_button = u"sign up", + rate_plan = u"2", + yearly = True, + ) ) + + assert result[ u"redirect" ] == u"/users/subscribe?rate_plan=2&yearly=True" def test_signup_without_email_address( self ): result = self.http_post( "/users/signup", dict( @@ -273,7 +286,7 @@ class Test_users( Test_controller ): ) ) session_id = result[ u"session_id" ] - assert result[ u"redirect" ] == u"/users/subscribe?rate_plan=2" + assert result[ u"redirect" ] == u"/users/subscribe?rate_plan=2&yearly=False" user = self.database.last_saved_obj assert isinstance( user, User ) @@ -341,6 +354,19 @@ class Test_users( Test_controller ): assert form == plan[ u"button" ] % self.user.object_id + def test_subscribe_yearly( self ): + self.login() + + result = self.http_post( "/users/subscribe", dict( + rate_plan = u"1", + yearly = True, + ), session_id = self.session_id ) + + form = result.get( u"form" ) + plan = self.settings[ u"global" ][ u"luminotes.rate_plans" ][ 1 ] + + assert form == plan[ u"yearly_button" ] % self.user.object_id + def test_subscribe_with_free_rate_plan( self ): self.login() diff --git a/view/Upgrade_page.py b/view/Upgrade_page.py index 6dadfa5..0e10443 100644 --- a/view/Upgrade_page.py +++ b/view/Upgrade_page.py @@ -187,13 +187,13 @@ class Upgrade_page( Product_page ): separator = u"", ), user and user.username not in ( u"anonymous", None ) and user.rate_plan != index \ - and yearly and ( plan.get( u"yearly_button" ).strip() and plan.get( u"yearly_button" ) % user.object_id or None ) or \ - ( plan.get( u"button" ).strip() and plan.get( u"button" ) % user.object_id or None ), + and ( yearly and ( plan.get( u"yearly_button" ).strip() and plan.get( u"yearly_button" ) % user.object_id or None ) or \ + ( plan.get( u"button" ).strip() and plan.get( u"button" ) % user.object_id or None ) ) or None, ) or None, ( not user or user.username in ( u"anonymous", None ) ) and Div( A( Img( src = u"/static/images/sign_up_button.png", width = "76", height = "23" ), - href = u"/sign_up?plan=%s" % index, + href = u"/sign_up?plan=%s&yearly=%s" % ( index, yearly ), ), class_ = u"sign_up_button_area", ) or None,