Ignore:
Timestamp:
12 Mar 2015, 05:29:43 (10 years ago)
Author:
uli
Message:

Merge changes from uli-payments back into trunk.

Location:
main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_demo_provider.py

    r12671 r12741  
    1 import decimal
     1import unittest
     2from zope.component import queryUtility
     3from zope.component.hooks import setSite
    24from zope.interface.verify import verifyClass, verifyObject
    35from waeup.ikoba.testing import (
     
    79    IPaymentGatewayService, IPayment, STATE_UNPAID,
    810    )
    9 from waeup.ikoba.payments.payment import Payer, PaymentItem, Payee
     11from waeup.ikoba.app import Company
     12from waeup.ikoba.payments.payment import Payer, Payee, Payment
    1013from waeup.ikoba.payments.demo_provider import (
    11     DemoCreditcardPaymentService,
     14    DemoCreditcardPaymentService, RE_CC_NUMBER, RE_CSC,
    1215    )
     16from waeup.ikoba.payments.tests.test_payment import FakePayer, FakePayable
    1317
    1418
    15 class DemoCreditcarPaymentServiceTests(FunctionalTestCase):
     19class TestDemoProviderHelpers(unittest.TestCase):
     20
     21    def test_re_cc_number(self):
     22        # we recognize valid numbers
     23        assert RE_CC_NUMBER.match('a') is None
     24        assert RE_CC_NUMBER.match('12345678') is None
     25        assert RE_CC_NUMBER.match('1234a5678') is None
     26        assert RE_CC_NUMBER.match('132456789') is not None
     27        assert RE_CC_NUMBER.match('123456789012345') is not None
     28
     29    def test_re_csc(self):
     30        # we recognize security numbers
     31        assert RE_CSC.match('12') is None
     32        assert RE_CSC.match('123') is not None
     33        assert RE_CSC.match('1234') is not None
     34        assert RE_CSC.match('12345') is None
     35        assert RE_CSC.match('12A2') is None
     36
     37
     38class DemoCreditcardPaymentServiceTests(FunctionalTestCase):
    1639
    1740    layer = FunctionalLayer
     41
     42    def setUp(self):
     43        super(DemoCreditcardPaymentServiceTests, self).setUp()
     44        self.app = Company()
     45        self.getRootFolder()['app'] = self.app
     46        setSite(self.app)
    1847
    1948    def test_iface(self):
     
    2655        # we can get payments from payment gateways
    2756        service = DemoCreditcardPaymentService()
    28         payer, payment_item, payee = Payer(), PaymentItem(), Payee()
     57        payer, payable, payee = Payer(), FakePayable(), Payee()
    2958        payer.payer_id = u'SOME_PAYER_ID'
    30         result = service.create_payment(payer, [], payee)
     59        result = service.create_payment(payer, payable, payee)
    3160        assert IPayment.providedBy(result)
    3261        assert result.gateway_service == u'demo_creditcard'
    3362        assert result.state == STATE_UNPAID
    34         assert len(result) == 0  # no items stored
    35 
    36     def test_create_payment_honors_payment_item(self):
    37         # we inspect payment items and take their values
    38         service = DemoCreditcardPaymentService()
    39         payer, payment_item, payee = Payer(), PaymentItem(), Payee()
    40         payment_item.item_id = u'SOME_ITEM_ID'
    41         payer.payer_id = u'SOME_PAYER_ID'
    42         payment_item.amount = decimal.Decimal("300.99")
    43         result = service.create_payment(payer, [payment_item], payee)
    44         self.assertEqual(result.amount, payment_item.amount)
    45         assert len(result) == 1
    4663
    4764    def test_create_payment_honors_payer(self):
    4865        # we inspect payers when creating their payments
    4966        service = DemoCreditcardPaymentService()
    50         payer, payment_item, payee = Payer(), PaymentItem(), Payee()
    51         payment_item.item_id = u'SOME_ITEM_ID'
     67        payer, payable, payee = Payer(), FakePayable(), Payee()
    5268        payer.payer_id = u'SOME_PAYER_ID'
    53         result = service.create_payment(payer, [payment_item], payee)
     69        result = service.create_payment(payer, payable, payee)
    5470        assert result.payer_id == payer.payer_id
    5571
    5672    def test_get_service_by_utility_name(self):
    5773        # we can get the demo credit card service by its utility name
    58         from zope.component import queryUtility
    5974        service = queryUtility(
    6075            IPaymentGatewayService, name="demo_creditcard")
    6176        assert service is not None
     77
     78    def test_next_step_invalid_id(self):
     79        # we cannot go to non-existent payments
     80        service = DemoCreditcardPaymentService()
     81        result = service.next_step('not-existent-payment-id')
     82        assert result == (None, None)
     83
     84    def test_next_step(self):
     85        # we are redirected to 'index' in the beginning
     86        service = DemoCreditcardPaymentService()
     87        p1 = Payment(FakePayer(), FakePayable())
     88        self.app['payments']['1'] = p1
     89        p_id = p1.payment_id
     90        result = service.next_step(p_id)
     91        assert result == (p1, 'demo_cc1')
  • main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_payment.py

    r12671 r12741  
     1# -*- coding: utf-8 -*-
    12## $Id$
    23##
     
    2021import re
    2122import unittest
    22 from zope.component import getUtilitiesFor, getSiteManager, queryUtility
    23 from zope.interface import implements
     23from zope.component import (
     24    getUtilitiesFor, getSiteManager, queryUtility, getGlobalSiteManager,
     25    )
     26from zope.component.hooks import setSite
     27from zope.interface import implements, implementer
    2428from zope.interface.verify import verifyClass, verifyObject
    2529from waeup.ikoba.payments.interfaces import (
    2630    IPayment, STATE_UNPAID, STATE_PAID, STATE_FAILED,
    2731    IPaymentGatewayService, IPaymentItem, IPaymentGatewayServicesLister,
     32    IPayableFinder, IPayerFinder, IPayable, IPayer,
    2833    )
     34from waeup.ikoba.app import Company
    2935from waeup.ikoba.payments.payment import (
    30     Payment, get_payment_providers, PaymentItem,
     36    Payment, get_payment_providers, PaymentItem, format_payment_item_values,
     37    get_payment, find_payable_from_payable_id, find_payer_from_payer_id,
     38    format_amount,
    3139    )
    3240from waeup.ikoba.testing import (FunctionalLayer, FunctionalTestCase)
     41
     42
     43@implementer(IPayer)
     44class FakePayer(object):
     45
     46    def __init__(
     47        self, payer_id=u'PAYER_01', first_name=u'Anna', last_name='Tester'):
     48        self.payer_id = payer_id
     49        self.first_name = first_name
     50        self.last_name = last_name
     51
     52
     53FAKE_PAYMENT_ITEMS = (
     54    PaymentItem(u'ITEM1', u'Item title 1', decimal.Decimal("1.00")),
     55    PaymentItem(u'ITEM2', u'Item title 2', decimal.Decimal("2.2")),
     56    )
     57
     58
     59@implementer(IPayable)
     60class FakePayable(object):
     61
     62    payable_id = u'id1'
     63    items = (
     64        (u'item 1', decimal.Decimal("1.00")),
     65        (u'item 2', decimal.Decimal("2.12")),
     66        )
     67
     68    def __init__(self, payable_id=u'PAYABLE_01', title=u'title',
     69                 currency=u'USD', payment_items=FAKE_PAYMENT_ITEMS):
     70        self.payable_id = payable_id
     71        self.title = title
     72        self.currency = currency
     73        self.payment_items = payment_items
    3374
    3475
     
    61102        assert result['some_name'] is fake_util
    62103
     104    def test_format_payment_item_values(self):
     105        # we can format lists of payment item values
     106        result = format_payment_item_values(
     107            [(u'Item 1', 'USD', decimal.Decimal("12.123")),
     108             (u'Item 2', 'USD', decimal.Decimal("12.002")),
     109             ], 'USD')
     110        self.assertEqual(
     111            result, [(u'Item 1', 'USD 12.12'),
     112                     (u'Item 2', 'USD 12.00'),
     113                     (u'Total', 'USD 24.12')]
     114            )
     115
     116    def test_format_payment_item_values_req_single_currency(self):
     117        # we require one currency for all items, yet.
     118        self.assertRaises(
     119            ValueError, format_payment_item_values,
     120            [(u'Item 1', 'USD', decimal.Decimal("12.12")),
     121             (u'Item 2', 'EUR', decimal.Decimal("50")),
     122             ],
     123            'USD')
     124
     125    def test_format_amount(self):
     126        # we can make amounts readable
     127        D = decimal.Decimal
     128        self.assertEqual(format_amount(D("0"), 'USD'), u"US$ 0.00")
     129        self.assertEqual(format_amount(D("0.1"), 'EUR'), u"€ 0.10")
     130        self.assertEqual(format_amount(D("-1.2"), 'NGN'), u"₦ -1.20")
     131        self.assertEqual(format_amount(D("1234.5"), 'YEN'), u"YEN 1,234.50")
     132
    63133
    64134class FunctionalHelperTests(FunctionalTestCase):
     
    76146        assert len(util()) > 0
    77147
    78 
    79 class PaymentTests(unittest.TestCase):
     148    def test_get_payment(self):
     149        # we can lookup payments.
     150        self.getRootFolder()['app'] = Company()
     151        app = self.getRootFolder()['app']
     152        setSite(app)
     153        p1 = Payment(FakePayer(), FakePayable())
     154        app['payments']['1'] = p1
     155        p_id = p1.payment_id
     156        result = get_payment(p_id)
     157        self.assertTrue(result is p1)
     158        self.assertTrue(get_payment('not-valid') is None)
     159
     160    def test_find_payable_from_payable_id(self):
     161        # we can find payables.
     162        obj1 = object()
     163        obj2 = object()
     164
     165        class FakeFinder(object):
     166            valid = {'id1': obj1, 'id3': obj2}
     167
     168            def get_payable_by_id(self, the_id):
     169                return self.valid.get(the_id)
     170
     171        finder1 = FakeFinder()
     172        finder1.valid = {'id1': obj1}
     173        finder2 = FakeFinder()
     174        finder2.valid = {'id2': obj2}
     175        gsm = getGlobalSiteManager()
     176        try:
     177            gsm.registerUtility(finder1, provided=IPayableFinder, name='f1')
     178            gsm.registerUtility(finder2, provided=IPayableFinder, name='f2')
     179            result1 = find_payable_from_payable_id('id1')
     180            result2 = find_payable_from_payable_id('id2')
     181            result3 = find_payable_from_payable_id('id3')
     182        finally:
     183            gsm.unregisterUtility(finder1, IPayableFinder)
     184            gsm.unregisterUtility(finder2, IPayableFinder)
     185        self.assertTrue(result1 is obj1)
     186        self.assertTrue(result2 is obj2)
     187        self.assertTrue(result3 is None)
     188
     189    def test_find_payer_from_payer_id(self):
     190        # we can find payables.
     191        obj1 = object()
     192        obj2 = object()
     193
     194        class FakeFinder(object):
     195            valid = {'id1': obj1, 'id3': obj2}
     196
     197            def get_payer_by_id(self, the_id):
     198                return self.valid.get(the_id)
     199
     200        finder1 = FakeFinder()
     201        finder1.valid = {'id1': obj1}
     202        finder2 = FakeFinder()
     203        finder2.valid = {'id2': obj2}
     204        gsm = getGlobalSiteManager()
     205        try:
     206            gsm.registerUtility(finder1, provided=IPayerFinder, name='f1')
     207            gsm.registerUtility(finder2, provided=IPayerFinder, name='f2')
     208            result1 = find_payer_from_payer_id('id1')
     209            result2 = find_payer_from_payer_id('id2')
     210            result3 = find_payer_from_payer_id('id3')
     211        finally:
     212            gsm.unregisterUtility(finder1, IPayerFinder)
     213            gsm.unregisterUtility(finder2, IPayerFinder)
     214        self.assertTrue(result1 is obj1)
     215        self.assertTrue(result2 is obj2)
     216        self.assertTrue(result3 is None)
     217
     218
     219class PaymentTests(FunctionalTestCase):
     220
     221    layer = FunctionalLayer
     222
     223    def setUp(self):
     224        super(PaymentTests, self).setUp()
     225        self.payer = FakePayer()
     226        self.payable = FakePayable()
    80227
    81228    def test_iface(self):
    82229        # Payments fullfill any interface contracts
    83         obj = Payment()
     230        obj = Payment(self.payer, self.payable)
    84231        verifyClass(IPayment, Payment)
    85232        verifyObject(IPayment, obj)
    86233
     234    def test_initial_values(self):
     235        # important attributes are set initially
     236        payer = self.payer
     237        payer.payer_id = u'PAYER_ID'
     238        payable = self.payable
     239        payable.payable_id = u'PAYABLE_ID'
     240        payable.title = u'PAYABLE-TITLE'
     241        payable.currency = 'NGN'
     242        payment = Payment(payer, payable)
     243        assert payment.payer_id == u'PAYER_ID'
     244        assert payment.payable_id == u'PAYABLE_ID'
     245        assert payment.title == u'PAYABLE-TITLE'
     246        assert payment.currency == 'NGN'
     247        assert isinstance(payment.creation_date, datetime.datetime)
     248        assert payment.payment_date is None
     249
    87250    def test_payment_id_unique(self):
    88251        # we get unique payment ids
    89         p1, p2 = Payment(), Payment()
     252        p1 = Payment(self.payer, self.payable)
     253        p2 = Payment(self.payer, self.payable)
    90254        id1, id2 = p1.payment_id, p2.payment_id
    91255        assert id1 != id2
     
    93257    def test_payment_id_format(self):
    94258        # payment ids have a special format: "PAY_<32 hex digits>"
    95         id1 = Payment().payment_id
     259        id1 = Payment(self.payer, self.payable).payment_id
    96260        assert isinstance(id1, basestring)
    97261        assert re.match('PAY_[0-9a-f]{32}', id1)
     
    99263    def test_initial_state_is_unpaid(self):
    100264        # the initial state of payments is <unpaid>
    101         p1 = Payment()
     265        p1 = Payment(self.payer, self.payable)
    102266        assert p1.state == STATE_UNPAID
    103267
    104268    def test_approve(self):
    105269        # we can approve payments
    106         p1 = Payment()
     270        p1 = Payment(self.payer, self.payable)
    107271        p1.approve()
    108272        assert p1.state == STATE_PAID
     
    112276    def test_approve_datetime_given(self):
    113277        # we can give a datetime
    114         p1 = Payment()
     278        p1 = Payment(self.payer, self.payable)
    115279        some_datetime = datetime.datetime(2014, 1, 1, 0, 0, 0)
    116280        p1.approve(payment_date=some_datetime)
     
    120284        # if we do not give a datetime, current one will be used
    121285        current = datetime.datetime.utcnow()
    122         p1 = Payment()
     286        p1 = Payment(self.payer, self.payable)
    123287        p1.approve()
    124288        assert p1.payment_date >= current
     
    126290    def test_mark_failed(self):
    127291        # we can mark payments as failed
    128         p1 = Payment()
     292        p1 = Payment(self.payer, self.payable)
    129293        p1.mark_failed()
    130294        assert p1.state == STATE_FAILED
    131295
    132     def test_add_payment_item(self):
    133         # we can add payment items
    134         p1 = Payment()
    135         item1 = PaymentItem()
    136         result = p1.add_payment_item(item1)
    137         assert len(p1) == 1  # do not make assumptions about result content
    138         assert isinstance(result, basestring)
    139 
    140     def test_add_payment_item_multiple(self):
    141         # we can add several items
    142         p1 = Payment()
    143         item1 = PaymentItem()
    144         item2 = PaymentItem()
    145         result1 = p1.add_payment_item(item1)
    146         result2 = p1.add_payment_item(item2)
    147         assert len(p1) == 2  # do not make assumptions about result content
    148         assert isinstance(result1, basestring)
    149         assert isinstance(result2, basestring)
    150 
    151296    def test_amount(self):
    152297        # the amount of a payment is the sum of amounts of its items
    153         p1 = Payment()
    154         item1 = PaymentItem()
    155         item2 = PaymentItem()
    156         p1.add_payment_item(item1)
    157         p1.add_payment_item(item2)
    158         item1.amount = decimal.Decimal("12.25")
    159         item2.amount = decimal.Decimal("0.5")
     298        payable = self.payable
     299        payable.payment_items[0].amount = decimal.Decimal("12.25")
     300        payable.payment_items[1].amount = decimal.Decimal("0.5")
     301        p1 = Payment(self.payer, self.payable)
    160302        assert p1.amount == decimal.Decimal("12.75")
    161303
    162304    def test_amount_negative(self):
    163305        # we can sum up negative numbers
    164         p1 = Payment()
    165         item1 = PaymentItem()
    166         item2 = PaymentItem()
    167         p1.add_payment_item(item1)
    168         p1.add_payment_item(item2)
    169         item1.amount = decimal.Decimal("2.21")
    170         item2.amount = decimal.Decimal("-3.23")
     306        payable = self.payable
     307        payable.payment_items[0].amount = decimal.Decimal("2.21")
     308        payable.payment_items[1].amount = decimal.Decimal("-3.23")
     309        p1 = Payment(self.payer, payable)
    171310        assert p1.amount == decimal.Decimal("-1.02")
    172311
    173312    def test_amount_empty(self):
    174         # the amount of zero items is 0.00.
    175         p1 = Payment()
    176         assert p1.amount == decimal.Decimal("0.00")
    177         assert isinstance(p1.amount, decimal.Decimal)
     313        # the amount of zero items is None.
     314        payable = FakePayable(payment_items=())
     315        p1 = Payment(self.payer, payable)
     316        self.assertEqual(p1.amount, decimal.Decimal("0.00"))
    178317
    179318
  • main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_paypal.py

    r12498 r12741  
    11741174    def test_store_credit_card_invalid(self):
    11751175        # an exception is raised with invalid credit cards.
    1176         site = self.create_site()
     1176        self.create_site()
    11771177        service = PayPalCreditCardService()
    11781178        credit_card = CreditCard(
     
    12031203        # we can actually create payments
    12041204        service = PayPalCreditCardService()
    1205         site = self.create_site()
     1205        self.create_site()
    12061206        credit_card = self.get_credit_card()
    12071207        result = service.store_credit_card(credit_card)
Note: See TracChangeset for help on using the changeset viewer.