source: main/waeup.uniben/trunk/src/waeup/uniben/interswitch/tests.py @ 10220

Last change on this file since 10220 was 9869, checked in by Henrik Bettermann, 12 years ago

Take new balance payment into consideration.

  • Property svn:keywords set to Id
File size: 19.8 KB
RevLine 
[7894]1## $Id: tests.py 9869 2013-01-12 07:01:41Z 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##
[9775]18import os
[9713]19from zope.component import createObject, getUtility
20from zope.catalog.interfaces import ICatalog
[7894]21from hurry.workflow.interfaces import IWorkflowState
22from waeup.kofa.students.tests.test_browser import StudentsFullSetup
[8266]23from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
24from waeup.kofa.configuration import SessionConfiguration
[8020]25from waeup.uniben.testing import FunctionalLayer
[7894]26
[7970]27# Also run tests that send requests to external servers?
28#   If you enable this, please make sure the external services
29#   do exist really and are not bothered by being spammed by a test programme.
[9831]30EXTERNAL_TESTS = False
[7970]31
32def external_test(func):
33    if not EXTERNAL_TESTS:
34        myself = __file__
35        if myself.endswith('.pyc'):
36            myself = myself[:-2]
37        print "WARNING: external tests are skipped!"
38        print "WARNING: edit %s to enable them." % myself
39        return
40    return func
41
42
[8266]43class InterswitchTestsStudents(StudentsFullSetup):
[7929]44    """Tests for the Interswitch payment gateway.
[7894]45    """
46
47    layer = FunctionalLayer
48
[7970]49    def setUp(self):
[8266]50        super(InterswitchTestsStudents, self).setUp()
[7970]51        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
[7995]52        self.browser.open(self.payments_path)
[7970]53        IWorkflowState(self.student).setState('cleared')
[9006]54        self.student.nationality = u'NG'
[7995]55        self.browser.open(self.payments_path + '/addop')
[9384]56        self.browser.getControl(name="form.p_category").value = ['schoolfee']
[7970]57        self.browser.getControl("Create ticket").click()
[9435]58        self.assertMatches('...ticket created...',
59                           self.browser.contents)
60        ctrl = self.browser.getControl(name='val_id')
[9775]61        self.value = ctrl.options[0]
62        self.browser.getLink(self.value).click()
[9435]63        self.assertMatches('...Amount Authorized...',
64                           self.browser.contents)
65        self.assertMatches(
66            '...<span>40000.0</span>...',
67            self.browser.contents)
68        self.payment_url = self.browser.url
[7970]69
[8263]70#    def callback_url(self, payment_url, resp, apprAmt):
71#        return payment_url + (
72#            '/isw_callback?echo=' +
73#            '&resp=%s' +
74#            '&desc=Something went wrong' +
75#            '&txnRef=p1331792385335' +
76#            '&payRef=' + '&retRef=' +
77#            '&cardNum=0' +
78#            '&apprAmt=%s' +
79#            '&url=http://xyz') % (resp, apprAmt)
[7894]80
[7970]81    def test_interswitch_form(self):
[7894]82        # Manager can access InterswitchForm
83        self.browser.getLink("CollegePAY", index=0).click()
[8266]84        # The total amount to be processed by Interswitch
85        # has been reduced by the Interswitch fee of 150 Nairas
[9389]86        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5700" />...',
87                           self.browser.contents)
[9384]88        self.assertMatches('...Total Amount Authorized:...',
89                           self.browser.contents)
[9460]90        self.assertEqual(self.student.current_mode, 'ug_ft')
[7894]91        self.assertMatches(
[8276]92            '...<input type="hidden" name="amount" value="4000000.0" />...',
[7894]93            self.browser.contents)
[9384]94        self.assertMatches(
[9460]95            '...item_name="School Fee" item_amt="3835000" bank_id="8" acct_num="2017506430"...',
[9384]96            self.browser.contents)
97        self.assertMatches(
98            '...item_name="BT Education" item_amt="150000" bank_id="117" acct_num="1010764827"...',
99            self.browser.contents)
[7894]100
[9520]101        # Create school fee ticket for returning students. Payment is made
102        # for next session.
103        current_payment_key = self.student['payments'].keys()[0]
[9389]104        self.certificate.study_mode = u'ug_pt'
105        IWorkflowState(self.student).setState('returning')
106        configuration = createObject('waeup.SessionConfiguration')
107        configuration.academic_session = 2005
108        self.app['configuration'].addSessionConfiguration(configuration)
[9384]109        self.browser.open(self.payments_path + '/addop')
[9389]110        self.browser.getControl(name="form.p_category").value = ['schoolfee']
[9384]111        self.browser.getControl("Create ticket").click()
[9570]112
113        ## Next session payment can't be made ...
114        #self.assertMatches(
115        #    '...You have not yet paid your current/active session...',
116        #    self.browser.contents)
117        ## current session payment must be approved first.
118        #self.student['payments'][current_payment_key].approve()
119        #self.browser.open(self.payments_path + '/addop')
120        #self.browser.getControl(name="form.p_category").value = ['schoolfee']
121        #self.browser.getControl("Create ticket").click()
122
[9384]123        ctrl = self.browser.getControl(name='val_id')
124        value = ctrl.options[1]
[9775]125        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
126        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
[9384]127        self.browser.getLink(value).click()
[9389]128        self.browser.getLink("CollegePAY", index=0).click()
[9775]129        # Split amounts have been set.
130        self.assertEqual(self.student['payments'][value].provider_amt, 1500.0)
131        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
[9389]132        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5701" />...',
[9384]133                           self.browser.contents)
134        self.assertMatches(
[9389]135            '...<input type="hidden" name="amount" value="2000000.0" />...',
136            self.browser.contents)
137        self.assertMatches(
[9460]138            '...item_name="School Fee" item_amt="1835000" bank_id="16" acct_num="0122009929"...',
[9389]139            self.browser.contents)
140        self.assertMatches(
141            '...item_name="BT Education" item_amt="150000" bank_id="117" acct_num="1010764827"...',
142            self.browser.contents)
143
144        # Create clearance fee ticket
145        self.browser.open(self.payments_path + '/addop')
146        self.browser.getControl(name="form.p_category").value = ['clearance']
147        self.browser.getControl("Create ticket").click()
148        ctrl = self.browser.getControl(name='val_id')
149        value = ctrl.options[2]
150        self.browser.getLink(value).click()
151        self.assertMatches(
[9384]152            '...<span>45000.0</span>...',
153            self.browser.contents)
154        # Manager can access InterswitchForm
155        self.browser.getLink("CollegePAY", index=0).click()
[9775]156        self.assertEqual(self.student['payments'][value].provider_amt, 1500.0)
157        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
[9389]158        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5702" />...',
[9384]159                           self.browser.contents)
160        self.assertMatches('...Total Amount Authorized:...',
161                           self.browser.contents)
162        self.assertMatches(
163            '...<input type="hidden" name="amount" value="4500000.0" />...',
164            self.browser.contents)
165        self.assertMatches(
166            '...item_name="Acceptance Fee" item_amt="4335000" bank_id="7" acct_num="1003475516"...',
167            self.browser.contents)
168        self.assertMatches(
169            '...item_name="BT Education" item_amt="150000" bank_id="117" acct_num="1010764827"...',
170            self.browser.contents)
171
[9515]172        # Create gown fee ticket
173        configuration.maint_fee = 987.0
174        self.app['configuration']['2004'].gown_fee = 234.0
175        self.browser.open(self.payments_path + '/addop')
176        self.browser.getControl(name="form.p_category").value = ['gown']
177        self.browser.getControl("Create ticket").click()
178        ctrl = self.browser.getControl(name='val_id')
179        value = ctrl.options[3]
180        self.browser.getLink(value).click()
181        self.assertMatches(
182            '...<span>234.0</span>...',
183            self.browser.contents)
184        # Manager can access InterswitchForm
185        self.browser.getLink("CollegePAY", index=0).click()
[9775]186        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
187        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
[9515]188        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5704" />...',
189                           self.browser.contents)
190        self.assertMatches('...Total Amount Authorized:...',
191                           self.browser.contents)
192        self.assertMatches(
193            '...<input type="hidden" name="amount" value="23400.0" />...',
194            self.browser.contents)
195        self.assertMatches(
196            '...<item_detail item_id="1" item_name="Gown Hire Fee" item_amt="8400" bank_id="7" acct_num="1016232382" />...',
197            self.browser.contents)
198        self.assertFalse(
199            'item_name="BT Education"' in self.browser.contents)
[9384]200
[9727]201        # Create temp maint fee ticket
202        self.browser.open(self.payments_path + '/addop')
203        self.browser.getControl(name="form.p_category").value = ['tempmaint_1']
204        self.browser.getControl("Create ticket").click()
205        ctrl = self.browser.getControl(name='val_id')
206        value = ctrl.options[4]
207        self.browser.getLink(value).click()
208        self.assertMatches(
[9728]209            '...<span>8150.0</span>...',
[9727]210            self.browser.contents)
211        # Manager can access InterswitchForm
212        self.browser.getLink("CollegePAY", index=0).click()
[9775]213        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
214        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
[9727]215        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5705" />...',
216                           self.browser.contents)
217        self.assertMatches('...Total Amount Authorized:...',
218                           self.browser.contents)
219        self.assertMatches(
[9728]220            '...<input type="hidden" name="amount" value="815000.0" />...',
[9727]221            self.browser.contents)
222        self.assertMatches(
[9731]223            '...<item_detail item_id="1" item_name="Hostel Maintenance Fee" item_amt="800000" bank_id="129" acct_num="0014414547" />...',
[9727]224            self.browser.contents)
[9728]225        self.assertFalse(
226            'item_name="BT Education"' in self.browser.contents)
[9727]227
[9863]228        # Create previous session fee ticket
229        configuration = createObject('waeup.SessionConfiguration')
230        configuration.academic_session = 2003
231        configuration.clearance_fee = 3456.0
232        self.app['configuration'].addSessionConfiguration(configuration)
233        self.student['studycourse'].entry_session = 2002
234        self.browser.open(self.payments_path + '/addpp')
235        self.browser.getControl(name="form.p_category").value = ['clearance']
236        self.browser.getControl(name="form.p_session").value = ['2003']
237        self.browser.getControl(name="form.p_level").value = ['300']
238        self.browser.getControl("Create ticket").click()
239        ctrl = self.browser.getControl(name='val_id')
240        value = ctrl.options[5]
241        self.browser.getLink(value).click()
242        self.assertMatches(
243            '...<span>45000.0</span>...',
244            self.browser.contents)
245        # Manager can access InterswitchForm
246        self.browser.getLink("CollegePAY", index=0).click()
247        self.assertEqual(self.student['payments'][value].provider_amt, 1500.0)
248        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
249        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5702" />...',
250                           self.browser.contents)
251        self.assertMatches('...Total Amount Authorized:...',
252                           self.browser.contents)
253        self.assertMatches(
254            '...<input type="hidden" name="amount" value="4500000.0" />...',
255            self.browser.contents)
256        self.assertMatches(
257            '...<item_detail item_id="1" item_name="Acceptance Fee" item_amt="4335000" bank_id="7" acct_num="1003475516" />...',
258            self.browser.contents)
259
[9869]260        # Create balance payment ticket
261        self.browser.open(self.payments_path + '/addbp')
262        self.browser.getControl(name="form.p_category").value = ['schoolfee']
263        self.browser.getControl(name="form.balance_session").value = ['2003']
264        self.browser.getControl(name="form.balance_level").value = ['300']
265        self.browser.getControl(name="form.balance_amount").value = '200'
266        self.browser.getControl("Create ticket").click()
267        ctrl = self.browser.getControl(name='val_id')
268        value = ctrl.options[6]
269        self.browser.getLink(value).click()
270        self.assertMatches(
271            '...<span>200.0</span>...',
272            self.browser.contents)
273        # Manager can access InterswitchForm
274        self.browser.getLink("CollegePAY", index=0).click()
275        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
276        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
277        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5701" />...',
278                           self.browser.contents)
279        self.assertMatches(
280            '...<input type="hidden" name="amount" value="20000.0" />...',
281            self.browser.contents)
282        self.assertMatches(
283            '...item_name="School Fee" item_amt="5000" bank_id="16" acct_num="0122009929"...',
284            self.browser.contents)
285        self.assertFalse(
286            'item_name="BT Education"' in self.browser.contents)
[9863]287
[8263]288#    @external_test
289#    def test_callback(self):
[7970]290
[7894]291        # Manager can call callback manually
[8263]292#        self.browser.open(self.callback_url(self.payment_url, 'XX', '300'))
293#        self.assertMatches('...Unsuccessful callback: Something went wrong...',
294#                          self.browser.contents)
295#        self.assertMatches('...Failed...',
296#                           self.browser.contents)
297#        self.browser.open(self.payment_url + '/isw_callback')
298#        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
299#                          self.browser.contents)
300#        self.assertMatches('...Failed...',
301#                           self.browser.contents)
302#        self.browser.open(self.callback_url(self.payment_url, '00', '300000'))
303#        self.assertMatches('...Wrong amount...',
304#                          self.browser.contents)
305#        self.browser.open(self.callback_url(self.payment_url, '00', '4000000'))
306#        self.assertMatches('...Valid callback received...',
307#                          self.browser.contents)
[7930]308
[7970]309    @external_test
[7930]310    def test_webservice(self):
[9775]311        # First we have open InterswitchPageStudent to set provider_amt
312        # and gateway_amt
313        self.browser.open(self.payment_url + '/goto_interswitch')
314        # Now we can call the webservice
[7970]315        self.browser.open(self.payment_url + '/request_webservice')
[7930]316        self.assertMatches('...Unsuccessful callback...',
317                          self.browser.contents)
[9713]318        # The payment is now in state failed ...
[8266]319        self.assertMatches('...<span>Failed</span>...',
320                          self.browser.contents)
[9713]321        # ... and the catalog has been updated
322        cat = getUtility(ICatalog, name='payments_catalog')
323        results = list(
324            cat.searchResults(p_state=('failed', 'failed')))
325        self.assertEqual(len(results), 1)
326        self.assertEqual(results[0].p_state, 'failed')
[8266]327
[9775]328        # Let's replace the p_id with a valid p_id of the Uniben
329        # live system. This is definitely not an appropriate
330        # solution for testing, but we have no choice since
331        # Interswitch doesn't provide any interface
332        # for testing.
333        payment = self.student['payments'][self.value]
334        payment.p_id = 'p3547789850240'
335        self.browser.open(self.payment_url + '/request_webservice')
336        self.assertMatches('...Callback amount does not match...',
337                          self.browser.contents)
338        # The payment is now in state failed ...
339        self.assertMatches('...<span>Failed</span>...',
340                          self.browser.contents)
341        # Let's replace the amount autorized with the amount of the
342        # live system payment
343        payment.amount_auth = payment.r_amount_approved
344        self.browser.open(self.payment_url + '/request_webservice')
345        self.assertMatches('...Successful payment...',
346                          self.browser.contents)
347        # The payment is now in state paid ...
348        self.assertMatches('...<span>Paid</span>...',
349                          self.browser.contents)
350        # ... and the catalog has been updated
351        cat = getUtility(ICatalog, name='payments_catalog')
352        results = list(
353            cat.searchResults(p_state=('paid', 'paid')))
354        self.assertEqual(len(results), 1)
355        self.assertEqual(results[0].p_state, 'paid')
356        # Approval is logged in students.log ...
357        logfile = os.path.join(
358            self.app['datacenter'].storage, 'logs', 'students.log')
359        logcontent = open(logfile).read()
360        self.assertTrue(
361            'zope.mgr - '
362            'waeup.uniben.interswitch.browser.InterswitchPaymentRequestWebservicePageStudent - '
363            'B1000000 - successful schoolfee payment: p3547789850240\n'
364            in logcontent)
365        # ... and in payments.log
366        logfile = os.path.join(
367            self.app['datacenter'].storage, 'logs', 'payments.log')
368        logcontent = open(logfile).read()
369        self.assertTrue(
370            '"zope.mgr",B1000000,p3547789850240,schoolfee,'
371            '12000.0,00,1500.0,150.0,0.0,,,\n'
372            in logcontent)
373
374
[8266]375class InterswitchTestsApplicants(ApplicantsFullSetup):
376    """Tests for the Interswitch payment gateway.
377    """
378
379    layer = FunctionalLayer
380
381    def setUp(self):
382        super(InterswitchTestsApplicants, self).setUp()
383        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
384        self.browser.open(self.manage_path)
385        #IWorkflowState(self.student).setState('started')
386        super(InterswitchTestsApplicants, self).fill_correct_values()
[8526]387        self.applicantscontainer.application_fee = 1000.0
[9453]388        self.browser.getControl(name="form.nationality").value = ['NG']
[8266]389        self.browser.getControl(name="transition").value = ['start']
390        self.browser.getControl("Save").click()
391        self.browser.getControl("Add online").click()
392        self.assertMatches('...ticket created...',
393                           self.browser.contents)
[8281]394        #ctrl = self.browser.getControl(name='val_id')
395        #value = ctrl.options[0]
396        #self.browser.getLink(value).click()
[8266]397        self.assertMatches('...Amount Authorized...',
398                           self.browser.contents)
399        self.assertMatches(
400            '...<span>1000.0</span>...',
401            self.browser.contents)
402        self.payment_url = self.browser.url
403
404
405    def test_interswitch_form(self):
406
407        # Manager can access InterswitchForm
408        self.browser.getLink("CollegePAY", index=0).click()
409        self.assertMatches('...Total Amount Authorized:...',
410                           self.browser.contents)
411        self.assertMatches(
[8276]412            '...<input type="hidden" name="amount" value="100000.0" />...',
[8266]413            self.browser.contents)
414
415    @external_test
416    def test_webservice(self):
417
418        self.browser.open(self.payment_url + '/request_webservice')
419        self.assertMatches('...Unsuccessful callback...',
420                          self.browser.contents)
421        # The payment is now in state failed
422        self.assertMatches('...<span>Failed</span>...',
423                          self.browser.contents)
Note: See TracBrowser for help on using the repository browser.