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

Last change on this file since 15185 was 14931, checked in by Henrik Bettermann, 7 years ago

Change fees.

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