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

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

In Uniben fresh and returning students must not register courses with more than 50 credits. For final year students maximum credits is 51.

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