def create_client( httphost, connect_timeout=0.500, socket_timeout=0.500, max_connections=EndpointConfiguration.DEFAULT_MAX_CONNECTIONS): connection = DefaultConnection(connect_timeout, socket_timeout, max_connections) authenticator = DefaultAuthenticator(AuthorizationType.V1HMAC, "apiKey", "secret") meta_data_provider = MetaDataProvider("Ingenico") session = Session(httphost, connection, authenticator, meta_data_provider) communicator = Factory.create_communicator_from_session(session) return Factory.create_client_from_communicator(communicator)
def test_close_idle_connection_not_pooled(self): """Tests that the setting to close an idle connection in a client propagates to the connection for an unpooled connection """ mock = MagicMock(spec=Connection(), autospec=True) function_mock = Mock(name="close_idle_connections_mock") mock.attach_mock(function_mock, "close_idle_connections") session = Factory.create_session_from_file( configuration_file_name=PROPERTIES_URI, connection=mock, api_key_id=API_KEY_ID, secret_api_key=SECRET_API_KEY) client = Factory.create_client_from_session(session) client.close_idle_connections(timedelta(seconds=5)) # seconds function_mock.assert_not_called()
def test_close_expired_connections_pooled(self): """Tests that the setting to close an expired connection in a client propagates to the connection for a pooled connection """ pooled_mock = MagicMock(spec=PooledConnection(), autospec=True) function_mock = Mock(name="close_expired_connections_mock") pooled_mock.attach_mock(function_mock, "close_expired_connections") session = Factory.create_session_from_file( configuration_file_name=PROPERTIES_URI, connection=pooled_mock, api_key_id=API_KEY_ID, secret_api_key=SECRET_API_KEY) client = Factory.create_client_from_session(session) client.close_expired_connections() function_mock.assert_called_once()
def __get_client(self): api_key_id = os.getenv("connect.api.apiKeyId", "someKey") secret_api_key = os.getenv("connect.api.secretApiKey", "someSecret") configuration_file_name = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../example_configuration.ini')) return Factory.create_client_from_file(configuration_file_name=configuration_file_name, api_key_id=api_key_id, secret_api_key=secret_api_key)
def run_connection_pooling_test(self, request_count, max_connections): """Sends *request_count* requests with a maximum number of connection pools equal to *max_connections*""" communicator_configuration = init_utils.create_communicator_configuration( max_connections=max_connections) with Factory.create_communicator_from_configuration( communicator_configuration) as communicator: # Create a number of runner threads that will execute send_request runner_threads = [ threading.Thread(target=self.send_request, args=(i, communicator)) for i in range(0, request_count) ] for thread in runner_threads: thread.start() self.flag.set() # wait until threads are done before closing the communicator for i in range(0, request_count - 1): runner_threads[i].join() print("(*start time*, *end time*) for {} connection pools".format( max_connections)) for item in self.result_list: if isinstance(item, Exception): self.fail("an exception occurred in one of the threads:/n" + str(item)) else: print(repr(item))
def test_create_rejected(self): """Tests that a 400 failure response with a payment result will throw a DeclinedPaymentException""" client = Factory.create_client_from_session(self.session) response_body = read_resource("rejected.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start:start + 1024].encode('utf-8') return 400, None, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(DeclinedPaymentException) as exception: client.merchant("merchantId").payments().create(request_body) self.assertIn("payment '000002000020142544360000100001'", str(exception.exception.message)) self.assertIn("status 'REJECTED'", str(exception.exception)) self.assertIn(response_body, str(exception.exception)) self.assertIsNotNone(exception.exception.create_payment_result) self.assertEqual("000002000020142544360000100001", exception.exception.create_payment_result.payment.id) self.assertEqual( "REJECTED", exception.exception.create_payment_result.payment.status)
def test_create_communicator(self): """Tests that the factory is correctly able to create a communicator""" communicator = Factory.create_communicator_from_file( PROPERTIES_URI, API_KEY_ID, SECRET_API_KEY) self.assertIs(communicator.marshaller, DefaultMarshaller.INSTANCE()) session = communicator._Communicator__session connection = session.connection self.assertIsInstance(connection, DefaultConnection) DefaultConnectionTest.assertConnection(self, connection, None, None, 100, None) authenticator = session.authenticator self.assertIsInstance(authenticator, DefaultAuthenticator) with warnings.catch_warnings(): warnings.simplefilter("ignore") self.assertEqual( AuthorizationType.V1HMAC, authenticator._DefaultAuthenticator__authorization_type) self.assertEqual(API_KEY_ID, authenticator._DefaultAuthenticator__api_id_key) self.assertEqual( SECRET_API_KEY, authenticator._DefaultAuthenticator__secret_api_key) meta_data_provider = session.meta_data_provider self.assertIsInstance(meta_data_provider, MetaDataProvider) request_headers = meta_data_provider.meta_data_headers self.assertEqual(1, len(request_headers)) self.assertEqual("X-GCS-ServerMetaInfo", request_headers[0].name)
def test_multiline_header(self): """Test if the products service can function with a multiline header""" multi_line_header = " some value \r\n \n with a liberal amount of \r\n spaces " configuration = init_utils.create_communicator_configuration() meta_data_provider = MetaDataProvider( integrator="Ingenico", additional_request_headers=(RequestHeader("X-GCS-MultiLineHeader", multi_line_header), )) params = DirectoryParams() params.country_code = "NL" params.currency_code = "EUR" session = Factory.create_session_from_configuration( configuration, meta_data_provider=meta_data_provider) with Factory.create_client_from_session(session) as client: response = client.merchant(MERCHANT_ID).products().directory( 809, params) self.assertGreater(len(response.entries), 0)
def test_create_configuration(self): """Tests that the factory is correctly able to create a communicator configuration""" configuration = Factory.create_configuration(PROPERTIES_URI, API_KEY_ID, SECRET_API_KEY) self.assertEqual(urlparse("https://eu.sandbox.api-ingenico.com"), configuration.api_endpoint) self.assertEqual(AuthorizationType.get_authorization("v1HMAC"), configuration.authorization_type) self.assertEqual(-1, configuration.connect_timeout) self.assertEqual(-1, configuration.socket_timeout) self.assertEqual(100, configuration.max_connections) self.assertEqual(API_KEY_ID, configuration.api_key_id) self.assertEqual(SECRET_API_KEY, configuration.secret_api_key) self.assertIsNone(configuration.proxy_configuration)
def test_create_invalid_authorization(self): """Tests that a 401 failure response without a payment result will throw an ApiException""" client = Factory.create_client_from_session(self.session) response_body = read_resource("invalid_authorization.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 401, None, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(ApiException) as exception: client.merchant("merchantId").payments().create(request_body) self.assertIn(response_body, str(exception.exception))
def test_create_success(self): """Tests that a payment can be created and communicated appropriately when responded to with a 201 message""" client = Factory.create_client_from_session(self.session) response_body = read_resource("pending_approval.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_body(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 201, None, generate_body() self.mock_connection.post.side_effect = receive_post response = client.merchant("merchantId").payments().create(request_body) self.assertEqual("000002000020142549460000100001", response.payment.id) self.assertEqual("PENDING_APPROVAL", response.payment.status)
def test_connect_nonexistent_proxy(self): """Try connecting to a nonexistent proxy and assert it fails to connect to it""" configparser = ConfigParser.ConfigParser() configparser.read(init_utils.PROPERTIES_URL_PROXY) communicator_config = CommunicatorConfiguration( configparser, connect_timeout=1, socket_timeout=1, api_key_id=init_utils.API_KEY_ID, secret_api_key=init_utils.SECRET_API_KEY, proxy_configuration=ProxyConfiguration(host="localhost", port=65535, username="******", password="******")) with Factory.create_client_from_configuration( communicator_config) as client: with self.assertRaises(CommunicationException): client.merchant(MERCHANT_ID).services().testconnection()
def test_multipart_form_data_upload_put_multipart_form_data_object_with_response( self): """Test a multipart/form-data PUT upload with a response""" configuration = init_utils.create_communicator_configuration() configuration.api_endpoint = 'http://httpbin.org' multipart = MultipartFormDataObject() multipart.add_file( 'file', UploadableFile('file.txt', 'file-content', 'text/plain')) multipart.add_value('value', 'Hello World') with Factory.create_communicator_from_configuration( configuration) as communicator: response = communicator.put('/put', None, None, multipart, HttpBinResponse, None) self.assertEqual(response.form['value'], 'Hello World') self.assertEqual(response.files['file'], 'file-content')
def test_with_client_meta_info(self): """Tests if the function withClientMetaInfo alters a client when it needs to and does nothing if not required""" client1 = Factory.create_client_from_file(PROPERTIES_URI, API_KEY_ID, SECRET_API_KEY) # client2 = client1.with_client_meta_info(None) client2 = client1.with_client_meta_info(None) client_meta_info = DefaultMarshaller.INSTANCE().marshal({"test": "test"}) client3 = client1.with_client_meta_info(client_meta_info) client4 = client3.with_client_meta_info(client_meta_info) client5 = client3.with_client_meta_info(None) self.assertIsNone(client1._client_headers) self.assertIs(client1, client2) self.assertIsNot(client1, client3) self.assertClientHeaders(client3, client_meta_info) self.assertIs(client3, client4) self.assertIsNot(client3, client5) self.assertIsNone(client5._client_headers)
def test_create_reference_error(self): """Tests that a 409 failure response with a duplicate request code but without an idempotence key will throw a ReferenceException """ client = Factory.create_client_from_session(self.session) response_body = read_resource("duplicate_request.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 409, None, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(ReferenceException) as exception: client.merchant("merchantId").payments().create(request_body) self.assertIn(response_body, str(exception.exception))
def send_request(self, i, communicator): """runs a (concurrent) request""" request = ConvertAmountParams() request.source = "USD" request.target = "EUR" request.amount = (100 * (i + 1)) try: client = Factory.create_client_from_communicator(communicator) self.flag.wait() start_time = timeit.default_timer() dummy = client.merchant(MERCHANT_ID).services().convert_amount( request).converted_amount end_time = timeit.default_timer() with self.lock: self.result_list.append((start_time, end_time)) except Exception as e: with self.lock: self.result_list.append(e)
def test_create_method_not_allowed(self): """Tests that a 405 response with a non-JSON response will throw a CommunicationException """ client = Factory.create_client_from_session(self.session) response_body = read_resource("method_not_allowed.html") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 405, {"content-type": "text/html"}, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(CommunicationException) as exception: client.merchant("merchantId").payments().create(request_body) self.assertIsNotNone(exception.exception.cause) self.assertIsInstance(exception.exception.cause, ResponseException) self.assertIn(response_body, str(exception.exception.cause))
def test_multipart_form_data_upload_post_multipart_form_data_object_with_binary_response( self): """Test a multipart/form-data POST upload with a binary response""" configuration = init_utils.create_communicator_configuration() configuration.api_endpoint = 'http://httpbin.org' multipart = MultipartFormDataObject() multipart.add_file( 'file', UploadableFile('file.txt', 'file-content', 'text/plain')) multipart.add_value('value', 'Hello World') with Factory.create_communicator_from_configuration( configuration) as communicator: response = communicator.post_with_binary_response( '/post', None, None, multipart, None) data = '' for chunk in response[1]: data += chunk.decode('utf-8') response = json.loads(data) self.assertEqual(response['form']['value'], 'Hello World') self.assertEqual(response['files']['file'], 'file-content')
def create_client_with_proxy(max_connections=False): configuration = create_communicator_configuration( PROPERTIES_URL_PROXY, max_connections=max_connections) return Factory.create_client_from_configuration( configuration).with_client_meta_info('{"test":"test"}')
def create_client(max_connections=False): configuration = create_communicator_configuration( max_connections=max_connections) return Factory.create_client_from_configuration( configuration).with_client_meta_info('{"test":"test"}')