source: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/interswitch/tests.py @ 10597

Last change on this file since 10597 was 10597, checked in by Henrik Bettermann, 11 years ago

Configure fee and bank account data for pre-admission applications.

  • Property svn:keywords set to Id
File size: 18.1 KB
RevLine 
[7894]1## $Id: tests.py 10597 2013-09-09 06:00:24Z 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##
[9789]18import os
[9387]19import grok
[7894]20from hurry.workflow.interfaces import IWorkflowState
[9710]21from zope.component import createObject, getUtility
22from zope.catalog.interfaces import ICatalog
[9387]23from zope.event import notify
24from waeup.kofa.university.faculty import Faculty
25from waeup.kofa.university.department import Department
[7894]26from waeup.kofa.students.tests.test_browser import StudentsFullSetup
[8266]27from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
28from waeup.kofa.configuration import SessionConfiguration
[9347]29from waeup.kwarapoly.testing import FunctionalLayer
[7894]30
[7970]31# Also run tests that send requests to external servers?
32#   If you enable this, please make sure the external services
33#   do exist really and are not bothered by being spammed by a test programme.
[9811]34EXTERNAL_TESTS = False
[7970]35
36def external_test(func):
37    if not EXTERNAL_TESTS:
38        myself = __file__
39        if myself.endswith('.pyc'):
40            myself = myself[:-2]
41        print "WARNING: external tests are skipped!"
42        print "WARNING: edit %s to enable them." % myself
43        return
44    return func
45
46
[8266]47class InterswitchTestsStudents(StudentsFullSetup):
[7929]48    """Tests for the Interswitch payment gateway.
[7894]49    """
50
51    layer = FunctionalLayer
52
[7970]53    def setUp(self):
[8266]54        super(InterswitchTestsStudents, self).setUp()
[9387]55
56        # Create at least one Kwarapoly faculty
57        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
58        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
59        self.certificate2 = createObject('waeup.Certificate')
60        self.certificate2.code = u'CERT2'
61        self.certificate2.application_category = 'basic'
62        self.certificate2.study_mode = 'nd_ft'
63        self.certificate2.start_level = 100
64        self.certificate2.end_level = 300
65        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
66            self.certificate2)
67        # Set study course attributes of test student
68        self.student['studycourse'].certificate = self.certificate2
69        self.student['studycourse'].current_session = 2004
70        self.student['studycourse'].entry_session = 2004
71        self.student['studycourse'].current_verdict = 'A'
72        self.student['studycourse'].current_level = 100
[9392]73        # Set local lga
74        self.student.lga = u'kwara_asa'
[9387]75        # Update the catalog
76        notify(grok.ObjectModifiedEvent(self.student))
77
[7970]78        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
[7995]79        self.browser.open(self.payments_path)
[7970]80        IWorkflowState(self.student).setState('cleared')
[7995]81        self.browser.open(self.payments_path + '/addop')
[9737]82        self.browser.getControl(name="form.p_category").value = ['schoolfee']
[7970]83        self.browser.getControl("Create ticket").click()
[9436]84        self.assertMatches('...ticket created...',
85                           self.browser.contents)
86        ctrl = self.browser.getControl(name='val_id')
[9789]87        self.value = ctrl.options[0]
88        self.browser.getLink(self.value).click()
[9436]89        self.assertMatches('...Amount Authorized...',
90                           self.browser.contents)
91        self.assertMatches(
[9528]92            '...<span>36600.0</span>...',
[9436]93            self.browser.contents)
94        self.payment_url = self.browser.url
[7970]95
96
[8263]97#    def callback_url(self, payment_url, resp, apprAmt):
98#        return payment_url + (
99#            '/isw_callback?echo=' +
100#            '&resp=%s' +
101#            '&desc=Something went wrong' +
102#            '&txnRef=p1331792385335' +
103#            '&payRef=' + '&retRef=' +
104#            '&cardNum=0' +
105#            '&apprAmt=%s' +
106#            '&url=http://xyz') % (resp, apprAmt)
[7894]107
[7970]108    def test_interswitch_form(self):
[7894]109        # Manager can access InterswitchForm
[9789]110        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
111        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
112        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
[7894]113        self.browser.getLink("CollegePAY", index=0).click()
[9789]114        # Split amounts have been set.
115        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
116        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
117        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
[7894]118        self.assertMatches('...Total Amount Authorized:...',
119                           self.browser.contents)
[9811]120        self.assertTrue(
121            '<input type="hidden" name="amount" value="3660000.0" />' in
[7894]122            self.browser.contents)
[9811]123        self.assertTrue(
124            'item_name="School Fee" item_amt="3330000" bank_id="120" acct_num="1771180233"' in
[9129]125            self.browser.contents)
[9811]126        self.assertTrue(
127            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
[9129]128            self.browser.contents)
[9811]129        self.assertTrue(
130            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
[9129]131            self.browser.contents)
[7894]132
[9616]133        # Let's do the same for maintenance fee payment
134
135        self.browser.open(self.payments_path)
136        self.browser.open(self.payments_path + '/addop')
137        self.browser.getControl(
138            name="form.p_category").value = ['hostel_maintenance']
139        self.browser.getControl("Create ticket").click()
140        self.assertMatches('...You have not yet booked accommodation...',
141                           self.browser.contents)
142        # Students have to book bed first
143        self.browser.open(self.acco_path)
144        IWorkflowState(self.student).setState('admitted')
145        self.browser.getLink("Book accommodation").click()
146        self.assertFalse('Activation Code:' in self.browser.contents)
147        self.browser.getControl("Create bed ticket").click()
148        # Bed is randomly selected but, since there is only
149        # one bed for this student, we know that ...
150        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
151                           self.browser.contents)
152        self.assertMatches('...ticket created...',
153                           self.browser.contents)
154        self.browser.open(self.payments_path + '/addop')
155        self.browser.getControl(
156            name="form.p_category").value = ['hostel_maintenance']
157        self.browser.getControl("Create ticket").click()
158        self.assertMatches('...ticket created...',
159                           self.browser.contents)
160        ctrl = self.browser.getControl(name='val_id')
161        value = ctrl.options[1]
162        self.browser.getLink(value).click()
163        self.assertMatches('...Amount Authorized...',
164                           self.browser.contents)
165        # Maint fee is taken from the session configuration object
166        self.assertMatches(
167            '...<span>987.0</span>...',
168            self.browser.contents)
169        self.payment_url = self.browser.url
170        # Manager can access InterswitchForm
171        self.browser.getLink("CollegePAY", index=0).click()
[9789]172        # Split amounts have been set.
173        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
174        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
175        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
[9616]176        # The total amount to be processed by Interswitch
177        # has been reduced by the Interswitch fee of 150 Nairas
178        self.assertMatches('...Total Amount Authorized:...',
179                           self.browser.contents)
180        self.assertMatches(
[9626]181            '...<input type="hidden" name="pay_item_id" value="102" />...',
182            self.browser.contents)
183        self.assertMatches(
[9616]184            '...<input type="hidden" name="amount" value="98700.0" />...',
185            self.browser.contents)
186        self.assertMatches(
[9617]187            '...item_name="Hostel Maintenance Fee" item_amt="68700" bank_id="31" acct_num="0039050937"...',
[9616]188            self.browser.contents)
189
[9737]190        # Create carryover ticket
191        self.browser.open(self.payments_path + '/addop')
192        self.browser.getControl(name="form.p_category").value = ['carryover1']
193        self.browser.getControl("Create ticket").click()
194        ctrl = self.browser.getControl(name='val_id')
195        value = ctrl.options[2]
196        self.browser.getLink(value).click()
197        self.assertMatches(
198            '...<span>6000.0</span>...',
199            self.browser.contents)
200        # Manager can access InterswitchForm
201        self.browser.getLink("CollegePAY", index=0).click()
[9789]202        # Split amounts have been set.
203        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
204        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
205        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
[9737]206        self.assertMatches('...<input type="hidden" name="pay_item_id" value="101" />...',
207                           self.browser.contents)
208        self.assertMatches('...Total Amount Authorized:...',
209                           self.browser.contents)
210        self.assertMatches(
211            '...<input type="hidden" name="amount" value="600000.0" />...',
212            self.browser.contents)
213        self.assertMatches(
214            '...item_name="School Fee" item_amt="270000" bank_id="120" acct_num="1771180233"...',
215            self.browser.contents)
216        self.assertMatches(
217            '...item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"...',
218            self.browser.contents)
219        self.assertMatches(
220            '...item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"...',
221            self.browser.contents)
222
[7970]223    @external_test
[7930]224    def test_webservice(self):
[9789]225        # First we have open InterswitchPageStudent to set provider_amt
226        # and gateway_amt
227        self.browser.open(self.payment_url + '/goto_interswitch')
228        # Now we can call the webservice
[7970]229        self.browser.open(self.payment_url + '/request_webservice')
[7930]230        self.assertMatches('...Unsuccessful callback...',
231                          self.browser.contents)
[9710]232        # The payment is now in state failed ...
[8266]233        self.assertMatches('...<span>Failed</span>...',
234                          self.browser.contents)
[9710]235        # ... and the catalog has been updated
236        cat = getUtility(ICatalog, name='payments_catalog')
237        results = list(
238            cat.searchResults(p_state=('failed', 'failed')))
239        self.assertEqual(len(results), 1)
240        self.assertEqual(results[0].p_state, 'failed')
[8266]241
[9789]242        # Let's replace the p_id with a valid p_id of the Kwarapoly
243        # live system. This is definitely not an appropriate
244        # solution for testing, but we have no choice since
245        # Interswitch doesn't provide any interface
246        # for testing.
247        payment = self.student['payments'][self.value]
248        payment.p_id = 'p3543612043224'
[8266]249        self.browser.open(self.payment_url + '/request_webservice')
[9789]250        self.assertMatches('...Callback amount does not match...',
[8266]251                          self.browser.contents)
[9789]252        # The payment is now in state failed ...
[8266]253        self.assertMatches('...<span>Failed</span>...',
254                          self.browser.contents)
[9789]255        # Let's replace the amount autorized with the amount of the
256        # live system payment
257        payment.amount_auth = payment.r_amount_approved
258        self.browser.open(self.payment_url + '/request_webservice')
259        self.assertMatches('...Successful payment...',
260                          self.browser.contents)
261        # The payment is now in state paid ...
262        self.assertMatches('...<span>Paid</span>...',
263                          self.browser.contents)
264        # ... and the catalog has been updated
265        cat = getUtility(ICatalog, name='payments_catalog')
266        results = list(
267            cat.searchResults(p_state=('paid', 'paid')))
268        self.assertEqual(len(results), 1)
269        self.assertEqual(results[0].p_state, 'paid')
270        # Approval is logged in students.log ...
271        logfile = os.path.join(
272            self.app['datacenter'].storage, 'logs', 'students.log')
273        logcontent = open(logfile).read()
274        self.assertTrue(
275            'zope.mgr - '
276            'waeup.kwarapoly.interswitch.browser.InterswitchPaymentRequestWebservicePageStudent - '
277            'W1000000 - successful schoolfee payment: p3543612043224\n'
278            in logcontent)
279        # ... and in payments.log
280        logfile = os.path.join(
281            self.app['datacenter'].storage, 'logs', 'payments.log')
282        logcontent = open(logfile).read()
283        self.assertTrue(
284            '"zope.mgr",W1000000,p3543612043224,schoolfee,'
285            '52100.0,00,1200.0,300.0,1800.0,,,\n'
[10131]286            in logcontent)
287
288
289class InterswitchTestsApplicants(ApplicantsFullSetup):
290    """Tests for the Interswitch payment gateway.
291    """
292
293    layer = FunctionalLayer
294
295    def setUp(self):
296        super(InterswitchTestsApplicants, self).setUp()
297        # Create at least one Kwarapoly faculty
298        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
299        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
300        self.certificate2 = createObject('waeup.Certificate')
301        self.certificate2.code = u'CERT2'
[10133]302        self.certificate2.application_category = 'ndft'
[10131]303        self.certificate2.study_mode = 'nd_ft'
304        self.certificate2.start_level = 100
305        self.certificate2.end_level = 300
306        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
307            self.certificate2)
[10133]308        self.applicantscontainer.application_category = 'ndft'
[10131]309        self.applicant.applicant_id = u'nd_anything'
310       
311        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
312        self.browser.open(self.manage_path)
313        #IWorkflowState(self.student).setState('started')
314        super(InterswitchTestsApplicants, self).fill_correct_values()
315        self.browser.getControl(name="form.course1").value = ['CERT2']
316        self.applicantscontainer.application_fee = 3333.0
317        self.browser.getControl(name="form.nationality").value = ['NG']
318        self.browser.getControl(name="transition").value = ['start']
319        self.browser.getControl("Save").click()
320        self.browser.getControl("Add online").click()
321        self.assertMatches('...ticket created...',
322                           self.browser.contents)
323        #ctrl = self.browser.getControl(name='val_id')
324        #value = ctrl.options[0]
325        #self.browser.getLink(value).click()
326        self.assertMatches('...Amount Authorized...',
327                           self.browser.contents)
328        self.assertMatches(
329            '...<span>3333.0</span>...',
330            self.browser.contents)
331        self.payment_url = self.browser.url
332
333
334    def test_interswitch_form(self):
335
336        # Manager can access InterswitchForm
337        self.browser.getLink("CollegePAY", index=0).click()
338        self.assertMatches('...Total Amount Authorized:...',
339                           self.browser.contents)
340        self.assertTrue(
341            '<input type="hidden" name="amount" value="333300.0" />'
342            in self.browser.contents)
343        self.assertTrue(
344            '<item_detail item_id="1" item_name="application" '
345            'item_amt="253300" bank_id="8" acct_num="2014191363" />'
346            in self.browser.contents)
347
[10133]348        # hndft fee goes to another account
[10131]349        self.applicant.applicant_id = u'hnd_anything'
350        self.browser.open(self.manage_path)
351        ctrl = self.browser.getControl(name='val_id')
352        value = ctrl.options[0]
353        self.browser.getLink(value).click()
354        self.browser.getLink("CollegePAY", index=0).click()
355        self.assertTrue(
356            '<item_detail item_id="1" item_name="application" '
[10254]357            'item_amt="253300" bank_id="9" acct_num="7000016724" />'
[10131]358            in self.browser.contents)
[10176]359        # Commission or bribe?
[10142]360        self.assertTrue(
[10176]361            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
362            'bank_id="117" acct_num="1013196791" />'
[10142]363            in self.browser.contents)
[10176]364        self.assertTrue(
365            '<item_detail item_id="3" item_name="BT Education" '
366            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
367            in self.browser.contents)
[10597]368
369        # prehndft fee goes to another account
370        self.applicant.applicant_id = u'prehnd_anything'
371        self.browser.open(self.manage_path)
372        ctrl = self.browser.getControl(name='val_id')
373        value = ctrl.options[0]
374        self.browser.getLink(value).click()
375        self.browser.getLink("CollegePAY", index=0).click()
376        self.assertTrue(
377            '<item_detail item_id="1" item_name="application" '
378            'item_amt="303300" bank_id="8" acct_num="2013910271" />'
379            in self.browser.contents)
380        # No 'commission', no provider fee
381        self.assertFalse('Dalash' in self.browser.contents)
382        self.assertFalse('BT Education' in self.browser.contents)
383
384        # prejambites fee goes to another account
385        self.applicant.applicant_id = u'prejambites_anything'
386        self.browser.open(self.manage_path)
387        ctrl = self.browser.getControl(name='val_id')
388        value = ctrl.options[0]
389        self.browser.getLink(value).click()
390        self.browser.getLink("CollegePAY", index=0).click()
391        self.assertTrue(
392            '<item_detail item_id="1" item_name="application" '
393            'item_amt="303300" bank_id="10" acct_num="0106259811" />'
394            in self.browser.contents)
395        # No 'commission', no provider fee
396        self.assertFalse('Dalash' in self.browser.contents)
397        self.assertFalse('BT Education' in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.