Stripe checkout #104411
@ -152,7 +152,9 @@ def _on_subscription_expired(sender: looper.models.Subscription, **kwargs):
|
||||
assert sender.status == 'expired', f'Expected expired, got "{sender.status} (pk={sender.pk})"'
|
||||
|
||||
# Only send a "subscription expired" email when there are no other active subscriptions
|
||||
if not queries.has_active_subscription(sender.user):
|
||||
customer = sender.customer
|
||||
user = customer.user
|
||||
if user and not queries.has_active_subscription(user):
|
||||
tasks.send_mail_subscription_expired(subscription_id=sender.pk)
|
||||
|
||||
|
||||
|
@ -44,8 +44,9 @@ def _construct_subscription_mail(mail_name: str, context: Dict[str, Any]) -> Tup
|
||||
def send_mail_bank_transfer_required(subscription_id: int):
|
||||
"""Send out an email notifying about the required bank transfer payment."""
|
||||
subscription = looper.models.Subscription.objects.get(pk=subscription_id)
|
||||
user = subscription.user
|
||||
email = user.customer.billing_address.email or user.email
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
email = customer.billing_address.email or user.email
|
||||
assert (
|
||||
email
|
||||
), f'Cannot send notification about bank payment for subscription {subscription.pk}: no email'
|
||||
@ -65,7 +66,7 @@ def send_mail_bank_transfer_required(subscription_id: int):
|
||||
assert order, "Can't send a notificaton about bank transfer without an existing order"
|
||||
|
||||
context = {
|
||||
'user': subscription.user,
|
||||
'user': user,
|
||||
'subscription': subscription,
|
||||
'order': order,
|
||||
**get_template_context(),
|
||||
@ -134,8 +135,8 @@ def send_mail_automatic_payment_performed(order_id: int, transaction_id: int):
|
||||
"""Send out an email notifying about the soft-failed payment."""
|
||||
order = looper.models.Order.objects.get(pk=order_id)
|
||||
transaction = looper.models.Transaction.objects.get(pk=transaction_id)
|
||||
user = order.user
|
||||
customer = user.customer
|
||||
customer = order.customer
|
||||
user = customer.user
|
||||
email = customer.billing_address.email or user.email
|
||||
logger.debug('Sending %r notification to %s', order.status, email)
|
||||
|
||||
@ -149,7 +150,7 @@ def send_mail_automatic_payment_performed(order_id: int, transaction_id: int):
|
||||
receipt_url = absolute_url('subscriptions:receipt', kwargs={'order_id': order.pk})
|
||||
|
||||
context = {
|
||||
'user': subscription.user,
|
||||
'user': user,
|
||||
'email': email,
|
||||
'order': order,
|
||||
'subscription': subscription,
|
||||
@ -186,7 +187,8 @@ def send_mail_managed_subscription_notification(subscription_id: int):
|
||||
subscription.pk,
|
||||
)
|
||||
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
admin_url = absolute_url(
|
||||
'admin:looper_subscription_change',
|
||||
kwargs={'object_id': subscription.id},
|
||||
@ -221,7 +223,8 @@ def send_mail_managed_subscription_notification(subscription_id: int):
|
||||
def send_mail_subscription_expired(subscription_id: int):
|
||||
"""Send out an email notifying about an expired subscription."""
|
||||
subscription = looper.models.Subscription.objects.get(pk=subscription_id)
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
|
||||
assert (
|
||||
subscription.status == 'expired'
|
||||
@ -230,7 +233,7 @@ def send_mail_subscription_expired(subscription_id: int):
|
||||
if queries.has_active_subscription(user):
|
||||
logger.error(
|
||||
'Not sending subscription-expired notification: pk=%s has other active subscriptions',
|
||||
subscription.user_id,
|
||||
user.pk,
|
||||
)
|
||||
return
|
||||
|
||||
@ -249,7 +252,7 @@ def send_mail_subscription_expired(subscription_id: int):
|
||||
|
||||
logger.debug('Sending subscription-expired notification to %s', email)
|
||||
context = {
|
||||
'user': subscription.user,
|
||||
'user': user,
|
||||
'subscription': subscription,
|
||||
'latest_trainings': get_latest_trainings_and_production_lessons(),
|
||||
'latest_posts': Post.objects.filter(is_published=True)[:5],
|
||||
@ -281,8 +284,8 @@ def send_mail_no_payment_method(order_id: int):
|
||||
), 'send_mail_no_payment_method expects automatic subscription'
|
||||
assert 'fail' in order.status, f'Unexpected order pk={order_id} status: {order.status}'
|
||||
|
||||
user = order.user
|
||||
customer = user.customer
|
||||
customer = order.customer
|
||||
user = customer.user
|
||||
email = customer.billing_address.email or user.email
|
||||
logger.debug('Sending %r notification to %s', order.status, email)
|
||||
|
||||
@ -296,7 +299,7 @@ def send_mail_no_payment_method(order_id: int):
|
||||
receipt_url = absolute_url('subscriptions:receipt', kwargs={'order_id': order.pk})
|
||||
|
||||
context = {
|
||||
'user': subscription.user,
|
||||
'user': user,
|
||||
'email': email,
|
||||
'order': order,
|
||||
'subscription': subscription,
|
||||
|
@ -440,7 +440,8 @@ class BaseSubscriptionTestCase(TestCase):
|
||||
self.assertIn('Blender Studio Team', email_body)
|
||||
|
||||
def _assert_payment_soft_failed_email_is_sent(self, subscription):
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
_write_mail(mail)
|
||||
email = mail.outbox[0]
|
||||
@ -470,7 +471,8 @@ class BaseSubscriptionTestCase(TestCase):
|
||||
self.assertIn('Blender Studio Team', email_body)
|
||||
|
||||
def _assert_payment_failed_email_is_sent(self, subscription):
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
_write_mail(mail)
|
||||
email = mail.outbox[0]
|
||||
@ -497,7 +499,8 @@ class BaseSubscriptionTestCase(TestCase):
|
||||
self.assertIn('Blender Studio Team', email_body)
|
||||
|
||||
def _assert_payment_paid_email_is_sent(self, subscription):
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
_write_mail(mail)
|
||||
email = mail.outbox[0]
|
||||
@ -523,7 +526,8 @@ class BaseSubscriptionTestCase(TestCase):
|
||||
self.assertIn('Blender Studio Team', email_body)
|
||||
|
||||
def _assert_managed_subscription_notification_email_is_sent(self, subscription):
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
_write_mail(mail)
|
||||
email = mail.outbox[0]
|
||||
@ -542,11 +546,12 @@ class BaseSubscriptionTestCase(TestCase):
|
||||
)
|
||||
|
||||
def _assert_subscription_expired_email_is_sent(self, subscription):
|
||||
user = subscription.user
|
||||
customer = subscription.customer
|
||||
user = customer.user
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
_write_mail(mail)
|
||||
email = mail.outbox[0]
|
||||
self.assertEqual(email.to, [subscription.user.email])
|
||||
self.assertEqual(email.to, [user.email])
|
||||
self.assertEqual(email.from_email, 'webmaster@localhost')
|
||||
self.assertEqual(email.subject, 'We miss you at Blender Studio')
|
||||
self.assertEqual(email.alternatives[0][1], 'text/html')
|
||||
|
@ -17,18 +17,20 @@ from subscriptions.tests.base import BaseSubscriptionTestCase
|
||||
import subscriptions.tasks
|
||||
import users.tasks
|
||||
import users.tests.util as util
|
||||
from common.tests.factories.users import OAuthUserInfoFactory
|
||||
|
||||
|
||||
class TestClock(BaseSubscriptionTestCase):
|
||||
class TestClockBraintree(BaseSubscriptionTestCase):
|
||||
def _create_subscription_due_now(self) -> Subscription:
|
||||
user = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
customer = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
OAuthUserInfoFactory(user=customer.user, oauth_user_id=554433)
|
||||
now = timezone.now()
|
||||
with mock.patch('django.utils.timezone.now') as mock_now:
|
||||
mock_now.return_value = now + relativedelta(months=-1)
|
||||
# print('fake now:', mock_now.return_value)
|
||||
subscription = SubscriptionFactory(
|
||||
user=user,
|
||||
payment_method__customer_id=user.customer.pk,
|
||||
customer=customer,
|
||||
payment_method__customer_id=customer.pk,
|
||||
payment_method__recognisable_name='Test payment method',
|
||||
payment_method__gateway=Gateway.objects.get(name='braintree'),
|
||||
currency='USD',
|
||||
@ -111,7 +113,7 @@ class TestClock(BaseSubscriptionTestCase):
|
||||
|
||||
# Tick the clock and check that order and transaction were created
|
||||
util.mock_blender_id_badger_badger_response(
|
||||
'revoke', 'cloud_subscriber', self.subscription.user.oauth_info.oauth_user_id
|
||||
'revoke', 'cloud_subscriber', self.subscription.customer.user.oauth_info.oauth_user_id
|
||||
)
|
||||
Clock().tick()
|
||||
|
||||
@ -164,7 +166,7 @@ class TestClock(BaseSubscriptionTestCase):
|
||||
|
||||
# Create another active subscription for the same user
|
||||
SubscriptionFactory(
|
||||
user=self.subscription.user,
|
||||
customer=self.subscription.customer,
|
||||
payment_method=self.subscription.payment_method,
|
||||
currency='USD',
|
||||
price=Money('USD', 1110),
|
||||
@ -187,10 +189,12 @@ class TestClock(BaseSubscriptionTestCase):
|
||||
)
|
||||
def test_automated_payment_paid_email_is_sent(self):
|
||||
now = timezone.now()
|
||||
self.assertEqual(self.subscription.collection_method, 'automatic')
|
||||
|
||||
# Tick the clock and check that subscription renews, order and transaction were created
|
||||
with patch(
|
||||
'looper.gateways.BraintreeGateway.transact_sale', return_value='mock-transaction-id'
|
||||
'looper.gateways.BraintreeGateway.transact_sale',
|
||||
return_value={'transaction_id': 'mock-transaction-id'},
|
||||
):
|
||||
Clock().tick()
|
||||
|
||||
@ -251,9 +255,9 @@ class TestClock(BaseSubscriptionTestCase):
|
||||
class TestClockExpiredSubscription(BaseSubscriptionTestCase):
|
||||
def test_subscription_on_hold_not_long_enough(self):
|
||||
now = timezone.now()
|
||||
user = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
customer = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
self.subscription = SubscriptionFactory(
|
||||
user=user,
|
||||
customer=customer,
|
||||
status='on-hold',
|
||||
# payment date has passed, but not long enough ago
|
||||
next_payment=now - timedelta(weeks=4),
|
||||
@ -280,15 +284,16 @@ class TestClockExpiredSubscription(BaseSubscriptionTestCase):
|
||||
@responses.activate
|
||||
def test_subscription_on_hold_too_long_status_changed_to_expired_email_sent(self):
|
||||
now = timezone.now()
|
||||
user = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
customer = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
OAuthUserInfoFactory(user=customer.user, oauth_user_id=223344)
|
||||
self.subscription = SubscriptionFactory(
|
||||
user=user,
|
||||
customer=customer,
|
||||
status='on-hold',
|
||||
# payment date has passed a long long time ago
|
||||
next_payment=now - timedelta(weeks=4 * 10),
|
||||
)
|
||||
util.mock_blender_id_badger_badger_response(
|
||||
'revoke', 'cloud_subscriber', user.oauth_info.oauth_user_id
|
||||
'revoke', 'cloud_subscriber', customer.user.oauth_info.oauth_user_id
|
||||
)
|
||||
|
||||
Clock().tick()
|
||||
|
Loading…
Reference in New Issue
Block a user