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

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

We can't test clearance payment ticket creation at the moment, since Uniben decided to deactivate clearance for ug students.

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