def test_http_proxy(self): config = securetrading.Config() self.assertEqual(None, config.http_proxy) exp_message = "A dict is required with https only e.g:\ {'https':'https://IP:PORT'}" tests = [ ("HTTPPROXY", AssertionError), (["1.3.4.3"], AssertionError), ({ "https": "https://1.1.1.1" }, None), ({ "http": "http://1.1.1.1" }, AssertionError), ({ "https": "https://1.1.1.1", "http": "http://1.1.1.1" }, AssertionError), ] for proxy_value, exp_exception in tests: if exp_exception is None: config.http_proxy = proxy_value self.assertEqual(proxy_value, config.http_proxy) else: six.assertRaisesRegex(self, exp_exception, exp_message, setattr, config, "http_proxy", proxy_value)
def test_http_response_headers(self): config = securetrading.Config() self.assertEqual([], config.http_response_headers) exp_message = "A list of strings are required to flag whether the \ header is returned" tests = [ ("True", None, AssertionError), ([True], None, AssertionError), ({ "max": False }, None, AssertionError), (["True"], ["true"], None), (["a"], ["a"], None), (["b", "Content-type"], ["b", "content-type"], None), (["b", u"\xa3", "Content-type"], ["b", u"\xa3", "content-type"], None), ] for sleep_value, exp_value, exp_exception in tests: if exp_exception is None: config.http_response_headers = sleep_value self.assertEqual(exp_value, config.http_response_headers) else: six.assertRaisesRegex(self, exp_exception, exp_message, setattr, config, "http_response_headers", sleep_value)
def test__get_response_headers(self): tests = [({}, [], {}), ({}, ["content-type"], {}), ({"Content-type": "application/json"}, ["content-type"], {"Content-type": "application/json"}), ({"ConTent-TypE": "application/json"}, ["content-type"], {"ConTent-TypE": "application/json"}), ({"Content-type": "application/json", "Content-length": "1234"}, ["content-type"], {"Content-type": "application/json"}), ({"Content-type": "application/json", "Content-length": "1234"}, ["content-type", "content-length"], {"Content-type": "application/json", "Content-length": "1234"}), ({}, ["content-type", "another"], {}), ({"Content-type": "application/json"}, ["content-type", "another"], {"Content-type": "application/json"}), ] for headers, requested_headers, exp_headers in tests: response = requests.Response() response.headers = headers self.http_client.response = response config = securetrading.Config() config.http_response_headers = requested_headers self.http_client.config = config actual = self.http_client._get_response_headers() self.assertEqual(actual, exp_headers)
def test_lookup(self): tmp_phrase_book = securetrading.phrase_book try: securetrading.phrase_book = {"testing": {"de_de": "testen", "fr_fr": "essai", }, } tests = [({"locale": "en_gb"}, {"testing": "testing", "HERE": "HERE"}), ({"locale": "fr_fr"}, {"testing": "essai", "HERE": "HERE"}), ({"locale": "de_de"}, {"testing": "testen", "HERE": "HERE"}), ] for configData, expected in tests: config = securetrading.Config() for key in configData: setattr(config, key, configData[key]) phrasebook = securetrading.PhraseBook(config) for message in expected: self.assertEquals(expected[message], phrasebook.lookup(message), ) finally: securetrading.phrase_book = tmp_phrase_book
def test_locale(self): config = securetrading.Config() self.assertEqual("en_gb", config.locale) tests = [ ("fr_fr", None, ""), ("de_de", None, ""), ("TESTING", Exception, "Please specifiy a valid locale according\ to, the locale module"), ] for locale, exp_exception, exp_message in tests: if exp_exception is None: config.locale = locale self.assertEqual(locale, config.locale) else: six.assertRaisesRegex(self, exp_exception, exp_message, setattr, config, "locale", locale)
def test__get_client(self): original_requests = securetrading.httpclient.requests config = securetrading.Config() request_reference = self.uni httpclient = securetrading.httpclient try: securetrading.httpclient.requests = True client = httpclient._get_client(request_reference, config) self.assertTrue(isinstance(client, httpclient.HTTPRequestsClient)) securetrading.httpclient.requests = False self.assertRaises(securetrading.SecureTradingError, httpclient._get_client, request_reference, config) finally: securetrading.httpclient.requests = original_requests
def test__get_connection_time_out(self): tests = [(time.time(), 10, 5, False, "5"), # The regular expressions due to changes in box times (time.time(), 4, 5, False, "[34].\\d+"), (time.time()-2, 4, 5, False, "[12].\\d+"), (time.time()-2, 4, 3, False, "[12].\\d+"), ] config = securetrading.Config() for start_time, max_connection_time, connect_time_out, \ expected_timed_out, expected_connection_time in tests: config.http_max_allowed_connection_time = max_connection_time config.http_connect_timeout = connect_time_out client = self.client(config) (timed_out, connection_time) = client._get_connection_time_out( start_time) self.assertEqual(timed_out, expected_timed_out) six.assertRegex(self, "{0}".format(connection_time), expected_connection_time)
def get_converter(self, config_data=None): if config_data is None: config_data = { "username": "******", "password": "******", "jsonversion": "1.00", "http_response_headers": ["content-type", "header", "bad_requesttype"], } config = securetrading.Config() config.username = config_data["username"] config.password = config_data["password"] config.jsonversion = config_data["jsonversion"] config.http_response_headers = config_data["http_response_headers"] converter = securetrading.Converter(config) return converter
def test_http_max_retries(self): config = securetrading.Config() self.assertEqual(6, config.http_max_retries) exp_message = "An int is required for maximum number of retries" tests = [ ("10", AssertionError), ([10], AssertionError), ({ "max": 10.10 }, AssertionError), (10, None), (234.56, AssertionError), ] for max_value, exp_exception in tests: if exp_exception is None: config.http_max_retries = max_value self.assertEqual(max_value, config.http_max_retries) else: self.assertRaisesRegexp(exp_exception, exp_message, setattr, config, "http_max_retries", max_value)
def test_datacenterpath(self): config = securetrading.Config() self.assertEqual("/json/", config.datacenterpath) tests = [ ("2.45", "2.45"), (8.65, 8.65), ("/some/path/", "/some/path/"), (3, 3), ([3, "3", 2.5], [3, "3", 2.5]), ({ "value": 2 }, { "value": 2 }), (None, None), ("", ""), ] for set_value, exp_value in tests: config.datacenterpath = set_value self.assertEqual(exp_value, config.datacenterpath)
def test_password(self): config = securetrading.Config() self.assertEqual("", config.password) tests = [ ("2.45", "2.45"), (8.65, 8.65), ("one", "one"), (3, 3), ([3, "3", 2.5], [3, "3", 2.5]), ({ "value": 2 }, { "value": 2 }), (None, None), ("", ""), ] for set_value, exp_value in tests: config.password = set_value self.assertEqual(exp_value, config.password)
def test_http_retry_sleep(self): config = securetrading.Config() self.assertEqual(0.5, config.http_retry_sleep) exp_message = "An int or float is required for the sleep period" tests = [ ("10", AssertionError), ([10], AssertionError), ({ "max": 10.10 }, AssertionError), (10, None), (234.56, None), ] for sleep_value, exp_exception in tests: if exp_exception is None: config.http_retry_sleep = sleep_value self.assertEqual(sleep_value, config.http_retry_sleep) else: six.assertRaisesRegex(self, exp_exception, exp_message, setattr, config, "http_retry_sleep", sleep_value)
def test_http_receive_timeout(self): config = securetrading.Config() self.assertEqual(60, config.http_receive_timeout) exp_message = "An int or float is required for the timeout" tests = [ ("10", AssertionError), ([10], AssertionError), ({ "max": 10.10 }, AssertionError), (10, None), (234.56, None), ] for timeout_value, exp_exception in tests: if exp_exception is None: config.http_receive_timeout = timeout_value self.assertEqual(timeout_value, config.http_receive_timeout) else: six.assertRaisesRegex(self, exp_exception, exp_message, setattr, config, "http_receive_timeout", timeout_value)
def test_ssl_certificate_file(self): config = securetrading.Config() self.assertEqual(None, config.ssl_certificate_file) tests = [ ("2.45", "2.45"), (8.65, 8.65), ("one", "one"), (3, 3), ([3, "3", 2.5], [3, "3", 2.5]), ({ "value": 2 }, { "value": 2 }), (None, None), ("", ""), ("/usr/local/certFile", "/usr/local/certFile"), ] for set_value, exp_value in tests: config.ssl_certificate_file = set_value self.assertEqual(exp_value, config.ssl_certificate_file)
def test_datacenterurl(self): config = securetrading.Config() self.assertEqual("https://webservices.securetrading.net", config.datacenterurl) tests = [ ("2.45", "2.45"), (8.65, 8.65), ("http://some.address.com", "http://some.address.com"), (3, 3), ([3, "3", 2.5], [3, "3", 2.5]), ({ "value": 2 }, { "value": 2 }), (None, None), ("", ""), ] for set_value, exp_value in tests: config.datacenterurl = set_value self.assertEqual(exp_value, config.datacenterurl)
def test_http_max_allowed_connection_time(self): config = securetrading.Config() self.assertEqual(10, config.http_max_allowed_connection_time) exp_message = "An int or float is required for the timeout" tests = [ ("30", AssertionError), ([30], AssertionError), ({ "max": 30.10 }, AssertionError), (30, None), (134.56, None), ] for max_value, exp_exception in tests: if exp_exception is None: config.http_max_allowed_connection_time = max_value self.assertEqual(max_value, config.http_max_allowed_connection_time) else: six.assertRaisesRegex(self, exp_exception, exp_message, setattr, config, "http_max_allowed_connection_time", max_value)
def get_config(self, data={}): config = securetrading.Config() for key in data: setattr(config, key, data[key]) return config
#!/usr/bin/env python import logging import pprint import securetrading logging.basicConfig(filename='example.log', level=logging.INFO) # Configure global settings st_config = securetrading.Config() st_config.username = "******" st_config.password = "******" # create the Api object with the config st_api = securetrading.Api(st_config) # Create the request dictionary. AUTH_example = { "pan": "4111111111111111", "expirydate": "11/2031", "securitycode": "123", "requesttypedescription": "AUTH", "accounttypedescription": "ECOM", "sitereference": "YOURSITEREF", "paymenttypedescription": "VISA", "currencyiso3a": "GBP", "baseamount": "100", "billingfirstname": "first", } # Process the request or more requests st_response = st_api.process(AUTH_example)
def test__main(self): c2_exp_eng = "7 Connect Error" tests = [(None, None, (200, "Success"), {"example": "headers"}, None, None, None, None, None, None, None, "Success", {"example": "headers"}), (Exception("Connect Error"), None, None, None, None, None, None, ConnectionError, ["Connect Error"], c2_exp_eng, "7", None, {}), (None, Exception("Send Error"), None, None, None, None, None, SendReceiveError, ["Send Error"], "4 Send Error", "4", None, {}), (None, None, None, None, Exception("Receive Error"), None, None, SendReceiveError, ["Receive Error"], "4 Receive Error", "4", None, {} ), (None, None, (200, "Verification Error"), {"error": "headers"}, None, Exception("Verify Error"), None, Exception, None, "Verify Error", None, None, {} ), (None, None, (200, "Closing Error"), {"error": "headers"}, None, None, Exception("Close Error"), Exception, None, "Close Error", None, None, {} ), (Exception("Connect Error"), None, None, None, None, None, Exception("Close"), ConnectionError, ["Connect Error"], "7 Connect Error", "7", None, {} # Connect Error takes precedence ), (None, Exception("Send Error"), None, None, None, None, Exception("Close"), Exception, None, "Close", None, None, {}), # The close Exception takes precedence (None, None, None, None, Exception("Receive Error"), None, Exception("Close"), Exception, None, "Close", None, None, {}), # The close Exception takes precedence (None, None, None, None, None, Exception("Verify Error"), Exception("Close"), Exception, None, "Close", None, None, {}), # The close Exception takes precedence ] config = securetrading.Config() for connect_raises, send_raises, receive_response, header_response,\ receive_raises, verify_raises, close_raises, exp_exception,\ exp_data, exp_english, exp_code, exp_response, exp_headers\ in tests: mock_client = self.client(config) mock_client._connect = self.mock_method(exception=connect_raises) mock_client._send = self.mock_method(exception=send_raises) mock_client._receive = self.mock_method(result=receive_response, exception=receive_raises) mock_client._get_response_headers =\ self.mock_method(result=header_response) mock_client._verify_response =\ self.mock_method(exception=verify_raises) mock_client._close = self.mock_method(exception=close_raises) # As we have mocked all of the methods, the args have no value main_args = ("https://www.securetrading.com", {"request": "data"}, "request_reference", "version_info") if exp_exception: self.check_st_exception(exp_exception, exp_data, exp_english, exp_code, mock_client._main, func_args=main_args) else: actual_response, actual_headers = mock_client._main(*main_args) self.assertEqual(actual_response, exp_response) self.assertEqual(actual_headers, exp_headers)
def __init__(self, *args, **kwargs): super(Module_Test_Api, self).__init__(*args, **kwargs) self.sitereference = passed_args.sitereference # Please contact Secure Trading support to set up a test site # The following options are required. # A currency rate account for USD Visa # test account with the following: # GBP ECOM VISA # GBP MOTO VISA # dcc USD ECOM VISA # GBP ECOM PAYPAL # EUR ECOM SOFORT # USD ECOM ACH # Fraud Control # Identity Check # GBP CFT VISA # GBP RECUR VISA # The site also needs a webservices user set up via MySt. username = passed_args.username password = passed_args.password datacenterurl = passed_args.datacenterurl ssl_cert_file = passed_args.overridecacerts base_path = self.get_package_path() # st_api valid credentials st_config = securetrading.Config() st_config.username = username st_config.password = password st_config.ssl_certificate_file = ssl_cert_file st_config.datacenterurl = datacenterurl # st_api2 is intentionally using bad credentials. st_config2 = securetrading.Config() st_config2.username = "******" st_config2.password = "******" st_config2.ssl_certificate_file = ssl_cert_file st_config2.datacenterurl = datacenterurl # st_api3 is intentionally using a corrupt cacerts file. st_config3 = securetrading.Config() st_config3.username = username st_config3.password = password st_config3.ssl_certificate_file = os.path.join(base_path, "test/badcacert.pem") st_config3.datacenterurl = datacenterurl # st_api4 is intentionally using a cacerts file that is not our ca. st_config4 = securetrading.Config() st_config4.username = username st_config4.password = password st_config4.ssl_certificate_file = os.path.join(base_path, "test/testcacert.pem") st_config4.datacenterurl = datacenterurl # st_api valid credentials fr setup st_config_fr = securetrading.Config() st_config_fr.username = username st_config_fr.password = password st_config_fr.ssl_certificate_file = ssl_cert_file st_config_fr.locale = "fr_fr" st_config_fr.datacenterurl = datacenterurl # st_api valid credentials de setup st_config_de = securetrading.Config() st_config_de.username = username st_config_de.password = password st_config_de.ssl_certificate_file = ssl_cert_file st_config_de.locale = "de_de" st_config_de.datacenterurl = datacenterurl # st_api valid credentials with Content-type response header st_config_content_type = securetrading.Config() st_config_content_type.username = username st_config_content_type.password = password st_config_content_type.ssl_certificate_file = ssl_cert_file st_config_content_type.http_response_headers = ["content-type"] st_config_content_type.datacenterurl = datacenterurl # initialise all the st_api objects with their respective config self.st_api = securetrading.Api(st_config) self.st_api2 = securetrading.Api(st_config2) self.st_api3 = securetrading.Api(st_config3) self.st_api4 = securetrading.Api(st_config4) self.st_api_fr = securetrading.Api(st_config_fr) self.st_api_de = securetrading.Api(st_config_de) self.st_api_content_type = securetrading.Api(st_config_content_type) if self.PARENT_RESPONSES is None: # Singleton so that it doenst get set always Module_Test_Api.PARENT_RESPONSES = self.set_up_parents() # Sleeping to allow parent transactions to be fully processed transfersleeptime = passed_args.transfersleeptime print( "Sleeping for {0:d} seconds to allow parent transactions to be\ fully processed".format(transfersleeptime)) time.sleep(transfersleeptime)
def setUp(self): config = securetrading.Config() self.http_client = self.client(config)
def test__send(self): c1_exp_data = ["request_reference Maximum time reached whilst \ trying to connect to https://www.securetrading.com"] c1_exp_msg = "7 request_reference Maximum time reached whilst \ trying to connect to https://www.securetrading.com" c2_exp_data = c1_exp_data c2_exp_msg = c1_exp_msg c3_exp_data = c1_exp_data c3_exp_msg = c1_exp_msg c7_exp_data = ["request_reference Maximum number of attempts reached \ whilst trying to connect to https://www.securetrading.com"] c7_exp_msg = "7 request_reference Maximum number of attempts reached \ whilst trying to connect to https://www.securetrading.com" c8_exp_data = ["request_reference Maximum number of attempts reached \ whilst trying to connect to https://www.securetrading.com"] c8_exp_msg = c7_exp_msg c9_exp_data = ["request_reference Maximum number of attempts reached \ whilst trying to connect to https://www.securetrading.com"] c9_exp_msg = c7_exp_msg c14_exp_msg = "8 Some other error" c15_exp_msg = "8 Some other error" c16_exp_msg = c1_exp_msg c17_exp_msg = c7_exp_msg tests = [(-1, 50, [None], ConnectionError, c1_exp_data, c1_exp_msg, "7", None), (0, 50, [ConnectTimeout], ConnectionError, c2_exp_data, c2_exp_msg, "7", None), (1, 50, [ConnectTimeout] * 100, ConnectionError, c3_exp_data, c3_exp_msg, "7", None), (50, 50, ["Successful response"], None, None, None, None, "Successful response"), (50, 50, [ConnectTimeout, "Successful response"], None, None, None, None, "Successful response"), (50, 50, [ConnectTimeout, ConnectTimeout, "Successful response"], None, None, None, None, "Successful response"), (50, -1, [None], ConnectionError, c7_exp_data, c7_exp_msg, "7", None), (50, 0, [ConnectTimeout], ConnectionError, c8_exp_data, c8_exp_msg, "7", None), (50, 1, [ConnectTimeout] * 2, ConnectionError, c9_exp_data, c9_exp_msg, "7", None), (50, 0, ["Successful response"], None, None, None, None, "Successful response"), (50, 1, ["Successful response"], None, None, None, None, "Successful response"), (50, 2, [ConnectTimeout, "Successful response"], None, None, None, None, "Successful response"), (50, 50, [ConnectTimeout, RequestsConnectionError, "Successful response"], None, None, None, None, "Successful response"), (50, 50, [Exception("Some other error")], ConnectionError, ["Some other error"], c14_exp_msg, "8", None), (50, 50, [ConnectTimeout, RequestsConnectionError, Exception("Some other error")], ConnectionError, ["Some other error"], c15_exp_msg, "8", None), (50, 50, [RequestException], ConnectionError, [""], "7", "7", None), (50, 50, [ConnectTimeout, RequestsConnectionError, RequestException], ConnectionError, [""], "7", "7", None), ] original_request = requests.request try: for max_timeout, max_retry, request_responses, \ exp_exception, exp_data, exp_english, exp_code, \ exp_response in tests: config = securetrading.Config() config.http_max_allowed_connection_time = max_timeout config.http_max_retries = max_retry mock_client = securetrading.httpclient.\ HTTPRequestsClient(config) requests.request = self.mock_method( multiple_calls=request_responses) # As we have mocked the requests.request, # the args have no value send_args = ("https://www.securetrading.com", {"requestreference": "data"}, "request_reference", ) if exp_exception: self.check_st_exception(exp_exception, exp_data, exp_english, exp_code, mock_client._send, func_args=send_args) else: mock_client._send(*send_args) self.assertEqual(mock_client.response, exp_response) finally: requests.request = original_request