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

Last change on this file since 13798 was 13752, checked in by Henrik Bettermann, 9 years ago

New single account configuration.

  • Property svn:keywords set to Id
File size: 22.3 KB
Line 
1## $Id: tests.py 13752 2016-02-29 12:33:05Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import os
19from datetime import datetime, timedelta, date
20from zope.component import getUtility
21from zope.catalog.interfaces import ICatalog
22from hurry.workflow.interfaces import IWorkflowState
23from waeup.kofa.students.tests.test_browser import StudentsFullSetup
24from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
25from waeup.kofa.configuration import SessionConfiguration
26from waeup.fceokene.testing import FunctionalLayer
27
28# Also run tests that send requests to external servers?
29#   If you enable this, please make sure the external services
30#   do exist really and are not bothered by being spammed by a test programme.
31EXTERNAL_TESTS = False
32
33def external_test(func):
34    if not EXTERNAL_TESTS:
35        myself = __file__
36        if myself.endswith('.pyc'):
37            myself = myself[:-2]
38        print "WARNING: external tests are skipped!"
39        print "WARNING: edit %s to enable them." % myself
40        return
41    return func
42
43
44class InterswitchTestsStudents(StudentsFullSetup):
45    """Tests for the Interswitch payment gateway.
46    """
47
48    layer = FunctionalLayer
49
50    def setUp(self):
51        super(InterswitchTestsStudents, self).setUp()
52        self.certificate.study_mode = 'pd_ft'
53        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
54        self.browser.open(self.payments_path)
55        IWorkflowState(self.student).setState('cleared')
56        self.browser.open(self.payments_path + '/addop')
57        self.browser.getControl(name="form.p_category").value = ['schoolfee']
58        self.browser.getControl("Create ticket").click()
59        self.assertMatches('...ticket created...',
60                           self.browser.contents)
61        ctrl = self.browser.getControl(name='val_id')
62        self.value = ctrl.options[0]
63        self.browser.getLink(self.value).click()
64        self.assertMatches('...Amount Authorized...',
65                           self.browser.contents)
66        self.assertTrue(
67            '<span>70450.0</span>' in self.browser.contents)
68        self.payment_url = self.browser.url
69        self.payment = self.student['payments'][self.value]
70
71
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)
82
83    def test_interswitch_form(self):
84
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)
88        # Manager can access InterswitchForm for the created school fee ticket
89        self.browser.getLink("CollegePAY", index=0).click()
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)
93        self.assertMatches('...Total Amount Authorized:...',
94                           self.browser.contents)
95        self.assertTrue(
96            '<input type="hidden" name="amount" value="7045000" />'
97            in self.browser.contents)
98        self.assertTrue(
99            'item_name="School Fee" item_amt="6870000" bank_id="8" acct_num="2003670143"'
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)
104
105        # Third semester payment
106        self.certificate.study_mode = 'nce_ft'
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(
118            '<input type="hidden" name="amount" value="791300" />'
119            in self.browser.contents)
120        self.assertTrue(
121            'item_name="NCE Third Semester Fee" item_amt="616300" bank_id="8" acct_num="2003670143"'
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
127        # Maintenance fee payment
128        self.certificate.study_mode = 'nce_ft'
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')
139        self.browser.getControl("Book accommodation").click()
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 ...
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)
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')
157        value = ctrl.options[2]
158        self.browser.getLink(value).click()
159        self.assertMatches('...Amount Authorized...',
160                           self.browser.contents)
161        self.assertTrue(
162            '<span>1026.0</span>' in self.browser.contents)
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)
168        self.payment_url = self.browser.url
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)
172        # Manager can access InterswitchForm
173        self.browser.getLink("CollegePAY", index=0).click()
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)
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)
182        self.assertTrue(
183            '<input type="hidden" name="amount" value="102600" />'
184            in self.browser.contents)
185        self.assertTrue(
186            'item_name="Hostel Maintenance Fee" item_amt="87600" bank_id="8" acct_num="2003670143"'
187            in self.browser.contents)
188        # BT does nor charge a fee for maintenance fee
189        self.assertFalse("BT Education" in self.browser.contents)
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)
202
203        # Acceptance fee payment
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')
213        value = ctrl.options[3]
214        self.browser.getLink(value).click()
215        self.assertMatches('...Amount Authorized...',
216                           self.browser.contents)
217        self.assertTrue(
218            '<span>3606.0</span>' in self.browser.contents)
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(
234            '<input type="hidden" name="amount" value="360600" />' in
235            self.browser.contents)
236        self.assertTrue(
237            'item_name="Acceptance Fee" item_amt="345600" bank_id="8" acct_num="2003670143"'
238            in self.browser.contents)
239        # BT does nor charge a fee for maintenance fee
240        self.assertFalse("BT Education" in self.browser.contents)
241
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)
249        self.assertEqual(self.student.current_mode, 'pd_ft')
250        self.assertMatches(
251            '...<input type="hidden" name="amount" value="4000000" />...',
252            self.browser.contents)
253        delta = timedelta(days=8)
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)
260        delta = timedelta(days=2)
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
267#    @external_test
268#    def test_callback(self):
269
270        # Manager can call callback manually
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)
287
288    @external_test
289    def test_webservice(self):
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
294        self.browser.open(self.payment_url + '/request_webservice')
295        #self.assertMatches('...Unsuccessful callback...',
296        #                  self.browser.contents)
297        self.assertMatches('...Unsuccessful callback...',
298                          self.browser.contents)
299        # The payment is now in state failed ...
300        self.assertMatches('...<span>Failed</span>...',
301                          self.browser.contents)
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')
308
309        # Let's replace the p_id with a valid p_id of the FCEOkene
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 - '
343            'waeup.fceokene.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
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
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()
363        configuration = SessionConfiguration()
364        configuration.academic_session = datetime.now().year - 2
365        self.app['configuration'].addSessionConfiguration(configuration)
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()
370        self.applicantscontainer.application_fee = 1000.0
371        self.browser.getControl(name="form.nationality").value = ['NG']
372        self.browser.getControl(name="transition").value = ['start']
373        self.browser.getControl("Save").click()
374
375    def test_interswitch_form(self):
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
383        self.browser.open(self.manage_path)
384        ctrl = self.browser.getControl(name='val_id')
385        self.value = ctrl.options[0]
386        # Manager can access InterswitchForm
387        self.browser.open(self.payment_url)
388        self.browser.getLink("CollegePAY", index=0).click()
389        self.assertMatches('...Total Amount Authorized:...',
390                           self.browser.contents)
391        self.assertTrue(
392            '<input type="hidden" name="amount" value="100000" />'
393            in self.browser.contents)
394        self.assertTrue(
395            '<item_detail item_id="1" item_name="application"'
396            ' item_amt="35000" bank_id="8" acct_num="2003670143" />'
397            in self.browser.contents)
398        delta = timedelta(days=8)
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)
405
406    @external_test
407    def test_webservice(self):
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]
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
422        self.browser.open(self.payment_url + '/request_webservice')
423        self.assertMatches('...Unsuccessful callback...',
424                          self.browser.contents)
425        # The payment is now in state failed ...
426        self.assertMatches('...<span>Failed</span>...',
427                          self.browser.contents)
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 - '
469            'waeup.fceokene.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageApplicant - '
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.