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

Last change on this file since 11920 was 11920, checked in by Henrik Bettermann, 10 years ago

Third semester fee applies to nce_sw and not nce_ft.

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