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

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

Third semester fee applies to nce_ft and not nce_sw.
Increase fees.

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