def test_logging_convert_amount(self):
        """Test that a GET service with parameters can connect to a server and is logged appropriately"""
        test_path = "/v1/1234/services/convert/amount"  # relative url through which the request should be sent
        logger = TestLogger()

        query_params = ConvertAmountParams()
        query_params.amount = 1000
        query_params.source = "EUR"
        query_params.target = "USD"

        response_body = read_resource("convertAmount.json")
        handler = self.create_handler(
            body=response_body,
            additional_headers=(('Content-type', 'application/json'), ))
        with create_server_listening(
                handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                response = client.merchant("1234").services().convert_amount(
                    query_params)

        self.assertIsNotNone(response)
        self.assertIsNotNone(response.converted_amount)
        self.assertEqual(
            test_path,
            self.request_path.split("?")[0],
            'Request has arrived at {} instead of {}'.format(
                self.request_path.split("?")[0], test_path))
        self.assertLogsRequestAndResponse(logger, "convertAmount")
    def test_create_payment_rejected(self):
        """Test that a POST service that is rejected results in an error, which is logged appropriately"""
        test_path = "/v1/1234/payments"  # relative url through which the request should be sent
        logger = TestLogger()

        request = create_payment_request()

        response_body = read_resource("createPayment.failure.rejected.json")
        handler = self.create_handler(
            response_code=402,
            body=response_body,
            additional_headers=(('Content-type', 'application/json'), ))
        with create_server_listening(
                handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                with self.assertRaises(DeclinedPaymentException) as exc:
                    client.merchant("1234").payments().create(request)

        self.assertIsNotNone(exc.exception.create_payment_result)
        self.assertIsNotNone(exc.exception.create_payment_result.payment)
        self.assertIsNotNone(exc.exception.create_payment_result.payment.id)
        self.assertEqual(test_path, self.request_path,
                         'Request has arrived at the wrong path')
        self.assertLogsRequestAndResponse(logger,
                                          "createPayment_failure_rejected")
    def test_logging_test_connection(self):
        """Test that a GET service without parameters can connect to a server and is logged appropriately"""
        test_path = "/v1/1234/services/testconnection"  # relative url through which the request should be sent
        logger = TestLogger()

        response_body = read_resource("testConnection.json")
        handler = self.create_handler(
            body=response_body,
            additional_headers=(('Content-type', 'application/json'), ))
        with create_server_listening(
                handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                response = client.merchant("1234").services().testconnection()

        self.assertIsNotNone(response)
        self.assertEqual(test_path, self.request_path,
                         'Request has arrived at the wrong path')
        self.assertEqual('OK', response.result)
        self.assertEqual(2, len(logger.entries))
        # for request and response, check that the message exists in the logs and there are no errors
        request_entry = logger.entries[0]
        self.assertIsNotNone(request_entry[0])
        self.assertIsNone(request_entry[1])
        response_entry = logger.entries[1]
        self.assertIsNotNone(response_entry[0])
        self.assertIsNone(response_entry[1])
        # for request and response, check that their output is as predicted and that they match each other
        self.assertRequestAndResponse(request_entry[0], response_entry[0],
                                      "testConnection")
    def test_create_payment(self):
        """Test that a POST service with 201 response can connect to a server and is logged appropriately"""
        test_path = "/v1/1234/payments"  # relative url through which the request should be sent
        logger = TestLogger()

        request = create_payment_request()

        response_body = read_resource("createPayment.json")
        additional_headers = (("content-Type", "application/json"), (
            "Location",
            "http://localhost/v1/1234/payments/000000123410000595980000100001")
                              )
        handler = self.create_handler(response_code=201,
                                      body=response_body,
                                      additional_headers=additional_headers)
        with create_server_listening(
                handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                response = client.merchant("1234").payments().create(request)

        self.assertIsNotNone(response)
        self.assertIsNotNone(response.payment)
        self.assertIsNotNone(response.payment.id)
        self.assertEqual(
            test_path, self.request_path,
            'Request has arrived at "{1}" while it should have been delivered to "{0}"'
            .format(test_path, self.request_path))
        self.assertLogsRequestAndResponse(logger, "createPayment")
    def test_create_payment_invalid_card_number(self):
        """Test that a POST service that is invalid results in an error, which is logged appropriately"""
        test_path = "/v1/1234/payments"  # relative url through which the request should be sent
        logger = TestLogger()

        request = create_payment_request()

        response_body = read_resource(
            "createPayment.failure.invalidCardNumber.json")
        handler = self.create_handler(
            response_code=400,
            body=response_body,
            additional_headers=(('Content-type', 'application/json'), ))
        with create_server_listening(
                handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                self.assertRaises(ValidationException,
                                  client.merchant("1234").payments().create,
                                  request)

        self.assertEqual(test_path, self.request_path,
                         'Request has arrived at the wrong path')
        self.assertLogsRequestAndResponse(
            logger, "createPayment_failure_invalidCardNumber")
Example #6
0
    def test_logging_error_only(self):
        """Test that an error can be logged separately by enabling log between request and response"""
        test_path = "/v2/1/services/testconnection"  # relative url through which the request should be sent
        logger = TestLogger()

        response_body = read_resource("notFound.html")
        handler = self.create_handler(response_code=404, body=response_body,
                                      additional_headers=(("Content-Type", "text/html"),))

        def enable_logging_late_response(*args, **kwargs):  # handler that enables the log of the client
            self.client.enable_logging(logger)  # and waits for a timeout before responding
            time.sleep(0.1)
            handler(*args, **kwargs)

        with create_server_listening(enable_logging_late_response) as address:  # start server to listen to request
            with create_client(address, connect_timeout=0.500, socket_timeout=0.050) as client:
                self.client = client
                with self.assertRaises(CommunicationException):
                    client.merchant("1").services().test_connection()

        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertEqual(1, len(logger.entries))
        # check that the response message exists in the logs and there are no errors
        error_entry = logger.entries[0]
        self.assertIsNotNone(error_entry[0])
        self.assertIsNotNone(error_entry[1])
        # check that the error is formatted correctly
        self.assertError(error_entry[0])
        self.assertIsInstance(error_entry[1], Timeout,
                              "logger should have logged a timeout error, logged {} instead".format(error_entry[1]))
Example #7
0
    def test_idempotence_second_request(self):
        """
        Test that the client can successfully handle a response
         indicating a request has been sent prior
        """
        response_body = read_resource("idempotence_success.json")
        idempotence_key = str(uuid.uuid4())
        idempotence_timestamp = str(int(time.time() * 1000))
        call_context = CallContext(idempotence_key)
        request = create_payment_request()
        test_path = "/v2/1/payments"  # relative url through which the request should be sent
        additional_headers \
            = (("Content-Type", "application/json"),
               ("Location", "http://localhost/v2/1/payments/1_1"),
               ("X-GCS-Idempotence-Request-Timestamp", idempotence_timestamp))
        handler = self.create_handler(response_code=201,
                                      body=response_body,
                                      additional_headers=additional_headers)
        with create_server_listening(handler) as address:
            with create_client(address) as client:
                response = client.merchant("1").payments().create_payment(request, call_context)

        self.assertIsNotNone(response)
        self.assertIsNotNone(response.payment)
        self.assertIsNotNone(response.payment.id)
        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertEqual(idempotence_key, self.idempotence_header, "Wrong idempotence key is sent in the request")
        self.assertEqual(idempotence_key, call_context.idempotence_key)
        self.assertEqual(int(idempotence_timestamp), int(call_context.idempotence_request_timestamp))
Example #8
0
    def test_logging_response_only(self):
        """Test that a response can be logged separately by enabling log between request and response"""
        test_path = "/v2/1/services/testconnection"  # relative url through which the request should be sent
        logger = TestLogger()

        response_body = read_resource("testConnection.json")
        handler = self.create_handler(response_code=200, body=response_body,
                                      additional_headers=(("Content-Type", "application/json"),))

        def enable_logging_response(*args, **kwargs):  # handler that enables the log of the client
            self.client.enable_logging(logger)  # before responding
            handler(*args, **kwargs)

        with create_server_listening(enable_logging_response) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                self.client = client
                response = client.merchant("1").services().test_connection()

        self.assertEqual("OK", response.result)
        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertEqual(1, len(logger.entries))
        # check that the response message exists in the logs and there are no errors
        response_entry = logger.entries[0]
        self.assertIsNotNone(response_entry[0])
        self.assertIsNone(response_entry[1],
                          "Error '{}' logged that should not have been thrown".format(response_entry[1]))
        # check that the response is formatted correctly
        self.assertResponse(response_entry[0], "testConnection")
Example #9
0
    def test_logging_read_timeout(self):
        """Test that if an exception is thrown before log due to a timeout, it is logged"""
        test_path = "/v2/1/services/testconnection"  # relative url through which the request should be sent
        logger = TestLogger()

        response_body = read_resource("notFound.html")
        handler = self.create_handler(response_code=404, body=response_body,
                                      additional_headers=(("Content-Type", "text/html"),))

        def delayed_response(*args, **kwargs):
            time.sleep(0.100)
            handler(*args, **kwargs)

        with create_server_listening(delayed_response) as address:  # start server to listen to request
            with create_client(address, socket_timeout=0.05) as client:  # create client under test
                client.enable_logging(logger)
                with self.assertRaises(CommunicationException):
                    client.merchant("1").services().test_connection()

        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertEqual(2, len(logger.entries))
        # for request and response, check that the message exists in the logs and there is an error in the response
        request_entry = logger.entries[0]
        self.assertIsNotNone(request_entry[0])
        self.assertIsNone(request_entry[1])
        response_entry = logger.entries[1]
        self.assertIsNotNone(response_entry[0])
        self.assertIsNotNone(response_entry[1])
        # for request and error, check that their output is as predicted and that they match each other
        self.assertRequestAndError(request_entry[0], response_entry[0], "testConnection")
        self.assertIsInstance(response_entry[1], Timeout, "logger should have logged a timeout error")
Example #10
0
 def test_idempotence_duplicate_request(self):
     """Test a request where a request arrived twice"""
     response_body = read_resource("idempotence_duplicate_failure.json")
     idempotence_key = str(uuid.uuid4())
     idempotence_timestamp = str(int(time.time() * 1000))
     call_context = CallContext(idempotence_key)
     request = create_payment_request()
     test_path = "/v2/1/payments"  # relative url through which the request should be sent
     additional_headers = (("Content-Type", "application/json"),
                           ("X-GCS-Idempotence-Request-Timestamp", idempotence_timestamp))
     handler = self.create_handler(response_code=409, body=response_body,
                                   additional_headers=additional_headers)
     with create_server_listening(handler) as address:
         with create_client(address) as client:
             with self.assertRaises(IdempotenceException) as exc:
                 client.merchant("1").payments().create_payment(request, call_context)
     self.assertEqual(409, exc.exception.status_code)
     self.assertEqual(response_body, exc.exception.response_body)
     self.assertEqual(idempotence_key, exc.exception.idempotence_key)
     self.assertEqual(idempotence_key, self.idempotence_header,
                      "Wrong idempotence key is sent in the request")
     self.assertEqual(idempotence_key, call_context.idempotence_key)
     self.assertEqual(test_path, self.request_path,
                      'Request has arrived at the wrong path')
     self.assertEqual(int(idempotence_timestamp),
                      int(call_context.idempotence_request_timestamp))
    def test_create_payment_unicode(self):
        """Tests if the body is encoded correctly"""
        test_path = "/v1/1234/payments"  # relative url through which the request should be sent
        logger = TestLogger()

        request = create_payment_request()

        response_body = read_resource("createPayment.unicode.json")

        additional_headers = (("Content-Type", "application/json"), (
            "Location",
            "http://localhost/v1/1234/payments/000000123410000595980000100001")
                              )
        handler = self.create_handler(response_code=201,
                                      body=response_body,
                                      additional_headers=additional_headers)
        with create_server_listening(
                handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                response = client.merchant("1234").payments().create(request)

        self.assertIsNotNone(response)
        self.assertIsNotNone(response.payment)
        self.assertIsNotNone(response.payment.id)
        surname = response.payment.payment_output.redirect_payment_method_specific_output.\
            payment_product840_specific_output.customer_account.surname
        self.assertEqual(surname, u"Schr\xf6der")
        self.assertEqual(
            test_path, self.request_path,
            'Request has arrived at "{1}" while it should have been delivered to "{0}"'
            .format(test_path, self.request_path))
        self.assertLogsRequestAndResponse(logger, "createPayment_unicode")
Example #12
0
    def test_logging_delete(self):
        """Test that a POST service without body and a void response can connect to a server and is logged appropriately
        """
        test_path = "/v2/1/tokens/5678"  # relative url through which the request should be sent
        logger = TestLogger()

        handler = self.create_handler(response_code=204)
        with create_server_listening(handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                client.merchant("1").tokens().delete_token("5678", None)

        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertLogsRequestAndResponse(logger, "deleteToken")
Example #13
0
    def test_logging_unknown_server_error(self):
        """Test that a GET service that results in an error is logged appropriately"""
        test_path = "/v2/1/services/testconnection"  # relative url through which the request should be sent
        logger = TestLogger()

        response_body = read_resource("unknownServerError.json")
        handler = self.create_handler(response_code=500, body=response_body,
                                      additional_headers=(('Content-type', 'application/json'),))
        with create_server_listening(handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                with self.assertRaises(PaymentPlatformException):
                    client.merchant("1").services().test_connection()

        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertLogsRequestAndResponse(logger, "testConnection", "unknownServerError")
Example #14
0
    def test_logging_non_json(self):
        """Test that a GET service that results in a not found error is logged appropriately"""
        test_path = "/v2/1/services/testconnection"  # relative url through which the request should be sent
        logger = TestLogger()

        response_body = read_resource("notFound.html")
        handler = self.create_handler(response_code=404, body=response_body,
                                      additional_headers=(("Content-Type", "text/html"),))
        with create_server_listening(handler) as address:  # start server to listen to request
            with create_client(address, connect_timeout=0.500, socket_timeout=0.050) as client:
                client.enable_logging(logger)
                with self.assertRaises(NotFoundException):
                    client.merchant("1").services().test_connection()

        self.assertEqual(test_path, self.request_path, 'Request has arrived at the wrong path')
        self.assertLogsRequestAndResponse(logger, "testConnection", "notFound")
Example #15
0
 def test_idempotence_first_failure(self):
     """Test a request where a request is rejected without prior requests"""
     response_body = read_resource("idempotence_rejected.json")
     idempotence_key = str(uuid.uuid4())
     call_context = CallContext(idempotence_key)
     request = create_payment_request()
     test_path = "/v2/1/payments"  # relative url through which the request should be sent
     handler = self.create_handler(response_code=402, body=response_body,
                                   additional_headers=(("Content-Type", "application/json"),))
     with create_server_listening(handler) as address:
         with create_client(address) as client:
             with self.assertRaises(DeclinedPaymentException) as exc:
                 client.merchant("1").payments().create_payment(request, call_context)
     self.assertEqual(402, exc.exception.status_code)
     self.assertEqual(response_body, exc.exception.response_body)
     self.assertEqual(test_path, self.request_path,
                      'Request has arrived at the wrong path')
     self.assertEqual(idempotence_key, self.idempotence_header,
                      "Wrong idempotence key is sent in the request")
     self.assertEqual(idempotence_key, call_context.idempotence_key)
     self.assertIsNone(call_context.idempotence_request_timestamp)
Example #16
0
    def test_logging_get(self):
        """Test that a GET service with parameters can connect to a server and is logged appropriately"""
        test_path = "/v2/1/products/1"  # relative url through which the request should be sent
        logger = TestLogger()

        query_params = GetPaymentProductParams()
        query_params.amount = 1000
        query_params.country_code = "BE"
        query_params.currency_code = "EUR"

        response_body = read_resource("getPaymentProduct.json")
        handler = self.create_handler(body=response_body,
                                      additional_headers=(('Content-type', 'application/json'),))
        with create_server_listening(handler) as address:  # start server to listen to request
            with create_client(address) as client:  # create client under test
                client.enable_logging(logger)
                response = client.merchant("1").products().get_payment_product(1, query_params)

        self.assertIsNotNone(response)
        self.assertIsNotNone(response.id)
        self.assertEqual(test_path, self.request_path.split("?")[0],
                         'Request has arrived at {} instead of {}'.format(self.request_path.split("?")[0], test_path))
        self.assertLogsRequestAndResponse(logger, "getPaymentProduct")
    def test_idempotence_first_request(self):
        """Test a request with idempotence key where the first request is successful"""
        response_body = read_resource("idempotence_success.json")
        idempotence_key = str(uuid.uuid4())
        call_context = CallContext(idempotence_key)
        request = create_payment_request()
        test_path = "/v1/20000/payments"  # relative url through which the request should be sent
        additional_headers \
            = (("Content-Type", "application/json"),
               ("Location", "http://localhost/v1/20000/payments/000002000020142549460000100001"))
        handler = self.create_handler(response_code=201, body=response_body,
                                      additional_headers=additional_headers)
        with create_server_listening(handler) as address:
            with create_client(address) as client:
                response = client.merchant("20000").payments().create(request, call_context)

        self.assertIsNotNone(response)
        self.assertIsNotNone(response.payment)
        self.assertIsNotNone(response.payment.id)
        self.assertEqual(test_path, self.request_path,
                         'Request has arrived at the wrong path')
        self.assertEqual(idempotence_key, self.idempotence_header,
                         "Wrong idempotence key is sent in the request")
        self.assertEqual(idempotence_key, call_context.idempotence_key)