source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/remita/tests.py @ 14786

Last change on this file since 14786 was 14781, checked in by Henrik Bettermann, 7 years ago

Implement Payment Notification Listener.

  • Property svn:keywords set to Id
File size: 15.6 KB
Line 
1## $Id: tests.py 14781 2017-08-09 08:49:45Z henrik $
2##
3## Copyright (C) 2017 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 unittest
20import random
21import json
22from datetime import datetime, timedelta, date
23from zope.component import createObject, getUtility
24from zope.catalog.interfaces import ICatalog
25from hurry.workflow.interfaces import IWorkflowState
26from waeup.kofa.students.tests.test_browser import StudentsFullSetup
27from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
28from waeup.kofa.configuration import SessionConfiguration
29from kofacustom.nigeria.students.payments import NigeriaStudentOnlinePayment
30from kofacustom.nigeria.testing import FunctionalLayer
31
32from kofacustom.nigeria.remita.helpers import (
33    get_JSON_POST_response, get_payment_status_via_rrr, query_remita)
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 = True
39
40def external_test(func):
41    if not EXTERNAL_TESTS:
42        myself = __file__
43        if myself.endswith('.pyc'):
44            myself = myself[:-1]
45        print "WARNING: external tests are skipped!"
46        print "WARNING: edit %s to enable them." % myself
47        return
48    return func
49
50class HelperTests(unittest.TestCase):
51
52    merchantId = '2547916'
53    serviceTypeId = '4430731'
54    api_key = '1946'
55    responseurl = 'http://xxxx'
56    host = 'www.remitademo.net'
57    url = '/remita/ecomm/split/init.reg'  # /remita/ecomm/v2/init.reg
58    lineitems = (
59                  {"lineItemsId":"itemid1","beneficiaryName":"Oshadami Mike",
60                  "beneficiaryAccount":"6020067886","bankCode":"011",
61                  "beneficiaryAmount":"500","deductFeeFrom":"1"},
62                  {"lineItemsId":"itemid2","beneficiaryName":"Ogunseye Mujib",
63                  "beneficiaryAccount":"0360883515","bankCode":"050",
64                  "beneficiaryAmount":"500","deductFeeFrom":"0"}
65                )
66    amount = 1000.0
67
68    def _get_transaction_data(self):
69        self.orderId = str(random.randint(100000000, 999999999))
70        resp = get_JSON_POST_response(
71                merchantId=self.merchantId, serviceTypeId=self.serviceTypeId,
72                api_key=self.api_key, orderId=self.orderId,
73                amount=self.amount, responseurl=self.responseurl,
74                host=self.host, url=self.url, https=False,
75                fullname='Anton Meier', email='am@xxx.de',
76                lineitems=self.lineitems)
77        self.rrr = resp['RRR'].rstrip()
78
79    @external_test
80    def test_get_JSON_POST_response(self):
81        self._get_transaction_data()
82        resp = get_JSON_POST_response(
83                merchantId=self.merchantId, serviceTypeId=self.serviceTypeId,
84                api_key=self.api_key, orderId=self.orderId,
85                amount=self.amount, responseurl=self.responseurl,
86                host=self.host, url=self.url, https=False,
87                fullname='Anton Meier', email='am@xxx.de',
88                lineitems=self.lineitems)
89        assert resp == {
90            u'status': u'RRR Already Exist for the orderId',
91            u'orderID': self.orderId,
92            u'RRR': self.rrr + ' ',  # strange trailing whitespace which
93                                     # obviously does not belong to the RRR
94            u'statuscode': u'055'}
95
96        resp = get_payment_status_via_rrr(
97                merchantId=self.merchantId,
98                api_key=self.api_key,
99                RRR=self.rrr,
100                host=self.host,
101                https=False,
102                )
103        assert resp['orderId'] == self.orderId
104        assert resp['status'] == '021'
105        assert resp['amount'] == self.amount
106        assert resp['lineitems'] == [
107            {u'status': u'021', u'lineItemsId': u'itemid1'},
108            {u'status': u'021', u'lineItemsId': u'itemid2'}]
109        assert resp['RRR'] == self.rrr
110        assert resp['message'] == u'Transaction Pending'
111
112class RemitaTestsStudents(StudentsFullSetup):
113    """Tests for the Remita payment gateway.
114    """
115
116    layer = FunctionalLayer
117
118    merchantId = '2547916'
119    serviceTypeId = '4430731'
120    api_key = '1946'
121    responseurl = 'http://xxxx'
122    host = 'www.remitademo.net'
123
124    # successful transaction
125    # (hopefully this transaction remains in the Remita database)
126    orderId = '3456346346'
127    rrr = u'280007640804'
128    amount = 1000.0
129
130    # pending transaction
131    #orderId_p = '987698769876'
132    rrr_p = u'320007640976'
133
134    def setUp(self):
135        super(RemitaTestsStudents, self).setUp()
136        self.app['configuration']['2004'].remita_enabled = True
137        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
138        self.browser.open(self.payments_path)
139        IWorkflowState(self.student).setState('cleared')
140        self.student.nationality = u'NG'
141        self.browser.open(self.payments_path + '/addop')
142        self.browser.getControl(name="form.p_category").value = ['schoolfee']
143        self.browser.getControl("Create ticket").click()
144        self.assertMatches('...ticket created...',
145                           self.browser.contents)
146        ctrl = self.browser.getControl(name='val_id')
147        self.value = ctrl.options[0]
148        self.browser.getLink(self.value).click()
149        self.assertMatches('...Amount Authorized...',
150                           self.browser.contents)
151        self.assertTrue('<span>40000.0</span>', self.browser.contents)
152        self.payment_url = self.browser.url
153        self.payment = self.student['payments'][self.value]
154
155    @external_test
156    def test_query_remita(self):
157        #requery pending transaction
158        qr = query_remita(
159            self.payment,
160            merchantId=self.merchantId,
161            api_key=self.api_key,
162            RRR=self.rrr_p,
163            host=self.host,
164            https=False,
165            verify=False)
166        assert qr == (
167            False,
168            u'Unsuccessful callback: ${a}',
169            u'unsuccessful callback for schoolfee payment %s: Transaction Pending'
170            % self.payment.p_id)
171
172        #requery successful transaction
173        self.payment.amount_auth = 1000.0
174        self.payment.p_id = self.orderId
175        qr = query_remita(
176            self.payment,
177            merchantId=self.merchantId,
178            api_key=self.api_key,
179            RRR=self.rrr,
180            host=self.host,
181            https=False,
182            verify=False)
183        assert qr[0] == True
184        assert qr[1] == u'Successful callback received'
185
186    @external_test
187    def test_student_remita_form(self):
188        # Manager can access Remita form
189        self.browser.getLink("Pay via Remita").click()
190        # The RRR has been retrieved
191        self.assertTrue('<input name="rrr" type="hidden" value="%s">' % self.rrr
192            in self.browser.contents)
193        self.assertEqual(self.payment.r_pay_reference, self.rrr)
194        self.assertEqual(self.payment.r_company, 'remita')
195        # Retrieval has been logged
196        logfile = os.path.join(
197            self.app['datacenter'].storage, 'logs', 'students.log')
198        logcontent = open(logfile).read()
199        self.assertTrue(
200            'zope.mgr - kofacustom.nigeria.remita.studentsbrowser.RemitaPageStudent'
201            ' - K1000000 - RRR retrieved: %s' % self.rrr in logcontent)
202        # Means of testing end here.
203        return
204
205    @external_test
206    def test_requery_verify_payment_status(self):
207        # Manager can access Remita form
208        self.browser.getLink("Requery Remita Payment Status").click()
209        self.assertTrue('Remita Retrieval Reference not found.'
210            in self.browser.contents)
211        self.payment.r_pay_reference = self.rrr
212        self.browser.getLink("Requery Remita Payment Status").click()
213        self.assertTrue('Callback amount does not match.'
214            in self.browser.contents)
215        self.payment.amount_auth = self.amount
216        self.browser.getLink("Requery Remita Payment Status").click()
217        self.assertTrue('Callback order id does not match.'
218            in self.browser.contents)
219        self.payment.p_id = self.orderId
220        self.browser.getLink("Requery Remita Payment Status").click()
221        self.assertTrue('Successful payment' in self.browser.contents)
222        self.assertEqual(self.payment.r_desc, 'Approved')
223        self.assertEqual(self.payment.r_amount_approved , 1000.0)
224        self.assertEqual(self.payment.r_code, '01')
225        self.browser.getLink("Verify Remita Payment Status").click()
226        self.assertTrue('Successful callback received' in self.browser.contents)
227        return
228
229class RemitaTestsWebserviceStudent(StudentsFullSetup):
230    """Tests for the Remita payment gateway.
231    """
232    layer = FunctionalLayer
233
234    merchantId = '2547916'
235    serviceTypeId = '4430731'
236    api_key = '1946'
237    responseurl = 'http://xxxx'
238    host = 'www.remitademo.net'
239
240    # successful transaction
241    # (hopefully this transaction remains in the Remita database)
242    orderId = '3456346346'
243    rrr = u'280007640804'
244    amount = 1000.0
245
246    @external_test
247    def test_payment_notification_listener_student(self):
248        payment = createObject('waeup.StudentOnlinePayment')
249        payment.p_category = u'schoolfee'
250        payment.p_session = self.student.current_session
251        payment.p_item = u'My Certificate'
252        payment.p_id = self.orderId
253        self.student['payments']['anykey'] = payment
254        data = [{'orderRef': self.orderId, 'rrr': self.rrr},]
255        # Send POST request with wrong payment amount
256        payment.amount_auth = 2000.0
257        self.browser.post('http://localhost/app/paymentnotificationlistener',
258            json.dumps(data), 'application/json; charset=utf-8')
259        self.assertEqual('0 (1)', self.browser.contents)
260        # Send POST request with correct payment amount
261        payment.amount_auth = self.amount
262        self.browser.post('http://localhost/app/paymentnotificationlistener',
263            json.dumps(data), 'application/json; charset=utf-8')
264        self.assertEqual('1 (1)', self.browser.contents)
265        logfile = os.path.join(
266            self.app['datacenter'].storage, 'logs', 'students.log')
267        logcontent = open(logfile).read()
268        self.assertTrue(
269            'zope.anybody - kofacustom.nigeria.remita.webservices.PaymentNotificationListenerWebservice'
270            ' - K1000000 - valid callback for schoolfee payment %s: '
271            % self.orderId   in logcontent)
272        self.assertTrue(
273            'zope.anybody - kofacustom.nigeria.remita.webservices.PaymentNotificationListenerWebservice'
274            ' - K1000000 - successful schoolfee payment: %s'
275            % self.orderId in logcontent)
276        logfile = os.path.join(
277            self.app['datacenter'].storage, 'logs', 'main.log')
278        logcontent = open(logfile).read()
279        self.assertTrue(
280            'zope.anybody - PaymentNotificationListenerWebservice called: '
281            '[{"rrr": "%s", "orderRef": "%s"}]'
282            % (self.rrr, self.orderId) in logcontent)
283        return
284
285class RemitaTestsWebserviceApplicant(ApplicantsFullSetup):
286    """Tests for the Remita payment gateway.
287    """
288    layer = FunctionalLayer
289
290    merchantId = '2547916'
291    serviceTypeId = '4430731'
292    api_key = '1946'
293    responseurl = 'http://xxxx'
294    host = 'www.remitademo.net'
295
296    # successful transaction
297    # (hopefully this transaction remains in the Remita database)
298    orderId = '3456346346'
299    rrr = u'280007640804'
300    amount = 1000.0
301
302    @external_test
303    def test_payment_notification_listener_applicant(self):
304        self.applicantscontainer.application_fee = self.amount
305        payment = createObject('waeup.ApplicantOnlinePayment')
306        payment.p_category = u'application'
307        payment.p_session = self.applicantscontainer.year
308        payment.p_item = u'My Certificate'
309        payment.p_id = self.orderId
310        payment.amount_auth = self.amount
311        self.applicant['anykey'] = payment
312        IWorkflowState(self.applicant).setState('started')
313        # Send POST request
314        data = [{'orderRef': self.orderId, 'rrr': self.rrr},]
315        self.browser.post('http://localhost/app/paymentnotificationlistener',
316            json.dumps(data), 'application/json; charset=utf-8')
317        self.assertEqual('1 (1)', self.browser.contents)
318        logfile = os.path.join(
319            self.app['datacenter'].storage, 'logs', 'applicants.log')
320        logcontent = open(logfile).read()
321        self.assertTrue(
322            'zope.anybody - kofacustom.nigeria.remita.webservices.PaymentNotificationListenerWebservice'
323            ' - %s - valid callback for application payment %s: '
324            % (self.applicant.applicant_id, self.orderId) in logcontent)
325        self.assertTrue(
326            'zope.anybody - kofacustom.nigeria.remita.webservices.PaymentNotificationListenerWebservice'
327            ' - %s - successful payment: %s'
328            % (self.applicant.applicant_id, self.orderId) in logcontent)
329        return
330
331class RemitaTestsApplicants(ApplicantsFullSetup):
332    """Tests for the Remita payment gateway.
333    """
334
335    layer = FunctionalLayer
336
337    # successful transaction
338    # (hopefully this transaction remains in the Remita database)
339    #orderId = '3456346346'
340    rrr = u'280007640804'
341    #amount = 1000.0
342
343    def setUp(self):
344        super(RemitaTestsApplicants, self).setUp()
345        configuration = SessionConfiguration()
346        configuration.academic_session = datetime.now().year - 2
347        configuration.remita_enabled = True
348        self.app['configuration'].addSessionConfiguration(configuration)
349        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
350        self.browser.open(self.manage_path)
351        #IWorkflowState(self.student).setState('started')
352        super(RemitaTestsApplicants, self).fill_correct_values()
353        self.applicantscontainer.application_fee = 1000.0
354        self.browser.getControl(name="form.nationality").value = ['NG']
355        self.browser.getControl(name="transition").value = ['start']
356        self.browser.getControl("Save").click()
357        self.browser.getControl("Add online").click()
358        self.assertMatches('...ticket created...',
359                           self.browser.contents)
360        self.payment = self.applicant.values()[0]
361        self.payment_url = self.browser.url
362
363    @external_test
364    def test_applicant_remita_form(self):
365        # Manager can access Remita form
366        self.browser.getLink("Pay via Remita").click()
367        # The RRR has been retrieved
368        self.assertTrue('<input name="rrr" type="hidden" value="%s">' % self.rrr
369            in self.browser.contents)
370        self.assertEqual(self.payment.r_pay_reference, self.rrr)
371        self.assertEqual(self.payment.r_company, 'remita')
372        # Retrieval has been logged
373        logfile = os.path.join(
374            self.app['datacenter'].storage, 'logs', 'applicants.log')
375        logcontent = open(logfile).read()
376        self.assertTrue(
377            'zope.mgr - kofacustom.nigeria.remita.applicantsbrowser.RemitaPageApplicant'
378            ' - %s - RRR retrieved: %s'
379            % (self.applicant.applicant_id, self.rrr) in logcontent)
380        # Means of testing end here.
381        return
Note: See TracBrowser for help on using the repository browser.