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

Last change on this file since 15475 was 15427, checked in by Henrik Bettermann, 6 years ago

Construct fullname.

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