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

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

Adjust tests.

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