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

Last change on this file since 13648 was 13251, checked in by Henrik Bettermann, 10 years ago

Remove temporary solution for payment of maintenance fee and revert to original bed allocation.

Copy and adjust test_student_accommodation method.

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