import decimal
from zope.interface.verify import verifyClass, verifyObject
from waeup.ikoba.testing import (
    FunctionalLayer, FunctionalTestCase,
    )
from waeup.ikoba.payments.interfaces import (
    IPaymentGatewayService, IPayment, STATE_UNPAID,
    )
from waeup.ikoba.payments.payment import Payer, PaymentItem, Payee
from waeup.ikoba.payments.demo_provider import (
    DemoCreditcardPaymentService,
    )


class DemoCreditcarPaymentServiceTests(FunctionalTestCase):

    layer = FunctionalLayer

    def test_iface(self):
        # we fullfill all interface contracts
        service = DemoCreditcardPaymentService()
        verifyClass(IPaymentGatewayService, DemoCreditcardPaymentService)
        verifyObject(IPaymentGatewayService, service)

    def test_create_payment(self):
        # we can get payments from payment gateways
        service = DemoCreditcardPaymentService()
        payer, payment_item, payee = Payer(), PaymentItem(), Payee()
        payer.payer_id = u'SOME_PAYER_ID'
        result = service.create_payment(payer, [], payee)
        assert IPayment.providedBy(result)
        assert result.gateway_service == u'demo_creditcard'
        assert result.state == STATE_UNPAID
        assert len(result) == 0  # no items stored

    def test_create_payment_honors_payment_item(self):
        # we inspect payment items and take their values
        service = DemoCreditcardPaymentService()
        payer, payment_item, payee = Payer(), PaymentItem(), Payee()
        payment_item.item_id = u'SOME_ITEM_ID'
        payer.payer_id = u'SOME_PAYER_ID'
        payment_item.amount = decimal.Decimal("300.99")
        result = service.create_payment(payer, [payment_item], payee)
        self.assertEqual(result.amount, payment_item.amount)
        assert len(result) == 1

    def test_create_payment_honors_payer(self):
        # we inspect payers when creating their payments
        service = DemoCreditcardPaymentService()
        payer, payment_item, payee = Payer(), PaymentItem(), Payee()
        payment_item.item_id = u'SOME_ITEM_ID'
        payer.payer_id = u'SOME_PAYER_ID'
        result = service.create_payment(payer, [payment_item], payee)
        assert result.payer_id == payer.payer_id

    def test_get_service_by_utility_name(self):
        # we can get the demo credit card service by its utility name
        from zope.component import queryUtility
        service = queryUtility(
            IPaymentGatewayService, name="demo_creditcard")
        assert service is not None
