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

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

Adjust tests.

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