def test_get_access_token_api_call_fails_throws_exception(self): mocked_serializer = mock.MagicMock(spec=Serializer) mocked_serializer.serialize.return_value = "access token request" test_scope = "test" fake_response = ApiClientResponse() fake_response.status_code = 400 fake_response.body = "test_body" fake_api_client = mock.MagicMock(spec=ApiClient) fake_api_client.invoke.return_value = fake_response mocked_serializer.deserialize.return_value = "test error body" test_lwa_client = LwaClient( api_configuration=ApiConfiguration(serializer=mocked_serializer, api_client=fake_api_client), authentication_configuration=AuthenticationConfiguration()) with raises(ServiceException) as exc: _actual_token_value = test_lwa_client.get_access_token_for_scope( scope=test_scope) self.assertIn( "Bad Request", str(exc.value), ("LWA Client get access token threw unknown exception when " "the LWA API call failed with an known exception"))
def test_invoke_throw_exception_if_no_response_status_code(self): mocked_serializer = mock.MagicMock(spec=Serializer) fake_response = ApiClientResponse() fake_response.status_code = None fake_api_client = mock.MagicMock(spec=ApiClient) fake_api_client.invoke.return_value = fake_response fake_api_config = ApiConfiguration(serializer=mocked_serializer, api_client=fake_api_client, authorization_value="test_token", api_endpoint="test_endpoint") fake_base_service_client = BaseServiceClient( api_configuration=fake_api_config) with raises(ServiceException) as exc: fake_base_service_client.invoke(method="GET", endpoint="http://test.com", path="", query_params=[], header_params=[], path_params={}, response_definitions=[], body=None, response_type=None) self.assertEqual(str(exc.value), "Invalid Response, no status code", ( "Service exception raised during base service client invoke, when response is unsuccessful, " "has no status code"))
def test_invoke_throw_exception_if_no_definitions_provided_for_unsuccessful_response( self): mocked_serializer = mock.MagicMock(spec=Serializer) fake_response = ApiClientResponse() fake_response.status_code = 450 fake_api_client = mock.MagicMock(spec=ApiClient) fake_api_client.invoke.return_value = fake_response fake_api_config = ApiConfiguration(serializer=mocked_serializer, api_client=fake_api_client, authorization_value="test_token", api_endpoint="test_endpoint") fake_base_service_client = BaseServiceClient( api_configuration=fake_api_config) with raises(ServiceException) as exc: fake_base_service_client.invoke(method="GET", endpoint="http://test.com", path="", query_params=[], header_params=[], path_params={}, response_definitions=[], body=None, response_type=None) self.assertEqual(str(exc.value), "Unknown error", ( "Service exception not raised during base service client invoke when response is unsuccessful and " "no response definitions provided")) self.assertEqual(exc.value.status_code, 450, ( "Service exception raised during base service client invoke has different status code than expected, " "when response is unsuccessful and no response definitions provided" ))
def test_invoke_serializes_response_if_present(self): mocked_serializer = mock.MagicMock(spec=Serializer) fake_response = ApiClientResponse() fake_response.body = "test_body" fake_response.status_code = 200 fake_response_type = "test_response_type" fake_api_client = mock.MagicMock(spec=ApiClient) fake_api_client.invoke.return_value = fake_response mocked_serializer.deserialize.return_value = "deserialized_payload" fake_api_config = ApiConfiguration(serializer=mocked_serializer, api_client=fake_api_client, authorization_value="test_token", api_endpoint="test_endpoint") fake_base_service_client = BaseServiceClient( api_configuration=fake_api_config) response = fake_base_service_client.invoke( method="GET", endpoint="http://test.com", path="", query_params=[], header_params=[], path_params={}, response_definitions=[], body=None, response_type=fake_response_type) self.assertEqual( response.body, "deserialized_payload", "Response from api client not deserialized by base service client") mocked_serializer.deserialize.assert_called_with(payload=fake_response.body, obj_type=fake_response_type), \ "Base service client called deserialize on Response from api client with wrong values"
def test_invoke_throw_exception_with_matched_definition_for_unsuccessful_response( self): mocked_serializer = mock.MagicMock(spec=Serializer) fake_response = ApiClientResponse() fake_response.status_code = 450 fake_response.body = "test_body" fake_api_client = mock.MagicMock(spec=ApiClient) fake_api_client.invoke.return_value = fake_response mocked_serializer.deserialize.return_value = "deserialized_error_body" fake_api_config = ApiConfiguration(serializer=mocked_serializer, api_client=fake_api_client, authorization_value="test_token", api_endpoint="test_endpoint") fake_base_service_client = BaseServiceClient( api_configuration=fake_api_config) fake_response_definition_1 = ServiceClientResponse( response_type="test_definition_1", status_code=450, message="test exception with definition 1") fake_response_definition_2 = ServiceClientResponse( response_type="test_definition_2", status_code=475, message="test exception with definition 2") fake_response_definitions = [ fake_response_definition_2, fake_response_definition_1 ] with raises(ServiceException) as exc: fake_base_service_client.invoke( method="GET", endpoint="http://test.com", path="", query_params=[], header_params=[], path_params={}, response_definitions=fake_response_definitions, body=None, response_type=None) self.assertEqual(str(exc.value), "test exception with definition 1", ( "Incorrect service exception raised during base service client invoke when response is unsuccessful and " "matching response definitions provided")) mocked_serializer.deserialize.assert_called_with( payload=fake_response.body, obj_type="test_definition_1") self.assertEqual(str(exc.value.body), "deserialized_error_body", ( "Service exception raised during base service client invoke, when response is unsuccessful, " "has different body that expected response"))
def test_invoke_return_api_response_with_none_body(self): mocked_serializer = mock.MagicMock(spec=Serializer) fake_response = ApiClientResponse() fake_response.body = "" fake_response.status_code = 204 fake_response.headers = "test_headers" fake_response_type = "test_response_type" fake_api_client = mock.MagicMock(spec=ApiClient) fake_api_client.invoke.return_value = fake_response fake_api_config = ApiConfiguration(serializer=mocked_serializer, api_client=fake_api_client, authorization_value="test_token", api_endpoint="test_endpoint") fake_base_service_client = BaseServiceClient( api_configuration=fake_api_config) response = fake_base_service_client.invoke( method="GET", endpoint="http://test.com", path="", query_params=[], header_params=[], path_params={}, response_definitions=[], body=None, response_type=fake_response_type) self.assertIsNone(response.body, ( "Base service client returns invalid api response when status code is 204" )) self.assertEqual(response.headers, "test_headers", ( "Base service client return invalid api response with null headers" )) self.assertEqual(response.status_code, 204, ( "Base service client return invalid api response with null status_code" )) self.assertIsNot(mocked_serializer.deserialize.called, ( "Base service client invoke method deserialized no content response body" ))
def invoke(self, request): # type: (ApiClientRequest) -> ApiClientResponse """Dispatches a request to an API endpoint described in the request. Resolves the method from input request object, converts the list of header tuples to the required format (dict) for the `requests` lib call and invokes the method with corresponding parameters on `requests` library. The response from the call is wrapped under the `ApiClientResponse` object and the responsibility of translating a response code and response/ error lies with the caller. :param request: Request to dispatch to the ApiClient :type request: ApiClientRequest :return: Response from the client call :rtype: ApiClientResponse :raises: :py:class:`ask_sdk_model_runtime.exceptions.ApiClientException` """ try: http_method = self._resolve_method(request) http_headers = self._convert_list_tuples_to_dict( headers_list=request.headers) parsed_url = parse_url(request.url) if parsed_url.scheme is None or parsed_url.scheme != "https": raise ApiClientException( "Requests against non-HTTPS endpoints are not allowed.") if request.body: body_content_type = http_headers.get("Content-type", None) if (body_content_type is not None and "json" in body_content_type): raw_data = json.dumps(request.body) else: raw_data = request.body else: raw_data = None http_response = http_method(url=request.url, headers=http_headers, data=raw_data) return ApiClientResponse(headers=self._convert_dict_to_list_tuples( http_response.headers), status_code=http_response.status_code, body=http_response.text) except Exception as e: raise ApiClientException("Error executing the request: {}".format( str(e)))
def empty_response(self): fake_response = ApiClientResponse() fake_response.status_code = 200 return fake_response