コード例 #1
0
 def test_subscribe(self, StripeCustomerMock, UpdateSubscriptionMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)]
     self.assertEqual(self.customer.has_active_subscription(), False)
     self.customer.subscribe("basic", charge_immediately=False)
     self.assertEqual(self.customer.has_active_subscription(), True)
     sub = self.customer.current_subscription
     self.assertEqual(sub.quantity, 1)
     self.assertEqual(sub.amount, decimal.Decimal("100.00"))
コード例 #2
0
 def test_update_quantity(self, StripeCustomerMock, UpdateSubscriptionMock):
     dummy_customer = copy.deepcopy(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     dummy_customer["subscription"]["quantity"] = 2
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(dummy_customer)]
     create_subscription(self.customer)
     self.customer.update_plan_quantity(2, charge_immediately=False)
     self.assertEqual(self.customer.current_subscription.quantity, 2)
コード例 #3
0
 def test_cancel_with_stripe_sub(self, StripeCustomerMock, CancelSubscriptionMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     CancelSubscriptionMock.return_value = convert_to_fake_stripe_object(DUMMY_SUB_BASIC_CANCELED)
     create_subscription(self.customer)
     self.assertEqual(self.customer.current_subscription.status, "trialing")
     self.customer.cancel_subscription(at_period_end=False)
     self.assertEqual(self.customer.has_active_subscription(), False)
     self.assertEqual(self.customer.current_subscription.status, "canceled")
     self.assertEqual(self.customer.current_subscription.ended_at, None)
     self.assertEqual(self.customer.current_subscription.canceled_at, convert_tstamp(CANCELED_TIME))
コード例 #4
0
    def test_cancel_with_stripe_sub_future(self, stripe_customer_mock, cancel_subscription_mock):
        stripe_customer_mock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)
        cancel_subscription_mock.return_value = convert_to_fake_stripe_object(DUMMY_SUB_BASIC_CANCELED)
        subscription_instance = create_subscription(self.customer)
        subscription_instance.trial_end = timezone.now() + datetime.timedelta(days=5)
        subscription_instance.save()

        self.customer.cancel_subscription(at_period_end=True)
        self.assertEqual(self.customer.has_active_subscription(), False)
        self.assertEqual(self.customer.current_subscription.status, "canceled")
コード例 #5
0
 def test_update_quantity(self, StripeCustomerMock, SubscriptionSaveMock):
     dummy_customer = copy.deepcopy(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     dummy_customer["subscriptions"]["data"][0]["quantity"] = 2
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(dummy_customer)]
     create_subscription(self.customer)
     self.customer.update_plan_quantity(2, charge_immediately=False,
                                        subscription=self.customer.subscriptions.get(plan="basic"))
     self.assertEqual(self.customer.subscriptions.get(plan="basic").quantity, 2)
コード例 #6
0
 def test_upgrade(self, StripeCustomerMock, SubscriptionSaveMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_GOLD)]
     create_subscription(self.customer)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     sub = self.customer.subscriptions.get(plan="basic")
     self.customer.subscribe("gold", charge_immediately=False, subscription=sub)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     sub = self.customer.subscriptions.get(plan="gold")
     self.assertEqual(sub.amount, decimal.Decimal("1000.00"))
コード例 #7
0
 def test_upgrade(self, StripeCustomerMock, UpdateSubscriptionMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_GOLD)]
     create_subscription(self.customer)
     self.assertEqual(self.customer.has_active_subscription(), True)
     self.assertEqual(self.customer.current_subscription.plan, "basic")
     self.customer.subscribe("gold", charge_immediately=False)
     self.assertEqual(self.customer.has_active_subscription(), True)
     sub = self.customer.current_subscription
     self.assertEqual(sub.amount, decimal.Decimal("1000.00"))
     self.assertEqual(sub.plan, "gold")
コード例 #8
0
 def test_update_quantity(self, StripeCustomerMock, UpdateSubscriptionMock):
     dummy_customer = copy.deepcopy(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     dummy_customer["subscription"]["quantity"] = 2
     StripeCustomerMock.side_effect = [
         convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
         convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
         convert_to_fake_stripe_object(dummy_customer)
     ]
     create_subscription(self.customer)
     self.customer.update_plan_quantity(2, charge_immediately=False)
     self.assertEqual(self.customer.current_subscription.quantity, 2)
コード例 #9
0
 def test_subscribe(self, StripeCustomerMock, UpdateSubscriptionMock):
     StripeCustomerMock.side_effect = [
         convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB),
         convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     ]
     self.assertEqual(self.customer.has_active_subscription(), False)
     self.customer.subscribe("basic", charge_immediately=False)
     self.assertEqual(self.customer.has_active_subscription(), True)
     sub = self.customer.current_subscription
     self.assertEqual(sub.quantity, 1)
     self.assertEqual(sub.amount, decimal.Decimal("100.00"))
コード例 #10
0
 def test_subscribe_with_sub(self, StripeCustomerMock, ListObjectCreateMock, SubscriptionSaveMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)]
     self.customer.subscribe("basic", charge_immediately=False)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     sub_basic = self.customer.subscriptions.all()[0]
     self.customer.subscribe("basic", trial_days=10, charge_immediately=False, subscription=sub_basic)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     SubscriptionSaveMock.assert_called_once_with()
コード例 #11
0
 def test_upgrade(self, StripeCustomerMock, UpdateSubscriptionMock):
     StripeCustomerMock.side_effect = [
         convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
         convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_GOLD)
     ]
     create_subscription(self.customer)
     self.assertEqual(self.customer.has_active_subscription(), True)
     self.assertEqual(self.customer.current_subscription.plan, "basic")
     self.customer.subscribe("gold", charge_immediately=False)
     self.assertEqual(self.customer.has_active_subscription(), True)
     sub = self.customer.current_subscription
     self.assertEqual(sub.amount, decimal.Decimal("1000.00"))
     self.assertEqual(sub.plan, "gold")
コード例 #12
0
    def test_cancel_with_stripe_sub_future(self, stripe_customer_mock,
                                           cancel_subscription_mock):
        stripe_customer_mock.return_value = convert_to_fake_stripe_object(
            DUMMY_CUSTOMER_WITH_SUB_BASIC)
        cancel_subscription_mock.return_value = convert_to_fake_stripe_object(
            DUMMY_SUB_BASIC_CANCELED)
        subscription_instance = create_subscription(self.customer)
        subscription_instance.trial_end = timezone.now() + datetime.timedelta(
            days=5)
        subscription_instance.save()

        self.customer.cancel_subscription(at_period_end=True)
        self.assertEqual(self.customer.has_active_subscription(), False)
        self.assertEqual(self.customer.current_subscription.status, "canceled")
コード例 #13
0
 def test_cancel_with_stripe_sub(self, StripeCustomerMock,
                                 CancelSubscriptionMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(
         DUMMY_CUSTOMER_WITH_SUB_BASIC)
     CancelSubscriptionMock.return_value = convert_to_fake_stripe_object(
         DUMMY_SUB_BASIC_CANCELED)
     create_subscription(self.customer)
     self.assertEqual(self.customer.current_subscription.status, "trialing")
     self.customer.cancel_subscription(at_period_end=False)
     self.assertEqual(self.customer.has_active_subscription(), False)
     self.assertEqual(self.customer.current_subscription.status, "canceled")
     self.assertEqual(self.customer.current_subscription.ended_at, None)
     self.assertEqual(self.customer.current_subscription.canceled_at,
                      convert_tstamp(CANCELED_TIME))
コード例 #14
0
    def test_cancel_with_bad_stripe_sub(self, StripeCustomerMock, SubscriptionDeleteMock):
        StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)
        SubscriptionDeleteMock.return_value = convert_to_fake_stripe_object(DUMMY_SUB_BASIC_CANCELED)
        create_subscription(self.customer)
        self.assertEqual(self.customer.subscriptions.count(), 1)

        stripe_subscription = MagicMock()
        p = PropertyMock(return_value="not_sub_id")
        type(stripe_subscription).stripe_id = p
        p = PropertyMock(return_value=timezone.now() - datetime.timedelta(days=1))
        type(stripe_subscription).trial_end = p

        self.customer.cancel_subscription(subscription=stripe_subscription)

        self.assertEqual(self.customer.subscriptions.count(), 1)
コード例 #15
0
 def test_update_quantity_badsub(self, StripeCustomerMock, SubscriptionSaveMock):
     dummy_customer = copy.deepcopy(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     dummy_customer["subscriptions"]["data"][0]["quantity"] = 2
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(dummy_customer)]
     create_subscription(self.customer)
     stripe_subscription = MagicMock()
     p = PropertyMock(return_value="not_sub_id")
     type(stripe_subscription).stripe_id = p
     self.customer.update_plan_quantity(2, charge_immediately=False,
                                        subscription=stripe_subscription)
     # didnt update anything, stripe_subscription matches nothing attached to this
     # customer
     self.assertEqual(self.customer.subscriptions.get(plan="basic").quantity, 1)
コード例 #16
0
 def test_extend(self, StripeCustomerMock, UpdateSubscriptionMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)
     subscription_instance = create_subscription(self.customer)
     subscription_instance.current_period_end = timezone.datetime.fromtimestamp(END_TIME, tz=timezone.utc)
     delta = timezone.timedelta(days=30)
     self.customer.current_subscription.extend(delta)
     UpdateSubscriptionMock.assert_called_once_with(prorate=False, trial_end=subscription_instance.current_period_end + delta)
コード例 #17
0
 def test_sync_with_no_subscriptions(self, StripeCustomerMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB)]
     create_subscription(self.customer)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     Customer.retain_canceled_subscriptions = False
     self.customer.sync_subscriptions()
     self.assertEqual(self.customer.subscriptions.count(), 0)
コード例 #18
0
 def test_cancel_without_stripe_sub(self, StripeCustomerMock, CancelSubscriptionMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB)
     CancelSubscriptionMock.side_effect = InvalidRequestError("No active subscriptions for customer: cus_xxxxxxxxxxxxxx", None)
     create_subscription(self.customer)
     self.assertEqual(self.customer.has_active_subscription(), True)
     self.assertEqual(self.customer.current_subscription.status, "trialing")
     with self.assertRaises(SubscriptionCancellationFailure):
         self.customer.cancel_subscription()
コード例 #19
0
 def test_subscribe(self, StripeCustomerMock, ListObjectCreateMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_BOTH_SUBS)]
     self.assertEqual(self.customer.subscriptions.count(), 0)
     self.customer.subscribe("basic", charge_immediately=False)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     sub_basic = self.customer.subscriptions.all()[0]
     self.assertEqual(sub_basic.quantity, 1)
     self.assertEqual(sub_basic.amount, decimal.Decimal("100.00"))
     self.customer.subscribe("gold", charge_immediately=False)
     self.assertEqual(self.customer.subscriptions.count(), 2)
     sub_gold = self.customer.subscriptions.get(plan="gold")
     self.assertEqual(sub_gold.quantity, 1)
     self.assertEqual(sub_gold.amount, decimal.Decimal("1000.00"))
     self.assertNotEqual(sub_basic.stripe_id, sub_gold.stripe_id)
コード例 #20
0
    def test_extend_with_trial(self, StripeCustomerMock, UpdateSubscriptionMock):
        StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_BASIC)
        subscription_instance = create_subscription(self.customer)
        subscription_instance.trial_end = timezone.now() + timezone.timedelta(days=5)

        delta = timezone.timedelta(days=30)
        new_trial_end = subscription_instance.trial_end + delta
        self.customer.current_subscription.extend(delta)
        UpdateSubscriptionMock.assert_called_once_with(prorate=False, trial_end=new_trial_end)
コード例 #21
0
 def test_cancel_without_stripe_sub(self, StripeCustomerMock,
                                    CancelSubscriptionMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(
         DUMMY_CUSTOMER_WITHOUT_SUB)
     CancelSubscriptionMock.side_effect = InvalidRequestError(
         "No active subscriptions for customer: cus_xxxxxxxxxxxxxx", None)
     create_subscription(self.customer)
     self.assertEqual(self.customer.has_active_subscription(), True)
     self.assertEqual(self.customer.current_subscription.status, "trialing")
     with self.assertRaises(SubscriptionCancellationFailure):
         self.customer.cancel_subscription()
コード例 #22
0
 def test_cancel_with_both_subs(self, StripeCustomerMock, SubscriptionDeleteMock):
     StripeCustomerMock.side_effect = [convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_BOTH_SUBS),
                                       convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITH_SUB_GOLD)]
     SubscriptionDeleteMock.return_value = convert_to_fake_stripe_object(DUMMY_SUB_BASIC_CANCELED)
     create_subscription(self.customer)
     create_subscription(self.customer, "gold")
     sub_basic = self.customer.subscriptions.get(plan="basic")
     self.assertEqual(sub_basic.status, "trialing")
     self.assertEqual(sub_basic.plan, "basic")
     self.customer.cancel_subscription(at_period_end=False, subscription=sub_basic)
     self.assertEqual(self.customer.subscriptions.count(), 2)
     self.assertEqual(sub_basic.status, "canceled")
     self.assertEqual(sub_basic.canceled_at, convert_tstamp(CANCELED_TIME))
     sub_gold = self.customer.subscriptions.get(plan="gold")
     self.assertEqual(sub_gold.status, "trialing")
     # Now, after a synchronise, canceled subs will be removed.
     self.customer.sync_subscriptions()
     self.assertEqual(self.customer.subscriptions.count(), 1)
     with self.assertRaises(Subscription.DoesNotExist):
         self.customer.subscriptions.get(plan="basic")
コード例 #23
0
 def test_cancel_without_stripe_sub(self, StripeCustomerMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB)
     create_subscription(self.customer)
     self.assertEqual(self.customer.subscriptions.count(), 1)
     self.assertEqual(self.customer.current_subscription.status, "trialing")
     self.customer.cancel_subscription()
     self.assertEqual(self.customer.subscriptions.count(), 1)
     self.assertEqual(self.customer.current_subscription.status, "canceled")
     self.assertEqual(self.customer.current_subscription.ended_at, None)
     self.assertLess(datetime.datetime.now(tz=timezone.utc) - self.customer.current_subscription.canceled_at,
                     datetime.timedelta(seconds=1))
コード例 #24
0
 def test_extend(self, StripeCustomerMock, UpdateSubscriptionMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(
         DUMMY_CUSTOMER_WITH_SUB_BASIC)
     subscription_instance = create_subscription(self.customer)
     subscription_instance.current_period_end = timezone.datetime.fromtimestamp(
         END_TIME, tz=timezone.utc)
     delta = timezone.timedelta(days=30)
     self.customer.current_subscription.extend(delta)
     UpdateSubscriptionMock.assert_called_once_with(
         prorate=False,
         trial_end=subscription_instance.current_period_end + delta)
コード例 #25
0
    def test_extend_with_trial(self, StripeCustomerMock,
                               UpdateSubscriptionMock):
        StripeCustomerMock.return_value = convert_to_fake_stripe_object(
            DUMMY_CUSTOMER_WITH_SUB_BASIC)
        subscription_instance = create_subscription(self.customer)
        subscription_instance.trial_end = timezone.now() + timezone.timedelta(
            days=5)

        delta = timezone.timedelta(days=30)
        new_trial_end = subscription_instance.trial_end + delta
        self.customer.current_subscription.extend(delta)
        UpdateSubscriptionMock.assert_called_once_with(prorate=False,
                                                       trial_end=new_trial_end)
コード例 #26
0
 def test_update_no_stripe_sub(self, StripeCustomerMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB)
     create_subscription(self.customer)
     with self.assertRaises(SubscriptionUpdateFailure):
         self.customer.update_plan_quantity(2)
コード例 #27
0
 def test_update_no_stripe_sub(self, StripeCustomerMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(
         DUMMY_CUSTOMER_WITHOUT_SUB)
     create_subscription(self.customer)
     with self.assertRaises(SubscriptionUpdateFailure):
         self.customer.update_plan_quantity(2)
コード例 #28
0
 def test_cancel_without_stripe_sub_immediately(self, StripeCustomerMock):
     StripeCustomerMock.return_value = convert_to_fake_stripe_object(DUMMY_CUSTOMER_WITHOUT_SUB)
     create_subscription(self.customer)
     self.customer.cancel_subscription(at_period_end=False)
     self.assertEqual(self.customer.current_subscription.ended_at, self.customer.current_subscription.canceled_at)
コード例 #29
0
ファイル: test_event.py プロジェクト: zkan/dj-stripe
class EventTest(TestCase):
    message = {
        "created": 1363911708,
        "data": {
            "object": {
                "account_balance": 0,
                "active_card": None,
                "created": 1363911708,
                "delinquent": False,
                "description": None,
                "discount": None,
                "email": "*****@*****.**",
                "id": "cus_yyyyyyyyyyyyyyyyyyyy",
                "customer": "cus_xxxxxxxxxxxxxxx",
                "livemode": True,
                "object": "customer",
                "subscription": None
            }
        },
        "id": "evt_xxxxxxxxxxxxx",
        "livemode": True,
        "object": "event",
        "pending_webhooks": 1,
        "type": "ping"
    }

    fake_current_subscription = CurrentSubscription(plan="test",
                                                    quantity=1,
                                                    start=timezone.now(),
                                                    amount=Decimal(25.00))

    def setUp(self):
        self.message["data"]["object"][
            "customer"] = "cus_xxxxxxxxxxxxxxx"  # Yes, this is intentional.

        self.user = get_user_model().objects.create_user(
            username="******", email="*****@*****.**")
        self.customer = Customer.objects.create(
            stripe_id=self.message["data"]["object"]["customer"],
            subscriber=self.user)

    def test_tostring(self):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="eventkind",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)
        self.assertEquals("<eventkind, stripe_id=evt_xxxxxxxxxxxxx>",
                          str(event))

    def test_link_customer_customer_created(self):
        msg = {
            "created": 1363911708,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1363911708,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "*****@*****.**",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.created"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.created",
            livemode=True,
            webhook_message=msg,
            validated_message=msg,
            valid=True,
        )
        event.process()
        self.assertEquals(event.customer, self.customer)

    def test_link_customer_customer_updated(self):
        msg = {
            "created": 1346855599,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": {
                        "address_city": None,
                        "address_country": None,
                        "address_line1": None,
                        "address_line1_check": None,
                        "address_line2": None,
                        "address_state": None,
                        "address_zip": None,
                        "address_zip_check": None,
                        "country": "MX",
                        "cvc_check": "pass",
                        "exp_month": 1,
                        "exp_year": 2014,
                        "fingerprint": "XXXXXXXXXXX",
                        "last4": "7992",
                        "name": None,
                        "object": "card",
                        "type": "MasterCard"
                    },
                    "created": 1346855596,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "*****@*****.**",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                },
                "previous_attributes": {
                    "active_card": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.updated"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.updated",
            livemode=True,
            webhook_message=msg,
            validated_message=msg,
            valid=True,
        )
        event.process()
        self.assertEquals(event.customer, self.customer)

    def test_link_customer_customer_deleted(self):
        msg = {
            "created": 1348286560,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1348286302,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "*****@*****.**",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.deleted"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.deleted",
            livemode=True,
            webhook_message=msg,
            validated_message=msg,
            valid=True,
        )
        event.process()
        self.assertEquals(event.customer, self.customer)

    @patch('stripe.Event.retrieve',
           return_value=convert_to_fake_stripe_object({
               "data": message["data"],
               "zebra": True,
               "alpha": False
           }))
    def test_validate_true(self, event_retrieve_mock):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="ping",
                                     webhook_message=self.message,
                                     validated_message=self.message)

        self.assertEqual(None, event.valid)
        event.validate()
        event_retrieve_mock.assert_called_once_with(self.message["id"])
        self.assertEqual(True, event.valid)

    @patch('stripe.Event.retrieve',
           return_value=convert_to_fake_stripe_object({
               "data": {
                   "object": {
                       "flavor": "chocolate"
                   }
               },
               "zebra": True,
               "alpha": False
           }))
    def test_validate_false(self, event_retrieve_mock):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="ping",
                                     webhook_message=self.message,
                                     validated_message=self.message)

        self.assertEqual(None, event.valid)
        event.validate()
        event_retrieve_mock.assert_called_once_with(self.message["id"])
        self.assertEqual(False, event.valid)

    def test_process_exit_immediately(self):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="ping",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=False)

        event.process()
        self.assertFalse(event.processed)

    @patch('djstripe.models.Customer.objects.get')
    @patch('stripe.Invoice.retrieve')
    @patch('djstripe.models.Invoice.sync_from_stripe_data')
    def test_process_invoice_event(self, stripe_sync_mock, retrieve_mock,
                                   customer_get):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="invoice.created",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)
        customer_get.return_value = self.customer
        retrieve_mock.return_value = self.message['object']
        event.process()
        customer_get.assert_called_once_with(stripe_id=self.customer.stripe_id)
        stripe_sync_mock.assert_called_once_with(self.message['object'],
                                                 send_receipt=True)
        self.assertTrue(event.processed)

    @patch('djstripe.models.Customer.objects.get')
    @patch('stripe.Invoice.retrieve')
    @patch('djstripe.models.Invoice.sync_from_stripe_data')
    def test_process_invoice_event_ignored(self, stripe_sync_mock,
                                           retrieve_mock, customer_get):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="invoice.notanevent",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)
        customer_get.return_value = self.customer
        retrieve_mock.return_value = self.message['object']
        event.process()
        self.assertFalse(stripe_sync_mock.called)
        self.assertTrue(event.processed)

    @patch('djstripe.models.Customer.objects.get')
    @patch('stripe.Invoice.retrieve')
    @patch('djstripe.models.Invoice.sync_from_stripe_data')
    def test_process_invoice_event_badcustomer(self, stripe_sync_mock,
                                               retrieve_mock, customer_get):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="invoice.created",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)
        customer_get.side_effect = Customer.DoesNotExist()
        retrieve_mock.return_value = self.message['object']
        event.process()
        customer_get.assert_called_once_with(stripe_id=self.customer.stripe_id)
        stripe_sync_mock.assert_called_once_with(self.message['object'],
                                                 send_receipt=True)
        self.assertTrue(event.processed)

    @patch('stripe.Charge.retrieve', return_value='hello')
    @patch('djstripe.models.Charge.sync_from_stripe_data')
    def test_process_charge_event(self, record_charge_mock, retrieve_mock):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="charge.created",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)

        event.process()
        self.assertEqual(event.customer, self.customer)
        retrieve_mock.assert_called_once_with(
            self.message["data"]["object"]["id"])
        record_charge_mock.assert_called_once_with("hello")
        self.assertTrue(event.processed)

    @patch('djstripe.models.Customer.sync_current_subscription')
    def test_customer_subscription_event(self, sync_current_subscription_mock):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="customer.subscription.created",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)

        event.process()
        sync_current_subscription_mock.assert_called_once_with()
        self.assertTrue(event.processed)

    @patch('djstripe.models.Customer.sync_current_subscription')
    def test_customer_subscription_event_no_customer(
            self, sync_current_subscription_mock):
        self.message["data"]["object"]["customer"] = None
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="customer.subscription.created",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)

        event.process()
        self.assertFalse(sync_current_subscription_mock.called)
        self.assertTrue(event.processed)

    @patch("djstripe.models.Customer.current_subscription",
           new_callable=PropertyMock,
           return_value=fake_current_subscription)
    def test_customer_subscription_deleted_event(self,
                                                 current_subscription_mock):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="customer.subscription.deleted",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)

        event.process()
        self.assertTrue(current_subscription_mock.status,
                        CurrentSubscription.STATUS_CANCELLED)
        self.assertTrue(event.processed)

    @patch("stripe.Customer.retrieve")
    def test_process_customer_deleted(self, customer_retrieve_mock):
        msg = {
            "created": 1348286560,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1348286302,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "*****@*****.**",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.deleted"
        }
        event = Event.objects.create(stripe_id=msg["id"],
                                     kind="customer.deleted",
                                     livemode=True,
                                     webhook_message=msg,
                                     validated_message=msg,
                                     valid=True)
        event.process()
        self.assertEquals(event.customer, self.customer)
        self.assertEquals(event.customer.subscriber, None)
        self.assertTrue(event.processed)

    def test_invalid_event_kind(self):
        """Should just fail silently and not do anything."""
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="fake.event.kind",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)

        event.process()
        self.assertTrue(event.processed)

    @patch('djstripe.models.EventProcessingException.log')
    @patch('djstripe.models.Event.send_signal',
           side_effect=stripe.StripeError())
    def test_stripe_error(self, send_signal_mock, event_exception_log):
        event = Event.objects.create(stripe_id=self.message["id"],
                                     kind="fake.event.kind",
                                     webhook_message=self.message,
                                     validated_message=self.message,
                                     valid=True)

        event.process()
        self.assertTrue(event_exception_log.called)
        self.assertFalse(event.processed)