Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make status_changed signal more robust #151

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion payments/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
import json
from uuid import uuid4
import logging

from django.conf import settings
from django.core.urlresolvers import reverse
Expand All @@ -10,6 +11,8 @@
from .core import provider_factory
from . import FraudStatus, PaymentStatus

# Get an instance of a logger
logger = logging.getLogger(__name__)

class PaymentAttributeProxy(object):

Expand Down Expand Up @@ -86,7 +89,9 @@ def change_status(self, status, message=''):
self.status = status
self.message = message
self.save()
status_changed.send(sender=type(self), instance=self)
for receiver, result in status_changed.send_robust(sender=type(self), instance=self):
if isinstance(result, Exception):
logger.critical(result)

def change_fraud_status(self, status, message='', commit=True):
available_statuses = [choice[0] for choice in FraudStatus.CHOICES]
Expand Down
24 changes: 24 additions & 0 deletions payments/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from unittest import TestCase
from mock import patch, NonCallableMock

from django.dispatch import Signal

from payments import core
from .forms import CreditCardPaymentFormWithName, PaymentForm
from .models import BasePayment
Expand Down Expand Up @@ -42,6 +44,28 @@ def test_capture_with_wrong_status(self):
payment = BasePayment(variant='default', status=PaymentStatus.WAITING)
self.assertRaises(ValueError, payment.capture)

@patch('payments.signals.status_changed', new_callable=Signal)
def test_robust_signals(self, mocked_signal):
with patch.object(BasePayment, 'save') as mocked_save_method:
mocked_save_method.return_value = None
def rogue_handler(sender, instance, **kwargs):
raise Exception("Here be dragons")
def benign_handler(sender, instance, **kwargs):
pass
class UnrelatedClass(object):
pass
def unrelated_handler(sender, instance, **kwargs):
raise Exception("Should not be called")
mocked_signal.connect(rogue_handler, sender=BasePayment)
mocked_signal.connect(benign_handler, sender=BasePayment)
mocked_signal.connect(unrelated_handler, sender=UnrelatedClass)
payment = BasePayment(variant='default', status=PaymentStatus.PREAUTH)
# python < 3.4 has no asserLogs
if hasattr(self, "assertLogs"):
with self.assertLogs("payments.models", "CRITICAL") as logs:
payment.change_status(PaymentStatus.WAITING, "fooo")
self.assertEqual(logs.output, ['CRITICAL:payments.models:Here be dragons'])

@patch('payments.dummy.DummyProvider.capture')
def test_capture_preauth_successfully(self, mocked_capture_method):
amount = Decimal('20')
Expand Down