From fb8af7abcb36588d06f28716df5a1b1c08159504 Mon Sep 17 00:00:00 2001 From: Nandika-A Date: Fri, 26 Jan 2024 12:52:19 +0530 Subject: [PATCH 1/3] added exception handling --- donations/views.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/donations/views.py b/donations/views.py index ab08f061a..7e9774882 100644 --- a/donations/views.py +++ b/donations/views.py @@ -27,11 +27,17 @@ def charge(request): if form.is_valid(): amount = int(request.POST["amount"]) currency = request.POST["currency"] - + # key = "" try: customer = stripe.Customer.create( - email=request.POST["email"], name=request.POST["name"], source=request.POST["stripeToken"] + email=request.POST["email"], + name=request.POST["name"], + source=request.POST["stripeToken"], + # idempotency_key=key, ) + except stripe.error.APIConnectionError as err: + request.session["stripe_message"] = err.user_message + return redirect(reverse("donations:error")) except CardError as err: request.session["stripe_message"] = err.user_message return redirect(reverse("donations:error")) From 216162201f0efc6a056fd9361e62c68d8a910a85 Mon Sep 17 00:00:00 2001 From: Nandika-A Date: Fri, 26 Jan 2024 14:19:29 +0530 Subject: [PATCH 2/3] integrated idempotency key --- donations/views.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/donations/views.py b/donations/views.py index 7e9774882..c4663a791 100644 --- a/donations/views.py +++ b/donations/views.py @@ -1,3 +1,5 @@ +import uuid + import stripe from django.conf import settings from django.http import HttpResponseForbidden @@ -27,13 +29,13 @@ def charge(request): if form.is_valid(): amount = int(request.POST["amount"]) currency = request.POST["currency"] - # key = "" + key = uuid.uuid4().hex try: customer = stripe.Customer.create( email=request.POST["email"], name=request.POST["name"], - source=request.POST["stripeToken"], - # idempotency_key=key, + source=request.POST.get("stripeToken"), + idempotency_key=key, ) except stripe.error.APIConnectionError as err: request.session["stripe_message"] = err.user_message From 0e1e389e4835c965fa4620d2aa9c9bf13b9207d4 Mon Sep 17 00:00:00 2001 From: Nandika-A Date: Mon, 29 Jan 2024 20:55:48 +0530 Subject: [PATCH 3/3] Added tests for conection error --- donations/views.py | 4 ++-- tests/donations/test_views.py | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/donations/views.py b/donations/views.py index c4663a791..7bd2b2cab 100644 --- a/donations/views.py +++ b/donations/views.py @@ -5,7 +5,7 @@ from django.http import HttpResponseForbidden from django.shortcuts import redirect, render from django.urls import reverse -from stripe.error import CardError, StripeError +from stripe.error import APIConnectionError, CardError, StripeError from patreonmanager.models import FundraisingStatus @@ -37,7 +37,7 @@ def charge(request): source=request.POST.get("stripeToken"), idempotency_key=key, ) - except stripe.error.APIConnectionError as err: + except APIConnectionError as err: request.session["stripe_message"] = err.user_message return redirect(reverse("donations:error")) except CardError as err: diff --git a/tests/donations/test_views.py b/tests/donations/test_views.py index f586c851e..1fa4696e7 100644 --- a/tests/donations/test_views.py +++ b/tests/donations/test_views.py @@ -1,10 +1,11 @@ import os +from unittest.mock import patch import pytest from django.test import override_settings from django.urls import reverse from pytest_django.asserts import assertContains -from stripe.error import StripeError +from stripe.error import APIConnectionError, StripeError STRIPE_PUBLIC_KEY = os.environ.get("STRIPE_PUBLIC_KEY", "test_public") STRIPE_SECRET_KEY = os.environ.get("STRIPE_SECRET_KEY", "test_public") @@ -62,3 +63,26 @@ def test_sponsors(client, globalpartner, globalpartner2): assert resp.status_code == 200 assertContains(resp, "Django Software Foundation") assertContains(resp, "Caktus Group") + + +@pytest.mark.django_db +def test_charge_post_api_connection_error(client): + # Mock the stripe.Customer.create method to simulate an API connection error + with patch("stripe.Customer.create", side_effect=APIConnectionError("A Network Connection error occured.")): + form_data = { + "name": "Paul Smith", + "email": "paul.smith@djangogirls.org", + "currency": "usd", + "amount": "10", + "stripeToken": "test_code", + } + + response = client.post(reverse("donations:charge"), data=form_data) + + # Check if the response redirects to the error view + assert response.status_code == 302 # 302 is the status code for a redirect + assert response.url == reverse("donations:error") + + # Check if the expected session variable is set + assert "stripe_message" in client.session + assert client.session["stripe_message"] == "A Network Connection error occured."