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

Last change on this file since 10709 was 10682, checked in by Henrik Bettermann, 11 years ago

Take hostel_maintenance fee from hostel objects. Store bed coordinates as payment item.

  • Property svn:keywords set to Id
File size: 20.2 KB
RevLine 
[7894]1## $Id: tests.py 10682 2013-11-01 09:11:10Z 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
[7894]20from hurry.workflow.interfaces import IWorkflowState
[9710]21from zope.component import createObject, getUtility
22from zope.catalog.interfaces import ICatalog
[9387]23from zope.event import notify
24from waeup.kofa.university.faculty import Faculty
25from waeup.kofa.university.department import Department
[7894]26from waeup.kofa.students.tests.test_browser import StudentsFullSetup
[8266]27from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
28from waeup.kofa.configuration import SessionConfiguration
[9347]29from waeup.kwarapoly.testing import FunctionalLayer
[10675]30from waeup.kwarapoly.students.payments import CustomStudentOnlinePayment
[7894]31
[7970]32# Also run tests that send requests to external servers?
33#   If you enable this, please make sure the external services
34#   do exist really and are not bothered by being spammed by a test programme.
[9811]35EXTERNAL_TESTS = False
[7970]36
37def external_test(func):
38    if not EXTERNAL_TESTS:
39        myself = __file__
40        if myself.endswith('.pyc'):
41            myself = myself[:-2]
42        print "WARNING: external tests are skipped!"
43        print "WARNING: edit %s to enable them." % myself
44        return
45    return func
46
47
[8266]48class InterswitchTestsStudents(StudentsFullSetup):
[7929]49    """Tests for the Interswitch payment gateway.
[7894]50    """
51
52    layer = FunctionalLayer
53
[7970]54    def setUp(self):
[8266]55        super(InterswitchTestsStudents, self).setUp()
[9387]56
57        # Create at least one Kwarapoly faculty
58        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
59        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
60        self.certificate2 = createObject('waeup.Certificate')
61        self.certificate2.code = u'CERT2'
62        self.certificate2.application_category = 'basic'
63        self.certificate2.study_mode = 'nd_ft'
64        self.certificate2.start_level = 100
65        self.certificate2.end_level = 300
66        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
67            self.certificate2)
68        # Set study course attributes of test student
69        self.student['studycourse'].certificate = self.certificate2
70        self.student['studycourse'].current_session = 2004
71        self.student['studycourse'].entry_session = 2004
72        self.student['studycourse'].current_verdict = 'A'
73        self.student['studycourse'].current_level = 100
[9392]74        # Set local lga
75        self.student.lga = u'kwara_asa'
[9387]76        # Update the catalog
77        notify(grok.ObjectModifiedEvent(self.student))
78
[10675]79
80    def test_schoolfee_ticket_creation(self):
[7970]81        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
[7995]82        self.browser.open(self.payments_path)
[7970]83        IWorkflowState(self.student).setState('cleared')
[7995]84        self.browser.open(self.payments_path + '/addop')
[9737]85        self.browser.getControl(name="form.p_category").value = ['schoolfee']
[7970]86        self.browser.getControl("Create ticket").click()
[10675]87        self.assertMatches('...Book and pay for accommodation first...',
88                           self.browser.contents)
89        # We add a fake maint. payment ticket to meet the condition
90        maint_payment = CustomStudentOnlinePayment()
91        self.student['payments']['any_key'] = maint_payment
92        maint_payment.p_category = 'hostel_maintenance'
93        maint_payment.p_state = 'unpaid'
94        maint_payment.p_session = 2004
95        self.browser.getControl(name="form.p_category").value = ['schoolfee']
96        self.browser.getControl("Create ticket").click()
97        self.assertMatches('...Book and pay for accommodation first...',
98                           self.browser.contents)
99        # Ticket must be paid
100        maint_payment.p_state = 'paid'
101        self.browser.getControl(name="form.p_category").value = ['schoolfee']
102        self.browser.getControl("Create ticket").click()
[9436]103        self.assertMatches('...ticket created...',
104                           self.browser.contents)
105        ctrl = self.browser.getControl(name='val_id')
[10675]106        self.value = ctrl.options[1]
[9789]107        self.browser.getLink(self.value).click()
[9436]108        self.assertMatches('...Amount Authorized...',
109                           self.browser.contents)
110        self.assertMatches(
[10672]111            '...<span>39400.0</span>...',
[9436]112            self.browser.contents)
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)
145        self.assertMatches(
146            '...<span>29500.0</span>...',
147            self.browser.contents)
148        self.payment_url = self.browser.url
149
[7894]150        # Manager can access InterswitchForm
[9789]151        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
152        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
153        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
[7894]154        self.browser.getLink("CollegePAY", index=0).click()
[9789]155        # Split amounts have been set.
156        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
157        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
158        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
[7894]159        self.assertMatches('...Total Amount Authorized:...',
160                           self.browser.contents)
[9811]161        self.assertTrue(
[10675]162            '<input type="hidden" name="amount" value="2950000.0" />' in
[7894]163            self.browser.contents)
[9811]164        self.assertTrue(
[10675]165            'item_name="School Fee" item_amt="2620000" bank_id="120" acct_num="1771180233"' in
[9129]166            self.browser.contents)
[9811]167        self.assertTrue(
168            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
[9129]169            self.browser.contents)
[9811]170        self.assertTrue(
171            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
[9129]172            self.browser.contents)
[7894]173
[9616]174        # Let's do the same for maintenance fee payment
175
176        self.browser.open(self.payments_path)
177        self.browser.open(self.payments_path + '/addop')
178        self.browser.getControl(
179            name="form.p_category").value = ['hostel_maintenance']
180        self.browser.getControl("Create ticket").click()
181        self.assertMatches('...You have not yet booked accommodation...',
182                           self.browser.contents)
183        # Students have to book bed first
184        self.browser.open(self.acco_path)
185        IWorkflowState(self.student).setState('admitted')
186        self.browser.getLink("Book accommodation").click()
187        self.assertFalse('Activation Code:' in self.browser.contents)
188        self.browser.getControl("Create bed ticket").click()
189        # Bed is randomly selected but, since there is only
190        # one bed for this student, we know that ...
191        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
192                           self.browser.contents)
193        self.assertMatches('...ticket created...',
194                           self.browser.contents)
195        self.browser.open(self.payments_path + '/addop')
196        self.browser.getControl(
197            name="form.p_category").value = ['hostel_maintenance']
198        self.browser.getControl("Create ticket").click()
199        self.assertMatches('...ticket created...',
200                           self.browser.contents)
201        ctrl = self.browser.getControl(name='val_id')
202        value = ctrl.options[1]
203        self.browser.getLink(value).click()
204        self.assertMatches('...Amount Authorized...',
205                           self.browser.contents)
[10682]206        # Maint fee is taken from the hostel object
[9616]207        self.assertMatches(
[10682]208            '...<span>876.0</span>...',
[9616]209            self.browser.contents)
210        self.payment_url = self.browser.url
211        # Manager can access InterswitchForm
212        self.browser.getLink("CollegePAY", index=0).click()
[9789]213        # Split amounts have been set.
214        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
215        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
216        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
[9616]217        # The total amount to be processed by Interswitch
218        # has been reduced by the Interswitch fee of 150 Nairas
219        self.assertMatches('...Total Amount Authorized:...',
220                           self.browser.contents)
221        self.assertMatches(
[9626]222            '...<input type="hidden" name="pay_item_id" value="102" />...',
223            self.browser.contents)
224        self.assertMatches(
[10682]225            '...<input type="hidden" name="amount" value="87600.0" />...',
[9616]226            self.browser.contents)
227        self.assertMatches(
[10682]228            '...item_name="Hostel Maintenance Fee" item_amt="57600" bank_id="31" acct_num="0039050937"...',
[9616]229            self.browser.contents)
230
[9737]231        # Create carryover ticket
232        self.browser.open(self.payments_path + '/addop')
233        self.browser.getControl(name="form.p_category").value = ['carryover1']
234        self.browser.getControl("Create ticket").click()
235        ctrl = self.browser.getControl(name='val_id')
236        value = ctrl.options[2]
237        self.browser.getLink(value).click()
238        self.assertMatches(
239            '...<span>6000.0</span>...',
240            self.browser.contents)
241        # Manager can access InterswitchForm
242        self.browser.getLink("CollegePAY", index=0).click()
[9789]243        # Split amounts have been set.
244        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
245        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
246        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
[9737]247        self.assertMatches('...<input type="hidden" name="pay_item_id" value="101" />...',
248                           self.browser.contents)
249        self.assertMatches('...Total Amount Authorized:...',
250                           self.browser.contents)
251        self.assertMatches(
252            '...<input type="hidden" name="amount" value="600000.0" />...',
253            self.browser.contents)
254        self.assertMatches(
255            '...item_name="School Fee" item_amt="270000" bank_id="120" acct_num="1771180233"...',
256            self.browser.contents)
257        self.assertMatches(
258            '...item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"...',
259            self.browser.contents)
260        self.assertMatches(
261            '...item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"...',
262            self.browser.contents)
263
[7970]264    @external_test
[7930]265    def test_webservice(self):
[9789]266        # First we have open InterswitchPageStudent to set provider_amt
267        # and gateway_amt
268        self.browser.open(self.payment_url + '/goto_interswitch')
269        # Now we can call the webservice
[7970]270        self.browser.open(self.payment_url + '/request_webservice')
[7930]271        self.assertMatches('...Unsuccessful callback...',
272                          self.browser.contents)
[9710]273        # The payment is now in state failed ...
[8266]274        self.assertMatches('...<span>Failed</span>...',
275                          self.browser.contents)
[9710]276        # ... and the catalog has been updated
277        cat = getUtility(ICatalog, name='payments_catalog')
278        results = list(
279            cat.searchResults(p_state=('failed', 'failed')))
280        self.assertEqual(len(results), 1)
281        self.assertEqual(results[0].p_state, 'failed')
[8266]282
[9789]283        # Let's replace the p_id with a valid p_id of the Kwarapoly
284        # live system. This is definitely not an appropriate
285        # solution for testing, but we have no choice since
286        # Interswitch doesn't provide any interface
287        # for testing.
288        payment = self.student['payments'][self.value]
289        payment.p_id = 'p3543612043224'
[8266]290        self.browser.open(self.payment_url + '/request_webservice')
[9789]291        self.assertMatches('...Callback amount does not match...',
[8266]292                          self.browser.contents)
[9789]293        # The payment is now in state failed ...
[8266]294        self.assertMatches('...<span>Failed</span>...',
295                          self.browser.contents)
[9789]296        # Let's replace the amount autorized with the amount of the
297        # live system payment
298        payment.amount_auth = payment.r_amount_approved
299        self.browser.open(self.payment_url + '/request_webservice')
300        self.assertMatches('...Successful payment...',
301                          self.browser.contents)
302        # The payment is now in state paid ...
303        self.assertMatches('...<span>Paid</span>...',
304                          self.browser.contents)
305        # ... and the catalog has been updated
306        cat = getUtility(ICatalog, name='payments_catalog')
307        results = list(
308            cat.searchResults(p_state=('paid', 'paid')))
309        self.assertEqual(len(results), 1)
310        self.assertEqual(results[0].p_state, 'paid')
311        # Approval is logged in students.log ...
312        logfile = os.path.join(
313            self.app['datacenter'].storage, 'logs', 'students.log')
314        logcontent = open(logfile).read()
315        self.assertTrue(
316            'zope.mgr - '
317            'waeup.kwarapoly.interswitch.browser.InterswitchPaymentRequestWebservicePageStudent - '
318            'W1000000 - successful schoolfee payment: p3543612043224\n'
319            in logcontent)
320        # ... and in payments.log
321        logfile = os.path.join(
322            self.app['datacenter'].storage, 'logs', 'payments.log')
323        logcontent = open(logfile).read()
324        self.assertTrue(
325            '"zope.mgr",W1000000,p3543612043224,schoolfee,'
326            '52100.0,00,1200.0,300.0,1800.0,,,\n'
[10131]327            in logcontent)
328
329
330class InterswitchTestsApplicants(ApplicantsFullSetup):
331    """Tests for the Interswitch payment gateway.
332    """
333
334    layer = FunctionalLayer
335
336    def setUp(self):
337        super(InterswitchTestsApplicants, self).setUp()
338        # Create at least one Kwarapoly faculty
339        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
340        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
341        self.certificate2 = createObject('waeup.Certificate')
342        self.certificate2.code = u'CERT2'
[10133]343        self.certificate2.application_category = 'ndft'
[10131]344        self.certificate2.study_mode = 'nd_ft'
345        self.certificate2.start_level = 100
346        self.certificate2.end_level = 300
347        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
348            self.certificate2)
[10133]349        self.applicantscontainer.application_category = 'ndft'
[10131]350        self.applicant.applicant_id = u'nd_anything'
351       
352        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
353        self.browser.open(self.manage_path)
354        #IWorkflowState(self.student).setState('started')
355        super(InterswitchTestsApplicants, self).fill_correct_values()
356        self.browser.getControl(name="form.course1").value = ['CERT2']
357        self.applicantscontainer.application_fee = 3333.0
358        self.browser.getControl(name="form.nationality").value = ['NG']
359        self.browser.getControl(name="transition").value = ['start']
360        self.browser.getControl("Save").click()
361        self.browser.getControl("Add online").click()
362        self.assertMatches('...ticket created...',
363                           self.browser.contents)
364        #ctrl = self.browser.getControl(name='val_id')
365        #value = ctrl.options[0]
366        #self.browser.getLink(value).click()
367        self.assertMatches('...Amount Authorized...',
368                           self.browser.contents)
369        self.assertMatches(
370            '...<span>3333.0</span>...',
371            self.browser.contents)
372        self.payment_url = self.browser.url
373
374
375    def test_interswitch_form(self):
376
377        # Manager can access InterswitchForm
378        self.browser.getLink("CollegePAY", index=0).click()
379        self.assertMatches('...Total Amount Authorized:...',
380                           self.browser.contents)
381        self.assertTrue(
382            '<input type="hidden" name="amount" value="333300.0" />'
383            in self.browser.contents)
384        self.assertTrue(
385            '<item_detail item_id="1" item_name="application" '
386            'item_amt="253300" bank_id="8" acct_num="2014191363" />'
387            in self.browser.contents)
388
[10133]389        # hndft fee goes to another account
[10131]390        self.applicant.applicant_id = u'hnd_anything'
391        self.browser.open(self.manage_path)
392        ctrl = self.browser.getControl(name='val_id')
393        value = ctrl.options[0]
394        self.browser.getLink(value).click()
395        self.browser.getLink("CollegePAY", index=0).click()
396        self.assertTrue(
397            '<item_detail item_id="1" item_name="application" '
[10254]398            'item_amt="253300" bank_id="9" acct_num="7000016724" />'
[10131]399            in self.browser.contents)
[10176]400        # Commission or bribe?
[10142]401        self.assertTrue(
[10176]402            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
403            'bank_id="117" acct_num="1013196791" />'
[10142]404            in self.browser.contents)
[10176]405        self.assertTrue(
406            '<item_detail item_id="3" item_name="BT Education" '
407            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
408            in self.browser.contents)
[10597]409
410        # prehndft fee goes to another account
411        self.applicant.applicant_id = u'prehnd_anything'
412        self.browser.open(self.manage_path)
413        ctrl = self.browser.getControl(name='val_id')
414        value = ctrl.options[0]
415        self.browser.getLink(value).click()
416        self.browser.getLink("CollegePAY", index=0).click()
417        self.assertTrue(
418            '<item_detail item_id="1" item_name="application" '
419            'item_amt="303300" bank_id="8" acct_num="2013910271" />'
420            in self.browser.contents)
421        # No 'commission', no provider fee
422        self.assertFalse('Dalash' in self.browser.contents)
423        self.assertFalse('BT Education' in self.browser.contents)
424
425        # prejambites fee goes to another account
426        self.applicant.applicant_id = u'prejambites_anything'
427        self.browser.open(self.manage_path)
428        ctrl = self.browser.getControl(name='val_id')
429        value = ctrl.options[0]
430        self.browser.getLink(value).click()
431        self.browser.getLink("CollegePAY", index=0).click()
432        self.assertTrue(
433            '<item_detail item_id="1" item_name="application" '
434            'item_amt="303300" bank_id="10" acct_num="0106259811" />'
435            in self.browser.contents)
436        # No 'commission', no provider fee
437        self.assertFalse('Dalash' in self.browser.contents)
438        self.assertFalse('BT Education' in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.