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

Last change on this file since 15596 was 15468, checked in by Henrik Bettermann, 5 years ago

Add p_split_data field.

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