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

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

Prepare all payment gateway modules for net amount fee configuration. In the future, provider and gateway surcharges will be determined and added just before the data are being send to the gateways for the first time.

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