def test_process_exception_is_logged(self, ProcessWebhookMock, ValidateMock, LinkMock): # note: we choose an event type for which we do no processing event = Event.objects.create(kind="account.application.deauthorized", webhook_message={}, valid=True, processed=False) ProcessWebhookMock.side_effect = stripe.StripeError("Message", "error") with self.assertRaises(stripe.StripeError): AccountApplicationDeauthorizeWebhook(event).process() self.assertTrue(EventProcessingException.objects.filter(event=event).exists())
def test_cancel_error(self, cancel_mock): cancel_mock.side_effect = stripe.StripeError("foo") self.client.login(username=self.user.username, password=self.password) response = self.client.post(reverse("payments_ajax_cancel"), {}, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(cancel_mock.call_count, 1) self.assertEqual(response.context['error'], 'foo')
def test_post_on_error(self, CancelMock): CancelMock.side_effect = stripe.StripeError("Bad Foo", "Param", "CODE") self.client.login(username=self.user.username, password=self.password) response = self.client.post( reverse("pinax_stripe_subscription_delete", args=[self.subscription.pk]), {}) self.assertEquals(response.status_code, 200) self.assertTrue("errors" in response.context_data)
def test_post_no_card(self, stripe_create_customer_mock, update_card_mock): update_card_mock.side_effect = stripe.StripeError( "Invalid source object:") response = self.client.post(self.url) update_card_mock.assert_called_once_with(self.user.customer, None) self.assertIn("stripe_error", response.context) self.assertIn("Invalid source object:", response.context["stripe_error"])
def test_change_plan_stripe_error(self, subscribe_mock): subscribe_mock.side_effect = stripe.StripeError( "Bad card", "Param", "CODE") self.client.login(username=self.user.username, password=self.password) response = self.client.post(reverse("payments_ajax_change_plan"), {"plan": "premium"}, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(subscribe_mock.call_count, 1) self.assertEqual(response.status_code, 200)
def test_delete_saved_card(rf, stripe_payment_processor): shop = factories.get_default_shop() user = factories.create_random_user() contact = get_person_contact(user) view = StripeSavedPaymentInfoView.as_view() delete_view = StripeDeleteSavedPaymentInfoView.as_view() # retrieve the saved card view request = apply_request_middleware(rf.get("/"), customer=contact, shop=shop, user=user) response = view(request) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "Save your card details for a faster checkout. You can change or delete it at any time." in content def return_stripe_mock_data(*args, **kwargs): return StripeCustomerData(**CUSTOMER_MOCK_DATA) with mock.patch("stripe.Customer.retrieve", new=return_stripe_mock_data): with mock.patch("stripe.Customer.modify", new=return_stripe_mock_data): with mock.patch("stripe.Customer.create", new=return_stripe_mock_data): # attach payment details request = apply_request_middleware(rf.post("/", { "stripeToken": "xpto" }), customer=contact, shop=shop, user=user) response = view(request) assert response.status_code == 302 assert response.url.endswith(reverse("shuup:stripe_saved_payment")) # make sure there is stripe customer assert StripeCustomer.objects.filter(contact=contact, customer_token=CUSTOMER_MOCK_DATA["id"]).exists() def get_delete_mock(): mock_for_delete = mock.Mock(wraps=StripeCustomerData(**CUSTOMER_MOCK_DATA)) mock_for_delete.sources = mock.Mock() mock_for_delete.sources.retrieve = mock.Mock() return mock_for_delete with mock.patch("stripe.Customer.retrieve") as mocked: mock_for_delete = get_delete_mock() mocked.return_value = mock_for_delete # Delete the source request = apply_request_middleware(rf.post("/", { "source_id": CUSTOMER_MOCK_DATA["sources"]["data"][0]["id"] }), customer=contact, shop=shop, user=user) response = delete_view(request) mock_for_delete.sources.retrieve.delete.asset_called() # delete with error mock_for_delete = get_delete_mock() mock_for_delete.sources.retrieve.side_effect = stripe.StripeError("dummy") mocked.return_value = mock_for_delete response = delete_view(request) mock_for_delete.sources.retrieve.delete.asset_called()
def test_post_on_error(self, CreateMock): Customer.objects.create(stripe_id="cus_1", user=self.user) CreateMock.side_effect = stripe.StripeError("Bad Mojo", "Param", "CODE") self.client.login(username=self.user.username, password=self.password) response = self.client.post( reverse("pinax_stripe_subscription_create"), {"plan": self.plan.id}) self.assertEquals(response.status_code, 200) self.assertTrue("errors" in response.context_data)
def test_post_no_card(self, stripe_customer_mock, update_card_mock, subscribe_mock): update_card_mock.side_effect = stripe.StripeError( "Invalid source object:") response = self.client.post(self.url, {"plan": "test0"}) self.assertEqual(200, response.status_code) self.assertIn("form", response.context) self.assertIn("Invalid source object:", response.context["form"].errors["__all__"])
def test_post_card_error(self, stripe_create_customer_mock, update_card_mock): update_card_mock.side_effect = stripe.StripeError( "An error occurred while processing your card.") response = self.client.post(self.url, {"stripe_token": "pie"}) update_card_mock.assert_called_once_with(self.user.customer, "pie") self.assertIn("stripe_error", response.context) self.assertIn("An error occurred while processing your card.", response.context["stripe_error"])
def test_process_exception_is_logged(self, ProcessWebhookMock, ValidateMock, LinkMock): event = Event.objects.create(kind="account.updated", webhook_message={}, valid=True, processed=False) ProcessWebhookMock.side_effect = stripe.StripeError("Message", "error") AccountUpdatedWebhook(event).process() self.assertTrue( EventProcessingException.objects.filter(event=event).exists())
def test_change_sub_stripe_error(self, subscribe_mock): subscribe_mock.side_effect = stripe.StripeError( "No such plan: test_id_3") self.assertTrue(self.client.login(username="******", password="******")) response = self.client.post(self.url, {"plan": "test_deletion"}) self.assertEqual(200, response.status_code) self.assertIn("form", response.context) self.assertIn("No such plan: test_id_3", response.context["form"].errors["__all__"])
def test_process_event_error(event_retrieve, event): event_retrieve.return_value = get_mock_resource("Event") handler = mock.Mock() handler.side_effect = stripe.StripeError(message="Bad Request") event_type, event_subtype = event.event_type.split(".", 1) webhooks.register(event_type)(handler) event.process() assert event.verified is True assert event.processed is False handler.assert_called_with(event, event.source["data"], event_subtype)
def test_subscribe_error(self, create_cus_mock, upd_card_mock, subscribe_mock): self.client.login(username=self.user.username, password=self.password) upd_card_mock.side_effect = stripe.StripeError("foo") response = self.client.post( reverse("payments_ajax_subscribe"), {"plan": "premium", "stripe_token": "XXXXX"}, HTTP_X_REQUESTED_WITH="XMLHttpRequest" ) self.assertEqual(create_cus_mock.call_count, 0) self.assertEqual(upd_card_mock.call_count, 1) self.assertEqual(subscribe_mock.call_count, 0) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['error'], 'foo')
def change_card_ajax(request): """""" if request.POST.get("stripe_token", None): customer = request.user.customer send_invoice = customer.card_fingerprint == "" customer.update_card(request.POST.get("stripe_token")) if send_invoice: customer.send_invoice() customer.retry_unpaid_invoices() messages.success( request, 'Les informations de la carte ont été modifié avec succès.') return JSONResponse({'message': 'Carte mise à jour.'}) else: raise stripe.StripeError('Invalid Stripe token')
def set_plan(self, customer, subscription, plan, coupon): elle.log.trace( 'set plan (customer: %s, subscription: %s, plan: %s, coupon: %s)' % (customer['email'], subscription, plan, coupon)) assert self.__in_with >= 0 if coupon is not None and not self.coupon_applicable(plan_id=plan, coupon_id=coupon): raise stripe.StripeError( message='coupon %s cannot be used for this plan' % coupon) if subscription is None: elle.log.trace('create subscription') subscription = customer.subscriptions.create(plan=plan, coupon=coupon) if coupon: subscription.metadata = {'coupons': '1', 'coupon_1': coupon} elle.log.debug('newly created subscription: %s' % subscription) else: elle.log.debug('update subscription') subscription.plan = plan Stripe.apply_coupon(subscription, coupon) return subscription
def apply_coupon(subscription, coupon_id): """ Apply a coupon to the subscription if not already used. subscription - The current subscription. coupon - The coupon id. """ if coupon_id is not None: number_of_coupons = 0 if 'coupons' in subscription.metadata: number_of_coupons = int(subscription.metadata['coupons']) previous_coupons = [ subscription.metadata['coupon_%s' % coupon] for coupon in range(1, number_of_coupons + 1) ] if coupon_id in previous_coupons: raise stripe.StripeError(message='coupon %s already used' % coupon_id) subscription.metadata.update({ 'coupons': number_of_coupons + 1, 'coupon_%s' % (number_of_coupons + 1): coupon_id, }) subscription.coupon = coupon_id
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)
def raise_stripe_exc(*args, **kwargs): raise stripe.StripeError("DUMMY")
def test_verify_event_error(event_retrieve, event): event_retrieve.side_effect = stripe.StripeError( message="Could not find event.") event.verify() assert event.verified is False assert 0 < event.processing_errors.count()