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

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

Fix tests. All amounts in form are now integers.

  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1## $Id: tests.py 11775 2014-08-02 05:09:09Z 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        # Maintenance fee payment
109
110        self.browser.open(self.payments_path)
111        self.browser.open(self.payments_path + '/addop')
112        self.browser.getControl(
113            name="form.p_category").value = ['hostel_maintenance']
114        self.browser.getControl("Create ticket").click()
115        self.assertMatches('...You have not yet booked accommodation...',
116                           self.browser.contents)
117        # Students have to book bed first
118        self.browser.open(self.acco_path)
119        IWorkflowState(self.student).setState('admitted')
120        self.browser.getLink("Book accommodation").click()
121        self.assertFalse('Activation Code:' in self.browser.contents)
122        self.browser.getControl("Create bed ticket").click()
123        # Bed is randomly selected but, since there is only
124        # one bed for this student, we know that ...
125        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
126                           in self.browser.contents)
127        self.assertTrue('(see payment slip)'
128                           in self.browser.contents)
129        self.assertTrue('ticket created'
130                           in self.browser.contents)
131        self.browser.open(self.payments_path + '/addop')
132        self.browser.getControl(
133            name="form.p_category").value = ['hostel_maintenance']
134        self.browser.getControl("Create ticket").click()
135        self.assertMatches('...ticket created...',
136                           self.browser.contents)
137        ctrl = self.browser.getControl(name='val_id')
138        value = ctrl.options[1]
139        self.browser.getLink(value).click()
140        self.assertMatches('...Amount Authorized...',
141                           self.browser.contents)
142        self.assertTrue(
143            '<span>4150.0</span>' in self.browser.contents)
144        # p_item is not unveiled
145        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
146            in self.browser.contents)
147        self.assertTrue('(visible after successful payment)'
148            in self.browser.contents)
149        self.payment_url = self.browser.url
150        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
151        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
152        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
153        # Manager can access InterswitchForm
154        self.browser.getLink("CollegePAY", index=0).click()
155        # Split amounts have been set
156        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
157        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
158        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
159        # The total amount to be processed by Interswitch
160        # has been reduced by the Interswitch fee of 150 Nairas
161        self.assertMatches('...Total Amount Authorized:...',
162                           self.browser.contents)
163        self.assertTrue(
164            '<input type="hidden" name="amount" value="415000" />'
165            in self.browser.contents)
166        self.assertTrue(
167            'item_name="Hostel Maintenance Fee" item_amt="400000" bank_id="117" acct_num="1012044132"'
168            in self.browser.contents)
169        # BT does nor charge a fee for maintenance fee
170        self.assertFalse("BT Education" in self.browser.contents)
171        # p_item is not unveiled
172        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
173            in self.browser.contents)
174        self.assertTrue('(visible after successful payment)'
175            in self.browser.contents)
176        # If the ticket is paid coordinates are shown
177        self.student['payments'][value].p_state = 'paid'
178        self.browser.open(self.payment_url)
179        self.assertTrue('Hall 1, Block A, Room 101, Bed A'
180            in self.browser.contents)
181        self.assertFalse('(visible after successful payment)'
182            in self.browser.contents)
183
184        # Acceptance fee payment
185
186        self.browser.open(self.payments_path)
187        self.browser.open(self.payments_path + '/addop')
188        self.browser.getControl(
189            name="form.p_category").value = ['clearance']
190        self.browser.getControl("Create ticket").click()
191        self.assertMatches('...ticket created...',
192                           self.browser.contents)
193        ctrl = self.browser.getControl(name='val_id')
194        value = ctrl.options[2]
195        self.browser.getLink(value).click()
196        self.assertMatches('...Amount Authorized...',
197                           self.browser.contents)
198        self.assertTrue(
199            '<span>3606.0</span>' in self.browser.contents)
200        self.payment_url = self.browser.url
201        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
202        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
203        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
204        # Manager can access InterswitchForm
205        self.browser.getLink("CollegePAY", index=0).click()
206        # Split amounts have been set
207        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
208        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
209        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
210        # The total amount to be processed by Interswitch
211        # has been reduced by the Interswitch fee of 150 Nairas
212        self.assertMatches('...Total Amount Authorized:...',
213                           self.browser.contents)
214        self.assertTrue(
215            '<input type="hidden" name="amount" value="360600" />' in
216            self.browser.contents)
217        self.assertTrue(
218            'item_name="Acceptance Fee" item_amt="345600" bank_id="8" acct_num="2003670143"'
219            in self.browser.contents)
220        # BT does nor charge a fee for maintenance fee
221        self.assertFalse("BT Education" in self.browser.contents)
222
223#    @external_test
224#    def test_callback(self):
225
226        # Manager can call callback manually
227#        self.browser.open(self.callback_url(self.payment_url, 'XX', '300'))
228#        self.assertMatches('...Unsuccessful callback: Something went wrong...',
229#                          self.browser.contents)
230#        self.assertMatches('...Failed...',
231#                           self.browser.contents)
232#        self.browser.open(self.payment_url + '/isw_callback')
233#        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
234#                          self.browser.contents)
235#        self.assertMatches('...Failed...',
236#                           self.browser.contents)
237#        self.browser.open(self.callback_url(self.payment_url, '00', '300000'))
238#        self.assertMatches('...Wrong amount...',
239#                          self.browser.contents)
240#        self.browser.open(self.callback_url(self.payment_url, '00', '4000000'))
241#        self.assertMatches('...Valid callback received...',
242#                          self.browser.contents)
243
244    @external_test
245    def test_webservice(self):
246        # First we have open InterswitchPageStudent to set provider_amt
247        # and gateway_amt
248        self.browser.open(self.payment_url + '/goto_interswitch')
249        # Now we can call the webservice
250        self.browser.open(self.payment_url + '/request_webservice')
251        #self.assertMatches('...Unsuccessful callback...',
252        #                  self.browser.contents)
253        self.assertMatches('...Unsuccessful callback...',
254                          self.browser.contents)
255        # The payment is now in state failed ...
256        self.assertMatches('...<span>Failed</span>...',
257                          self.browser.contents)
258        # ... and the catalog has been updated
259        cat = getUtility(ICatalog, name='payments_catalog')
260        results = list(
261            cat.searchResults(p_state=('failed', 'failed')))
262        self.assertEqual(len(results), 1)
263        self.assertEqual(results[0].p_state, 'failed')
264
265        # Let's replace the p_id with a valid p_id of the FCEOkene
266        # live system. This is definitely not an appropriate
267        # solution for testing, but we have no choice since
268        # Interswitch doesn't provide any interface
269        # for testing.
270        payment = self.student['payments'][self.value]
271        payment.p_id = 'p3536651296379'
272        self.browser.open(self.payment_url + '/request_webservice')
273        self.assertMatches('...Callback amount does not match...',
274                          self.browser.contents)
275        # The payment is now in state failed ...
276        self.assertMatches('...<span>Failed</span>...',
277                          self.browser.contents)
278        # Let's replace the amount autorized with the amount of the
279        # live system payment
280        payment.amount_auth = payment.r_amount_approved
281        self.browser.open(self.payment_url + '/request_webservice')
282        self.assertMatches('...Successful payment...',
283                          self.browser.contents)
284        # The payment is now in state paid ...
285        self.assertMatches('...<span>Paid</span>...',
286                          self.browser.contents)
287        # ... and the catalog has been updated
288        cat = getUtility(ICatalog, name='payments_catalog')
289        results = list(
290            cat.searchResults(p_state=('paid', 'paid')))
291        self.assertEqual(len(results), 1)
292        self.assertEqual(results[0].p_state, 'paid')
293        # Approval is logged in students.log ...
294        logfile = os.path.join(
295            self.app['datacenter'].storage, 'logs', 'students.log')
296        logcontent = open(logfile).read()
297        self.assertTrue(
298            'zope.mgr - '
299            'waeup.fceokene.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
300            'K1000000 - successful schoolfee payment: p3536651296379\n'
301            in logcontent)
302        # ... and in payments.log
303        logfile = os.path.join(
304            self.app['datacenter'].storage, 'logs', 'payments.log')
305        logcontent = open(logfile).read()
306        self.assertTrue(
307            '"zope.mgr",K1000000,p3536651296379,schoolfee,'
308            '3150.0,00,1600.0,150.0,1400.0,,,\n'
309            in logcontent)
310
311class InterswitchTestsApplicants(ApplicantsFullSetup):
312    """Tests for the Interswitch payment gateway.
313    """
314
315    layer = FunctionalLayer
316
317    def setUp(self):
318        super(InterswitchTestsApplicants, self).setUp()
319        configuration = SessionConfiguration()
320        configuration.academic_session = datetime.now().year - 2
321        self.app['configuration'].addSessionConfiguration(configuration)
322        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
323        self.browser.open(self.manage_path)
324        #IWorkflowState(self.student).setState('started')
325        super(InterswitchTestsApplicants, self).fill_correct_values()
326        self.applicantscontainer.application_fee = 1000.0
327        self.browser.getControl(name="form.nationality").value = ['NG']
328        self.browser.getControl(name="transition").value = ['start']
329        self.browser.getControl("Save").click()
330
331    def test_interswitch_form(self):
332        self.browser.getControl("Add online").click()
333        self.assertMatches('...ticket created...',
334                           self.browser.contents)
335        self.assertMatches(
336            '...<span>1000.0</span>...',
337            self.browser.contents)
338        self.payment_url = self.browser.url
339        self.browser.open(self.manage_path)
340        ctrl = self.browser.getControl(name='val_id')
341        self.value = ctrl.options[0]
342        # Manager can access InterswitchForm
343        self.browser.open(self.payment_url)
344        self.browser.getLink("CollegePAY", index=0).click()
345        self.assertMatches('...Total Amount Authorized:...',
346                           self.browser.contents)
347        self.assertTrue(
348            '<input type="hidden" name="amount" value="100000" />'
349            in self.browser.contents)
350        self.assertTrue(
351            '<item_detail item_id="1" item_name="application"'
352            ' item_amt="35000" bank_id="117" acct_num="1012445289" />'
353            in self.browser.contents)
354
355    @external_test
356    def test_webservice(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        # First we have open InterswitchPageStudent to set provider_amt
368        # and gateway_amt
369        self.browser.open(self.payment_url + '/goto_interswitch')
370        # Now we can call the webservice
371        self.browser.open(self.payment_url + '/request_webservice')
372        self.assertMatches('...Unsuccessful callback...',
373                          self.browser.contents)
374        # The payment is now in state failed ...
375        self.assertMatches('...<span>Failed</span>...',
376                          self.browser.contents)
377        # ... and the catalog has been updated
378        cat = getUtility(ICatalog, name='payments_catalog')
379        results = list(
380            cat.searchResults(p_state=('failed', 'failed')))
381        self.assertEqual(len(results), 1)
382        self.assertEqual(results[0].p_state, 'failed')
383
384        # Let's replace the p_id with a valid p_id of the Uniben
385        # live system. This is definitely not an appropriate
386        # solution for testing, but we have no choice since
387        # Interswitch doesn't provide any interface
388        # for testing.
389        payment = self.applicant[self.value]
390        payment.p_id = 'p3536651296379'
391        self.browser.open(self.payment_url + '/request_webservice')
392        self.assertMatches('...Callback amount does not match...',
393                          self.browser.contents)
394        # The payment is now in state failed ...
395        self.assertMatches('...<span>Failed</span>...',
396                          self.browser.contents)
397        # Let's replace the amount autorized with the amount of the
398        # live system payment
399        payment.amount_auth = payment.r_amount_approved
400        self.browser.open(self.payment_url + '/request_webservice')
401        self.assertMatches('...Successful payment...',
402                          self.browser.contents)
403        # The payment is now in state paid ...
404        self.assertMatches('...<span>Paid</span>...',
405                          self.browser.contents)
406        # ... and the catalog has been updated
407        cat = getUtility(ICatalog, name='payments_catalog')
408        results = list(
409            cat.searchResults(p_state=('paid', 'paid')))
410        self.assertEqual(len(results), 1)
411        self.assertEqual(results[0].p_state, 'paid')
412        # Approval is logged in students.log ...
413        logfile = os.path.join(
414            self.app['datacenter'].storage, 'logs', 'applicants.log')
415        logcontent = open(logfile).read()
416        self.assertTrue(
417            'zope.mgr - '
418            'waeup.fceokene.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageApplicant - '
419            '%s - successful payment: p3536651296379\n'
420            % self.applicant.applicant_id in logcontent)
421        # ... and in payments.log
422        logfile = os.path.join(
423            self.app['datacenter'].storage, 'logs', 'payments.log')
424        logcontent = open(logfile).read()
425        self.assertTrue(
426            '"zope.mgr",%s,p3536651296379,application,'
427            '3150.0,00,500.0,150.0,0.0,,,\n' % self.applicant.applicant_id
428            in logcontent)
Note: See TracBrowser for help on using the repository browser.