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

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

Carryover payments must not trigger workflow transitions.

  • Property svn:keywords set to Id
File size: 38.0 KB
Line 
1## $Id: tests.py 13653 2016-02-07 07:32:25Z 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
19import grok
20import pytz
21from datetime import datetime, date, timedelta
22from hurry.workflow.interfaces import IWorkflowState
23from zope.component import createObject, getUtility
24from zope.catalog.interfaces import ICatalog
25from zope.event import notify
26from waeup.kofa.applicants.container import ApplicantsContainer
27from waeup.kofa.university.faculty import Faculty
28from waeup.kofa.university.department import Department
29from waeup.kofa.students.tests.test_browser import StudentsFullSetup
30from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
31from waeup.kofa.configuration import SessionConfiguration
32from waeup.kwarapoly.testing import FunctionalLayer
33from waeup.kwarapoly.students.payments import CustomStudentOnlinePayment
34
35# Also run tests that send requests to external servers?
36#   If you enable this, please make sure the external services
37#   do exist really and are not bothered by being spammed by a test programme.
38EXTERNAL_TESTS = False
39
40def external_test(func):
41    if not EXTERNAL_TESTS:
42        myself = __file__
43        if myself.endswith('.pyc'):
44            myself = myself[:-2]
45        print "WARNING: external tests are skipped!"
46        print "WARNING: edit %s to enable them." % myself
47        return
48    return func
49
50
51class InterswitchTestsStudents(StudentsFullSetup):
52    """Tests for the Interswitch payment gateway.
53    """
54
55    layer = FunctionalLayer
56
57    def setUp(self):
58        super(InterswitchTestsStudents, self).setUp()
59
60        # Create at least one Kwarapoly faculty
61        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
62        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
63        self.certificate2 = createObject('waeup.Certificate')
64        self.certificate2.code = u'CERT2'
65        self.certificate2.application_category = 'basic'
66        self.certificate2.study_mode = 'nd_ft'
67        self.certificate2.start_level = 100
68        self.certificate2.end_level = 300
69        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
70            self.certificate2)
71        # Set study course attributes of test student
72        self.student['studycourse'].certificate = self.certificate2
73        self.student['studycourse'].current_session = 2004
74        self.student['studycourse'].entry_session = 2004
75        self.student['studycourse'].current_verdict = 'A'
76        self.student['studycourse'].current_level = 100
77        # Set local lga
78        self.student.lga = u'kwara_asa'
79        # Update the catalog
80        notify(grok.ObjectModifiedEvent(self.student))
81
82    def test_schoolfee_ticket_creation(self):
83        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
84        self.browser.open(self.payments_path)
85        IWorkflowState(self.student).setState('cleared')
86        self.browser.open(self.payments_path + '/addop')
87        self.browser.getControl(name="form.p_category").value = ['schoolfee']
88        self.browser.getControl("Create ticket").click()
89        self.assertMatches('...Book and pay for accommodation first...',
90                           self.browser.contents)
91        # We add a fake maint. payment ticket to meet the condition
92        maint_payment = CustomStudentOnlinePayment()
93        self.student['payments']['any_key'] = maint_payment
94        maint_payment.p_category = 'hostel_maintenance'
95        maint_payment.p_state = 'unpaid'
96        maint_payment.p_session = 2004
97        self.browser.getControl(name="form.p_category").value = ['schoolfee']
98        self.browser.getControl("Create ticket").click()
99        self.assertMatches('...Book and pay for accommodation first...',
100                           self.browser.contents)
101        # Ticket must be paid
102        maint_payment.p_state = 'paid'
103        self.browser.getControl(name="form.p_category").value = ['schoolfee']
104        self.browser.getControl("Create ticket").click()
105        self.assertMatches('...ticket created...',
106                           self.browser.contents)
107        ctrl = self.browser.getControl(name='val_id')
108        self.value = ctrl.options[1]
109        self.browser.getLink(self.value).click()
110        self.assertMatches('...Amount Authorized...',
111                           self.browser.contents)
112        self.assertTrue('<span>40700.0</span>' in self.browser.contents)
113        self.payment_url = self.browser.url
114
115
116#    def callback_url(self, payment_url, resp, apprAmt):
117#        return payment_url + (
118#            '/isw_callback?echo=' +
119#            '&resp=%s' +
120#            '&desc=Something went wrong' +
121#            '&txnRef=p1331792385335' +
122#            '&payRef=' + '&retRef=' +
123#            '&cardNum=0' +
124#            '&apprAmt=%s' +
125#            '&url=http://xyz') % (resp, apprAmt)
126
127    def test_interswitch_form(self):
128
129        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
130        self.browser.open(self.payments_path)
131        # In KwaraPoly only returning students can create school fee payment
132        # without haveing paid accommodation fee
133        IWorkflowState(self.student).setState('returning')
134        configuration = createObject('waeup.SessionConfiguration')
135        configuration.academic_session = 2005
136        self.app['configuration'].addSessionConfiguration(configuration)
137        self.browser.open(self.payments_path + '/addop')
138        self.browser.getControl(name="form.p_category").value = ['schoolfee']
139        self.browser.getControl("Create ticket").click()
140        self.assertMatches('...ticket created...', self.browser.contents)
141        ctrl = self.browser.getControl(name='val_id')
142        self.value = ctrl.options[0]
143        self.browser.getLink(self.value).click()
144        self.assertMatches('...Amount Authorized...', self.browser.contents)
145        self.assertTrue(
146            '<span>31500.0</span>' in self.browser.contents)
147        self.payment_url = self.browser.url
148
149        # Manager can access InterswitchForm
150        self.assertEqual(self.student['payments'][self.value].provider_amt, 0.0)
151        self.assertEqual(self.student['payments'][self.value].gateway_amt, 0.0)
152        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 0.0)
153        self.browser.getLink("CollegePAY", index=0).click()
154        # Split amounts have been set.
155        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
156        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
157        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
158        self.assertMatches('...Total Amount Authorized:...',
159                           self.browser.contents)
160        self.assertTrue(
161            '<input type="hidden" name="amount" value="3150000" />' in
162            self.browser.contents)
163        self.assertTrue(
164            'item_name="School Fee" item_amt="2820000" bank_id="10" acct_num="0106259811"' in
165            self.browser.contents)
166        self.assertTrue(
167            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
168            self.browser.contents)
169        self.assertTrue(
170            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
171            self.browser.contents)
172
173        # Let's do the same for maintenance fee payment
174
175        self.browser.open(self.payments_path)
176        self.browser.open(self.payments_path + '/addop')
177        self.browser.getControl(
178            name="form.p_category").value = ['hostel_maintenance']
179        self.browser.getControl("Create ticket").click()
180        self.assertMatches('...You have not yet booked accommodation...',
181                           self.browser.contents)
182        # Students have to book bed first
183        self.browser.open(self.acco_path)
184        IWorkflowState(self.student).setState('admitted')
185        self.browser.getControl("Book accommodation").click()
186        self.assertFalse('Activation Code:' in self.browser.contents)
187        self.browser.getControl("Create bed ticket").click()
188        # Bed is randomly selected but, since there is only
189        # one bed for this student, we know that ...
190        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
191                           self.browser.contents)
192        self.assertMatches('...ticket created...',
193                           self.browser.contents)
194        self.browser.open(self.payments_path + '/addop')
195        self.browser.getControl(
196            name="form.p_category").value = ['hostel_maintenance']
197        self.browser.getControl("Create ticket").click()
198        self.assertMatches('...ticket created...',
199                           self.browser.contents)
200        ctrl = self.browser.getControl(name='val_id')
201        value = ctrl.options[1]
202        self.browser.getLink(value).click()
203        self.assertMatches('...Amount Authorized...',
204                           self.browser.contents)
205        # Maint fee is taken from the hostel object
206        self.assertTrue('<span>876.0</span>' in self.browser.contents)
207        self.payment_url = self.browser.url
208        # Manager can access InterswitchForm
209        self.browser.getLink("CollegePAY", index=0).click()
210        # Split amounts have been set.
211        self.assertEqual(self.student['payments'][value].provider_amt, 0.0)
212        self.assertEqual(self.student['payments'][value].thirdparty_amt, 0.0)
213        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
214        # The total amount to be processed by Interswitch
215        # has been reduced by the Interswitch fee of 150 Nairas
216        self.assertMatches('...Total Amount Authorized:...',
217                           self.browser.contents)
218        self.assertTrue(
219            '<input type="hidden" name="pay_item_id" value="102" />' in
220            self.browser.contents)
221        self.assertTrue(
222            '<input type="hidden" name="amount" value="87600" />' in
223            self.browser.contents)
224        self.assertTrue(
225            'item_name="Hostel Maintenance" item_amt="57600" bank_id="10" acct_num="0106259811"' in
226            self.browser.contents)
227
228        # Create carryover ticket
229        self.browser.open(self.payments_path + '/addop')
230        self.browser.getControl(name="form.p_category").value = ['carryover1']
231        self.browser.getControl("Create ticket").click()
232        ctrl = self.browser.getControl(name='val_id')
233        value = ctrl.options[2]
234        self.browser.getLink(value).click()
235        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
236        # Manager can access InterswitchForm
237        self.browser.getLink("CollegePAY", index=0).click()
238        # Split amounts have been set.
239        self.assertEqual(self.student['payments'][self.value].provider_amt, 1200.0)
240        self.assertEqual(self.student['payments'][self.value].gateway_amt, 300.0)
241        self.assertEqual(self.student['payments'][self.value].thirdparty_amt, 1800.0)
242        self.assertTrue('<input type="hidden" name="pay_item_id" value="101" />' in
243                           self.browser.contents)
244        self.assertMatches('...Total Amount Authorized:...',
245                           self.browser.contents)
246        self.assertTrue(
247            '<input type="hidden" name="amount" value="600000" />' in
248            self.browser.contents)
249        self.assertTrue(
250            'item_name="One Carry-Over" item_amt="270000" bank_id="10" acct_num="0106259811"' in
251            self.browser.contents)
252        self.assertTrue(
253            'item_name="Dalash" item_amt="180000" bank_id="117" acct_num="1013196791"' in
254            self.browser.contents)
255        self.assertTrue(
256            'item_name="BT Education" item_amt="120000" bank_id="117" acct_num="1010764827"' in
257            self.browser.contents)
258
259    def test_interswitch_form_new_payment_cats(self):
260        # only a few categories covered
261
262        self.app['configuration']['2004'].certificate_fee = 6800.0
263        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
264        self.browser.open(self.payments_path + '/addop')
265        self.browser.getControl(name="form.p_category").value = ['certificate']
266        self.browser.getControl("Create ticket").click()
267        self.assertMatches('...ticket created...', self.browser.contents)
268        ctrl = self.browser.getControl(name='val_id')
269        value = ctrl.options[0]
270        self.browser.getLink(value).click()
271        self.assertMatches('...Amount Authorized...', self.browser.contents)
272        self.assertTrue('<span>6800.0</span>' in self.browser.contents)
273        self.browser.getLink("CollegePAY", index=0).click()
274        self.assertEqual(self.student['payments'][value].amount_auth, 6800.0)
275        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
276        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
277        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
278
279        self.app['configuration']['2004'].transcript_local_fee = 5000.0
280        self.browser.open(self.payments_path + '/addop')
281        self.browser.getControl(name="form.p_category").value = ['transcript_local']
282        self.browser.getControl("Create ticket").click()
283        ctrl = self.browser.getControl(name='val_id')
284        value = ctrl.options[1]
285        self.browser.getLink(value).click()
286        self.assertMatches('...Amount Authorized...', self.browser.contents)
287        self.assertTrue('<span>5000.0</span>' in self.browser.contents)
288        self.payment_url = self.browser.url
289        self.browser.getLink("CollegePAY", index=0).click()
290        self.assertEqual(self.student['payments'][value].amount_auth, 5000.0)
291        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
292        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
293        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
294
295        self.app['configuration']['2004'].loss_idcard_fee = 1015.0
296        self.browser.open(self.payments_path + '/addop')
297        self.browser.getControl(name="form.p_category").value = ['loss_idcard']
298        self.browser.getControl("Create ticket").click()
299        ctrl = self.browser.getControl(name='val_id')
300        value = ctrl.options[2]
301        self.browser.getLink(value).click()
302        self.assertMatches('...Amount Authorized...', self.browser.contents)
303        self.assertTrue(
304            '<span>1015.0</span>' in self.browser.contents)
305        self.payment_url = self.browser.url
306        self.browser.getLink("CollegePAY", index=0).click()
307        self.assertEqual(self.student['payments'][value].amount_auth, 1015.0)
308        self.assertEqual(self.student['payments'][value].provider_amt, 9.0)
309        self.assertEqual(self.student['payments'][value].gateway_amt, 15.22)
310        self.assertEqual(self.student['payments'][value].thirdparty_amt, 6.0)
311
312        self.app['configuration']['2004'].loss_examcard_fee = 500.0
313        self.browser.open(self.payments_path + '/addop')
314        self.browser.getControl(name="form.p_category").value = ['loss_examcard']
315        self.browser.getControl("Create ticket").click()
316        ctrl = self.browser.getControl(name='val_id')
317        value = ctrl.options[3]
318        self.browser.getLink(value).click()
319        self.assertMatches('...Amount Authorized...', self.browser.contents)
320        self.assertTrue('<span>500.0</span>' in self.browser.contents)
321        self.payment_url = self.browser.url
322        self.browser.getLink("CollegePAY", index=0).click()
323        self.assertEqual(self.student['payments'][value].amount_auth, 500.0)
324        self.assertEqual(self.student['payments'][value].provider_amt, 4.5)
325        self.assertEqual(self.student['payments'][value].gateway_amt, 7.5)
326        self.assertEqual(self.student['payments'][value].thirdparty_amt, 3)
327
328        self.app['configuration']['2004'].change_inst_fee = 6000.0
329        self.browser.open(self.payments_path + '/addop')
330        self.browser.getControl(name="form.p_category").value = ['change_inst']
331        self.browser.getControl("Create ticket").click()
332        ctrl = self.browser.getControl(name='val_id')
333        value = ctrl.options[4]
334        self.browser.getLink(value).click()
335        self.assertMatches('...Amount Authorized...', self.browser.contents)
336        self.assertTrue('<span>6000.0</span>' in self.browser.contents)
337        self.payment_url = self.browser.url
338        self.browser.getLink("CollegePAY", index=0).click()
339        self.assertEqual(self.student['payments'][value].amount_auth, 6000.0)
340        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
341        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
342        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
343
344        self.app['configuration']['2004'].loss_result_fee = 7000.0
345        self.browser.open(self.payments_path + '/addop')
346        self.browser.getControl(name="form.p_category").value = ['loss_result']
347        self.browser.getControl("Create ticket").click()
348        ctrl = self.browser.getControl(name='val_id')
349        value = ctrl.options[5]
350        self.browser.getLink(value).click()
351        self.assertMatches('...Amount Authorized...', self.browser.contents)
352        self.assertTrue('<span>7000.0</span>' in self.browser.contents)
353        self.payment_url = self.browser.url
354        self.browser.getLink("CollegePAY", index=0).click()
355        self.assertEqual(self.student['payments'][value].amount_auth, 7000.0)
356        self.assertEqual(self.student['payments'][value].provider_amt, 300.0)
357        self.assertEqual(self.student['payments'][value].gateway_amt, 300.0)
358        self.assertEqual(self.student['payments'][value].thirdparty_amt, 200.0)
359
360        self.app['configuration']['2004'].loss_idcard_fee = 1900.0
361        self.browser.open(self.payments_path + '/addop')
362        self.browser.getControl(name="form.p_category").value = ['loss_idcard']
363        self.browser.getControl("Create ticket").click()
364        ctrl = self.browser.getControl(name='val_id')
365        value = ctrl.options[6]
366        self.browser.getLink(value).click()
367        self.assertMatches('...Amount Authorized...', self.browser.contents)
368        self.assertTrue('<span>1900.0</span>' in self.browser.contents)
369        self.payment_url = self.browser.url
370        self.browser.getLink("CollegePAY", index=0).click()
371        self.assertEqual(self.student['payments'][value].amount_auth, 1900.0)
372        self.assertEqual(self.student['payments'][value].provider_amt, 9.0)
373        self.assertEqual(self.student['payments'][value].gateway_amt, 28.5)
374        self.assertEqual(self.student['payments'][value].thirdparty_amt, 6.0)
375
376
377    def test_interswitch_form_ticket_expired(self):
378        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
379        acc_payment = createObject('waeup.StudentOnlinePayment')
380        acc_payment.p_state = 'unpaid'
381        acc_payment.p_category = 'clearance'
382        acc_payment.p_id = 'xyz'
383        acc_payment.pay_item_id = '123'
384        acc_payment.amount_auth = 876.0
385        self.student['payments']['xyz'] = acc_payment
386        self.browser.open(self.payments_path + '/xyz')
387        self.browser.getLink("CollegePAY", index=0).click()
388        self.assertTrue('<input type="hidden" name="pay_item_id" value="000" />'
389                           in self.browser.contents)
390        self.assertMatches('...Total Amount Authorized:...',
391                           self.browser.contents)
392        self.assertEqual(self.student.current_mode, 'nd_ft')
393        self.assertTrue(
394            '<input type="hidden" name="amount" value="87600" />' in
395            self.browser.contents)
396        delta = timedelta(days=8)
397        acc_payment.creation_date -= delta
398        self.browser.open(self.payments_path + '/xyz')
399        self.browser.getLink("CollegePAY", index=0).click()
400        self.assertMatches(
401            '...This payment ticket is too old. Please create a new ticket...',
402            self.browser.contents)
403        delta = timedelta(days=2)
404        acc_payment.creation_date += delta
405        self.browser.open(self.payments_path + '/xyz')
406        self.browser.getLink("CollegePAY", index=0).click()
407        self.assertMatches('...Total Amount Authorized:...',
408                           self.browser.contents)
409
410    @external_test
411    def test_webservice(self):
412        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
413        IWorkflowState(self.student).setState('cleared')
414        # We add a fake maint. payment ticket to meet the condition
415        maint_payment = CustomStudentOnlinePayment()
416        self.student['payments']['any_key'] = maint_payment
417        maint_payment.p_category = 'hostel_maintenance'
418        maint_payment.p_state = 'paid'
419        maint_payment.p_session = 2004
420        # We create the school fee payment ticket
421        self.browser.open(self.payments_path + '/addop')
422        self.browser.getControl(name="form.p_category").value = ['schoolfee']
423        self.browser.getControl("Create ticket").click()
424        self.assertMatches('...ticket created...',
425                           self.browser.contents)
426        ctrl = self.browser.getControl(name='val_id')
427        self.value = ctrl.options[1]
428        self.browser.getLink(self.value).click()
429        self.payment_url = self.browser.url
430        # First we have open InterswitchPageStudent to set provider_amt
431        # and gateway_amt
432        self.browser.open(self.payment_url + '/goto_interswitch')
433        # Now we can call the webservice
434        self.browser.open(self.payment_url + '/request_webservice')
435        self.assertMatches('...Unsuccessful callback...',
436                          self.browser.contents)
437        # The payment is now in state failed ...
438        self.assertMatches('...<span>Failed</span>...',
439                          self.browser.contents)
440        # ... and the catalog has been updated
441        cat = getUtility(ICatalog, name='payments_catalog')
442        results = list(
443            cat.searchResults(p_state=('failed', 'failed')))
444        self.assertEqual(len(results), 1)
445        self.assertEqual(results[0].p_state, 'failed')
446
447        # Let's replace the p_id with a valid p_id of the Kwarapoly
448        # live system. This is definitely not an appropriate
449        # solution for testing, but we have no choice since
450        # Interswitch doesn't provide any interface
451        # for testing.
452        payment = self.student['payments'][self.value]
453        payment.p_id = 'p3543612043224'
454        self.browser.open(self.payment_url + '/request_webservice')
455        self.assertMatches('...Callback amount does not match...',
456                          self.browser.contents)
457        # The payment is now in state failed ...
458        self.assertMatches('...<span>Failed</span>...',
459                          self.browser.contents)
460        # Let's replace the amount autorized with the amount of the
461        # live system payment
462        payment.amount_auth = payment.r_amount_approved
463        self.browser.open(self.payment_url + '/request_webservice')
464        self.assertMatches('...Successful payment...',
465                          self.browser.contents)
466        # The payment is now in state paid ...
467        self.assertMatches('...<span>Paid</span>...',
468                          self.browser.contents)
469        # ... and the catalog has been updated
470        cat = getUtility(ICatalog, name='payments_catalog')
471        results = list(
472            cat.searchResults(p_state=('paid', 'paid')))
473        self.assertEqual(len(results), 1)
474        self.assertEqual(results[0].p_state, 'paid')
475        # Approval is logged in students.log ...
476        logfile = os.path.join(
477            self.app['datacenter'].storage, 'logs', 'students.log')
478        logcontent = open(logfile).read()
479        self.assertTrue(
480            'zope.mgr - '
481            'waeup.kwarapoly.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
482            'W1000000 - successful schoolfee payment: p3543612043224\n'
483            in logcontent)
484        # ... and in payments.log
485        logfile = os.path.join(
486            self.app['datacenter'].storage, 'logs', 'payments.log')
487        logcontent = open(logfile).read()
488        self.assertTrue(
489            '"zope.mgr",W1000000,p3543612043224,schoolfee,'
490            '52100.0,00,1200.0,300.0,1800.0,,,\n'
491            in logcontent)
492
493
494class InterswitchTestsApplicants(ApplicantsFullSetup):
495    """Tests for the Interswitch payment gateway.
496    """
497
498    layer = FunctionalLayer
499
500    def setUp(self):
501        super(InterswitchTestsApplicants, self).setUp()
502        configuration = SessionConfiguration()
503        configuration.academic_session = datetime.now().year - 2
504        self.app['configuration'].addSessionConfiguration(configuration)
505        self.configuration = configuration
506        # Create at least one Kwarapoly faculty
507        self.app['faculties']['CPGS'] = Faculty(code='CPGS')
508        self.app['faculties']['CPGS']['dep1'] = Department(code='dep1')
509        self.certificate2 = createObject('waeup.Certificate')
510        self.certificate2.code = u'CERT2'
511        self.certificate2.application_category = 'ndft'
512        self.certificate2.study_mode = 'nd_ft'
513        self.certificate2.start_level = 100
514        self.certificate2.end_level = 300
515        self.app['faculties']['CPGS']['dep1'].certificates.addCertificate(
516            self.certificate2)
517        self.applicantscontainer.application_category = 'ndft'
518        self.applicant.applicant_id = u'nd_anything'
519       
520        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
521        self.browser.open(self.manage_path)
522        #IWorkflowState(self.student).setState('started')
523        super(InterswitchTestsApplicants, self).fill_correct_values()
524        self.browser.getControl(name="form.course1").value = ['CERT2']
525        self.applicantscontainer.application_fee = 3333.0
526        self.browser.getControl(name="form.nationality").value = ['NG']
527        self.browser.getControl(name="transition").value = ['start']
528        self.browser.getControl("Save").click()
529        self.browser.getControl("Add online").click()
530        self.assertMatches('...ticket created...',
531                           self.browser.contents)
532        self.assertMatches('...Amount Authorized...',
533                           self.browser.contents)
534        self.assertTrue('<span>3333.0</span>' in self.browser.contents)
535        self.payment_url = self.browser.url
536
537
538    def test_interswitch_form(self):
539
540        # Manager can access InterswitchForm
541        self.browser.getLink("CollegePAY", index=0).click()
542        self.assertMatches('...Total Amount Authorized:...',
543                           self.browser.contents)
544        self.assertTrue(
545            '<input type="hidden" name="amount" value="333300" />'
546            in self.browser.contents)
547        self.assertTrue(
548            '<item_detail item_id="1" item_name="Application" '
549            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
550            in self.browser.contents)
551
552        # Meanwhile hndft fee goes to same account
553        self.applicant.applicant_id = u'hnd_anything'
554        self.browser.open(self.manage_path)
555        ctrl = self.browser.getControl(name='val_id')
556        value = ctrl.options[0]
557        self.browser.getLink(value).click()
558        self.browser.getLink("CollegePAY", index=0).click()
559        self.assertTrue(
560            '<item_detail item_id="1" item_name="Application" '
561            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
562            in self.browser.contents)
563        # Commission or bribe?
564        self.assertTrue(
565            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
566            'bank_id="117" acct_num="1013196791" />'
567            in self.browser.contents)
568        self.assertTrue(
569            '<item_detail item_id="3" item_name="BT Education" '
570            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
571            in self.browser.contents)
572
573        # prehndft fee goes to another account
574        self.applicant.applicant_id = u'prehnd_anything'
575        self.browser.open(self.manage_path)
576        ctrl = self.browser.getControl(name='val_id')
577        value = ctrl.options[0]
578        self.browser.getLink(value).click()
579        self.browser.getLink("CollegePAY", index=0).click()
580        self.assertTrue(
581            '<item_detail item_id="1" item_name="Application" '
582            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
583            in self.browser.contents)
584        # No 'commission', no provider fee in 2013
585        #self.assertFalse('Dalash' in self.browser.contents)
586        #self.assertFalse('BT Education' in self.browser.contents)
587        # Comission is charged from 14/09/2014
588        self.assertTrue(
589            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
590            'bank_id="117" acct_num="1013196791" />'
591            in self.browser.contents)
592        self.assertTrue(
593            '<item_detail item_id="3" item_name="BT Education" '
594            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
595            in self.browser.contents)
596
597        # prejambites fee goes to another account
598        self.applicant.applicant_id = u'prejambites_anything'
599        self.browser.open(self.manage_path)
600        ctrl = self.browser.getControl(name='val_id')
601        value = ctrl.options[0]
602        self.browser.getLink(value).click()
603        self.browser.getLink("CollegePAY", index=0).click()
604        self.assertTrue(
605            '<item_detail item_id="1" item_name="Application" '
606            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
607            in self.browser.contents)
608        # No 'commission', no provider fee in 2013
609        #self.assertFalse('Dalash' in self.browser.contents)
610        #self.assertFalse('BT Education' in self.browser.contents)
611        # Comission is charged from 14/09/2014
612        self.assertTrue(
613            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
614            'bank_id="117" acct_num="1013196791" />'
615            in self.browser.contents)
616        self.assertTrue(
617            '<item_detail item_id="3" item_name="BT Education" '
618            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
619            in self.browser.contents)
620        self.assertTrue(
621            '<input type="hidden" name="pay_item_id" value="104" />'
622            in self.browser.contents)
623
624        # putme goes into the prejambites account
625        self.applicant.applicant_id = u'putme_anything'
626        self.browser.open(self.manage_path)
627        ctrl = self.browser.getControl(name='val_id')
628        value = ctrl.options[0]
629        self.browser.getLink(value).click()
630        self.browser.getLink("CollegePAY", index=0).click()
631        self.assertTrue(
632            '<item_detail item_id="1" item_name="Application" '
633            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
634            in self.browser.contents)
635        self.assertTrue(
636            '<item_detail item_id="2" item_name="Dalash" item_amt="20000" '
637            'bank_id="117" acct_num="1013196791" />'
638            in self.browser.contents)
639        self.assertTrue(
640            '<item_detail item_id="3" item_name="BT Education" '
641            'item_amt="30000" bank_id="117" acct_num="1010764827" />'
642            in self.browser.contents)
643        self.assertTrue(
644            '<input type="hidden" name="pay_item_id" value="104" />'
645            in self.browser.contents)
646
647    def test_interswitch_form_ticket_expired(self):
648        # Manager can access InterswitchForm
649        self.browser.getLink("CollegePAY", index=0).click()
650        self.assertMatches('...Total Amount Authorized:...',
651                           self.browser.contents)
652        self.assertTrue(
653            '<input type="hidden" name="amount" value="333300" />'
654            in self.browser.contents)
655        self.assertTrue(
656            '<item_detail item_id="1" item_name="Application" '
657            'item_amt="253300" bank_id="10" acct_num="0106259811" />'
658            in self.browser.contents)
659        delta = timedelta(days=8)
660        self.applicant.values()[0].creation_date -= delta
661        self.browser.open(self.payment_url)
662        self.browser.getLink("CollegePAY", index=0).click()
663        self.assertMatches(
664            '...This payment ticket is too old. Please create a new ticket...',
665            self.browser.contents)
666
667    def prepare_special_container(self):
668        # Add special application container
669        container_name = u'special%s' % (datetime.now().year - 2)
670        applicantscontainer = ApplicantsContainer()
671        applicantscontainer.code = container_name
672        applicantscontainer.prefix = 'special'
673        applicantscontainer.year = datetime.now().year - 2
674        applicantscontainer.title = u'This is a special app container'
675        applicantscontainer.application_category = 'no'
676        applicantscontainer.mode = 'create'
677        delta = timedelta(days=10)
678        applicantscontainer.startdate = datetime.now(pytz.utc) - delta
679        applicantscontainer.enddate = datetime.now(pytz.utc) + delta
680        applicantscontainer.strict_deadline = True
681        self.app['applicants'][container_name] = applicantscontainer
682        # Add an applicant
683        applicant = createObject('waeup.Applicant')
684        # reg_number is the only field which has to be preset here
685        # because managers are allowed to edit this required field
686        applicant.reg_number = u'12345'
687        applicant.firstname = u'Vorname'
688        applicant.lastname = u'Nachname'
689        applicant.email = 'aa@aa.aa'
690        applicant.special_application = u'transcript_local'
691        applicant.applicant_id = u'special_anything'
692        self.app['applicants'][container_name].addApplicant(applicant)
693        self.special_applicant = applicant
694        self.configuration.transcript_local_fee = 5300.0
695        self.special_manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
696            container_name, applicant.application_number, 'manage')
697
698    def test_interswitch_form_special(self):
699        self.prepare_special_container()
700        self.browser.open(self.special_manage_path)
701        self.browser.getControl("Add online").click()
702        self.assertMatches('...ticket created...',
703                           self.browser.contents)
704        self.browser.getLink("CollegePAY", index=0).click()
705        self.assertTrue(
706            '<item_detail item_id="1" item_name="ND Transcript (local)" '
707            'item_amt="450000" bank_id="10" acct_num="0106259811" />'
708            in self.browser.contents)
709
710        self.special_applicant.special_application = u'log_book'
711        self.configuration.log_book_fee = 570.5
712        self.browser.open(self.special_manage_path)
713        self.browser.getControl("Add online").click()
714        self.assertMatches('...ticket created...',
715                           self.browser.contents)
716        self.browser.getLink("CollegePAY", index=0).click()
717        # The university gets 570.5 - (1.5% x 570.5) - 3 - 4.5
718        self.assertTrue(
719            '<item_detail item_id="1" item_name="Log Book" '
720            'item_amt="55444" bank_id="10" acct_num="0106259811" />'
721            in self.browser.contents)
722
723
724    @external_test
725    def test_webservice(self):
726        self.prepare_special_container()
727        IWorkflowState(self.special_applicant).setState('started')
728        self.browser.open(self.special_manage_path)
729        self.browser.getControl("Add online").click()
730        payment_url = self.browser.url
731        self.browser.open(payment_url + '/request_webservice')
732        self.assertMatches('...Unsuccessful callback...',
733                          self.browser.contents)
734        # The payment is now in state failed
735        self.assertMatches('...<span>Failed</span>...',
736                          self.browser.contents)
737        # Let's replace the p_id with a valid p_id of the Kwarapoly
738        # live system. This is definitely not an appropriate
739        # solution for testing, but we have no choice since
740        # Interswitch doesn't provide any interface
741        # for testing.
742        p_id = self.special_applicant.keys()[0]
743        payment = self.special_applicant[p_id]
744        payment.p_id = 'p3543612043224'
745        self.browser.open(payment_url + '/request_webservice')
746        self.assertMatches('...Callback amount does not match...',
747                          self.browser.contents)
748        payment.amount_auth = payment.r_amount_approved
749
750        self.browser.open(payment_url + '/request_webservice')
751        self.assertMatches('...Successful payment...',
752                          self.browser.contents)
753        # The payment is now in state paid ...
754        self.assertMatches('...<span>Paid</span>...',
755                          self.browser.contents)
756        # ... and the catalog has been updated
757        cat = getUtility(ICatalog, name='payments_catalog')
758        results = list(
759            cat.searchResults(p_state=('paid', 'paid')))
760        self.assertEqual(len(results), 1)
761        self.assertEqual(results[0].p_state, 'paid')
762        # Approval is logged in applicants.log ...
763        logfile = os.path.join(
764            self.app['datacenter'].storage, 'logs', 'applicants.log')
765        logcontent = open(logfile).read()
766        self.assertTrue(
767            'zope.mgr - waeup.kwarapoly.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageApplicant'
768            ' - special_anything - successful payment: p3543612043224\n'
769            in logcontent)
770        # ... and in payments.log
771        logfile = os.path.join(
772            self.app['datacenter'].storage, 'logs', 'payments.log')
773        logcontent = open(logfile).read()
774        self.assertTrue(
775            '"zope.mgr",special_anything,p3543612043224,transcript_local,52100.0,'
776            '00,0.0,0.0,0.0,,,\n'
777            in logcontent)
778        self.assertEqual(self.applicant.state, 'started')
779        # Special Payment applicant can add new payment
780        self.browser.open(self.edit_path)
781        self.assertTrue('Add online payment ticket' in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.