From a086f387bff732b542525b01e40baf27d2714d06 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Tue, 30 Dec 2008 11:46:41 -0800 Subject: [PATCH] Payment code can now handle an optional 30-day trial for any subscription plan. Also, PayPal's subcr_eot txn_type is now ignored. --- NEWS | 1 + controller/Users.py | 20 ++++++++++++++----- controller/test/Test_users.py | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 6e07870..e6c1bf6 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ renaming prematurely. * Potential fix for a bug in which product downloads and attached file downloads occasionally did not complete in Internet Explorer. + * Added 30-day trial to all Luminotes subscription plans. 1.5.11: December 27, 2008 * Added a font selection button to the toolbar. diff --git a/controller/Users.py b/controller/Users.py index d5773f4..b33ad41 100644 --- a/controller/Users.py +++ b/controller/Users.py @@ -1450,7 +1450,12 @@ class Users( object ): if mc_gross and mc_gross not in ( fee, yearly_fee ): raise Payment_error( u"invalid mc_gross", params ) - # verify mc_amount3 + # verify mc_amount1 (free 30-day trial) + mc_amount1 = params.get( u"mc_amount1" ) + if mc_amount1 and mc_amount1 != "0.00": + raise Payment_error( u"invalid mc_amount1", params ) + + # verify mc_amount3 (actual payment) mc_amount3 = params.get( u"mc_amount3" ) if mc_amount3 and mc_amount3 not in ( fee, yearly_fee ): raise Payment_error( u"invalid mc_amount3", params ) @@ -1460,9 +1465,14 @@ class Users( object ): if item_name and item_name.lower() != u"luminotes " + rate_plan[ u"name" ].lower(): raise Payment_error( u"invalid item_name", params ) - # verify period1 and period2 (should not be present) - if params.get( u"period1" ) or params.get( u"period2" ): - raise Payment_error( u"invalid period", params ) + # verify period1 (free 30-day trial) + period1 = params.get( u"period1" ) + if period1 and period1 != "30 D": + raise Payment_error( u"invalid period1", params ) + + # verify period2 (should not be present) + if params.get( u"period2" ): + raise Payment_error( u"invalid period2", params ) # verify period3 period3 = params.get( u"period3" ) @@ -1509,7 +1519,7 @@ class Users( object ): self.__database.save( user, commit = False ) self.update_groups( user ) self.__database.commit() - elif txn_type in ( u"subscr_payment", u"subscr_failed" ): + elif txn_type in ( u"subscr_payment", u"subscr_failed", "subscr_eot" ): pass # for now, ignore payments and let paypal handle them else: raise Payment_error( "unknown txn_type", params ) diff --git a/controller/test/Test_users.py b/controller/test/Test_users.py index 45a8485..b5f900a 100644 --- a/controller/test/Test_users.py +++ b/controller/test/Test_users.py @@ -3351,6 +3351,43 @@ class Test_users( Test_controller ): user = self.database.load( User, self.user.object_id ) assert user.rate_plan == 0 + def test_paypal_notify_payment_with_trial( self ): + data = dict( self.PAYMENT_DATA ) + data[ u"custom" ] = self.user.object_id + data[ u"mc_amount1" ] = u"0.00" + data[ u"period1" ] = u"30 D" + result = self.http_post( "/users/paypal_notify", data ); + + assert len( result ) == 1 + assert result.get( u"session_id" ) + assert Stub_urllib2.result == u"VERIFIED" + assert Stub_urllib2.headers.get( u"Content-type" ) == u"application/x-www-form-urlencoded" + assert Stub_urllib2.url.startswith( "https://" ) + assert u"paypal.com" in Stub_urllib2.url + assert Stub_urllib2.encoded_params + + # being notified of a mere payment should not change the user's rate plan + user = self.database.load( User, self.user.object_id ) + assert user.rate_plan == 0 + + def test_paypal_notify_payment_with_trial_invalid_period( self ): + data = dict( self.PAYMENT_DATA ) + data[ u"custom" ] = self.user.object_id + data[ u"mc_amount1" ] = u"0.00" + data[ u"period1" ] = u"31 D" + result = self.http_post( "/users/paypal_notify", data ); + + assert result.get( u"error" ) + + def test_paypal_notify_payment_with_trial_invalid_amount( self ): + data = dict( self.PAYMENT_DATA ) + data[ u"custom" ] = self.user.object_id + data[ u"mc_amount1" ] = u"2.50" + data[ u"period1" ] = u"30 D" + result = self.http_post( "/users/paypal_notify", data ); + + assert result.get( u"error" ) + def test_paypal_notify_payment_invalid( self ): data = dict( self.PAYMENT_DATA ) data[ u"custom" ] = self.user.object_id