## $Id: tests.py 16246 2020-09-24 06:42:10Z henrik $ ## ## Copyright (C) 2017 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## import os import unittest import random import json import hashlib import httplib from urllib import urlencode from datetime import datetime, timedelta, date from zope.component import createObject, getUtility from zope.catalog.interfaces import ICatalog from hurry.workflow.interfaces import IWorkflowState from waeup.kofa.students.tests.test_browser import StudentsFullSetup from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup from waeup.kofa.configuration import SessionConfiguration from kofacustom.nigeria.students.payments import NigeriaStudentOnlinePayment from kofacustom.nigeria.testing import FunctionalLayer from kofacustom.nigeria.etranzact.helpers import ( query_history, query_payoutlet, ERROR_PART1, ERROR_PART2) #from kofacustom.nigeria.etranzact.helpers import (query_etranzact) # Also run tests that send requests to external servers? # If you enable this, please make sure the external services # do exist really and are not bothered by being spammed by a test programme. EXTERNAL_TESTS = False TERMINAL_ID = '5003021194' HOST = 'demo.etranzact.com' HTTPS = True SECRET_KEY = 'DEMO_KEY' LOGO_URL = 'https://iuokada.waeup.org/static_custom/iou_logo.png' GATEWAY_AMT = 500.0 # Valid transaction id in Etranzact system TID = 'p5689785145198' def external_test(func): if not EXTERNAL_TESTS: myself = __file__ if myself.endswith('.pyc'): myself = myself[:-1] print "WARNING: external tests are skipped!" print "WARNING: edit %s to enable them." % myself return return func def post_caller(host, https, terminal_id, transaction_id, responseurl, amount_auth, email, phone, display_fullname, hashvalue, logo_url): headers={"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} url = "/webconnect/v3/caller.jsp" if https: h = httplib.HTTPSConnection(host) else: h = httplib.HTTPConnection(host) args = {'TERMINAL_ID': terminal_id, 'TRANSACTION_ID': transaction_id, 'RESPONSE_URL': responseurl, 'AMOUNT': amount_auth, 'EMAIL': email, 'PHONENO': phone, 'FULL_NAME': display_fullname, 'CURRENCY_CODE': 'NGN', 'CHECKSUM': hashvalue, 'LOGO_URL': logo_url, } h.request('POST', url, urlencode(args), headers) return response = h.getresponse() if response.status!=200: return 'Connection error (%s, %s)' % (response.status, response.reason) resp = response.read() return resp def create_transaction(transaction_id): responseurl = 'http://xxxx' amount = '4444.0' email = 'aa@aa.ng' phone = '12324' display_fullname = 'Tester' logo_url = 'http://xxxx' hashargs = amount + TERMINAL_ID + transaction_id \ + responseurl + 'DEMO_KEY' hashvalue = hashlib.md5(hashargs).hexdigest() response = post_caller(HOST, HTTPS, TERMINAL_ID, transaction_id, responseurl, amount, email, phone, display_fullname, hashvalue, logo_url) return response class HelperTests(unittest.TestCase): terminal_id = TERMINAL_ID @external_test def test_query_history(self): transaction_id = str(random.randint(100000000, 999999999)) raw, formvars = query_history(HOST, self.terminal_id, transaction_id, HTTPS) self.assertTrue( 'Transaction with the given transaction_id (%s) not found' % transaction_id in raw) # Okay, let's create a transaction caller_response = create_transaction(transaction_id) self.assertEqual(caller_response, None) # It seems that the transaction has been created but we don't get a # useful response raw, formvars = query_history(HOST, self.terminal_id, transaction_id, HTTPS) self.assertTrue( '' in raw) # The same, an 'empty' response obviously means that the transaction # was found but no result was sent to the response_url because the # payment was cancelled. # Peter: No response would be returned because payment status information # was not saved. Whenever you get a null response, means payment was # not received only payments with error code 0 is successful. # So in this case transaction fails. # We manually created and tried to pay a transaction # which seems to be valid till next restart of the demo portal. raw, formvars = query_history(HOST, self.terminal_id, TID, HTTPS) # Now Etranzact is redirecting but the response is still useless self.assertTrue('Redirecting...' in raw) self.assertEqual(formvars['TRANSACTION_ID'], TID) return @external_test def test_query_payoutlet(self): # We've got some test numbers from Etranzact for testing payment = NigeriaStudentOnlinePayment() payment.p_id = 'p5723474039401' success, msg, log = query_payoutlet( HOST, '5003021194', '500854291572447457669', payment, True) self.assertTrue(msg, 'Wrong amount') payment.amount_auth = 200000.0 success, msg, log = query_payoutlet( HOST, '5003021194', '500854291572447457669', payment, True) self.assertTrue(success) payment.p_id = 'xyz' success, msg, log = query_payoutlet( HOST, '5003021194', '500854291572447457669', payment, True) self.assertTrue(msg, 'Wrong payment id') return class EtranzactTestsApplicants(ApplicantsFullSetup): """Tests for the Etranzact payment gateway. """ layer = FunctionalLayer def setUp(self): super(EtranzactTestsApplicants, self).setUp() configuration = SessionConfiguration() configuration.academic_session = datetime.now().year - 2 configuration.etranzact_webconnect_enabled = True configuration.etranzact_payoutlet_enabled = True self.app['configuration'].addSessionConfiguration(configuration) self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') self.browser.open(self.manage_path) #IWorkflowState(self.student).setState('started') super(EtranzactTestsApplicants, self).fill_correct_values() self.applicantscontainer.application_fee = 3333.0 self.browser.getControl(name="form.nationality").value = ['NG'] self.browser.getControl(name="transition").value = ['start'] self.browser.getControl("Save").click() self.browser.getControl("Add online").click() self.assertMatches('...ticket created...', self.browser.contents) self.payment = self.applicant.values()[0] self.payment_url = self.browser.url @external_test def test_applicant_views(self): # Manager can access Etranzact form self.browser.getLink("Pay via Etranzact WebConnect").click() self.assertTrue("Pay now" in self.browser.contents) # Means of testing end here. # We requery an existing paiment now. self.payment.p_id = TID self.browser.open(self.payment_url) self.browser.getLink("Requery Etranzact WebConnect History").click() self.assertTrue('Wrong checksum.' in self.browser.contents) # ... probably because responseurl of the transaction stored in the # system and the responseurl generated in process_response are # different # Means of testing end here again. return class EtranzactTestsStudents(StudentsFullSetup): """Tests for the Etranzact payment gateway. """ layer = FunctionalLayer def setUp(self): super(EtranzactTestsStudents, self).setUp() self.app['configuration']['2004'].etranzact_webconnect_enabled = True self.app['configuration']['2004'].etranzact_payoutlet_enabled = True self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') self.browser.open(self.payments_path) IWorkflowState(self.student).setState('cleared') self.student.nationality = u'NG' self.browser.open(self.payments_path + '/addop') self.browser.getControl(name="form.p_category").value = ['schoolfee'] self.browser.getControl("Create ticket").click() self.assertMatches('...ticket created...', self.browser.contents) ctrl = self.browser.getControl(name='val_id') self.value = ctrl.options[0] self.browser.getLink(self.value).click() self.assertMatches('...Amount Authorized...', self.browser.contents) self.assertTrue('40000.0', self.browser.contents) self.payment_url = self.browser.url self.payment = self.student['payments'][self.value] @external_test def test_student_views(self): # Manager can access Etranzact form self.browser.getLink("Pay via Etranzact WebConnect").click() self.assertTrue("Pay now" in self.browser.contents) # Means of testing end here. # We requery an existing paiment now. self.payment.p_id = TID self.browser.open(self.payment_url) self.browser.getLink("Requery Etranzact WebConnect History").click() self.assertTrue('Wrong checksum.' in self.browser.contents) # ... probably because responseurl and amount stored in the # system and the responseurl generated in process_response are # different # Means of testing end here again. return @external_test def test_student_payoutlet_views(self): self.browser.getLink("Pay via Etranzact PayOutlet").click() self.browser.getControl(name="confirmation_number").value = '600854291572447457669' self.browser.getControl("Submit to Etranzact").click() # This response is strange self.assertTrue('-3:Wrong Setup' in self.browser.contents) self.browser.getLink("Pay via Etranzact PayOutlet").click() # This confirmation number exists self.browser.getControl(name="confirmation_number").value = '500854291572447457669' self.browser.getControl("Submit to Etranzact").click() self.assertTrue('Wrong amount' in self.browser.contents) # Some attributes have been set self.assertEqual(self.payment.r_desc, 'Test Test Test-CLEARANCE -001-p5723474039401') return def test_webservice(self): self.browser.open( 'http://localhost/app/feerequest?PAYEE_ID=%s&PAYMENT_TYPE=SCHOOLFEE' % self.payment.p_id) self.assertEqual(self.browser.contents, 'PayeeName=Anna Tester~' 'Faculty=fac1~Department=dep1~' 'Level=100~ProgrammeType=CERT1~' 'StudyType=ug_ft~Session=2004/2005~' 'PayeeID=%s~' 'Amount=40000.0~FeeStatus=unpaid~' 'Semester=N/A~PaymentType=School Fee~' 'MatricNumber=234~Email=aa@aa.ng~' 'PhoneNumber=1234' % self.payment.p_id) self.browser.open('http://localhost/app/feerequest') self.assertEqual(self.browser.contents, ERROR_PART1 + 'Missing PAYEE_ID' + ERROR_PART2) self.browser.open('http://localhost/app/feerequest?NONSENSE=nonsense') self.assertEqual(self.browser.contents, ERROR_PART1 + 'Missing PAYEE_ID' + ERROR_PART2) self.browser.open( 'http://localhost/app/feerequest?PAYEE_ID=nonsense&PAYMENT_TYPE=SCHOOLFEE') self.assertEqual(self.browser.contents, ERROR_PART1 + 'Invalid PAYEE_ID' + ERROR_PART2) self.browser.open( 'http://localhost/app/feerequest?PAYEE_ID=%s&PAYMENT_TYPE=NONSENSE' % self.payment.p_id) self.assertEqual(self.browser.contents, ERROR_PART1 + 'Invalid PAYMENT_TYPE' + ERROR_PART2) self.browser.open( 'http://localhost/app/feerequest?PAYEE_ID=%s' % self.payment.p_id) self.assertEqual(self.browser.contents, ERROR_PART1 + 'Invalid PAYMENT_TYPE' + ERROR_PART2) self.browser.open( 'http://localhost/app/feerequest?PAYEE_ID=%s&PAYMENT_TYPE=CLEARANCE' % self.payment.p_id) self.assertEqual(self.browser.contents, ERROR_PART1 + 'Wrong PAYMENT_TYPE' + ERROR_PART2) # Change payment state self.student['payments'][self.payment.p_id].p_state = 'paid' self.browser.open( 'http://localhost/app/feerequest?PAYEE_ID=%s&PAYMENT_TYPE=SCHOOLFEE' % self.payment.p_id) self.assertEqual(self.browser.contents, ERROR_PART1 + 'PAYEE_ID already used' + ERROR_PART2)