Source code for example_checkout.tests.test_payment_run

# -*- encoding: utf-8 -*-
import pytest

from datetime import date
from dateutil.relativedelta import relativedelta
from decimal import Decimal
from unittest import mock

from checkout.models import (
    CheckoutError,
    CheckoutState,
    PaymentRun,
    PaymentRunItem,
)
from checkout.tests.factories import (
    CustomerFactory,
    ObjectPaymentPlanFactory,
    ObjectPaymentPlanInstalmentFactory,
)
from example_checkout.tests.factories import SalesLedgerFactory
from mail.models import Message
from mail.tests.factories import NotifyFactory


def _instalment():
    """Create an instalment."""
    return ObjectPaymentPlanInstalmentFactory(
        object_payment_plan=ObjectPaymentPlanFactory(
            content_object=SalesLedgerFactory()
        ),
        state=CheckoutState.objects.pending,
    )


[docs]@pytest.mark.django_db def test_item_count(): obj = PaymentRun.objects.create_payment_run() PaymentRunItem.objects.create_payment_run_item(obj, _instalment()) PaymentRunItem.objects.create_payment_run_item(obj, _instalment()) assert 2 == obj.item_count()
[docs]@pytest.mark.django_db def test_item_count_zero(): obj = PaymentRun.objects.create_payment_run() assert 0 == obj.item_count()
[docs]@pytest.mark.django_db def test_manager(): obj = PaymentRun.objects.create_payment_run() assert date.today() == obj.created.date()
[docs]@pytest.mark.django_db def test_process_payments(mocker): """Process payments.""" mocker.patch("stripe.Charge.create") mocker.patch("stripe.Customer.create") today = date.today() install = ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("2"), count=2, object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), state=CheckoutState.objects.pending, ) CustomerFactory( email=install.object_payment_plan.content_object.checkout_email ) NotifyFactory() assert (1, 0) == PaymentRun.objects.process_payments() install.refresh_from_db() assert CheckoutState.objects.success == install.state assert 1 == install.retry_count # payment run assert 1 == PaymentRun.objects.count() payment_run = PaymentRun.objects.first() assert 1 == payment_run.paymentrunitem_set.count() payment_run_item = payment_run.paymentrunitem_set.first() assert install.pk == payment_run_item.instalment.pk assert payment_run_item.checkout is not None assert CheckoutState.SUCCESS == payment_run_item.checkout.state.slug # mail assert 1 == Message.objects.count() message = Message.objects.first() assert "Payment plan activity update" in message.subject assert "Processed 1 payment transaction" in message.description assert "failed" not in message.description
[docs]@pytest.mark.django_db def test_process_payments_retry(mocker): """Process various payments.""" mocker.patch("stripe.Charge.create") mocker.patch("stripe.Customer.create") today = date.today() install_1 = ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=1), amount=Decimal("1"), count=2, object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) install_2 = ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("2"), count=2, object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), state=CheckoutState.objects.fail, ) install_3 = ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-2), amount=Decimal("3"), count=2, object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), retry_count=1, ) CustomerFactory( email=install_2.object_payment_plan.content_object.checkout_email ) CustomerFactory( email=install_3.object_payment_plan.content_object.checkout_email ) NotifyFactory() assert (2, 0) == PaymentRun.objects.process_payments() # check install_1.refresh_from_db() assert CheckoutState.objects.pending == install_1.state assert install_1.retry_count is None install_2.refresh_from_db() assert CheckoutState.objects.success == install_2.state assert 1 == install_2.retry_count install_3.refresh_from_db() assert CheckoutState.objects.success == install_3.state assert 2 == install_3.retry_count # payment run assert 1 == PaymentRun.objects.count() payment_run = PaymentRun.objects.first() assert 2 == payment_run.paymentrunitem_set.count() # mail assert 1 == Message.objects.count() message = Message.objects.first() assert "Payment plan activity update" in message.subject assert "Processed 2 payment transaction" in message.description assert "failed" not in message.description
[docs]@pytest.mark.django_db def test_process_payments_fail(mocker): """Process payments.""" with mock.patch("stripe.Customer.create") as mock_customer: mock_customer.side_effect = CheckoutError("Mock") today = date.today() install = ObjectPaymentPlanInstalmentFactory( due=today + relativedelta(days=-1), amount=Decimal("1"), object_payment_plan=ObjectPaymentPlanFactory( content_object=SalesLedgerFactory() ), ) CustomerFactory( email=install.object_payment_plan.content_object.checkout_email ) NotifyFactory() assert (1, 1) == PaymentRun.objects.process_payments() # check install.refresh_from_db() assert install.state == CheckoutState.objects.fail assert 1 == Message.objects.count() message = Message.objects.first() assert "Payment plan activity update" in message.subject assert "Processed 1 payment transaction" in message.description assert "1 failed transaction" in message.description
[docs]@pytest.mark.django_db def test_str(): obj = PaymentRun.objects.create_payment_run() value = str(obj) assert "Payment Run" in value assert str(obj.pk) in value assert "created" in value