source: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/tests.py @ 14240

Last change on this file since 14240 was 14230, checked in by Henrik Bettermann, 8 years ago

gbenga ticket #169: Actually, all transactions with value <=5000 attract an Interswitch fee of 1.5% while transactions values >5000 attract a fee of 300 naira.

  • Property svn:keywords set to Id
File size: 37.4 KB
RevLine 
[7894]1## $Id: tests.py 14230 2016-10-27 09:29:58Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[9789]18import os
[9387]19import grok
[10844]20import pytz
21from datetime import datetime, date, timedelta
[7894]22from hurry.workflow.interfaces import IWorkflowState
[9710]23from zope.component import createObject, getUtility
24from zope.catalog.interfaces import ICatalog
[9387]25from zope.event import notify
[10844]26from waeup.kofa.applicants.container import ApplicantsContainer
[9387]27from waeup.kofa.university.faculty import Faculty
28from waeup.kofa.university.department import Department
[7894]29from waeup.kofa.students.tests.test_browser import StudentsFullSetup
[8266]30from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
31from waeup.kofa.configuration import SessionConfiguration
[9347]32from waeup.kwarapoly.testing import FunctionalLayer
[10675]33from waeup.kwarapoly.students.payments import CustomStudentOnlinePayment
[7894]34
[7970]35# Also run tests that send requests to external servers?
36#   If you enable this, please make sure the external services
37#   do exist really and are not bothered by being spammed by a test programme.
[11577]38EXTERNAL_TESTS = False
[7970]39
40def external_test(func):
41    if not EXTERNAL_TESTS:
42        myself = __file__
43        if myself.endswith('.pyc'):
44            myself = myself[:-2]
45        print "WARNING: external tests are skipped!"
46        print "WARNING: edit %s to enable them." % myself
47        return
48    return func
49
50
[8266]51class InterswitchTestsStudents(StudentsFullSetup):
[7929]52    """Tests for the Interswitch payment gateway.
[7894]53    """
54
55    layer = FunctionalLayer
56
[7970]57    def setUp(self):
[8266]58        super(InterswitchTestsStudents, self).setUp()
[9387]59
60        # Create at least one Kwarapoly faculty
61        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
62        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
63        self.certificate2 = createObject('waeup.Certificate')
64        self.certificate2.code = u'CERT2'
65        self.certificate2.application_category = 'basic'
66        self.certificate2.study_mode = 'nd_ft'
67        self.certificate2.start_level = 100
68        self.certificate2.end_level = 300
69        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
70            self.certificate2)
71        # Set study course attributes of test student
72        self.student['studycourse'].certificate = self.certificate2
73        self.student['studycourse'].current_session = 2004
74        self.student['studycourse'].entry_session = 2004
75        self.student['studycourse'].current_verdict = 'A'
76        self.student['studycourse'].current_level = 100
[9392]77        # Set local lga
78        self.student.lga = u'kwara_asa'
[9387]79        # Update the catalog
80        notify(grok.ObjectModifiedEvent(self.student))
81
[13389]82    def test_schoolfee_ticket_creation(self):
[7970]83        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
[7995]84        self.browser.open(self.payments_path)
[7970]85        IWorkflowState(self.student).setState('cleared')
[7995]86        self.browser.open(self.payments_path + '/addop')
[9737]87        self.browser.getControl(name="form.p_category").value = ['schoolfee']
[7970]88        self.browser.getControl("Create ticket").click()
[10675]89        self.assertMatches('...Book and pay for accommodation first...',
90                           self.browser.contents)
91        # We add a fake maint. payment ticket to meet the condition
92        maint_payment = CustomStudentOnlinePayment()
93        self.student['payments']['any_key'] = maint_payment
94        maint_payment.p_category = 'hostel_maintenance'
95        maint_payment.p_state = 'unpaid'
96        maint_payment.p_session = 2004
97        self.browser.getControl(name="form.p_category").value = ['schoolfee']
98        self.browser.getControl("Create ticket").click()
99        self.assertMatches('...Book and pay for accommodation first...',
100                           self.browser.contents)
101        # Ticket must be paid
102        maint_payment.p_state = 'paid'
103        self.browser.getControl(name="form.p_category").value = ['schoolfee']
104        self.browser.getControl("Create ticket").click()
[9436]105        self.assertMatches('...ticket created...',
106                           self.browser.contents)
107        ctrl = self.browser.getControl(name='val_id')
[10675]108        self.value = ctrl.options[1]
[9789]109        self.browser.getLink(self.value).click()
[9436]110        self.assertMatches('...Amount Authorized...',
111                           self.browser.contents)
[14218]112        self.assertTrue('<span>55500.0</span>' in self.browser.contents)
[9436]113        self.payment_url = self.browser.url
[7970]114
115
[8263]116#    def callback_url(self, payment_url, resp, apprAmt):
117#        return payment_url + (
118#            '/isw_callback?echo=' +
119#            '&resp=%s' +
120#            '&desc=Something went wrong' +
121#            '&txnRef=p1331792385335' +
122#            '&payRef=' + '&retRef=' +
123#            '&cardNum=0' +
124#            '&apprAmt=%s' +
125#            '&url=http://xyz') % (resp, apprAmt)
[7894]126
[7970]127    def test_interswitch_form(self):
[10675]128
129        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
130        self.browser.open(self.payments_path)
131        # In KwaraPoly only returning students can create school fee payment
132        # without haveing paid accommodation fee
133        IWorkflowState(self.student).setState('returning')
134        configuration = createObject('waeup.SessionConfiguration')
135        configuration.academic_session = 2005
136        self.app['configuration'].addSessionConfiguration(configuration)
137        self.browser.open(self.payments_path + '/addop')
138        self.browser.getControl(name="form.p_category").value = ['schoolfee']
139        self.browser.getControl("Create ticket").click()
140        self.assertMatches('...ticket created...', self.browser.contents)
141        ctrl = self.browser.getControl(name='val_id')
142        self.value = ctrl.options[0]
143        self.browser.getLink(self.value).click()
144        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]145        self.assertTrue(
[14218]146            '<span>42500.0</span>' in self.browser.contents)
[10675]147        self.payment_url = self.browser.url
148
[7894]149        # Manager can access InterswitchForm
[9789]150        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
151        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
152        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
[7894]153        self.browser.getLink("CollegePAY", index=0).click()
[9789]154        # Split amounts have been set.
155        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
156        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
157        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
[7894]158        self.assertMatches('...Total Amount Authorized:...',
159                           self.browser.contents)
[9811]160        self.assertTrue(
[14218]161            '<input type="hidden" name="amount" value="4250000" />' in
[7894]162            self.browser.contents)
[9811]163        self.assertTrue(
[14218]164            'item_name="School Fee" item_amt="3920000" bank_id="10" acct_num="0106259811"' in
[9129]165            self.browser.contents)
[9811]166        self.assertTrue(
167            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
[9129]168            self.browser.contents)
[9811]169        self.assertTrue(
170            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
[9129]171            self.browser.contents)
[7894]172
[9616]173        # Let's do the same for maintenance fee payment
174
175        self.browser.open(self.payments_path)
176        self.browser.open(self.payments_path + '/addop')
177        self.browser.getControl(
178            name="form.p_category").value = ['hostel_maintenance']
179        self.browser.getControl("Create ticket").click()
180        self.assertMatches('...You have not yet booked accommodation...',
181                           self.browser.contents)
182        # Students have to book bed first
183        self.browser.open(self.acco_path)
184        IWorkflowState(self.student).setState('admitted')
[13461]185        self.browser.getControl("Book accommodation").click()
[9616]186        self.assertFalse('Activation Code:' in self.browser.contents)
187        self.browser.getControl("Create bed ticket").click()
188        # Bed is randomly selected but, since there is only
189        # one bed for this student, we know that ...
190        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
191                           self.browser.contents)
192        self.assertMatches('...ticket created...',
193                           self.browser.contents)
194        self.browser.open(self.payments_path + '/addop')
195        self.browser.getControl(
196            name="form.p_category").value = ['hostel_maintenance']
197        self.browser.getControl("Create ticket").click()
198        self.assertMatches('...ticket created...',
199                           self.browser.contents)
200        ctrl = self.browser.getControl(name='val_id')
201        value = ctrl.options[1]
202        self.browser.getLink(value).click()
203        self.assertMatches('...Amount Authorized...',
204                           self.browser.contents)
[10682]205        # Maint fee is taken from the hostel object
[13329]206        self.assertTrue('<span>876.0</span>' in self.browser.contents)
[9616]207        self.payment_url = self.browser.url
208        # Manager can access InterswitchForm
209        self.browser.getLink("CollegePAY", index=0).click()
[9789]210        # Split amounts have been set.
211        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
212        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
213        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
[9616]214        # The total amount to be processed by Interswitch
215        # has been reduced by the Interswitch fee of 150 Nairas
216        self.assertMatches('...Total Amount Authorized:...',
217                           self.browser.contents)
[13329]218        self.assertTrue(
219            '<input type="hidden" name="pay_item_id" value="102" />' in
[9626]220            self.browser.contents)
[13329]221        self.assertTrue(
222            '<input type="hidden" name="amount" value="87600" />' in
[9616]223            self.browser.contents)
[13329]224        self.assertTrue(
225            'item_name="Hostel Maintenance" item_amt="57600" bank_id="10" acct_num="0106259811"' in
[9616]226            self.browser.contents)
227
[9737]228        # Create carryover ticket
229        self.browser.open(self.payments_path + '/addop')
230        self.browser.getControl(name="form.p_category").value = ['carryover1']
231        self.browser.getControl("Create ticket").click()
232        ctrl = self.browser.getControl(name='val_id')
233        value = ctrl.options[2]
234        self.browser.getLink(value).click()
[13329]235        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
[9737]236        # Manager can access InterswitchForm
237        self.browser.getLink("CollegePAY", index=0).click()
[9789]238        # Split amounts have been set.
239        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
240        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
241        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
[13329]242        self.assertTrue('<input type="hidden" name="pay_item_id" value="101" />' in
[9737]243                           self.browser.contents)
244        self.assertMatches('...Total Amount Authorized:...',
245                           self.browser.contents)
[13329]246        self.assertTrue(
247            '<input type="hidden" name="amount" value="600000" />' in
[9737]248            self.browser.contents)
[13329]249        self.assertTrue(
[13653]250            'item_name="One Carry-Over" item_amt="270000" bank_id="10" acct_num="0106259811"' in
[9737]251            self.browser.contents)
[13329]252        self.assertTrue(
253            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
[9737]254            self.browser.contents)
[13329]255        self.assertTrue(
256            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
[9737]257            self.browser.contents)
258
[10736]259    def test_interswitch_form_new_payment_cats(self):
260        # only a few categories covered
261
262        self.app['configuration']['2004'].certificate_fee = 6800.0
263        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
264        self.browser.open(self.payments_path + '/addop')
265        self.browser.getControl(name="form.p_category").value = ['certificate']
266        self.browser.getControl("Create ticket").click()
267        self.assertMatches('...ticket created...', self.browser.contents)
268        ctrl = self.browser.getControl(name='val_id')
269        value = ctrl.options[0]
270        self.browser.getLink(value).click()
271        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]272        self.assertTrue('<span>6800.0</span>' in self.browser.contents)
[10736]273        self.browser.getLink("CollegePAY", index=0).click()
274        self.assertEqual(self.student['payments'][value].amount_auth, 6800.0)
275        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
276        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
277        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
278
[14230]279        self.app['configuration']['2004'].transcript_local_fee = 6000.0
[10736]280        self.browser.open(self.payments_path + '/addop')
281        self.browser.getControl(name="form.p_category").value = ['transcript_local']
282        self.browser.getControl("Create ticket").click()
283        ctrl = self.browser.getControl(name='val_id')
284        value = ctrl.options[1]
285        self.browser.getLink(value).click()
286        self.assertMatches('...Amount Authorized...', self.browser.contents)
[14230]287        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
[10736]288        self.payment_url = self.browser.url
289        self.browser.getLink("CollegePAY", index=0).click()
[14230]290        self.assertEqual(self.student['payments'][value].amount_auth, 6000.0)
[10736]291        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
292        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
293        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
294
[11768]295        self.app['configuration']['2004'].loss_idcard_fee = 1015.0
[10736]296        self.browser.open(self.payments_path + '/addop')
297        self.browser.getControl(name="form.p_category").value = ['loss_idcard']
298        self.browser.getControl("Create ticket").click()
299        ctrl = self.browser.getControl(name='val_id')
300        value = ctrl.options[2]
301        self.browser.getLink(value).click()
302        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]303        self.assertTrue(
304            '<span>1015.0</span>' in self.browser.contents)
[10736]305        self.payment_url = self.browser.url
306        self.browser.getLink("CollegePAY", index=0).click()
[11768]307        self.assertEqual(self.student['payments'][value].amount_auth, 1015.0)
[10736]308        self.assertEqual(self.student['payments'][value].provider_amt, 9.0)
[11768]309        self.assertEqual(self.student['payments'][value].gateway_amt, 15.22)
[10736]310        self.assertEqual(self.student['payments'][value].thirdparty_amt, 6.0)
311
312        self.app['configuration']['2004'].loss_examcard_fee = 500.0
313        self.browser.open(self.payments_path + '/addop')
314        self.browser.getControl(name="form.p_category").value = ['loss_examcard']
315        self.browser.getControl("Create ticket").click()
316        ctrl = self.browser.getControl(name='val_id')
317        value = ctrl.options[3]
318        self.browser.getLink(value).click()
319        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]320        self.assertTrue('<span>500.0</span>' in self.browser.contents)
[10736]321        self.payment_url = self.browser.url
322        self.browser.getLink("CollegePAY", index=0).click()
323        self.assertEqual(self.student['payments'][value].amount_auth, 500.0)
324        self.assertEqual(self.student['payments'][value].provider_amt, 4.5)
325        self.assertEqual(self.student['payments'][value].gateway_amt, 7.5)
326        self.assertEqual(self.student['payments'][value].thirdparty_amt, 3)
327
328        self.app['configuration']['2004'].change_inst_fee = 6000.0
329        self.browser.open(self.payments_path + '/addop')
330        self.browser.getControl(name="form.p_category").value = ['change_inst']
331        self.browser.getControl("Create ticket").click()
332        ctrl = self.browser.getControl(name='val_id')
333        value = ctrl.options[4]
334        self.browser.getLink(value).click()
335        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]336        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
[10736]337        self.payment_url = self.browser.url
338        self.browser.getLink("CollegePAY", index=0).click()
339        self.assertEqual(self.student['payments'][value].amount_auth, 6000.0)
340        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
341        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
342        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
343
344        self.app['configuration']['2004'].loss_result_fee = 7000.0
345        self.browser.open(self.payments_path + '/addop')
346        self.browser.getControl(name="form.p_category").value = ['loss_result']
347        self.browser.getControl("Create ticket").click()
348        ctrl = self.browser.getControl(name='val_id')
349        value = ctrl.options[5]
350        self.browser.getLink(value).click()
351        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]352        self.assertTrue('<span>7000.0</span>' in self.browser.contents)
[10736]353        self.payment_url = self.browser.url
354        self.browser.getLink("CollegePAY", index=0).click()
355        self.assertEqual(self.student['payments'][value].amount_auth, 7000.0)
356        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
357        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
358        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
359
[11768]360        self.app['configuration']['2004'].loss_idcard_fee = 1900.0
[11682]361        self.browser.open(self.payments_path + '/addop')
362        self.browser.getControl(name="form.p_category").value = ['loss_idcard']
363        self.browser.getControl("Create ticket").click()
364        ctrl = self.browser.getControl(name='val_id')
365        value = ctrl.options[6]
366        self.browser.getLink(value).click()
367        self.assertMatches('...Amount Authorized...', self.browser.contents)
[13329]368        self.assertTrue('<span>1900.0</span>' in self.browser.contents)
[11682]369        self.payment_url = self.browser.url
370        self.browser.getLink("CollegePAY", index=0).click()
[11768]371        self.assertEqual(self.student['payments'][value].amount_auth, 1900.0)
[11682]372        self.assertEqual(self.student['payments'][value].provider_amt, 9.0)
[11768]373        self.assertEqual(self.student['payments'][value].gateway_amt, 28.5)
[11682]374        self.assertEqual(self.student['payments'][value].thirdparty_amt, 6.0)
375
376
[12978]377    def test_interswitch_form_ticket_expired(self):
378        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
379        acc_payment = createObject('waeup.StudentOnlinePayment')
380        acc_payment.p_state = 'unpaid'
381        acc_payment.p_category = 'clearance'
382        acc_payment.p_id = 'xyz'
383        acc_payment.pay_item_id = '123'
384        acc_payment.amount_auth = 876.0
385        self.student['payments']['xyz'] = acc_payment
386        self.browser.open(self.payments_path + '/xyz')
387        self.browser.getLink("CollegePAY", index=0).click()
[14218]388        self.assertTrue('<input type="hidden" name="pay_item_id" value="146" />'
[13329]389                           in self.browser.contents)
[12978]390        self.assertMatches('...Total Amount Authorized:...',
391                           self.browser.contents)
392        self.assertEqual(self.student.current_mode, 'nd_ft')
[13329]393        self.assertTrue(
394            '<input type="hidden" name="amount" value="87600" />' in
[12978]395            self.browser.contents)
[13019]396        delta = timedelta(days=8)
[12978]397        acc_payment.creation_date -= delta
398        self.browser.open(self.payments_path + '/xyz')
399        self.browser.getLink("CollegePAY", index=0).click()
400        self.assertMatches(
401            '...This payment ticket is too old. Please create a new ticket...',
402            self.browser.contents)
[13019]403        delta = timedelta(days=2)
[12978]404        acc_payment.creation_date += delta
405        self.browser.open(self.payments_path + '/xyz')
406        self.browser.getLink("CollegePAY", index=0).click()
407        self.assertMatches('...Total Amount Authorized:...',
408                           self.browser.contents)
409
[7970]410    @external_test
[7930]411    def test_webservice(self):
[11574]412        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
413        IWorkflowState(self.student).setState('cleared')
414        # We add a fake maint. payment ticket to meet the condition
415        maint_payment = CustomStudentOnlinePayment()
416        self.student['payments']['any_key'] = maint_payment
417        maint_payment.p_category = 'hostel_maintenance'
418        maint_payment.p_state = 'paid'
419        maint_payment.p_session = 2004
420        # We create the school fee payment ticket
421        self.browser.open(self.payments_path + '/addop')
422        self.browser.getControl(name="form.p_category").value = ['schoolfee']
423        self.browser.getControl("Create ticket").click()
424        self.assertMatches('...ticket created...',
425                           self.browser.contents)
426        ctrl = self.browser.getControl(name='val_id')
427        self.value = ctrl.options[1]
428        self.browser.getLink(self.value).click()
429        self.payment_url = self.browser.url
[9789]430        # First we have open InterswitchPageStudent to set provider_amt
431        # and gateway_amt
432        self.browser.open(self.payment_url + '/goto_interswitch')
433        # Now we can call the webservice
[7970]434        self.browser.open(self.payment_url + '/request_webservice')
[7930]435        self.assertMatches('...Unsuccessful callback...',
436                          self.browser.contents)
[9710]437        # The payment is now in state failed ...
[8266]438        self.assertMatches('...<span>Failed</span>...',
439                          self.browser.contents)
[9710]440        # ... and the catalog has been updated
441        cat = getUtility(ICatalog, name='payments_catalog')
442        results = list(
443            cat.searchResults(p_state=('failed', 'failed')))
444        self.assertEqual(len(results), 1)
445        self.assertEqual(results[0].p_state, 'failed')
[8266]446
[9789]447        # Let's replace the p_id with a valid p_id of the Kwarapoly
448        # live system. This is definitely not an appropriate
449        # solution for testing, but we have no choice since
450        # Interswitch doesn't provide any interface
451        # for testing.
452        payment = self.student['payments'][self.value]
453        payment.p_id = 'p3543612043224'
[8266]454        self.browser.open(self.payment_url + '/request_webservice')
[9789]455        self.assertMatches('...Callback amount does not match...',
[8266]456                          self.browser.contents)
[9789]457        # The payment is now in state failed ...
[8266]458        self.assertMatches('...<span>Failed</span>...',
459                          self.browser.contents)
[9789]460        # Let's replace the amount autorized with the amount of the
461        # live system payment
462        payment.amount_auth = payment.r_amount_approved
463        self.browser.open(self.payment_url + '/request_webservice')
464        self.assertMatches('...Successful payment...',
465                          self.browser.contents)
466        # The payment is now in state paid ...
467        self.assertMatches('...<span>Paid</span>...',
468                          self.browser.contents)
469        # ... and the catalog has been updated
470        cat = getUtility(ICatalog, name='payments_catalog')
471        results = list(
472            cat.searchResults(p_state=('paid', 'paid')))
473        self.assertEqual(len(results), 1)
474        self.assertEqual(results[0].p_state, 'paid')
475        # Approval is logged in students.log ...
476        logfile = os.path.join(
477            self.app['datacenter'].storage, 'logs', 'students.log')
478        logcontent = open(logfile).read()
479        self.assertTrue(
480            'zope.mgr - '
[11636]481            'waeup.kwarapoly.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
[9789]482            'W1000000 - successful schoolfee payment: p3543612043224\n'
483            in logcontent)
484        # ... and in payments.log
485        logfile = os.path.join(
486            self.app['datacenter'].storage, 'logs', 'payments.log')
487        logcontent = open(logfile).read()
488        self.assertTrue(
489            '"zope.mgr",W1000000,p3543612043224,schoolfee,'
490            '52100.0,00,1200.0,300.0,1800.0,,,\n'
[10131]491            in logcontent)
492
493
494class InterswitchTestsApplicants(ApplicantsFullSetup):
495    """Tests for the Interswitch payment gateway.
496    """
497
498    layer = FunctionalLayer
499
500    def setUp(self):
501        super(InterswitchTestsApplicants, self).setUp()
[10837]502        configuration = SessionConfiguration()
503        configuration.academic_session = datetime.now().year - 2
504        self.app['configuration'].addSessionConfiguration(configuration)
[10844]505        self.configuration = configuration
[10131]506        # Create at least one Kwarapoly faculty
507        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
508        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
509        self.certificate2 = createObject('waeup.Certificate')
510        self.certificate2.code = u'CERT2'
[10133]511        self.certificate2.application_category = 'ndft'
[10131]512        self.certificate2.study_mode = 'nd_ft'
513        self.certificate2.start_level = 100
514        self.certificate2.end_level = 300
515        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
516            self.certificate2)
[10133]517        self.applicantscontainer.application_category = 'ndft'
[10131]518        self.applicant.applicant_id = u'nd_anything'
519       
520        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
521        self.browser.open(self.manage_path)
522        #IWorkflowState(self.student).setState('started')
523        super(InterswitchTestsApplicants, self).fill_correct_values()
524        self.browser.getControl(name="form.course1").value = ['CERT2']
525        self.applicantscontainer.application_fee = 3333.0
526        self.browser.getControl(name="form.nationality").value = ['NG']
527        self.browser.getControl(name="transition").value = ['start']
528        self.browser.getControl("Save").click()
529        self.browser.getControl("Add online").click()
530        self.assertMatches('...ticket created...',
531                           self.browser.contents)
532        self.assertMatches('...Amount Authorized...',
533                           self.browser.contents)
[13329]534        self.assertTrue('<span>3333.0</span>' in self.browser.contents)
[10131]535        self.payment_url = self.browser.url
536
537
538    def test_interswitch_form(self):
539
540        # Manager can access InterswitchForm
541        self.browser.getLink("CollegePAY", index=0).click()
542        self.assertMatches('...Total Amount Authorized:...',
543                           self.browser.contents)
544        self.assertTrue(
[11791]545            '<input type="hidden" name="amount" value="333300" />'
[10131]546            in self.browser.contents)
547        self.assertTrue(
[11922]548            '<item_detail item_id="1" item_name="Application" '
[13329]549            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
[10131]550            in self.browser.contents)
551
[11677]552        # Meanwhile hndft fee goes to same account
[10131]553        self.applicant.applicant_id = u'hnd_anything'
554        self.browser.open(self.manage_path)
555        ctrl = self.browser.getControl(name='val_id')
556        value = ctrl.options[0]
557        self.browser.getLink(value).click()
558        self.browser.getLink("CollegePAY", index=0).click()
559        self.assertTrue(
[11922]560            '<item_detail item_id="1" item_name="Application" '
[13329]561            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
[10131]562            in self.browser.contents)
[10176]563        # Commission or bribe?
[10142]564        self.assertTrue(
[10176]565            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
566            'bank_id="117" acct_num="1013196791" />'
[10142]567            in self.browser.contents)
[10176]568        self.assertTrue(
569            '<item_detail item_id="3" item_name="BT Education" '
570            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
571            in self.browser.contents)
[10597]572
[14066]573        # prehndft fee goes to another account and has other split data
[10597]574        self.applicant.applicant_id = u'prehnd_anything'
575        self.browser.open(self.manage_path)
576        ctrl = self.browser.getControl(name='val_id')
577        value = ctrl.options[0]
578        self.browser.getLink(value).click()
579        self.browser.getLink("CollegePAY", index=0).click()
580        self.assertTrue(
[11922]581            '<item_detail item_id="1" item_name="Application" '
[14066]582            'item_amt="303300" bank_id="10" acct_num="0106259811" />'
[10597]583            in self.browser.contents)
[14066]584        self.assertFalse('Dalash' in self.browser.contents)
[11793]585        self.assertTrue(
[14066]586            '<item_detail item_id="2" item_name="BT Education" '
587            'item_amt="26250" bank_id="117" acct_num="1010764827" />'
[11793]588            in self.browser.contents)
[10597]589
590        # prejambites fee goes to another account
591        self.applicant.applicant_id = u'prejambites_anything'
592        self.browser.open(self.manage_path)
593        ctrl = self.browser.getControl(name='val_id')
594        value = ctrl.options[0]
595        self.browser.getLink(value).click()
596        self.browser.getLink("CollegePAY", index=0).click()
597        self.assertTrue(
[11922]598            '<item_detail item_id="1" item_name="Application" '
[14074]599            'item_amt="303300" bank_id="10" acct_num="0106259811" />'
[10597]600            in self.browser.contents)
[14074]601        self.assertFalse('Dalash' in self.browser.contents)
[14071]602        #self.assertFalse('BT Education' in self.browser.contents)
[11793]603        self.assertTrue(
[14074]604            '<item_detail item_id="2" item_name="BT Education" '
605            'item_amt="26250" bank_id="117" acct_num="1010764827" />'
[11793]606            in self.browser.contents)
607        self.assertTrue(
[11796]608            '<input type="hidden" name="pay_item_id" value="104" />'
609            in self.browser.contents)
[10844]610
[11883]611        # putme goes into the prejambites account
612        self.applicant.applicant_id = u'putme_anything'
613        self.browser.open(self.manage_path)
614        ctrl = self.browser.getControl(name='val_id')
615        value = ctrl.options[0]
616        self.browser.getLink(value).click()
617        self.browser.getLink("CollegePAY", index=0).click()
618        self.assertTrue(
[11922]619            '<item_detail item_id="1" item_name="Application" '
[13185]620            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
[11883]621            in self.browser.contents)
622        self.assertTrue(
623            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
624            'bank_id="117" acct_num="1013196791" />'
625            in self.browser.contents)
626        self.assertTrue(
627            '<item_detail item_id="3" item_name="BT Education" '
628            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
629            in self.browser.contents)
630        self.assertTrue(
631            '<input type="hidden" name="pay_item_id" value="104" />'
632            in self.browser.contents)
[10844]633
[12978]634    def test_interswitch_form_ticket_expired(self):
635        # Manager can access InterswitchForm
636        self.browser.getLink("CollegePAY", index=0).click()
637        self.assertMatches('...Total Amount Authorized:...',
638                           self.browser.contents)
639        self.assertTrue(
640            '<input type="hidden" name="amount" value="333300" />'
641            in self.browser.contents)
642        self.assertTrue(
643            '<item_detail item_id="1" item_name="Application" '
[13329]644            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
[12978]645            in self.browser.contents)
[13019]646        delta = timedelta(days=8)
[12978]647        self.applicant.values()[0].creation_date -= delta
648        self.browser.open(self.payment_url)
649        self.browser.getLink("CollegePAY", index=0).click()
650        self.assertMatches(
651            '...This payment ticket is too old. Please create a new ticket...',
652            self.browser.contents)
653
[10844]654    def prepare_special_container(self):
655        # Add special application container
656        container_name = u'special%s' % (datetime.now().year - 2)
657        applicantscontainer = ApplicantsContainer()
658        applicantscontainer.code = container_name
659        applicantscontainer.prefix = 'special'
660        applicantscontainer.year = datetime.now().year - 2
661        applicantscontainer.title = u'This is a special app container'
662        applicantscontainer.application_category = 'no'
663        applicantscontainer.mode = 'create'
664        delta = timedelta(days=10)
665        applicantscontainer.startdate = datetime.now(pytz.utc) - delta
666        applicantscontainer.enddate = datetime.now(pytz.utc) + delta
667        applicantscontainer.strict_deadline = True
668        self.app['applicants'][container_name] = applicantscontainer
669        # Add an applicant
670        applicant = createObject('waeup.Applicant')
671        # reg_number is the only field which has to be preset here
672        # because managers are allowed to edit this required field
673        applicant.reg_number = u'12345'
674        applicant.firstname = u'Vorname'
675        applicant.lastname = u'Nachname'
[10847]676        applicant.email = 'aa@aa.aa'
[10844]677        applicant.special_application = u'transcript_local'
678        applicant.applicant_id = u'special_anything'
679        self.app['applicants'][container_name].addApplicant(applicant)
680        self.special_applicant = applicant
681        self.configuration.transcript_local_fee = 5300.0
682        self.special_manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
683            container_name, applicant.application_number, 'manage')
684
685    def test_interswitch_form_special(self):
686        self.prepare_special_container()
687        self.browser.open(self.special_manage_path)
688        self.browser.getControl("Add online").click()
689        self.assertMatches('...ticket created...',
690                           self.browser.contents)
691        self.browser.getLink("CollegePAY", index=0).click()
692        self.assertTrue(
[11682]693            '<item_detail item_id="1" item_name="ND Transcript (local)" '
[13329]694            'item_amt="450000" bank_id="10" acct_num="0106259811" />'
[10844]695            in self.browser.contents)
[11574]696
[11769]697        self.special_applicant.special_application = u'log_book'
698        self.configuration.log_book_fee = 570.5
699        self.browser.open(self.special_manage_path)
700        self.browser.getControl("Add online").click()
701        self.assertMatches('...ticket created...',
702                           self.browser.contents)
703        self.browser.getLink("CollegePAY", index=0).click()
704        # The university gets 570.5 - (1.5% x 570.5) - 3 - 4.5
705        self.assertTrue(
[11922]706            '<item_detail item_id="1" item_name="Log Book" '
[13329]707            'item_amt="55444" bank_id="10" acct_num="0106259811" />'
[11769]708            in self.browser.contents)
709
710
[11574]711    @external_test
712    def test_webservice(self):
[11577]713        self.prepare_special_container()
[11636]714        IWorkflowState(self.special_applicant).setState('started')
[11577]715        self.browser.open(self.special_manage_path)
716        self.browser.getControl("Add online").click()
717        payment_url = self.browser.url
718        self.browser.open(payment_url + '/request_webservice')
[11574]719        self.assertMatches('...Unsuccessful callback...',
720                          self.browser.contents)
721        # The payment is now in state failed
722        self.assertMatches('...<span>Failed</span>...',
723                          self.browser.contents)
724        # Let's replace the p_id with a valid p_id of the Kwarapoly
725        # live system. This is definitely not an appropriate
726        # solution for testing, but we have no choice since
727        # Interswitch doesn't provide any interface
728        # for testing.
[11577]729        p_id = self.special_applicant.keys()[0]
730        payment = self.special_applicant[p_id]
[11574]731        payment.p_id = 'p3543612043224'
[11577]732        self.browser.open(payment_url + '/request_webservice')
[11574]733        self.assertMatches('...Callback amount does not match...',
734                          self.browser.contents)
735        payment.amount_auth = payment.r_amount_approved
736
[11577]737        self.browser.open(payment_url + '/request_webservice')
[11574]738        self.assertMatches('...Successful payment...',
739                          self.browser.contents)
740        # The payment is now in state paid ...
741        self.assertMatches('...<span>Paid</span>...',
742                          self.browser.contents)
743        # ... and the catalog has been updated
744        cat = getUtility(ICatalog, name='payments_catalog')
745        results = list(
746            cat.searchResults(p_state=('paid', 'paid')))
747        self.assertEqual(len(results), 1)
748        self.assertEqual(results[0].p_state, 'paid')
749        # Approval is logged in applicants.log ...
750        logfile = os.path.join(
751            self.app['datacenter'].storage, 'logs', 'applicants.log')
752        logcontent = open(logfile).read()
753        self.assertTrue(
[11636]754            'zope.mgr - waeup.kwarapoly.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageApplicant'
[11577]755            ' - special_anything - successful payment: p3543612043224\n'
[11574]756            in logcontent)
757        # ... and in payments.log
758        logfile = os.path.join(
759            self.app['datacenter'].storage, 'logs', 'payments.log')
760        logcontent = open(logfile).read()
761        self.assertTrue(
[11577]762            '"zope.mgr",special_anything,p3543612043224,transcript_local,52100.0,'
[11574]763            '00,0.0,0.0,0.0,,,\n'
764            in logcontent)
[11577]765        self.assertEqual(self.applicant.state, 'started')
766        # Special Payment applicant can add new payment
767        self.browser.open(self.edit_path)
768        self.assertTrue('Add online payment ticket' in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.