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

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

Requirements for adding application payment tickets customized.
Applicants must upload passport picture before adding payment tickets.

  • Property svn:keywords set to Id
File size: 21.4 KB
Line 
1## $Id: tests.py 11728 2014-07-03 08:17:34Z 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##
18import os
19from datetime import datetime
20from zope.component import createObject, getUtility
21from zope.catalog.interfaces import ICatalog
22from hurry.workflow.interfaces import IWorkflowState
23from waeup.kofa.students.tests.test_browser import StudentsFullSetup
24from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
25from waeup.kofa.configuration import SessionConfiguration
26from waeup.uniben.testing import FunctionalLayer
27
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.
31EXTERNAL_TESTS = False
32
33SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
34
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
46class InterswitchTestsStudents(StudentsFullSetup):
47    """Tests for the Interswitch payment gateway.
48    """
49
50    layer = FunctionalLayer
51
52    def setUp(self):
53        super(InterswitchTestsStudents, self).setUp()
54        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
55        self.browser.open(self.payments_path)
56        IWorkflowState(self.student).setState('cleared')
57        self.student.nationality = u'NG'
58        self.browser.open(self.payments_path + '/addop')
59        self.browser.getControl(name="form.p_category").value = ['schoolfee']
60        self.browser.getControl("Create ticket").click()
61        self.assertMatches('...ticket created...',
62                           self.browser.contents)
63        ctrl = self.browser.getControl(name='val_id')
64        self.value = ctrl.options[0]
65        self.browser.getLink(self.value).click()
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
72
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)
83
84    def test_interswitch_form(self):
85        # Manager can access InterswitchForm
86        self.browser.getLink("CollegePAY", index=0).click()
87        # The total amount to be processed by Interswitch
88        # has been reduced by the Interswitch fee of 150 Nairas
89        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5700" />...',
90                           self.browser.contents)
91        self.assertMatches('...Total Amount Authorized:...',
92                           self.browser.contents)
93        self.assertEqual(self.student.current_mode, 'ug_ft')
94        self.assertMatches(
95            '...<input type="hidden" name="amount" value="4000000.0" />...',
96            self.browser.contents)
97        self.assertMatches(
98            '...item_name="School Fee" item_amt="3835000" bank_id="8" acct_num="2017506430"...',
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)
103
104        # Create school fee ticket for returning students. Payment is made
105        # for next session.
106        current_payment_key = self.student['payments'].keys()[0]
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)
112        self.browser.open(self.payments_path + '/addop')
113        self.browser.getControl(name="form.p_category").value = ['schoolfee']
114        self.browser.getControl("Create ticket").click()
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
126        ctrl = self.browser.getControl(name='val_id')
127        value = ctrl.options[1]
128        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
129        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
130        self.browser.getLink(value).click()
131        self.browser.getLink("CollegePAY", index=0).click()
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)
135        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5701" />...',
136                           self.browser.contents)
137        self.assertMatches(
138            '...<input type="hidden" name="amount" value="2000000.0" />...',
139            self.browser.contents)
140        self.assertMatches(
141            '...item_name="School Fee" item_amt="1835000" bank_id="16" acct_num="0122009929"...',
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
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)
174
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')
182        value = ctrl.options[2]
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()
189        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
190        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
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(
196            '...<input type="hidden" name="amount" value="23400.0" />...',
197            self.browser.contents)
198        self.assertMatches(
199            '...<item_detail item_id="1" item_name="Gown Hire Fee" item_amt="8400" bank_id="16" acct_num="0122011401" />...',
200            self.browser.contents)
201        self.assertFalse(
202            'item_name="BT Education"' in self.browser.contents)
203
204        # Create temp maint fee ticket
205        self.browser.open(self.payments_path + '/addop')
206        self.browser.getControl(name="form.p_category").value = ['tempmaint_1']
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>8150.0</span>...',
213            self.browser.contents)
214        # Manager can access InterswitchForm
215        self.browser.getLink("CollegePAY", index=0).click()
216        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
217        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
218        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5705" />...',
219                           self.browser.contents)
220        self.assertMatches('...Total Amount Authorized:...',
221                           self.browser.contents)
222        self.assertMatches(
223            '...<input type="hidden" name="amount" value="815000.0" />...',
224            self.browser.contents)
225        self.assertMatches(
226            '...<item_detail item_id="1" item_name="Hostel Maintenance Fee" item_amt="800000" bank_id="17" acct_num="0009598925" />...',
227            self.browser.contents)
228        self.assertFalse(
229            'item_name="BT Education"' in self.browser.contents)
230
231        # Create previous session fee ticket
232        configuration = createObject('waeup.SessionConfiguration')
233        configuration.academic_session = 2003
234        configuration.clearance_fee = 3456.0
235        self.app['configuration'].addSessionConfiguration(configuration)
236        self.student['studycourse'].entry_session = 2002
237        #self.browser.open(self.payments_path + '/addpp')
238        #self.browser.getControl(name="form.p_category").value = ['clearance']
239        #self.browser.getControl(name="form.p_session").value = ['2003']
240        #self.browser.getControl(name="form.p_level").value = ['300']
241        #self.browser.getControl("Create ticket").click()
242        #ctrl = self.browser.getControl(name='val_id')
243        #value = ctrl.options[5]
244        #self.browser.getLink(value).click()
245        #self.assertMatches(
246        #    '...<span>45000.0</span>...',
247        #    self.browser.contents)
248        ## Manager can access InterswitchForm
249        #self.browser.getLink("CollegePAY", index=0).click()
250        #self.assertEqual(self.student['payments'][value].provider_amt, 1500.0)
251        #self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
252        #self.assertMatches('...<input type="hidden" name="pay_item_id" value="5702" />...',
253        #                   self.browser.contents)
254        #self.assertMatches('...Total Amount Authorized:...',
255        #                   self.browser.contents)
256        ##self.assertMatches(
257        #    '...<input type="hidden" name="amount" value="4500000.0" />...',
258        #    self.browser.contents)
259        #self.assertMatches(
260        #    '...<item_detail item_id="1" item_name="Acceptance Fee" item_amt="4335000" bank_id="7" acct_num="1003475516" />...',
261        #    self.browser.contents)
262
263        # Create balance payment ticket
264        self.browser.open(self.payments_path + '/addbp')
265        self.browser.getControl(name="form.p_category").value = ['schoolfee']
266        self.browser.getControl(name="form.balance_session").value = ['2003']
267        self.browser.getControl(name="form.balance_level").value = ['300']
268        self.browser.getControl(name="form.balance_amount").value = '200'
269        self.browser.getControl("Create ticket").click()
270        ctrl = self.browser.getControl(name='val_id')
271        value = ctrl.options[4]
272        self.browser.getLink(value).click()
273        self.assertMatches(
274            '...<span>200.0</span>...',
275            self.browser.contents)
276        # Manager can access InterswitchForm
277        self.browser.getLink("CollegePAY", index=0).click()
278        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
279        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
280        self.assertMatches('...<input type="hidden" name="pay_item_id" value="5701" />...',
281                           self.browser.contents)
282        self.assertMatches(
283            '...<input type="hidden" name="amount" value="20000.0" />...',
284            self.browser.contents)
285        self.assertMatches(
286            '...item_name="School Fee" item_amt="5000" bank_id="16" acct_num="0122009929"...',
287            self.browser.contents)
288        self.assertFalse(
289            'item_name="BT Education"' in self.browser.contents)
290
291#    @external_test
292#    def test_callback(self):
293
294        # Manager can call callback manually
295#        self.browser.open(self.callback_url(self.payment_url, 'XX', '300'))
296#        self.assertMatches('...Unsuccessful callback: Something went wrong...',
297#                          self.browser.contents)
298#        self.assertMatches('...Failed...',
299#                           self.browser.contents)
300#        self.browser.open(self.payment_url + '/isw_callback')
301#        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
302#                          self.browser.contents)
303#        self.assertMatches('...Failed...',
304#                           self.browser.contents)
305#        self.browser.open(self.callback_url(self.payment_url, '00', '300000'))
306#        self.assertMatches('...Wrong amount...',
307#                          self.browser.contents)
308#        self.browser.open(self.callback_url(self.payment_url, '00', '4000000'))
309#        self.assertMatches('...Valid callback received...',
310#                          self.browser.contents)
311
312    def test_pay_twice(self):
313        # Create second ticket
314        self.browser.open(self.payments_path + '/addop')
315        self.browser.getControl(name="form.p_category").value = ['schoolfee']
316        self.browser.getControl("Create ticket").click()
317        # Pay first ticket
318        self.student['payments'][self.value].approve()
319        # Try to pay second ticket
320        self.browser.open(self.payments_path)
321        ctrl = self.browser.getControl(name='val_id')
322        value = ctrl.options[1]
323        self.browser.getLink(value).click()
324        self.browser.getLink("CollegePAY", index=0).click()
325        self.assertMatches(
326            '...alert alert-danger">This type of payment has already been made...',
327            self.browser.contents)
328
329    @external_test
330    def test_webservice(self):
331        # First we have open InterswitchPageStudent to set provider_amt
332        # and gateway_amt
333        self.browser.open(self.payment_url + '/goto_interswitch')
334        # Now we can call the webservice
335        self.browser.open(self.payment_url + '/request_webservice')
336        self.assertMatches('...Unsuccessful callback...',
337                          self.browser.contents)
338        # The payment is now in state failed ...
339        self.assertMatches('...<span>Failed</span>...',
340                          self.browser.contents)
341        # ... and the catalog has been updated
342        cat = getUtility(ICatalog, name='payments_catalog')
343        results = list(
344            cat.searchResults(p_state=('failed', 'failed')))
345        self.assertEqual(len(results), 1)
346        self.assertEqual(results[0].p_state, 'failed')
347
348        # Let's replace the p_id with a valid p_id of the Uniben
349        # live system. This is definitely not an appropriate
350        # solution for testing, but we have no choice since
351        # Interswitch doesn't provide any interface
352        # for testing.
353        payment = self.student['payments'][self.value]
354        payment.p_id = 'p3547789850240'
355        self.browser.open(self.payment_url + '/request_webservice')
356        self.assertMatches('...Callback amount does not match...',
357                          self.browser.contents)
358        # The payment is now in state failed ...
359        self.assertMatches('...<span>Failed</span>...',
360                          self.browser.contents)
361        # Let's replace the amount autorized with the amount of the
362        # live system payment
363        payment.amount_auth = payment.r_amount_approved
364        self.browser.open(self.payment_url + '/request_webservice')
365        self.assertMatches('...Successful payment...',
366                          self.browser.contents)
367        # The payment is now in state paid ...
368        self.assertMatches('...<span>Paid</span>...',
369                          self.browser.contents)
370        # ... and the catalog has been updated
371        cat = getUtility(ICatalog, name='payments_catalog')
372        results = list(
373            cat.searchResults(p_state=('paid', 'paid')))
374        self.assertEqual(len(results), 1)
375        self.assertEqual(results[0].p_state, 'paid')
376        # Approval is logged in students.log ...
377        logfile = os.path.join(
378            self.app['datacenter'].storage, 'logs', 'students.log')
379        logcontent = open(logfile).read()
380        self.assertTrue(
381            'zope.mgr - '
382            'waeup.uniben.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
383            'B1000000 - successful schoolfee payment: p3547789850240\n'
384            in logcontent)
385        # ... and in payments.log
386        logfile = os.path.join(
387            self.app['datacenter'].storage, 'logs', 'payments.log')
388        logcontent = open(logfile).read()
389        self.assertTrue(
390            '"zope.mgr",B1000000,p3547789850240,schoolfee,'
391            '12000.0,00,1500.0,150.0,0.0,,,\n'
392            in logcontent)
393
394
395class InterswitchTestsApplicants(ApplicantsFullSetup):
396    """Tests for the Interswitch payment gateway.
397    """
398
399    layer = FunctionalLayer
400
401    def setUp(self):
402        super(InterswitchTestsApplicants, self).setUp()
403        configuration = SessionConfiguration()
404        configuration.academic_session = datetime.now().year - 2
405        self.app['configuration'].addSessionConfiguration(configuration)
406        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
407        self.browser.open(self.manage_path)
408        #IWorkflowState(self.student).setState('started')
409        self.applicantscontainer.application_fee = 1000.0
410        super(InterswitchTestsApplicants, self).fill_correct_values()
411        self.browser.getControl("Add online").click()
412        self.assertMatches('...Upload your passport photo before making payment...',
413                           self.browser.contents)
414        self.browser.open(self.manage_path)
415        super(InterswitchTestsApplicants, self).fill_correct_values()
416        #self.browser.getControl(name="form.nationality").value = ['NG']
417        #self.browser.getControl(name="transition").value = ['start']
418        image = open(SAMPLE_IMAGE, 'rb')
419        ctrl = self.browser.getControl(name='form.passport')
420        file_ctrl = ctrl.mech_control
421        file_ctrl.add_file(image, filename='myphoto.jpg')
422        self.browser.getControl("Save").click()
423        self.browser.getControl("Add online").click()
424        self.assertMatches('...ticket created...',
425                           self.browser.contents)
426        #ctrl = self.browser.getControl(name='val_id')
427        #value = ctrl.options[0]
428        #self.browser.getLink(value).click()
429        self.payment_url = self.browser.url
430
431    def test_interswitch_form(self):
432        self.assertMatches('...Amount Authorized...',
433                           self.browser.contents)
434        self.assertMatches(
435            '...<span>1000.0</span>...',
436            self.browser.contents)
437        # Manager can access InterswitchForm
438        self.browser.getLink("CollegePAY", index=0).click()
439        self.assertMatches('...Total Amount Authorized:...',
440                           self.browser.contents)
441        self.assertMatches(
442            '...<input type="hidden" name="amount" value="100000.0" />...',
443            self.browser.contents)
444
445    @external_test
446    def test_webservice(self):
447
448        self.browser.open(self.payment_url + '/request_webservice')
449        self.assertMatches('...Unsuccessful callback...',
450                          self.browser.contents)
451        # The payment is now in state failed
452        self.assertMatches('...<span>Failed</span>...',
453                          self.browser.contents)
Note: See TracBrowser for help on using the repository browser.