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

Last change on this file since 13331 was 13329, checked in by Henrik Bettermann, 9 years ago

Change banc account data and strengthen tests.

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