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

Last change on this file since 17183 was 16365, checked in by Henrik Bettermann, 4 years ago

Fix tests.

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