# Path: billing/psp.py
# class PreconditionError(Exception):
#     pass
# 
# def charge_credit_card(credit_card_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#     """
#     :param credit_card_psp_object: an instance representing the credit card in the psp
#     :param amount: the amount to charge
#     :param client_ref: a reference that will appear on the customer's credit card report
#     :return: a tuple (success, payment_psp_object)
#     """
#     logger.debug('charge-credit-card', credit_card_psp_object=credit_card_psp_object, amount=amount,
#                  client_ref=client_ref)
#     if amount.amount <= 0:
#         raise PreconditionError('Can only charge positive amounts')
#     psp = psp_for_model_instance(credit_card_psp_object)
#     return psp.charge_credit_card(credit_card_psp_object, amount, client_ref)
# 
# def refund_payment(payment_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#     """
#     :param payment_psp_object: an instance representing the original payment in the psp
#     :param amount: the amount to refund
#     :param client_ref: a reference that will appear on the customer's credit card statement
#     :return: a tuple (success, refund_psp_object)
#     """
#     logger.debug('refund-payment', payment_psp_object=payment_psp_object, amount=amount, client_ref=client_ref)
#     if amount.amount <= 0:
#         raise PreconditionError('Can only refund positive amounts')
#     psp = psp_for_model_instance(payment_psp_object)
#     return psp.refund_payment(payment_psp_object, amount, client_ref)
# 
# def register(psp: PSP) -> None:
#     for model_class in psp.model_classes():
#         _registry[model_class] = psp
# 
# def unregister(psp: PSP) -> None:
#     for model_class in psp.model_classes():
#         del _registry[model_class]
# 
# Path: tests/models.py
# class MyPSPCreditCard(models.Model):
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     token = models.CharField(max_length=20)
# 
# class MyPSPPayment(models.Model):
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     payment_ref = models.CharField(max_length=20)
# 
# Path: tests/my_psp.py
# class MyPSP(PSP):
#     """
#     Always succeeds, and remembers how it was invoked (like a mock)
#     """
# 
#     def __init__(self):
#         self.charges = []
#         self.refunds = []
# 
#     def model_classes(self):
#         return [MyPSPPayment, MyPSPCreditCard]
# 
#     def charge_credit_card(self, credit_card_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#         self.charges.append(dict(amount=amount, client_ref=client_ref))
#         payment = MyPSPPayment.objects.create(payment_ref='payment_12345')
#         return True, payment
# 
#     def refund_payment(self, payment_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#         """ Always succeeds
#         """
#         self.refunds.append(dict(amount=amount, client_ref=client_ref))
#         refund = MyPSPRefund.objects.create(refund_ref='refund_12345')
#         return True, refund


from django.test import TestCase
from moneyed import Money
from pytest import raises
from billing.psp import PreconditionError, charge_credit_card, refund_payment, register, unregister
from .models import MyPSPCreditCard, MyPSPPayment
from .my_psp import MyPSP



class PSPTest(TestCase):
    def setUp(self):
        register(MyPSP())
        self.psp_credit_card = MyPSPCreditCard.objects.create(token='atoken')
        self.psp_payment = MyPSPPayment.objects.create(payment_ref='apaymentref')

    def tearDown(self):

# Path: billing/psp.py
# class PreconditionError(Exception):
#     pass
# 
# def charge_credit_card(credit_card_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#     """
#     :param credit_card_psp_object: an instance representing the credit card in the psp
#     :param amount: the amount to charge
#     :param client_ref: a reference that will appear on the customer's credit card report
#     :return: a tuple (success, payment_psp_object)
#     """
#     logger.debug('charge-credit-card', credit_card_psp_object=credit_card_psp_object, amount=amount,
#                  client_ref=client_ref)
#     if amount.amount <= 0:
#         raise PreconditionError('Can only charge positive amounts')
#     psp = psp_for_model_instance(credit_card_psp_object)
#     return psp.charge_credit_card(credit_card_psp_object, amount, client_ref)
# 
# def refund_payment(payment_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#     """
#     :param payment_psp_object: an instance representing the original payment in the psp
#     :param amount: the amount to refund
#     :param client_ref: a reference that will appear on the customer's credit card statement
#     :return: a tuple (success, refund_psp_object)
#     """
#     logger.debug('refund-payment', payment_psp_object=payment_psp_object, amount=amount, client_ref=client_ref)
#     if amount.amount <= 0:
#         raise PreconditionError('Can only refund positive amounts')
#     psp = psp_for_model_instance(payment_psp_object)
#     return psp.refund_payment(payment_psp_object, amount, client_ref)
# 
# def register(psp: PSP) -> None:
#     for model_class in psp.model_classes():
#         _registry[model_class] = psp
# 
# def unregister(psp: PSP) -> None:
#     for model_class in psp.model_classes():
#         del _registry[model_class]
# 
# Path: tests/models.py
# class MyPSPCreditCard(models.Model):
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     token = models.CharField(max_length=20)
# 
# class MyPSPPayment(models.Model):
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     payment_ref = models.CharField(max_length=20)
# 
# Path: tests/my_psp.py
# class MyPSP(PSP):
#     """
#     Always succeeds, and remembers how it was invoked (like a mock)
#     """
# 
#     def __init__(self):
#         self.charges = []
#         self.refunds = []
# 
#     def model_classes(self):
#         return [MyPSPPayment, MyPSPCreditCard]
# 
#     def charge_credit_card(self, credit_card_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#         self.charges.append(dict(amount=amount, client_ref=client_ref))
#         payment = MyPSPPayment.objects.create(payment_ref='payment_12345')
#         return True, payment
# 
#     def refund_payment(self, payment_psp_object: Model, amount: Money, client_ref: str) -> Tuple[bool, Model]:
#         """ Always succeeds
#         """
#         self.refunds.append(dict(amount=amount, client_ref=client_ref))
#         refund = MyPSPRefund.objects.create(refund_ref='refund_12345')
#         return True, refund


# Path: tests/test_psp.py
from django.test import TestCase
from moneyed import Money
from pytest import raises
from billing.psp import PreconditionError, charge_credit_card, refund_payment, register, unregister
from .models import MyPSPCreditCard, MyPSPPayment
from .my_psp import MyPSP




class PSPTest(TestCase):
    def setUp(self):
        register(MyPSP())
        self.psp_credit_card = MyPSPCreditCard.objects.create(token='atoken')
        self.psp_payment = MyPSPPayment.objects.create(payment_ref='apaymentref')

    def tearDown(self):

        unregister(MyPSP())