witten
/
luminotes
Archived
1
0
Fork 0

Made signup support yearly subscriptions.

This commit is contained in:
Dan Helfman 2008-05-08 19:14:39 +00:00
parent 269c28983d
commit a6baa45435
6 changed files with 68 additions and 12 deletions

3
NEWS
View File

@ -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.

View File

@ -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 ) )

View File

@ -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." % \

View File

@ -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()

View File

@ -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()

View File

@ -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,