Résolue

Django : mock (pytest) + stripe

# Stripe # Django # Tests unitaires

Gabriel Trouvé

Mentor

Bonjour,

J'ai vu pas mal de choses sur le mock. Du coup je ne sais pas trop comment m'y prendre.
J'utilise pytest-django.

Je voudrais tester mon processus stripe.

Typiquement j'ai un checkout, et un webhook :

def create_checkout_session(request, pk_reservation):
    user = request.user
    reservation = get_object_or_404(Reservation, pk=pk_reservation)
    options: ReservationOption = ReservationOption.objects.filter(reservation=reservation)
    vats: Tva = Tva.objects.all()
    reservation_verification_access(user, reservation)
    line_items = []
    tva_20 = "txr_1OeMXPJsRK4NkkZV2g1hfpHz"
    vat_dict = {vat.rate: vat.stripe_id for vat in vats}

    if not reservation.slot_in_day:
        line_items.append({
            'price_data': {
                'currency': 'eur',
                'product_data': {
                    'name': f'{reservation} sans option',
                },
                'unit_amount': reservation.total_price_night_reservation * 100,
            },
            'quantity': 1,
            'tax_rates': [tva_20],
        })
    else:
        line_items.append({
            'price_data': {
                'currency': 'eur',
                'product_data': {
                    'name': f'{reservation} sans option',
                },
                'unit_amount': reservation.get_total_price_slot_reservation * 100,
            },
            'quantity': 1,
            'tax_rates': [tva_20],
        })
    for option in options:
        tax = vat_dict.get(option.option.tva_code)
        if tax is None:
            tax = tva_20

        line_items.append({
            'price_data': {
                'currency': 'eur',
                'product_data': {
                    'name': f'{option.option.name}',
                },
                'unit_amount': option.get_price * 100,
            },
            'quantity': option.quantity,
            'tax_rates': [tax],
        })

    checkout_data = {
        "metadata": {"reservation_id": str(reservation.pk), "reservation_order": reservation.order},
        "locale": "fr",
        "line_items": line_items,
        # "automatic_tax": {'enabled': True},
        "billing_address_collection": 'required',
        "mode": 'payment',
        "invoice_creation": {"enabled": True},
        "success_url": request.build_absolute_uri(
            reverse("spa:checkout-success", kwargs={"pk_reservation": reservation.pk})),
        "cancel_url": request.build_absolute_uri(
            reverse("spa:checkout-cancel", kwargs={"pk_reservation": reservation.pk}))
    }
    if user.stripe_id:
        checkout_data["customer"] = user.stripe_id
        checkout_data["customer_update"] = {"shipping": "auto"}
    else:
        checkout_data["customer_email"] = user.email
        checkout_data["customer_creation"] = "always"
    session = stripe.checkout.Session.create(**checkout_data)

    return redirect(session.url, code=303)


def checkout_success(request, pk_reservation):
    reservation = get_object_or_404(Reservation, pk=pk_reservation)
    reservation_verification_access(request.user, reservation)
    messages.add_message(request, level=messages.INFO,
                         message=f"Votre réservation numéro {reservation.order} a bien été payée.")
    return redirect("spa:summary")


def checkout_cancel(request, pk_reservation):
    reservation = get_object_or_404(Reservation, pk=pk_reservation)
    reservation_verification_access(request.user, reservation)
    messages.add_message(request, level=messages.INFO,
                         message=f"Votre réservation numéro {reservation.order} n'a pas été payée.")
    return redirect("spa:summary")


@csrf_exempt
def stripe_webhook(request):
    # ./stripe listen --forward-to 127.0.0.1:8000/spa/stripe-webhook/
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    endpoint_secret = settings.ENDPOINT_KEY
    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)

    if event["type"] == "checkout.session.completed":
        data = event["data"]["object"]
        user = update_user(data)
        update_reservation(data, user)

    # Passed signature verification
    return HttpResponse(status=200)

Ma question c'est, quelle est la bonne façon de mocker ça ?
Car j'ai vu qu'avec pytest on pouvait mocker avec unitest, ou on peut installer pytest mock.
Et j'ai vu aussi différentes façon de mocker.

C'est la première fois que je suis amené à le faire et j'avoue que je ne suis pas sûr de moi ^^

Merci d'avance ! :)

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.