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

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

Enable Remita payment gateway.

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