source: main/waeup.fceokene/trunk/src/waeup/fceokene/interswitch/tests.py @ 10468

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

Add Interswitch surcharge to all student fees.

  • Property svn:keywords set to Id
File size: 19.1 KB
Line 
1## $Id: tests.py 10388 2013-06-27 07:33:45Z 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 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.fceokene.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.certificate.study_mode = 'nce_ft'
52        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
53        self.browser.open(self.payments_path)
54        IWorkflowState(self.student).setState('cleared')
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.assertTrue(
66            '<span>12645.0</span>' in self.browser.contents)
67        self.payment_url = self.browser.url
68
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
83        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
84        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
85        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
86        # Manager can access InterswitchForm for the created school fee ticket
87        self.browser.getLink("CollegePAY", index=0).click()
88        # Split amounts have been set
89        self.assertEqual(self.student['payments'][self.value].provider_amt, 1600.0)
90        self.assertEqual(self.student['payments'][self.value].gateway_amt, 150.0)
91        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1400.0)
92        self.assertMatches('...Total Amount Authorized:...',
93                           self.browser.contents)
94        self.assertTrue(
95            '<input type="hidden" name="amount" value="1264500.0" />'
96            in self.browser.contents)
97        self.assertTrue(
98            'item_name="School Fee" item_amt="949500" bank_id="117" acct_num="1012044015"'
99            in self.browser.contents)
100        self.assertTrue(
101            'item_name="FCEOkene Split" item_amt="140000" bank_id="117" acct_num="1012044039"'
102            in self.browser.contents)
103        self.assertTrue(
104            'item_name="BT Education" item_amt="160000" bank_id="31" acct_num="0026781725"'
105            in self.browser.contents)
106
107        # Maintenance fee payment
108
109        self.browser.open(self.payments_path)
110        self.browser.open(self.payments_path + '/addop')
111        self.browser.getControl(
112            name="form.p_category").value = ['hostel_maintenance']
113        self.browser.getControl("Create ticket").click()
114        self.assertMatches('...You have not yet booked accommodation...',
115                           self.browser.contents)
116        # Students have to book bed first
117        self.browser.open(self.acco_path)
118        IWorkflowState(self.student).setState('admitted')
119        self.browser.getLink("Book accommodation").click()
120        self.assertFalse('Activation Code:' in self.browser.contents)
121        self.browser.getControl("Create bed ticket").click()
122        # Bed is randomly selected but, since there is only
123        # one bed for this student, we know that ...
124        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
125                           in self.browser.contents)
126        self.assertTrue('(see payment slip)'
127                           in self.browser.contents)
128        self.assertTrue('ticket created'
129                           in self.browser.contents)
130        self.browser.open(self.payments_path + '/addop')
131        self.browser.getControl(
132            name="form.p_category").value = ['hostel_maintenance']
133        self.browser.getControl("Create ticket").click()
134        self.assertMatches('...ticket created...',
135                           self.browser.contents)
136        ctrl = self.browser.getControl(name='val_id')
137        value = ctrl.options[1]
138        self.browser.getLink(value).click()
139        self.assertMatches('...Amount Authorized...',
140                           self.browser.contents)
141        self.assertTrue(
142            '<span>4300.0</span>' in self.browser.contents)
143        # p_item is not unveiled
144        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
145            in self.browser.contents)
146        self.assertTrue('(visible after successful payment)'
147            in self.browser.contents)
148        self.payment_url = self.browser.url
149        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
150        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
151        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
152        # Manager can access InterswitchForm
153        self.browser.getLink("CollegePAY", index=0).click()
154        # Split amounts have been set
155        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
156        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
157        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
158        # The total amount to be processed by Interswitch
159        # has been reduced by the Interswitch fee of 150 Nairas
160        self.assertMatches('...Total Amount Authorized:...',
161                           self.browser.contents)
162        self.assertTrue(
163            '<input type="hidden" name="amount" value="430000.0" />'
164            in self.browser.contents)
165        self.assertTrue(
166            'item_name="Hostel Maintenance Fee" item_amt="415000" bank_id="117" acct_num="1012044132"'
167            in self.browser.contents)
168        # BT does nor charge a fee for maintenance fee
169        self.assertFalse("BT Education" in self.browser.contents)
170        # p_item is not unveiled
171        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
172            in self.browser.contents)
173        self.assertTrue('(visible after successful payment)'
174            in self.browser.contents)
175        # If the ticket is paid coordinates are shown
176        self.student['payments'][value].p_state = 'paid'
177        self.browser.open(self.payment_url)
178        self.assertTrue('Hall 1, Block A, Room 101, Bed A'
179            in self.browser.contents)
180        self.assertFalse('(visible after successful payment)'
181            in self.browser.contents)
182
183        # Acceptance fee payment
184
185        self.browser.open(self.payments_path)
186        self.browser.open(self.payments_path + '/addop')
187        self.browser.getControl(
188            name="form.p_category").value = ['clearance']
189        self.browser.getControl("Create ticket").click()
190        self.assertMatches('...ticket created...',
191                           self.browser.contents)
192        ctrl = self.browser.getControl(name='val_id')
193        value = ctrl.options[2]
194        self.browser.getLink(value).click()
195        self.assertMatches('...Amount Authorized...',
196                           self.browser.contents)
197        self.assertTrue(
198            '<span>3606.0</span>' in self.browser.contents)
199        self.payment_url = self.browser.url
200        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
201        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
202        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
203        # Manager can access InterswitchForm
204        self.browser.getLink("CollegePAY", index=0).click()
205        # Split amounts have been set
206        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
207        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
208        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
209        # The total amount to be processed by Interswitch
210        # has been reduced by the Interswitch fee of 150 Nairas
211        self.assertMatches('...Total Amount Authorized:...',
212                           self.browser.contents)
213        self.assertTrue(
214            '<input type="hidden" name="amount" value="360600.0" />' in
215            self.browser.contents)
216        self.assertTrue(
217            'item_name="Acceptance Fee" item_amt="345600" bank_id="8" acct_num="2003670143"'
218            in self.browser.contents)
219        # BT does nor charge a fee for maintenance fee
220        self.assertFalse("BT Education" in self.browser.contents)
221
222#    @external_test
223#    def test_callback(self):
224
225        # Manager can call callback manually
226#        self.browser.open(self.callback_url(self.payment_url, 'XX', '300'))
227#        self.assertMatches('...Unsuccessful callback: Something went wrong...',
228#                          self.browser.contents)
229#        self.assertMatches('...Failed...',
230#                           self.browser.contents)
231#        self.browser.open(self.payment_url + '/isw_callback')
232#        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
233#                          self.browser.contents)
234#        self.assertMatches('...Failed...',
235#                           self.browser.contents)
236#        self.browser.open(self.callback_url(self.payment_url, '00', '300000'))
237#        self.assertMatches('...Wrong amount...',
238#                          self.browser.contents)
239#        self.browser.open(self.callback_url(self.payment_url, '00', '4000000'))
240#        self.assertMatches('...Valid callback received...',
241#                          self.browser.contents)
242
243    @external_test
244    def test_webservice(self):
245        # First we have open InterswitchPageStudent to set provider_amt
246        # and gateway_amt
247        self.browser.open(self.payment_url + '/goto_interswitch')
248        # Now we can call the webservice
249        self.browser.open(self.payment_url + '/request_webservice')
250        #self.assertMatches('...Unsuccessful callback...',
251        #                  self.browser.contents)
252        self.assertMatches('...Unsuccessful callback...',
253                          self.browser.contents)
254        # The payment is now in state failed ...
255        self.assertMatches('...<span>Failed</span>...',
256                          self.browser.contents)
257        # ... and the catalog has been updated
258        cat = getUtility(ICatalog, name='payments_catalog')
259        results = list(
260            cat.searchResults(p_state=('failed', 'failed')))
261        self.assertEqual(len(results), 1)
262        self.assertEqual(results[0].p_state, 'failed')
263
264        # Let's replace the p_id with a valid p_id of the FCEOkene
265        # live system. This is definitely not an appropriate
266        # solution for testing, but we have no choice since
267        # Interswitch doesn't provide any interface
268        # for testing.
269        payment = self.student['payments'][self.value]
270        payment.p_id = 'p3536651296379'
271        self.browser.open(self.payment_url + '/request_webservice')
272        self.assertMatches('...Callback amount does not match...',
273                          self.browser.contents)
274        # The payment is now in state failed ...
275        self.assertMatches('...<span>Failed</span>...',
276                          self.browser.contents)
277        # Let's replace the amount autorized with the amount of the
278        # live system payment
279        payment.amount_auth = payment.r_amount_approved
280        self.browser.open(self.payment_url + '/request_webservice')
281        self.assertMatches('...Successful payment...',
282                          self.browser.contents)
283        # The payment is now in state paid ...
284        self.assertMatches('...<span>Paid</span>...',
285                          self.browser.contents)
286        # ... and the catalog has been updated
287        cat = getUtility(ICatalog, name='payments_catalog')
288        results = list(
289            cat.searchResults(p_state=('paid', 'paid')))
290        self.assertEqual(len(results), 1)
291        self.assertEqual(results[0].p_state, 'paid')
292        # Approval is logged in students.log ...
293        logfile = os.path.join(
294            self.app['datacenter'].storage, 'logs', 'students.log')
295        logcontent = open(logfile).read()
296        self.assertTrue(
297            'zope.mgr - '
298            'waeup.fceokene.interswitch.browser.InterswitchPaymentRequestWebservicePageStudent - '
299            'K1000000 - successful schoolfee payment: p3536651296379\n'
300            in logcontent)
301        # ... and in payments.log
302        logfile = os.path.join(
303            self.app['datacenter'].storage, 'logs', 'payments.log')
304        logcontent = open(logfile).read()
305        self.assertTrue(
306            '"zope.mgr",K1000000,p3536651296379,schoolfee,'
307            '3150.0,00,1600.0,150.0,1400.0,,,\n'
308            in logcontent)
309
310class InterswitchTestsApplicants(ApplicantsFullSetup):
311    """Tests for the Interswitch payment gateway.
312    """
313
314    layer = FunctionalLayer
315
316    def setUp(self):
317        super(InterswitchTestsApplicants, self).setUp()
318        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
319        self.browser.open(self.manage_path)
320        #IWorkflowState(self.student).setState('started')
321        super(InterswitchTestsApplicants, self).fill_correct_values()
322        self.applicantscontainer.application_fee = 1000.0
323        self.browser.getControl(name="form.nationality").value = ['NG']
324        self.browser.getControl(name="transition").value = ['start']
325        self.browser.getControl("Save").click()
326        self.browser.getControl("Add online").click()
327        self.assertMatches('...ticket created...',
328                           self.browser.contents)
329        self.assertMatches('...Amount Authorized...',
330                           self.browser.contents)
331        self.assertMatches(
332            '...<span>1000.0</span>...',
333            self.browser.contents)
334        self.payment_url = self.browser.url
335        self.browser.open(self.manage_path)
336        ctrl = self.browser.getControl(name='val_id')
337        self.value = ctrl.options[0]
338
339
340    def test_interswitch_form(self):
341
342        # Manager can access InterswitchForm
343        self.browser.open(self.payment_url)
344        self.browser.getLink("CollegePAY", index=0).click()
345        self.assertMatches('...Total Amount Authorized:...',
346                           self.browser.contents)
347        self.assertTrue(
348            '<input type="hidden" name="amount" value="100000.0" />'
349            in self.browser.contents)
350
351    @external_test
352    def test_webservice(self):
353        # First we have open InterswitchPageStudent to set provider_amt
354        # and gateway_amt
355        self.browser.open(self.payment_url + '/goto_interswitch')
356        # Now we can call the webservice
357        self.browser.open(self.payment_url + '/request_webservice')
358        self.assertMatches('...Unsuccessful callback...',
359                          self.browser.contents)
360        # The payment is now in state failed ...
361        self.assertMatches('...<span>Failed</span>...',
362                          self.browser.contents)
363        # ... and the catalog has been updated
364        cat = getUtility(ICatalog, name='payments_catalog')
365        results = list(
366            cat.searchResults(p_state=('failed', 'failed')))
367        self.assertEqual(len(results), 1)
368        self.assertEqual(results[0].p_state, 'failed')
369
370        # Let's replace the p_id with a valid p_id of the Uniben
371        # live system. This is definitely not an appropriate
372        # solution for testing, but we have no choice since
373        # Interswitch doesn't provide any interface
374        # for testing.
375        payment = self.applicant[self.value]
376        payment.p_id = 'p3536651296379'
377        self.browser.open(self.payment_url + '/request_webservice')
378        self.assertMatches('...Callback amount does not match...',
379                          self.browser.contents)
380        # The payment is now in state failed ...
381        self.assertMatches('...<span>Failed</span>...',
382                          self.browser.contents)
383        # Let's replace the amount autorized with the amount of the
384        # live system payment
385        payment.amount_auth = payment.r_amount_approved
386        self.browser.open(self.payment_url + '/request_webservice')
387        self.assertMatches('...Successful payment...',
388                          self.browser.contents)
389        # The payment is now in state paid ...
390        self.assertMatches('...<span>Paid</span>...',
391                          self.browser.contents)
392        # ... and the catalog has been updated
393        cat = getUtility(ICatalog, name='payments_catalog')
394        results = list(
395            cat.searchResults(p_state=('paid', 'paid')))
396        self.assertEqual(len(results), 1)
397        self.assertEqual(results[0].p_state, 'paid')
398        # Approval is logged in students.log ...
399        logfile = os.path.join(
400            self.app['datacenter'].storage, 'logs', 'applicants.log')
401        logcontent = open(logfile).read()
402        self.assertTrue(
403            'zope.mgr - '
404            'waeup.fceokene.interswitch.browser.InterswitchPaymentRequestWebservicePageApplicant - '
405            '%s - successful payment: p3536651296379\n'
406            % self.applicant.applicant_id in logcontent)
407        # ... and in payments.log
408        logfile = os.path.join(
409            self.app['datacenter'].storage, 'logs', 'payments.log')
410        logcontent = open(logfile).read()
411        self.assertTrue(
412            '"zope.mgr",%s,p3536651296379,application,'
413            '3150.0,00,500.0,150.0,0.0,,,\n' % self.applicant.applicant_id
414            in logcontent)
Note: See TracBrowser for help on using the repository browser.