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

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

Wow, Remita has modified the software. get_JSON_POST_response can only be called once with th esame same orderId to retrieve the RRR. Also the trailing whitespace disappeared. Last but not least lineitems are no longer part of the transaction status request response.

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