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

Last change on this file since 9997 was 9956, checked in by Henrik Bettermann, 12 years ago

Configure acceptance fee payment.

We must not use assertMatches in browser tests when comparing payment amounts and bank account numbers because we need exact comparisons.

  • Property svn:keywords set to Id
File size: 18.3 KB
Line 
1## $Id: tests.py 9956 2013-02-15 11:49:44Z 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 zope.component import getUtility
20from zope.catalog.interfaces import ICatalog
21from hurry.workflow.interfaces import IWorkflowState
22from waeup.kofa.students.tests.test_browser import StudentsFullSetup
23from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
24from waeup.kofa.configuration import SessionConfiguration
25from waeup.fceokene.testing import FunctionalLayer
26
27# Also run tests that send requests to external servers?
28#   If you enable this, please make sure the external services
29#   do exist really and are not bothered by being spammed by a test programme.
30EXTERNAL_TESTS = False
31
32def external_test(func):
33    if not EXTERNAL_TESTS:
34        myself = __file__
35        if myself.endswith('.pyc'):
36            myself = myself[:-2]
37        print "WARNING: external tests are skipped!"
38        print "WARNING: edit %s to enable them." % myself
39        return
40    return func
41
42
43class InterswitchTestsStudents(StudentsFullSetup):
44    """Tests for the Interswitch payment gateway.
45    """
46
47    layer = FunctionalLayer
48
49    def setUp(self):
50        super(InterswitchTestsStudents, self).setUp()
51        self.certificate.study_mode = 'nce_ft'
52        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
53        self.browser.open(self.payments_path)
54        IWorkflowState(self.student).setState('cleared')
55        self.browser.open(self.payments_path + '/addop')
56        self.browser.getControl(name="form.p_category").value = ['schoolfee']
57        self.browser.getControl("Create ticket").click()
58        self.assertMatches('...ticket created...',
59                           self.browser.contents)
60        ctrl = self.browser.getControl(name='val_id')
61        self.value = ctrl.options[0]
62        self.browser.getLink(self.value).click()
63        self.assertMatches('...Amount Authorized...',
64                           self.browser.contents)
65        self.assertTrue(
66            '<span>12495.0</span>' in self.browser.contents)
67        self.payment_url = self.browser.url
68
69
70#    def callback_url(self, payment_url, resp, apprAmt):
71#        return payment_url + (
72#            '/isw_callback?echo=' +
73#            '&resp=%s' +
74#            '&desc=Something went wrong' +
75#            '&txnRef=p1331792385335' +
76#            '&payRef=' + '&retRef=' +
77#            '&cardNum=0' +
78#            '&apprAmt=%s' +
79#            '&url=http://xyz') % (resp, apprAmt)
80
81    def test_interswitch_form(self):
82
83        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
84        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
85        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
86        # Manager can access InterswitchForm for the created school fee ticket
87        self.browser.getLink("CollegePAY", index=0).click()
88        # Split amounts have been set
89        self.assertEqual(self.student['payments'][self.value].provider_amt, 1600.0)
90        self.assertEqual(self.student['payments'][self.value].gateway_amt, 150.0)
91        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1400.0)
92        self.assertMatches('...Total Amount Authorized:...',
93                           self.browser.contents)
94        self.assertTrue(
95            '<input type="hidden" name="amount" value="1249500.0" />'
96            in self.browser.contents)
97        self.assertTrue(
98            'item_name="School Fee" item_amt="934500" bank_id="117" acct_num="1012044015"'
99            in self.browser.contents)
100        self.assertTrue(
101            'item_name="FCEOkene Split" item_amt="140000" bank_id="117" acct_num="1012044039"'
102            in self.browser.contents)
103        self.assertTrue(
104            'item_name="BT Education" item_amt="160000" bank_id="31" acct_num="0026781725"'
105            in self.browser.contents)
106
107        # Let's do the same for maintenance fee payment
108
109        self.browser.open(self.payments_path)
110        self.browser.open(self.payments_path + '/addop')
111        self.browser.getControl(
112            name="form.p_category").value = ['hostel_maintenance']
113        self.browser.getControl("Create ticket").click()
114        self.assertMatches('...You have not yet booked accommodation...',
115                           self.browser.contents)
116        # Students have to book bed first
117        self.browser.open(self.acco_path)
118        IWorkflowState(self.student).setState('admitted')
119        self.browser.getLink("Book accommodation").click()
120        self.assertFalse('Activation Code:' in self.browser.contents)
121        self.browser.getControl("Create bed ticket").click()
122        # Bed is randomly selected but, since there is only
123        # one bed for this student, we know that ...
124        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
125                           self.browser.contents)
126        self.assertMatches('...ticket created...',
127                           self.browser.contents)
128        self.browser.open(self.payments_path + '/addop')
129        self.browser.getControl(
130            name="form.p_category").value = ['hostel_maintenance']
131        self.browser.getControl("Create ticket").click()
132        self.assertMatches('...ticket created...',
133                           self.browser.contents)
134        ctrl = self.browser.getControl(name='val_id')
135        value = ctrl.options[1]
136        self.browser.getLink(value).click()
137        self.assertMatches('...Amount Authorized...',
138                           self.browser.contents)
139        self.assertTrue(
140            '<span>4150.0</span>' in self.browser.contents)
141        self.payment_url = self.browser.url
142        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
143        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
144        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
145        # Manager can access InterswitchForm
146        self.browser.getLink("CollegePAY", index=0).click()
147        # Split amounts have been set
148        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
149        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
150        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
151        # The total amount to be processed by Interswitch
152        # has been reduced by the Interswitch fee of 150 Nairas
153        self.assertMatches('...Total Amount Authorized:...',
154                           self.browser.contents)
155        self.assertTrue(
156            '<input type="hidden" name="amount" value="415000.0" />'
157            in self.browser.contents)
158        self.assertTrue(
159            'item_name="Hostel Maintenance Fee" item_amt="400000" bank_id="117" acct_num="1012044132"'
160            in self.browser.contents)
161        # BT does nor charge a fee for maintenance fee
162        self.assertFalse("BT Education" in self.browser.contents)
163
164        # Let's do the same for acceptance fee
165
166        self.browser.open(self.payments_path)
167        self.browser.open(self.payments_path + '/addop')
168        self.browser.getControl(
169            name="form.p_category").value = ['clearance']
170        self.browser.getControl("Create ticket").click()
171        self.assertMatches('...ticket created...',
172                           self.browser.contents)
173        ctrl = self.browser.getControl(name='val_id')
174        value = ctrl.options[2]
175        self.browser.getLink(value).click()
176        self.assertMatches('...Amount Authorized...',
177                           self.browser.contents)
178        self.assertTrue(
179            '<span>3456.0</span>' in self.browser.contents)
180        self.payment_url = self.browser.url
181        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
182        self.assertEqual(self.student['payments'][value].gateway_amt, 0.0)
183        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
184        # Manager can access InterswitchForm
185        self.browser.getLink("CollegePAY", index=0).click()
186        # Split amounts have been set
187        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
188        self.assertEqual(self.student['payments'][value].gateway_amt, 150.0)
189        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
190        # The total amount to be processed by Interswitch
191        # has been reduced by the Interswitch fee of 150 Nairas
192        self.assertMatches('...Total Amount Authorized:...',
193                           self.browser.contents)
194        self.assertTrue(
195            '<input type="hidden" name="amount" value="345600.0" />' in
196            self.browser.contents)
197        self.assertTrue(
198            'item_name="Acceptance Fee" item_amt="330600" bank_id="8" acct_num="2003670143"'
199            in self.browser.contents)
200        # BT does nor charge a fee for maintenance fee
201        self.assertFalse("BT Education" in self.browser.contents)
202
203#    @external_test
204#    def test_callback(self):
205
206        # Manager can call callback manually
207#        self.browser.open(self.callback_url(self.payment_url, 'XX', '300'))
208#        self.assertMatches('...Unsuccessful callback: Something went wrong...',
209#                          self.browser.contents)
210#        self.assertMatches('...Failed...',
211#                           self.browser.contents)
212#        self.browser.open(self.payment_url + '/isw_callback')
213#        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
214#                          self.browser.contents)
215#        self.assertMatches('...Failed...',
216#                           self.browser.contents)
217#        self.browser.open(self.callback_url(self.payment_url, '00', '300000'))
218#        self.assertMatches('...Wrong amount...',
219#                          self.browser.contents)
220#        self.browser.open(self.callback_url(self.payment_url, '00', '4000000'))
221#        self.assertMatches('...Valid callback received...',
222#                          self.browser.contents)
223
224    @external_test
225    def test_webservice(self):
226        # First we have open InterswitchPageStudent to set provider_amt
227        # and gateway_amt
228        self.browser.open(self.payment_url + '/goto_interswitch')
229        # Now we can call the webservice
230        self.browser.open(self.payment_url + '/request_webservice')
231        #self.assertMatches('...Unsuccessful callback...',
232        #                  self.browser.contents)
233        self.assertMatches('...Unsuccessful callback...',
234                          self.browser.contents)
235        # The payment is now in state failed ...
236        self.assertMatches('...<span>Failed</span>...',
237                          self.browser.contents)
238        # ... and the catalog has been updated
239        cat = getUtility(ICatalog, name='payments_catalog')
240        results = list(
241            cat.searchResults(p_state=('failed', 'failed')))
242        self.assertEqual(len(results), 1)
243        self.assertEqual(results[0].p_state, 'failed')
244
245        # Let's replace the p_id with a valid p_id of the FCEOkene
246        # live system. This is definitely not an appropriate
247        # solution for testing, but we have no choice since
248        # Interswitch doesn't provide any interface
249        # for testing.
250        payment = self.student['payments'][self.value]
251        payment.p_id = 'p3536651296379'
252        self.browser.open(self.payment_url + '/request_webservice')
253        self.assertMatches('...Callback amount does not match...',
254                          self.browser.contents)
255        # The payment is now in state failed ...
256        self.assertMatches('...<span>Failed</span>...',
257                          self.browser.contents)
258        # Let's replace the amount autorized with the amount of the
259        # live system payment
260        payment.amount_auth = payment.r_amount_approved
261        self.browser.open(self.payment_url + '/request_webservice')
262        self.assertMatches('...Successful payment...',
263                          self.browser.contents)
264        # The payment is now in state paid ...
265        self.assertMatches('...<span>Paid</span>...',
266                          self.browser.contents)
267        # ... and the catalog has been updated
268        cat = getUtility(ICatalog, name='payments_catalog')
269        results = list(
270            cat.searchResults(p_state=('paid', 'paid')))
271        self.assertEqual(len(results), 1)
272        self.assertEqual(results[0].p_state, 'paid')
273        # Approval is logged in students.log ...
274        logfile = os.path.join(
275            self.app['datacenter'].storage, 'logs', 'students.log')
276        logcontent = open(logfile).read()
277        self.assertTrue(
278            'zope.mgr - '
279            'waeup.fceokene.interswitch.browser.InterswitchPaymentRequestWebservicePageStudent - '
280            'K1000000 - successful schoolfee payment: p3536651296379\n'
281            in logcontent)
282        # ... and in payments.log
283        logfile = os.path.join(
284            self.app['datacenter'].storage, 'logs', 'payments.log')
285        logcontent = open(logfile).read()
286        self.assertTrue(
287            '"zope.mgr",K1000000,p3536651296379,schoolfee,'
288            '3150.0,00,1600.0,150.0,1400.0,,,\n'
289            in logcontent)
290
291class InterswitchTestsApplicants(ApplicantsFullSetup):
292    """Tests for the Interswitch payment gateway.
293    """
294
295    layer = FunctionalLayer
296
297    def setUp(self):
298        super(InterswitchTestsApplicants, self).setUp()
299        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
300        self.browser.open(self.manage_path)
301        #IWorkflowState(self.student).setState('started')
302        super(InterswitchTestsApplicants, self).fill_correct_values()
303        self.applicantscontainer.application_fee = 1000.0
304        self.browser.getControl(name="form.nationality").value = ['NG']
305        self.browser.getControl(name="transition").value = ['start']
306        self.browser.getControl("Save").click()
307        self.browser.getControl("Add online").click()
308        self.assertMatches('...ticket created...',
309                           self.browser.contents)
310        self.assertMatches('...Amount Authorized...',
311                           self.browser.contents)
312        self.assertMatches(
313            '...<span>1000.0</span>...',
314            self.browser.contents)
315        self.payment_url = self.browser.url
316        self.browser.open(self.manage_path)
317        ctrl = self.browser.getControl(name='val_id')
318        self.value = ctrl.options[0]
319
320
321    def test_interswitch_form(self):
322
323        # Manager can access InterswitchForm
324        self.browser.open(self.payment_url)
325        self.browser.getLink("CollegePAY", index=0).click()
326        self.assertMatches('...Total Amount Authorized:...',
327                           self.browser.contents)
328        self.assertTrue(
329            '<input type="hidden" name="amount" value="100000.0" />'
330            in self.browser.contents)
331
332    @external_test
333    def test_webservice(self):
334        # First we have open InterswitchPageStudent to set provider_amt
335        # and gateway_amt
336        self.browser.open(self.payment_url + '/goto_interswitch')
337        # Now we can call the webservice
338        self.browser.open(self.payment_url + '/request_webservice')
339        self.assertMatches('...Unsuccessful callback...',
340                          self.browser.contents)
341        # The payment is now in state failed ...
342        self.assertMatches('...<span>Failed</span>...',
343                          self.browser.contents)
344        # ... and the catalog has been updated
345        cat = getUtility(ICatalog, name='payments_catalog')
346        results = list(
347            cat.searchResults(p_state=('failed', 'failed')))
348        self.assertEqual(len(results), 1)
349        self.assertEqual(results[0].p_state, 'failed')
350
351        # Let's replace the p_id with a valid p_id of the Uniben
352        # live system. This is definitely not an appropriate
353        # solution for testing, but we have no choice since
354        # Interswitch doesn't provide any interface
355        # for testing.
356        payment = self.applicant[self.value]
357        payment.p_id = 'p3536651296379'
358        self.browser.open(self.payment_url + '/request_webservice')
359        self.assertMatches('...Callback amount does not match...',
360                          self.browser.contents)
361        # The payment is now in state failed ...
362        self.assertMatches('...<span>Failed</span>...',
363                          self.browser.contents)
364        # Let's replace the amount autorized with the amount of the
365        # live system payment
366        payment.amount_auth = payment.r_amount_approved
367        self.browser.open(self.payment_url + '/request_webservice')
368        self.assertMatches('...Successful payment...',
369                          self.browser.contents)
370        # The payment is now in state paid ...
371        self.assertMatches('...<span>Paid</span>...',
372                          self.browser.contents)
373        # ... and the catalog has been updated
374        cat = getUtility(ICatalog, name='payments_catalog')
375        results = list(
376            cat.searchResults(p_state=('paid', 'paid')))
377        self.assertEqual(len(results), 1)
378        self.assertEqual(results[0].p_state, 'paid')
379        # Approval is logged in students.log ...
380        logfile = os.path.join(
381            self.app['datacenter'].storage, 'logs', 'applicants.log')
382        logcontent = open(logfile).read()
383        self.assertTrue(
384            'zope.mgr - '
385            'waeup.fceokene.interswitch.browser.InterswitchPaymentRequestWebservicePageApplicant - '
386            '%s - successful payment: p3536651296379\n'
387            % self.applicant.applicant_id in logcontent)
388        # ... and in payments.log
389        logfile = os.path.join(
390            self.app['datacenter'].storage, 'logs', 'payments.log')
391        logcontent = open(logfile).read()
392        self.assertTrue(
393            '"zope.mgr",%s,p3536651296379,application,'
394            '3150.0,00,500.0,150.0,0.0,,,\n' % self.applicant.applicant_id
395            in logcontent)
Note: See TracBrowser for help on using the repository browser.