Index: main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_demo_provider.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_demo_provider.py	(revision 12671)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_demo_provider.py	(revision 12671)
@@ -0,0 +1,61 @@
+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
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_payment.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_payment.py	(revision 12498)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_payment.py	(revision 12671)
@@ -17,16 +17,18 @@
 ##
 import datetime
+import decimal
 import re
 import unittest
-from zope.component import getUtilitiesFor, getSiteManager
+from zope.component import getUtilitiesFor, getSiteManager, queryUtility
 from zope.interface import implements
 from zope.interface.verify import verifyClass, verifyObject
 from waeup.ikoba.payments.interfaces import (
     IPayment, STATE_UNPAID, STATE_PAID, STATE_FAILED,
-    IPaymentGatewayService, IPaymentItem
+    IPaymentGatewayService, IPaymentItem, IPaymentGatewayServicesLister,
     )
 from waeup.ikoba.payments.payment import (
     Payment, get_payment_providers, PaymentItem,
     )
+from waeup.ikoba.testing import (FunctionalLayer, FunctionalTestCase)
 
 
@@ -58,4 +60,19 @@
         assert result.keys() == ['some_name', ]
         assert result['some_name'] is fake_util
+
+
+class FunctionalHelperTests(FunctionalTestCase):
+
+    layer = FunctionalLayer
+
+    def test_services_lister_is_registered(self):
+        # a lister of gateway services is registered on startup
+        util = queryUtility(IPaymentGatewayServicesLister)
+        assert util is not None
+
+    def test_services_are_really_listed(self):
+        # we can really get locally registered gateways when calling
+        util = queryUtility(IPaymentGatewayServicesLister)
+        assert len(util()) > 0
 
 
@@ -113,4 +130,51 @@
         assert p1.state == STATE_FAILED
 
+    def test_add_payment_item(self):
+        # we can add payment items
+        p1 = Payment()
+        item1 = PaymentItem()
+        result = p1.add_payment_item(item1)
+        assert len(p1) == 1  # do not make assumptions about result content
+        assert isinstance(result, basestring)
+
+    def test_add_payment_item_multiple(self):
+        # we can add several items
+        p1 = Payment()
+        item1 = PaymentItem()
+        item2 = PaymentItem()
+        result1 = p1.add_payment_item(item1)
+        result2 = p1.add_payment_item(item2)
+        assert len(p1) == 2  # do not make assumptions about result content
+        assert isinstance(result1, basestring)
+        assert isinstance(result2, basestring)
+
+    def test_amount(self):
+        # the amount of a payment is the sum of amounts of its items
+        p1 = Payment()
+        item1 = PaymentItem()
+        item2 = PaymentItem()
+        p1.add_payment_item(item1)
+        p1.add_payment_item(item2)
+        item1.amount = decimal.Decimal("12.25")
+        item2.amount = decimal.Decimal("0.5")
+        assert p1.amount == decimal.Decimal("12.75")
+
+    def test_amount_negative(self):
+        # we can sum up negative numbers
+        p1 = Payment()
+        item1 = PaymentItem()
+        item2 = PaymentItem()
+        p1.add_payment_item(item1)
+        p1.add_payment_item(item2)
+        item1.amount = decimal.Decimal("2.21")
+        item2.amount = decimal.Decimal("-3.23")
+        assert p1.amount == decimal.Decimal("-1.02")
+
+    def test_amount_empty(self):
+        # the amount of zero items is 0.00.
+        p1 = Payment()
+        assert p1.amount == decimal.Decimal("0.00")
+        assert isinstance(p1.amount, decimal.Decimal)
+
 
 class PaymentItemTests(unittest.TestCase):
