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

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

Fix tests.

  • Property svn:keywords set to Id
File size: 22.4 KB
RevLine 
[7894]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##
[9780]18import os
[12976]19from datetime import datetime, timedelta, date
[9711]20from zope.component import getUtility
21from zope.catalog.interfaces import ICatalog
[7894]22from hurry.workflow.interfaces import IWorkflowState
23from waeup.kofa.students.tests.test_browser import StudentsFullSetup
[8266]24from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
25from waeup.kofa.configuration import SessionConfiguration
[8460]26from waeup.fceokene.testing import FunctionalLayer
[7894]27
[7970]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.
[9903]31EXTERNAL_TESTS = False
[7970]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
[8266]44class InterswitchTestsStudents(StudentsFullSetup):
[7929]45    """Tests for the Interswitch payment gateway.
[7894]46    """
47
48    layer = FunctionalLayer
49
[7970]50    def setUp(self):
[8266]51        super(InterswitchTestsStudents, self).setUp()
[15271]52        self.app['configuration']['2004'].interswitch_enabled = True
[13022]53        self.certificate.study_mode = 'pd_ft'
[7970]54        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
[7995]55        self.browser.open(self.payments_path)
[7970]56        IWorkflowState(self.student).setState('cleared')
[7995]57        self.browser.open(self.payments_path + '/addop')
[9613]58        self.browser.getControl(name="form.p_category").value = ['schoolfee']
[7970]59        self.browser.getControl("Create ticket").click()
60        self.assertMatches('...ticket created...',
61                           self.browser.contents)
[16365]62        self.browser.open(self.payments_path)
[7970]63        ctrl = self.browser.getControl(name='val_id')
[9780]64        self.value = ctrl.options[0]
65        self.browser.getLink(self.value).click()
[7970]66        self.assertMatches('...Amount Authorized...',
67                           self.browser.contents)
68        self.payment_url = self.browser.url
[12976]69        self.payment = self.student['payments'][self.value]
[7970]70
[15427]71    def test_foo(self):
72        '''Test method foo.
73        '''
74        return
[7970]75
[8263]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)
[7894]86
[15303]87    def deactivated_test_interswitch_form(self):
[7894]88
[9780]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)
[9613]92        # Manager can access InterswitchForm for the created school fee ticket
[7894]93        self.browser.getLink("CollegePAY", index=0).click()
[9780]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)
[7894]97        self.assertMatches('...Total Amount Authorized:...',
98                           self.browser.contents)
[9956]99        self.assertTrue(
[13274]100            '<input type="hidden" name="amount" value="7045000" />'
[9956]101            in self.browser.contents)
102        self.assertTrue(
[13752]103            'item_name="School Fee" item_amt="6870000" bank_id="8" acct_num="2003670143"'
[9956]104            in self.browser.contents)
105        self.assertTrue(
[15271]106            'item_name="WAeAC" item_amt="160000" bank_id="31" acct_num="0773411069"'
[9956]107            in self.browser.contents)
[7894]108
[11919]109        # Third semester payment
[13022]110        self.certificate.study_mode = 'nce_ft'
[11919]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(
[14931]122            '<input type="hidden" name="amount" value="808800" />'
[11919]123            in self.browser.contents)
124        self.assertTrue(
[14931]125            'item_name="NCE Third Semester Fee" item_amt="633800" bank_id="8" acct_num="2003670143"'
[11919]126            in self.browser.contents)
127        self.assertTrue(
[15271]128            'item_name="WAeAC" item_amt="160000" bank_id="31" acct_num="0773411069"'
[11919]129            in self.browser.contents)
130
[9998]131        # Maintenance fee payment
[11920]132        self.certificate.study_mode = 'nce_ft'
[9613]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')
[13459]143        self.browser.getControl("Book accommodation").click()
[9613]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 ...
[9998]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)
[9613]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')
[11919]161        value = ctrl.options[2]
[9613]162        self.browser.getLink(value).click()
163        self.assertMatches('...Amount Authorized...',
164                           self.browser.contents)
[9956]165        self.assertTrue(
[13616]166            '<span>1026.0</span>' in self.browser.contents)
[9998]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)
[9613]172        self.payment_url = self.browser.url
[9780]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)
[9613]176        # Manager can access InterswitchForm
177        self.browser.getLink("CollegePAY", index=0).click()
[9780]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)
[9613]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)
[9956]186        self.assertTrue(
[13616]187            '<input type="hidden" name="amount" value="102600" />'
[9956]188            in self.browser.contents)
189        self.assertTrue(
[13752]190            'item_name="Hostel Maintenance Fee" item_amt="87600" bank_id="8" acct_num="2003670143"'
[9956]191            in self.browser.contents)
192        # BT does nor charge a fee for maintenance fee
193        self.assertFalse("BT Education" in self.browser.contents)
[9998]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)
[9956]206
[9998]207        # Acceptance fee payment
[9956]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')
[11919]217        value = ctrl.options[3]
[9956]218        self.browser.getLink(value).click()
219        self.assertMatches('...Amount Authorized...',
220                           self.browser.contents)
221        self.assertTrue(
[10388]222            '<span>3606.0</span>' in self.browser.contents)
[9956]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(
[11775]238            '<input type="hidden" name="amount" value="360600" />' in
[9613]239            self.browser.contents)
[9956]240        self.assertTrue(
[13752]241            'item_name="Acceptance Fee" item_amt="345600" bank_id="8" acct_num="2003670143"'
[9956]242            in self.browser.contents)
[9613]243        # BT does nor charge a fee for maintenance fee
244        self.assertFalse("BT Education" in self.browser.contents)
245
[15303]246    def deactivated_test_interswitch_form_ticket_expired(self):
[12976]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)
[13022]253        self.assertEqual(self.student.current_mode, 'pd_ft')
[12976]254        self.assertMatches(
255            '...<input type="hidden" name="amount" value="4000000" />...',
256            self.browser.contents)
[13018]257        delta = timedelta(days=8)
[12976]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)
[13018]264        delta = timedelta(days=2)
[12976]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
[8263]271#    @external_test
272#    def test_callback(self):
[7970]273
[7894]274        # Manager can call callback manually
[8263]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)
[7930]291
[7970]292    @external_test
[7930]293    def test_webservice(self):
[9780]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
[7970]298        self.browser.open(self.payment_url + '/request_webservice')
[9711]299        #self.assertMatches('...Unsuccessful callback...',
300        #                  self.browser.contents)
[9780]301        self.assertMatches('...Unsuccessful callback...',
[7930]302                          self.browser.contents)
[9711]303        # The payment is now in state failed ...
[8266]304        self.assertMatches('...<span>Failed</span>...',
305                          self.browser.contents)
[9711]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')
[8266]312
[9790]313        # Let's replace the p_id with a valid p_id of the FCEOkene
[9780]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 - '
[11635]347            'waeup.fceokene.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
[9780]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
[8266]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()
[10833]367        configuration = SessionConfiguration()
368        configuration.academic_session = datetime.now().year - 2
369        self.app['configuration'].addSessionConfiguration(configuration)
[8266]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()
[8528]374        self.applicantscontainer.application_fee = 1000.0
[9455]375        self.browser.getControl(name="form.nationality").value = ['NG']
[8266]376        self.browser.getControl(name="transition").value = ['start']
377        self.browser.getControl("Save").click()
[10833]378
[15303]379    def deactivated_test_interswitch_form(self):
[8266]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
[9780]387        self.browser.open(self.manage_path)
388        ctrl = self.browser.getControl(name='val_id')
389        self.value = ctrl.options[0]
[8266]390        # Manager can access InterswitchForm
[9780]391        self.browser.open(self.payment_url)
[8266]392        self.browser.getLink("CollegePAY", index=0).click()
393        self.assertMatches('...Total Amount Authorized:...',
394                           self.browser.contents)
[9956]395        self.assertTrue(
[11775]396            '<input type="hidden" name="amount" value="100000" />'
[9956]397            in self.browser.contents)
[10528]398        self.assertTrue(
399            '<item_detail item_id="1" item_name="application"'
[13752]400            ' item_amt="35000" bank_id="8" acct_num="2003670143" />'
[10528]401            in self.browser.contents)
[13018]402        delta = timedelta(days=8)
[12976]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)
[8266]409
410    @external_test
411    def test_webservice(self):
[10835]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]
[9780]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
[8266]426        self.browser.open(self.payment_url + '/request_webservice')
427        self.assertMatches('...Unsuccessful callback...',
428                          self.browser.contents)
[9780]429        # The payment is now in state failed ...
[8266]430        self.assertMatches('...<span>Failed</span>...',
431                          self.browser.contents)
[9780]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 - '
[11635]473            'waeup.fceokene.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageApplicant - '
[9780]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.