diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery/gapic_version.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery/gapic_version.py index 668eac0d72ce..558c8aab67c5 100644 --- a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery/gapic_version.py +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/gapic_version.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/gapic_version.py index 668eac0d72ce..558c8aab67c5 100644 --- a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/gapic_version.py +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/async_client.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/async_client.py index 57872ce521af..91ee9321250f 100644 --- a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/async_client.py +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/async_client.py @@ -413,11 +413,17 @@ async def sample_create_delivery_vehicle(): self._client._transport.create_delivery_vehicle ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -529,11 +535,17 @@ async def sample_get_delivery_vehicle(): self._client._transport.get_delivery_vehicle ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -668,13 +680,17 @@ async def sample_update_delivery_vehicle(): self._client._transport.update_delivery_vehicle ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("delivery_vehicle.name", request.delivery_vehicle.name),) - ), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.delivery_vehicle.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -758,11 +774,17 @@ async def sample_batch_create_tasks(): self._client._transport.batch_create_tasks ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -928,11 +950,17 @@ async def sample_create_task(): self._client._transport.create_task ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -1047,11 +1075,17 @@ async def sample_get_task(): # and friendly error handling. rpc = self._client._transport._wrapped_methods[self._client._transport.get_task] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -1201,13 +1235,17 @@ async def sample_update_task(): self._client._transport.update_task ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("task.name", request.task.name),) - ), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.task.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -1314,11 +1352,17 @@ async def sample_list_tasks(): self._client._transport.list_tasks ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -1437,11 +1481,17 @@ async def sample_get_task_tracking_info(): self._client._transport.get_task_tracking_info ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -1548,11 +1598,17 @@ async def sample_list_delivery_vehicles(): self._client._transport.list_delivery_vehicles ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/README.rst b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/README.rst new file mode 100644 index 000000000000..db6050755ee5 --- /dev/null +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`DeliveryServiceTransport` is the ABC for all transports. +- public child `DeliveryServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `DeliveryServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseDeliveryServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `DeliveryServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/grpc_asyncio.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/grpc_asyncio.py index d7b52ec92816..bbd2979ba6a6 100644 --- a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/grpc_asyncio.py +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -231,6 +232,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -535,7 +539,7 @@ def list_delivery_vehicles( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.create_delivery_vehicle: gapic_v1.method_async.wrap_method( + self.create_delivery_vehicle: self._wrap_method( self.create_delivery_vehicle, default_retry=retries.AsyncRetry( initial=1.0, @@ -549,7 +553,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.get_delivery_vehicle: gapic_v1.method_async.wrap_method( + self.get_delivery_vehicle: self._wrap_method( self.get_delivery_vehicle, default_retry=retries.AsyncRetry( initial=1.0, @@ -563,7 +567,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.update_delivery_vehicle: gapic_v1.method_async.wrap_method( + self.update_delivery_vehicle: self._wrap_method( self.update_delivery_vehicle, default_retry=retries.AsyncRetry( initial=1.0, @@ -577,7 +581,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.batch_create_tasks: gapic_v1.method_async.wrap_method( + self.batch_create_tasks: self._wrap_method( self.batch_create_tasks, default_retry=retries.AsyncRetry( initial=1.0, @@ -591,7 +595,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.create_task: gapic_v1.method_async.wrap_method( + self.create_task: self._wrap_method( self.create_task, default_retry=retries.AsyncRetry( initial=1.0, @@ -605,7 +609,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.get_task: gapic_v1.method_async.wrap_method( + self.get_task: self._wrap_method( self.get_task, default_retry=retries.AsyncRetry( initial=1.0, @@ -619,7 +623,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.update_task: gapic_v1.method_async.wrap_method( + self.update_task: self._wrap_method( self.update_task, default_retry=retries.AsyncRetry( initial=1.0, @@ -633,7 +637,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.list_tasks: gapic_v1.method_async.wrap_method( + self.list_tasks: self._wrap_method( self.list_tasks, default_retry=retries.AsyncRetry( initial=1.0, @@ -647,7 +651,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.get_task_tracking_info: gapic_v1.method_async.wrap_method( + self.get_task_tracking_info: self._wrap_method( self.get_task_tracking_info, default_retry=retries.AsyncRetry( initial=1.0, @@ -661,7 +665,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.list_delivery_vehicles: gapic_v1.method_async.wrap_method( + self.list_delivery_vehicles: self._wrap_method( self.list_delivery_vehicles, default_retry=retries.AsyncRetry( initial=1.0, @@ -677,8 +681,17 @@ def _prep_wrapped_messages(self, client_info): ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("DeliveryServiceGrpcAsyncIOTransport",) diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest.py index 80eec93ef857..f90ff33f7b31 100644 --- a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest.py +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest.py @@ -16,26 +16,17 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - from google.maps.fleetengine_delivery_v1.types import ( delivery_api, delivery_vehicles, @@ -44,7 +35,13 @@ ) from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import DeliveryServiceTransport +from .rest_base import _BaseDeliveryServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, @@ -384,8 +381,8 @@ class DeliveryServiceRestStub: _interceptor: DeliveryServiceRestInterceptor -class DeliveryServiceRestTransport(DeliveryServiceTransport): - """REST backend transport for DeliveryService. +class DeliveryServiceRestTransport(_BaseDeliveryServiceRestTransport): + """REST backend synchronous transport for DeliveryService. The Last Mile Delivery service. @@ -394,7 +391,6 @@ class DeliveryServiceRestTransport(DeliveryServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -448,21 +444,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -473,19 +460,34 @@ def __init__( self._interceptor = interceptor or DeliveryServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _BatchCreateTasks(DeliveryServiceRestStub): + class _BatchCreateTasks( + _BaseDeliveryServiceRestTransport._BaseBatchCreateTasks, DeliveryServiceRestStub + ): def __hash__(self): - return hash("BatchCreateTasks") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.BatchCreateTasks") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -511,47 +513,34 @@ def __call__( The ``BatchCreateTask`` response message. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=providers/*}/tasks:batchCreate", - "body": "*", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseBatchCreateTasks._get_http_options() + ) request, metadata = self._interceptor.pre_batch_create_tasks( request, metadata ) - pb_request = delivery_api.BatchCreateTasksRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDeliveryServiceRestTransport._BaseBatchCreateTasks._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDeliveryServiceRestTransport._BaseBatchCreateTasks._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseBatchCreateTasks._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = DeliveryServiceRestTransport._BatchCreateTasks._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -567,21 +556,35 @@ def __call__( resp = self._interceptor.post_batch_create_tasks(resp) return resp - class _CreateDeliveryVehicle(DeliveryServiceRestStub): + class _CreateDeliveryVehicle( + _BaseDeliveryServiceRestTransport._BaseCreateDeliveryVehicle, + DeliveryServiceRestStub, + ): def __hash__(self): - return hash("CreateDeliveryVehicle") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "deliveryVehicleId": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.CreateDeliveryVehicle") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -619,47 +622,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=providers/*}/deliveryVehicles", - "body": "delivery_vehicle", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseCreateDeliveryVehicle._get_http_options() + ) request, metadata = self._interceptor.pre_create_delivery_vehicle( request, metadata ) - pb_request = delivery_api.CreateDeliveryVehicleRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDeliveryServiceRestTransport._BaseCreateDeliveryVehicle._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDeliveryServiceRestTransport._BaseCreateDeliveryVehicle._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseCreateDeliveryVehicle._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + DeliveryServiceRestTransport._CreateDeliveryVehicle._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -675,21 +667,34 @@ def __call__( resp = self._interceptor.post_create_delivery_vehicle(resp) return resp - class _CreateTask(DeliveryServiceRestStub): + class _CreateTask( + _BaseDeliveryServiceRestTransport._BaseCreateTask, DeliveryServiceRestStub + ): def __hash__(self): - return hash("CreateTask") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "taskId": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.CreateTask") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -731,45 +736,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=providers/*}/tasks", - "body": "task", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseCreateTask._get_http_options() + ) request, metadata = self._interceptor.pre_create_task(request, metadata) - pb_request = delivery_api.CreateTaskRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDeliveryServiceRestTransport._BaseCreateTask._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDeliveryServiceRestTransport._BaseCreateTask._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseCreateTask._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = DeliveryServiceRestTransport._CreateTask._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -785,19 +777,34 @@ def __call__( resp = self._interceptor.post_create_task(resp) return resp - class _GetDeliveryVehicle(DeliveryServiceRestStub): + class _GetDeliveryVehicle( + _BaseDeliveryServiceRestTransport._BaseGetDeliveryVehicle, + DeliveryServiceRestStub, + ): def __hash__(self): - return hash("GetDeliveryVehicle") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.GetDeliveryVehicle") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -835,40 +842,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=providers/*/deliveryVehicles/*}", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseGetDeliveryVehicle._get_http_options() + ) request, metadata = self._interceptor.pre_get_delivery_vehicle( request, metadata ) - pb_request = delivery_api.GetDeliveryVehicleRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDeliveryServiceRestTransport._BaseGetDeliveryVehicle._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseGetDeliveryVehicle._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DeliveryServiceRestTransport._GetDeliveryVehicle._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -884,19 +880,33 @@ def __call__( resp = self._interceptor.post_get_delivery_vehicle(resp) return resp - class _GetTask(DeliveryServiceRestStub): + class _GetTask( + _BaseDeliveryServiceRestTransport._BaseGetTask, DeliveryServiceRestStub + ): def __hash__(self): - return hash("GetTask") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.GetTask") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -938,38 +948,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=providers/*/tasks/*}", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseGetTask._get_http_options() + ) request, metadata = self._interceptor.pre_get_task(request, metadata) - pb_request = delivery_api.GetTaskRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseDeliveryServiceRestTransport._BaseGetTask._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseDeliveryServiceRestTransport._BaseGetTask._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DeliveryServiceRestTransport._GetTask._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -985,19 +988,34 @@ def __call__( resp = self._interceptor.post_get_task(resp) return resp - class _GetTaskTrackingInfo(DeliveryServiceRestStub): + class _GetTaskTrackingInfo( + _BaseDeliveryServiceRestTransport._BaseGetTaskTrackingInfo, + DeliveryServiceRestStub, + ): def __hash__(self): - return hash("GetTaskTrackingInfo") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.GetTaskTrackingInfo") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1028,40 +1046,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=providers/*/taskTrackingInfo/*}", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseGetTaskTrackingInfo._get_http_options() + ) request, metadata = self._interceptor.pre_get_task_tracking_info( request, metadata ) - pb_request = delivery_api.GetTaskTrackingInfoRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDeliveryServiceRestTransport._BaseGetTaskTrackingInfo._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseGetTaskTrackingInfo._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DeliveryServiceRestTransport._GetTaskTrackingInfo._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1077,19 +1084,34 @@ def __call__( resp = self._interceptor.post_get_task_tracking_info(resp) return resp - class _ListDeliveryVehicles(DeliveryServiceRestStub): + class _ListDeliveryVehicles( + _BaseDeliveryServiceRestTransport._BaseListDeliveryVehicles, + DeliveryServiceRestStub, + ): def __hash__(self): - return hash("ListDeliveryVehicles") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.ListDeliveryVehicles") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1115,40 +1137,29 @@ def __call__( The ``ListDeliveryVehicles`` response message. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=providers/*}/deliveryVehicles", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseListDeliveryVehicles._get_http_options() + ) request, metadata = self._interceptor.pre_list_delivery_vehicles( request, metadata ) - pb_request = delivery_api.ListDeliveryVehiclesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDeliveryServiceRestTransport._BaseListDeliveryVehicles._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseListDeliveryVehicles._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DeliveryServiceRestTransport._ListDeliveryVehicles._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1164,19 +1175,33 @@ def __call__( resp = self._interceptor.post_list_delivery_vehicles(resp) return resp - class _ListTasks(DeliveryServiceRestStub): + class _ListTasks( + _BaseDeliveryServiceRestTransport._BaseListTasks, DeliveryServiceRestStub + ): def __hash__(self): - return hash("ListTasks") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.ListTasks") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1205,38 +1230,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=providers/*}/tasks", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseListTasks._get_http_options() + ) request, metadata = self._interceptor.pre_list_tasks(request, metadata) - pb_request = delivery_api.ListTasksRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDeliveryServiceRestTransport._BaseListTasks._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseDeliveryServiceRestTransport._BaseListTasks._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DeliveryServiceRestTransport._ListTasks._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1252,21 +1268,35 @@ def __call__( resp = self._interceptor.post_list_tasks(resp) return resp - class _UpdateDeliveryVehicle(DeliveryServiceRestStub): + class _UpdateDeliveryVehicle( + _BaseDeliveryServiceRestTransport._BaseUpdateDeliveryVehicle, + DeliveryServiceRestStub, + ): def __hash__(self): - return hash("UpdateDeliveryVehicle") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.UpdateDeliveryVehicle") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -1304,47 +1334,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{delivery_vehicle.name=providers/*/deliveryVehicles/*}", - "body": "delivery_vehicle", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseUpdateDeliveryVehicle._get_http_options() + ) request, metadata = self._interceptor.pre_update_delivery_vehicle( request, metadata ) - pb_request = delivery_api.UpdateDeliveryVehicleRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDeliveryServiceRestTransport._BaseUpdateDeliveryVehicle._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDeliveryServiceRestTransport._BaseUpdateDeliveryVehicle._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseUpdateDeliveryVehicle._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + DeliveryServiceRestTransport._UpdateDeliveryVehicle._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1360,21 +1379,34 @@ def __call__( resp = self._interceptor.post_update_delivery_vehicle(resp) return resp - class _UpdateTask(DeliveryServiceRestStub): + class _UpdateTask( + _BaseDeliveryServiceRestTransport._BaseUpdateTask, DeliveryServiceRestStub + ): def __hash__(self): - return hash("UpdateTask") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DeliveryServiceRestTransport.UpdateTask") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -1416,45 +1448,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{task.name=providers/*/tasks/*}", - "body": "task", - }, - ] + http_options = ( + _BaseDeliveryServiceRestTransport._BaseUpdateTask._get_http_options() + ) request, metadata = self._interceptor.pre_update_task(request, metadata) - pb_request = delivery_api.UpdateTaskRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDeliveryServiceRestTransport._BaseUpdateTask._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDeliveryServiceRestTransport._BaseUpdateTask._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDeliveryServiceRestTransport._BaseUpdateTask._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = DeliveryServiceRestTransport._UpdateTask._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest_base.py b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest_base.py new file mode 100644 index 000000000000..84681d7e12a9 --- /dev/null +++ b/packages/google-maps-fleetengine-delivery/google/maps/fleetengine_delivery_v1/services/delivery_service/transports/rest_base.py @@ -0,0 +1,624 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.maps.fleetengine_delivery_v1.types import ( + delivery_api, + delivery_vehicles, + task_tracking_info, + tasks, +) + +from .base import DEFAULT_CLIENT_INFO, DeliveryServiceTransport + + +class _BaseDeliveryServiceRestTransport(DeliveryServiceTransport): + """Base REST backend transport for DeliveryService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "fleetengine.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'fleetengine.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchCreateTasks: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=providers/*}/tasks:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.BatchCreateTasksRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseBatchCreateTasks._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateDeliveryVehicle: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "deliveryVehicleId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=providers/*}/deliveryVehicles", + "body": "delivery_vehicle", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.CreateDeliveryVehicleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseCreateDeliveryVehicle._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateTask: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "taskId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=providers/*}/tasks", + "body": "task", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.CreateTaskRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseCreateTask._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDeliveryVehicle: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=providers/*/deliveryVehicles/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.GetDeliveryVehicleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseGetDeliveryVehicle._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetTask: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=providers/*/tasks/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.GetTaskRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseGetTask._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetTaskTrackingInfo: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=providers/*/taskTrackingInfo/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.GetTaskTrackingInfoRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseGetTaskTrackingInfo._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDeliveryVehicles: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=providers/*}/deliveryVehicles", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.ListDeliveryVehiclesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseListDeliveryVehicles._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListTasks: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=providers/*}/tasks", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.ListTasksRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseListTasks._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateDeliveryVehicle: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{delivery_vehicle.name=providers/*/deliveryVehicles/*}", + "body": "delivery_vehicle", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.UpdateDeliveryVehicleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseUpdateDeliveryVehicle._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateTask: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{task.name=providers/*/tasks/*}", + "body": "task", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = delivery_api.UpdateTaskRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeliveryServiceRestTransport._BaseUpdateTask._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseDeliveryServiceRestTransport",) diff --git a/packages/google-maps-fleetengine-delivery/samples/generated_samples/snippet_metadata_maps.fleetengine.delivery.v1.json b/packages/google-maps-fleetengine-delivery/samples/generated_samples/snippet_metadata_maps.fleetengine.delivery.v1.json index 685d1554024c..884ac226d0e4 100644 --- a/packages/google-maps-fleetengine-delivery/samples/generated_samples/snippet_metadata_maps.fleetengine.delivery.v1.json +++ b/packages/google-maps-fleetengine-delivery/samples/generated_samples/snippet_metadata_maps.fleetengine.delivery.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-fleetengine-delivery", - "version": "0.2.4" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-maps-fleetengine-delivery/setup.py b/packages/google-maps-fleetengine-delivery/setup.py index e53f1eafa314..0336e9cd7c8d 100644 --- a/packages/google-maps-fleetengine-delivery/setup.py +++ b/packages/google-maps-fleetengine-delivery/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-geo-type >= 0.1.0, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-fleetengine-delivery" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-fleetengine-delivery/tests/unit/gapic/fleetengine_delivery_v1/test_delivery_service.py b/packages/google-maps-fleetengine-delivery/tests/unit/gapic/fleetengine_delivery_v1/test_delivery_service.py index 6788563f65e5..1b9b8f49a309 100644 --- a/packages/google-maps-fleetengine-delivery/tests/unit/gapic/fleetengine_delivery_v1/test_delivery_service.py +++ b/packages/google-maps-fleetengine-delivery/tests/unit/gapic/fleetengine_delivery_v1/test_delivery_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -37,17 +54,9 @@ from google.oauth2 import service_account from google.protobuf import duration_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore from google.type import latlng_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.maps.fleetengine_delivery_v1.services.delivery_service import ( DeliveryServiceAsyncClient, @@ -65,10 +74,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1200,27 +1223,6 @@ def test_create_delivery_vehicle(request_type, transport: str = "grpc"): assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO -def test_create_delivery_vehicle_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_delivery_vehicle), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_delivery_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.CreateDeliveryVehicleRequest() - - def test_create_delivery_vehicle_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1293,34 +1295,6 @@ def test_create_delivery_vehicle_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_delivery_vehicle_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_delivery_vehicle), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - delivery_vehicles.DeliveryVehicle( - name="name_value", - navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, - current_route_segment=b"current_route_segment_blob", - type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, - ) - ) - response = await client.create_delivery_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.CreateDeliveryVehicleRequest() - - @pytest.mark.asyncio async def test_create_delivery_vehicle_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1329,7 +1303,7 @@ async def test_create_delivery_vehicle_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1369,7 +1343,7 @@ async def test_create_delivery_vehicle_async( request_type=delivery_api.CreateDeliveryVehicleRequest, ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1413,34 +1387,6 @@ async def test_create_delivery_vehicle_async_from_dict(): await test_create_delivery_vehicle_async(request_type=dict) -def test_create_delivery_vehicle_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.CreateDeliveryVehicleRequest( - **{"parent": "providers/sample1"} - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_delivery_vehicle), "__call__" - ) as call: - call.return_value = delivery_vehicles.DeliveryVehicle() - client.create_delivery_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_create_delivery_vehicle_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -1494,7 +1440,7 @@ def test_create_delivery_vehicle_flattened_error(): @pytest.mark.asyncio async def test_create_delivery_vehicle_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1533,7 +1479,7 @@ async def test_create_delivery_vehicle_flattened_async(): @pytest.mark.asyncio async def test_create_delivery_vehicle_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1593,27 +1539,6 @@ def test_get_delivery_vehicle(request_type, transport: str = "grpc"): assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO -def test_get_delivery_vehicle_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_delivery_vehicle), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_delivery_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.GetDeliveryVehicleRequest() - - def test_get_delivery_vehicle_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1683,34 +1608,6 @@ def test_get_delivery_vehicle_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_delivery_vehicle_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_delivery_vehicle), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - delivery_vehicles.DeliveryVehicle( - name="name_value", - navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, - current_route_segment=b"current_route_segment_blob", - type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, - ) - ) - response = await client.get_delivery_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.GetDeliveryVehicleRequest() - - @pytest.mark.asyncio async def test_get_delivery_vehicle_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1719,7 +1616,7 @@ async def test_get_delivery_vehicle_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1758,7 +1655,7 @@ async def test_get_delivery_vehicle_async( transport: str = "grpc_asyncio", request_type=delivery_api.GetDeliveryVehicleRequest ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1802,32 +1699,6 @@ async def test_get_delivery_vehicle_async_from_dict(): await test_get_delivery_vehicle_async(request_type=dict) -def test_get_delivery_vehicle_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.GetDeliveryVehicleRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_delivery_vehicle), "__call__" - ) as call: - call.return_value = delivery_vehicles.DeliveryVehicle() - client.get_delivery_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_get_delivery_vehicle_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -1871,7 +1742,7 @@ def test_get_delivery_vehicle_flattened_error(): @pytest.mark.asyncio async def test_get_delivery_vehicle_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1902,7 +1773,7 @@ async def test_get_delivery_vehicle_flattened_async(): @pytest.mark.asyncio async def test_get_delivery_vehicle_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1960,27 +1831,6 @@ def test_update_delivery_vehicle(request_type, transport: str = "grpc"): assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO -def test_update_delivery_vehicle_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_delivery_vehicle), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_delivery_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.UpdateDeliveryVehicleRequest() - - def test_update_delivery_vehicle_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2047,34 +1897,6 @@ def test_update_delivery_vehicle_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_delivery_vehicle_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_delivery_vehicle), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - delivery_vehicles.DeliveryVehicle( - name="name_value", - navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, - current_route_segment=b"current_route_segment_blob", - type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, - ) - ) - response = await client.update_delivery_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.UpdateDeliveryVehicleRequest() - - @pytest.mark.asyncio async def test_update_delivery_vehicle_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2083,7 +1905,7 @@ async def test_update_delivery_vehicle_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2123,7 +1945,7 @@ async def test_update_delivery_vehicle_async( request_type=delivery_api.UpdateDeliveryVehicleRequest, ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2167,34 +1989,6 @@ async def test_update_delivery_vehicle_async_from_dict(): await test_update_delivery_vehicle_async(request_type=dict) -def test_update_delivery_vehicle_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.UpdateDeliveryVehicleRequest( - **{"delivery_vehicle": {"name": "providers/sample1"}} - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_delivery_vehicle), "__call__" - ) as call: - call.return_value = delivery_vehicles.DeliveryVehicle() - client.update_delivery_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_update_delivery_vehicle_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2243,7 +2037,7 @@ def test_update_delivery_vehicle_flattened_error(): @pytest.mark.asyncio async def test_update_delivery_vehicle_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2278,7 +2072,7 @@ async def test_update_delivery_vehicle_flattened_async(): @pytest.mark.asyncio async def test_update_delivery_vehicle_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2326,27 +2120,6 @@ def test_batch_create_tasks(request_type, transport: str = "grpc"): assert isinstance(response, delivery_api.BatchCreateTasksResponse) -def test_batch_create_tasks_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_tasks), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.batch_create_tasks() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.BatchCreateTasksRequest() - - def test_batch_create_tasks_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2416,29 +2189,6 @@ def test_batch_create_tasks_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_batch_create_tasks_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_tasks), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - delivery_api.BatchCreateTasksResponse() - ) - response = await client.batch_create_tasks() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.BatchCreateTasksRequest() - - @pytest.mark.asyncio async def test_batch_create_tasks_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2447,7 +2197,7 @@ async def test_batch_create_tasks_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2486,7 +2236,7 @@ async def test_batch_create_tasks_async( transport: str = "grpc_asyncio", request_type=delivery_api.BatchCreateTasksRequest ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2519,32 +2269,6 @@ async def test_batch_create_tasks_async_from_dict(): await test_batch_create_tasks_async(request_type=dict) -def test_batch_create_tasks_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.BatchCreateTasksRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_tasks), "__call__" - ) as call: - call.return_value = delivery_api.BatchCreateTasksResponse() - client.batch_create_tasks(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -2596,25 +2320,6 @@ def test_create_task(request_type, transport: str = "grpc"): assert response.delivery_vehicle_id == "delivery_vehicle_id_value" -def test_create_task_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_task), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_task() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.CreateTaskRequest() - - def test_create_task_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2680,35 +2385,6 @@ def test_create_task_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_task_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_task), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tasks.Task( - name="name_value", - type_=tasks.Task.Type.PICKUP, - state=tasks.Task.State.OPEN, - task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, - task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, - tracking_id="tracking_id_value", - delivery_vehicle_id="delivery_vehicle_id_value", - ) - ) - response = await client.create_task() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.CreateTaskRequest() - - @pytest.mark.asyncio async def test_create_task_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2717,7 +2393,7 @@ async def test_create_task_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2756,7 +2432,7 @@ async def test_create_task_async( transport: str = "grpc_asyncio", request_type=delivery_api.CreateTaskRequest ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2805,30 +2481,6 @@ async def test_create_task_async_from_dict(): await test_create_task_async(request_type=dict) -def test_create_task_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.CreateTaskRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_task), "__call__") as call: - call.return_value = tasks.Task() - client.create_task(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_create_task_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2880,7 +2532,7 @@ def test_create_task_flattened_error(): @pytest.mark.asyncio async def test_create_task_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2915,7 +2567,7 @@ async def test_create_task_flattened_async(): @pytest.mark.asyncio async def test_create_task_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2980,25 +2632,6 @@ def test_get_task(request_type, transport: str = "grpc"): assert response.delivery_vehicle_id == "delivery_vehicle_id_value" -def test_get_task_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_task), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_task() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.GetTaskRequest() - - def test_get_task_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3062,42 +2695,13 @@ def test_get_task_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_task_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_task), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tasks.Task( - name="name_value", - type_=tasks.Task.Type.PICKUP, - state=tasks.Task.State.OPEN, - task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, - task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, - tracking_id="tracking_id_value", - delivery_vehicle_id="delivery_vehicle_id_value", - ) - ) - response = await client.get_task() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.GetTaskRequest() - - @pytest.mark.asyncio async def test_get_task_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3136,7 +2740,7 @@ async def test_get_task_async( transport: str = "grpc_asyncio", request_type=delivery_api.GetTaskRequest ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3185,30 +2789,6 @@ async def test_get_task_async_from_dict(): await test_get_task_async(request_type=dict) -def test_get_task_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.GetTaskRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_task), "__call__") as call: - call.return_value = tasks.Task() - client.get_task(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_get_task_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3250,7 +2830,7 @@ def test_get_task_flattened_error(): @pytest.mark.asyncio async def test_get_task_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3277,7 +2857,7 @@ async def test_get_task_flattened_async(): @pytest.mark.asyncio async def test_get_task_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3340,25 +2920,6 @@ def test_update_task(request_type, transport: str = "grpc"): assert response.delivery_vehicle_id == "delivery_vehicle_id_value" -def test_update_task_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_task), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_task() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.UpdateTaskRequest() - - def test_update_task_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3418,35 +2979,6 @@ def test_update_task_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_task_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_task), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - tasks.Task( - name="name_value", - type_=tasks.Task.Type.PICKUP, - state=tasks.Task.State.OPEN, - task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, - task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, - tracking_id="tracking_id_value", - delivery_vehicle_id="delivery_vehicle_id_value", - ) - ) - response = await client.update_task() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.UpdateTaskRequest() - - @pytest.mark.asyncio async def test_update_task_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -3455,7 +2987,7 @@ async def test_update_task_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3494,7 +3026,7 @@ async def test_update_task_async( transport: str = "grpc_asyncio", request_type=delivery_api.UpdateTaskRequest ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3543,30 +3075,6 @@ async def test_update_task_async_from_dict(): await test_update_task_async(request_type=dict) -def test_update_task_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.UpdateTaskRequest(**{"task": {"name": "providers/sample1"}}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_task), "__call__") as call: - call.return_value = tasks.Task() - client.update_task(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_update_task_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3613,7 +3121,7 @@ def test_update_task_flattened_error(): @pytest.mark.asyncio async def test_update_task_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3644,7 +3152,7 @@ async def test_update_task_flattened_async(): @pytest.mark.asyncio async def test_update_task_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3695,25 +3203,6 @@ def test_list_tasks(request_type, transport: str = "grpc"): assert response.total_size == 1086 -def test_list_tasks_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_tasks() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.ListTasksRequest() - - def test_list_tasks_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3781,37 +3270,13 @@ def test_list_tasks_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_tasks_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - delivery_api.ListTasksResponse( - next_page_token="next_page_token_value", - total_size=1086, - ) - ) - response = await client.list_tasks() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.ListTasksRequest() - - @pytest.mark.asyncio async def test_list_tasks_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3850,7 +3315,7 @@ async def test_list_tasks_async( transport: str = "grpc_asyncio", request_type=delivery_api.ListTasksRequest ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3886,30 +3351,6 @@ async def test_list_tasks_async_from_dict(): await test_list_tasks_async(request_type=dict) -def test_list_tasks_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.ListTasksRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: - call.return_value = delivery_api.ListTasksResponse() - client.list_tasks(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_list_tasks_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3951,7 +3392,7 @@ def test_list_tasks_flattened_error(): @pytest.mark.asyncio async def test_list_tasks_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3980,7 +3421,7 @@ async def test_list_tasks_flattened_async(): @pytest.mark.asyncio async def test_list_tasks_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -4087,7 +3528,7 @@ def test_list_tasks_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_tasks_async_pager(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4137,7 +3578,7 @@ async def test_list_tasks_async_pager(): @pytest.mark.asyncio async def test_list_tasks_async_pages(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4227,30 +3668,9 @@ def test_get_task_tracking_info(request_type, transport: str = "grpc"): assert response.task_outcome == tasks.Task.TaskOutcome.SUCCEEDED -def test_get_task_tracking_info_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_task_tracking_info), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_task_tracking_info() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.GetTaskTrackingInfoRequest() - - -def test_get_task_tracking_info_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. +def test_get_task_tracking_info_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="grpc", @@ -4318,34 +3738,6 @@ def test_get_task_tracking_info_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_task_tracking_info_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_task_tracking_info), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - task_tracking_info.TaskTrackingInfo( - name="name_value", - tracking_id="tracking_id_value", - state=tasks.Task.State.OPEN, - task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, - ) - ) - response = await client.get_task_tracking_info() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.GetTaskTrackingInfoRequest() - - @pytest.mark.asyncio async def test_get_task_tracking_info_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -4354,7 +3746,7 @@ async def test_get_task_tracking_info_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4394,7 +3786,7 @@ async def test_get_task_tracking_info_async( request_type=delivery_api.GetTaskTrackingInfoRequest, ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4436,32 +3828,6 @@ async def test_get_task_tracking_info_async_from_dict(): await test_get_task_tracking_info_async(request_type=dict) -def test_get_task_tracking_info_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.GetTaskTrackingInfoRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_task_tracking_info), "__call__" - ) as call: - call.return_value = task_tracking_info.TaskTrackingInfo() - client.get_task_tracking_info(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_get_task_tracking_info_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4505,7 +3871,7 @@ def test_get_task_tracking_info_flattened_error(): @pytest.mark.asyncio async def test_get_task_tracking_info_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4536,7 +3902,7 @@ async def test_get_task_tracking_info_flattened_async(): @pytest.mark.asyncio async def test_get_task_tracking_info_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -4588,27 +3954,6 @@ def test_list_delivery_vehicles(request_type, transport: str = "grpc"): assert response.total_size == 1086 -def test_list_delivery_vehicles_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_delivery_vehicles), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_delivery_vehicles() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.ListDeliveryVehiclesRequest() - - def test_list_delivery_vehicles_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -4683,32 +4028,6 @@ def test_list_delivery_vehicles_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_delivery_vehicles_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_delivery_vehicles), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - delivery_api.ListDeliveryVehiclesResponse( - next_page_token="next_page_token_value", - total_size=1086, - ) - ) - response = await client.list_delivery_vehicles() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == delivery_api.ListDeliveryVehiclesRequest() - - @pytest.mark.asyncio async def test_list_delivery_vehicles_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -4717,7 +4036,7 @@ async def test_list_delivery_vehicles_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4757,7 +4076,7 @@ async def test_list_delivery_vehicles_async( request_type=delivery_api.ListDeliveryVehiclesRequest, ): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4795,34 +4114,6 @@ async def test_list_delivery_vehicles_async_from_dict(): await test_list_delivery_vehicles_async(request_type=dict) -def test_list_delivery_vehicles_routing_parameters(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = delivery_api.ListDeliveryVehiclesRequest( - **{"parent": "providers/sample1"} - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_delivery_vehicles), "__call__" - ) as call: - call.return_value = delivery_api.ListDeliveryVehiclesResponse() - client.list_delivery_vehicles(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_list_delivery_vehicles_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4866,7 +4157,7 @@ def test_list_delivery_vehicles_flattened_error(): @pytest.mark.asyncio async def test_list_delivery_vehicles_flattened_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4897,7 +4188,7 @@ async def test_list_delivery_vehicles_flattened_async(): @pytest.mark.asyncio async def test_list_delivery_vehicles_flattened_error_async(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -5008,7 +4299,7 @@ def test_list_delivery_vehicles_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_delivery_vehicles_async_pager(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -5060,7 +4351,7 @@ async def test_list_delivery_vehicles_async_pager(): @pytest.mark.asyncio async def test_list_delivery_vehicles_async_pages(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -5108,222 +4399,39 @@ async def test_list_delivery_vehicles_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - delivery_api.CreateDeliveryVehicleRequest, - dict, - ], -) -def test_create_delivery_vehicle_rest(request_type): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +def test_create_delivery_vehicle_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} - request_init["delivery_vehicle"] = { - "name": "name_value", - "last_location": { - "location": {"latitude": 0.86, "longitude": 0.971}, - "horizontal_accuracy": {"value": 0.541}, - "latlng_accuracy": {}, - "heading": {"value": 541}, - "bearing_accuracy": {}, - "heading_accuracy": {}, - "altitude": {}, - "vertical_accuracy": {}, - "altitude_accuracy": {}, - "speed_kmph": {}, - "speed": {}, - "speed_accuracy": {}, - "update_time": {"seconds": 751, "nanos": 543}, - "server_time": {}, - "location_sensor": 1, - "is_road_snapped": {"value": True}, - "is_gps_sensor_enabled": {}, - "time_since_update": {}, - "num_stale_updates": {}, - "raw_location": {}, - "raw_location_time": {}, - "raw_location_sensor": 1, - "raw_location_accuracy": {}, - "supplemental_location": {}, - "supplemental_location_time": {}, - "supplemental_location_sensor": 1, - "supplemental_location_accuracy": {}, - "road_snapped": True, - }, - "navigation_status": 1, - "current_route_segment": b"current_route_segment_blob", - "current_route_segment_end_point": {}, - "remaining_distance_meters": {}, - "remaining_duration": {"seconds": 751, "nanos": 543}, - "remaining_vehicle_journey_segments": [ - { - "stop": { - "planned_location": {"point": {}}, - "tasks": [ - { - "task_id": "task_id_value", - "task_duration": {}, - "target_time_window": {"start_time": {}, "end_time": {}}, - } - ], - "state": 1, - }, - "driving_distance_meters": {}, - "driving_duration": {}, - "path": {}, - } - ], - "attributes": [ - { - "key": "key_value", - "value": "value_value", - "string_value": "string_value_value", - "bool_value": True, - "number_value": 0.1285, - } - ], - "type_": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Determine if the message type is proto-plus or protobuf - test_field = delivery_api.CreateDeliveryVehicleRequest.meta.fields[ - "delivery_vehicle" - ] + # Ensure method has been cached + assert ( + client._transport.create_delivery_vehicle + in client._transport._wrapped_methods + ) - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_delivery_vehicle + ] = mock_rpc - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + request = {} + client.create_delivery_vehicle(request) - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["delivery_vehicle"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["delivery_vehicle"][field])): - del request_init["delivery_vehicle"][field][i][subfield] - else: - del request_init["delivery_vehicle"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = delivery_vehicles.DeliveryVehicle( - name="name_value", - navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, - current_route_segment=b"current_route_segment_blob", - type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = delivery_vehicles.DeliveryVehicle.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_delivery_vehicle(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, delivery_vehicles.DeliveryVehicle) - assert response.name == "name_value" - assert ( - response.navigation_status == common.DeliveryVehicleNavigationStatus.NO_GUIDANCE - ) - assert response.current_route_segment == b"current_route_segment_blob" - assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO - - -def test_create_delivery_vehicle_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.create_delivery_vehicle - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.create_delivery_vehicle - ] = mock_rpc - - request = {} - client.create_delivery_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 client.create_delivery_vehicle(request) @@ -5450,87 +4558,6 @@ def test_create_delivery_vehicle_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_delivery_vehicle_rest_interceptors(null_interceptor): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DeliveryServiceRestInterceptor(), - ) - client = DeliveryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_create_delivery_vehicle" - ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_create_delivery_vehicle" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = delivery_api.CreateDeliveryVehicleRequest.pb( - delivery_api.CreateDeliveryVehicleRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = delivery_vehicles.DeliveryVehicle.to_json( - delivery_vehicles.DeliveryVehicle() - ) - - request = delivery_api.CreateDeliveryVehicleRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = delivery_vehicles.DeliveryVehicle() - - client.create_delivery_vehicle( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_delivery_vehicle_rest_bad_request( - transport: str = "rest", request_type=delivery_api.CreateDeliveryVehicleRequest -): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_delivery_vehicle(request) - - def test_create_delivery_vehicle_rest_flattened(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5591,60 +4618,6 @@ def test_create_delivery_vehicle_rest_flattened_error(transport: str = "rest"): ) -def test_create_delivery_vehicle_rest_error(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - delivery_api.GetDeliveryVehicleRequest, - dict, - ], -) -def test_get_delivery_vehicle_rest(request_type): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "providers/sample1/deliveryVehicles/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = delivery_vehicles.DeliveryVehicle( - name="name_value", - navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, - current_route_segment=b"current_route_segment_blob", - type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = delivery_vehicles.DeliveryVehicle.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_delivery_vehicle(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, delivery_vehicles.DeliveryVehicle) - assert response.name == "name_value" - assert ( - response.navigation_status == common.DeliveryVehicleNavigationStatus.NO_GUIDANCE - ) - assert response.current_route_segment == b"current_route_segment_blob" - assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO - - def test_get_delivery_vehicle_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5770,91 +4743,10 @@ def test_get_delivery_vehicle_rest_unset_required_fields(): assert set(unset_fields) == (set(("header",)) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_delivery_vehicle_rest_interceptors(null_interceptor): - transport = transports.DeliveryServiceRestTransport( +def test_get_delivery_vehicle_rest_flattened(): + client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DeliveryServiceRestInterceptor(), - ) - client = DeliveryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_get_delivery_vehicle" - ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_get_delivery_vehicle" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = delivery_api.GetDeliveryVehicleRequest.pb( - delivery_api.GetDeliveryVehicleRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = delivery_vehicles.DeliveryVehicle.to_json( - delivery_vehicles.DeliveryVehicle() - ) - - request = delivery_api.GetDeliveryVehicleRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = delivery_vehicles.DeliveryVehicle() - - client.get_delivery_vehicle( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_delivery_vehicle_rest_bad_request( - transport: str = "rest", request_type=delivery_api.GetDeliveryVehicleRequest -): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "providers/sample1/deliveryVehicles/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_delivery_vehicle(request) - - -def test_get_delivery_vehicle_rest_flattened(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="rest", ) # Mock the http request call within the method and fake a response. @@ -5907,197 +4799,6 @@ def test_get_delivery_vehicle_rest_flattened_error(transport: str = "rest"): ) -def test_get_delivery_vehicle_rest_error(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - delivery_api.UpdateDeliveryVehicleRequest, - dict, - ], -) -def test_update_delivery_vehicle_rest(request_type): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "delivery_vehicle": {"name": "providers/sample1/deliveryVehicles/sample2"} - } - request_init["delivery_vehicle"] = { - "name": "providers/sample1/deliveryVehicles/sample2", - "last_location": { - "location": {"latitude": 0.86, "longitude": 0.971}, - "horizontal_accuracy": {"value": 0.541}, - "latlng_accuracy": {}, - "heading": {"value": 541}, - "bearing_accuracy": {}, - "heading_accuracy": {}, - "altitude": {}, - "vertical_accuracy": {}, - "altitude_accuracy": {}, - "speed_kmph": {}, - "speed": {}, - "speed_accuracy": {}, - "update_time": {"seconds": 751, "nanos": 543}, - "server_time": {}, - "location_sensor": 1, - "is_road_snapped": {"value": True}, - "is_gps_sensor_enabled": {}, - "time_since_update": {}, - "num_stale_updates": {}, - "raw_location": {}, - "raw_location_time": {}, - "raw_location_sensor": 1, - "raw_location_accuracy": {}, - "supplemental_location": {}, - "supplemental_location_time": {}, - "supplemental_location_sensor": 1, - "supplemental_location_accuracy": {}, - "road_snapped": True, - }, - "navigation_status": 1, - "current_route_segment": b"current_route_segment_blob", - "current_route_segment_end_point": {}, - "remaining_distance_meters": {}, - "remaining_duration": {"seconds": 751, "nanos": 543}, - "remaining_vehicle_journey_segments": [ - { - "stop": { - "planned_location": {"point": {}}, - "tasks": [ - { - "task_id": "task_id_value", - "task_duration": {}, - "target_time_window": {"start_time": {}, "end_time": {}}, - } - ], - "state": 1, - }, - "driving_distance_meters": {}, - "driving_duration": {}, - "path": {}, - } - ], - "attributes": [ - { - "key": "key_value", - "value": "value_value", - "string_value": "string_value_value", - "bool_value": True, - "number_value": 0.1285, - } - ], - "type_": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = delivery_api.UpdateDeliveryVehicleRequest.meta.fields[ - "delivery_vehicle" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["delivery_vehicle"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["delivery_vehicle"][field])): - del request_init["delivery_vehicle"][field][i][subfield] - else: - del request_init["delivery_vehicle"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = delivery_vehicles.DeliveryVehicle( - name="name_value", - navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, - current_route_segment=b"current_route_segment_blob", - type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = delivery_vehicles.DeliveryVehicle.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_delivery_vehicle(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, delivery_vehicles.DeliveryVehicle) - assert response.name == "name_value" - assert ( - response.navigation_status == common.DeliveryVehicleNavigationStatus.NO_GUIDANCE - ) - assert response.current_route_segment == b"current_route_segment_blob" - assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO - - def test_update_delivery_vehicle_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -6238,91 +4939,8 @@ def test_update_delivery_vehicle_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_delivery_vehicle_rest_interceptors(null_interceptor): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DeliveryServiceRestInterceptor(), - ) - client = DeliveryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_update_delivery_vehicle" - ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_update_delivery_vehicle" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = delivery_api.UpdateDeliveryVehicleRequest.pb( - delivery_api.UpdateDeliveryVehicleRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = delivery_vehicles.DeliveryVehicle.to_json( - delivery_vehicles.DeliveryVehicle() - ) - - request = delivery_api.UpdateDeliveryVehicleRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = delivery_vehicles.DeliveryVehicle() - - client.update_delivery_vehicle( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_delivery_vehicle_rest_bad_request( - transport: str = "rest", request_type=delivery_api.UpdateDeliveryVehicleRequest -): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = { - "delivery_vehicle": {"name": "providers/sample1/deliveryVehicles/sample2"} - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_delivery_vehicle(request) - - -def test_update_delivery_vehicle_rest_flattened(): - client = DeliveryServiceClient( +def test_update_delivery_vehicle_rest_flattened(): + client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) @@ -6382,49 +5000,6 @@ def test_update_delivery_vehicle_rest_flattened_error(transport: str = "rest"): ) -def test_update_delivery_vehicle_rest_error(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - delivery_api.BatchCreateTasksRequest, - dict, - ], -) -def test_batch_create_tasks_rest(request_type): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = delivery_api.BatchCreateTasksResponse() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = delivery_api.BatchCreateTasksResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.batch_create_tasks(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, delivery_api.BatchCreateTasksResponse) - - def test_batch_create_tasks_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -6557,201 +5132,2678 @@ def test_batch_create_tasks_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_batch_create_tasks_rest_interceptors(null_interceptor): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DeliveryServiceRestInterceptor(), - ) - client = DeliveryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_batch_create_tasks" - ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_batch_create_tasks" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = delivery_api.BatchCreateTasksRequest.pb( - delivery_api.BatchCreateTasksRequest() +def test_create_task_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = delivery_api.BatchCreateTasksResponse.to_json( - delivery_api.BatchCreateTasksResponse() - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - request = delivery_api.BatchCreateTasksRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = delivery_api.BatchCreateTasksResponse() + # Ensure method has been cached + assert client._transport.create_task in client._transport._wrapped_methods - client.batch_create_tasks( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) + client._transport._wrapped_methods[client._transport.create_task] = mock_rpc - pre.assert_called_once() - post.assert_called_once() + request = {} + client.create_task(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -def test_batch_create_tasks_rest_bad_request( - transport: str = "rest", request_type=delivery_api.BatchCreateTasksRequest -): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + client.create_task(request) - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_task_rest_required_fields(request_type=delivery_api.CreateTaskRequest): + transport_class = transports.DeliveryServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["task_id"] = "" request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.batch_create_tasks(request) + # verify fields with default values are dropped + assert "taskId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + # verify required fields with default values are now present + assert "taskId" in jsonified_request + assert jsonified_request["taskId"] == request_init["task_id"] -def test_batch_create_tasks_rest_error(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" + jsonified_request["parent"] = "parent_value" + jsonified_request["taskId"] = "task_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_task._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "header", + "task_id", + ) ) + jsonified_request.update(unset_fields) + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "taskId" in jsonified_request + assert jsonified_request["taskId"] == "task_id_value" -@pytest.mark.parametrize( - "request_type", - [ - delivery_api.CreateTaskRequest, - dict, - ], -) -def test_create_task_rest(request_type): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) + request = request_type(**request_init) + # Designate an appropriate value for the returned response. + return_value = tasks.Task() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tasks.Task.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_task(request) + + expected_params = [ + ( + "taskId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_task_rest_unset_required_fields(): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_task._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "header", + "taskId", + ) + ) + & set( + ( + "parent", + "taskId", + "task", + ) + ) + ) + + +def test_create_task_rest_flattened(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tasks.Task() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "providers/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + task=tasks.Task(name="name_value"), + task_id="task_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tasks.Task.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_task(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=providers/*}/tasks" % client.transport._host, args[1] + ) + + +def test_create_task_rest_flattened_error(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_task( + delivery_api.CreateTaskRequest(), + parent="parent_value", + task=tasks.Task(name="name_value"), + task_id="task_id_value", + ) + + +def test_get_task_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_task in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_task] = mock_rpc + + request = {} + client.get_task(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_task(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_task_rest_required_fields(request_type=delivery_api.GetTaskRequest): + transport_class = transports.DeliveryServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_task._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("header",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = tasks.Task() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tasks.Task.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_task(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_task_rest_unset_required_fields(): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_task._get_unset_required_fields({}) + assert set(unset_fields) == (set(("header",)) & set(("name",))) + + +def test_get_task_rest_flattened(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tasks.Task() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "providers/sample1/tasks/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tasks.Task.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_task(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=providers/*/tasks/*}" % client.transport._host, args[1] + ) + + +def test_get_task_rest_flattened_error(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_task( + delivery_api.GetTaskRequest(), + name="name_value", + ) + + +def test_update_task_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_task in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_task] = mock_rpc + + request = {} + client.update_task(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_task(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_task_rest_required_fields(request_type=delivery_api.UpdateTaskRequest): + transport_class = transports.DeliveryServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_task._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_task._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "header", + "update_mask", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = tasks.Task() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tasks.Task.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_task(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_task_rest_unset_required_fields(): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_task._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "header", + "updateMask", + ) + ) + & set( + ( + "task", + "updateMask", + ) + ) + ) + + +def test_update_task_rest_flattened(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tasks.Task() + + # get arguments that satisfy an http rule for this method + sample_request = {"task": {"name": "providers/sample1/tasks/sample2"}} + + # get truthy value for each flattened field + mock_args = dict( + task=tasks.Task(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tasks.Task.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_task(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{task.name=providers/*/tasks/*}" % client.transport._host, args[1] + ) + + +def test_update_task_rest_flattened_error(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_task( + delivery_api.UpdateTaskRequest(), + task=tasks.Task(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_list_tasks_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_tasks in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_tasks] = mock_rpc + + request = {} + client.list_tasks(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_tasks(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_tasks_rest_required_fields(request_type=delivery_api.ListTasksRequest): + transport_class = transports.DeliveryServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_tasks._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_tasks._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "header", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = delivery_api.ListTasksResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = delivery_api.ListTasksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_tasks(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_tasks_rest_unset_required_fields(): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_tasks._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "header", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_tasks_rest_flattened(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = delivery_api.ListTasksResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "providers/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = delivery_api.ListTasksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_tasks(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=providers/*}/tasks" % client.transport._host, args[1] + ) + + +def test_list_tasks_rest_flattened_error(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_tasks( + delivery_api.ListTasksRequest(), + parent="parent_value", + ) + + +def test_list_tasks_rest_pager(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + delivery_api.ListTasksResponse( + tasks=[ + tasks.Task(), + tasks.Task(), + tasks.Task(), + ], + next_page_token="abc", + ), + delivery_api.ListTasksResponse( + tasks=[], + next_page_token="def", + ), + delivery_api.ListTasksResponse( + tasks=[ + tasks.Task(), + ], + next_page_token="ghi", + ), + delivery_api.ListTasksResponse( + tasks=[ + tasks.Task(), + tasks.Task(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(delivery_api.ListTasksResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "providers/sample1"} + + pager = client.list_tasks(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, tasks.Task) for i in results) + + pages = list(client.list_tasks(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_task_tracking_info_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_task_tracking_info + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_task_tracking_info + ] = mock_rpc + + request = {} + client.get_task_tracking_info(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_task_tracking_info(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_task_tracking_info_rest_required_fields( + request_type=delivery_api.GetTaskTrackingInfoRequest, +): + transport_class = transports.DeliveryServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_task_tracking_info._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_task_tracking_info._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("header",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = task_tracking_info.TaskTrackingInfo() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = task_tracking_info.TaskTrackingInfo.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_task_tracking_info(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_task_tracking_info_rest_unset_required_fields(): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_task_tracking_info._get_unset_required_fields({}) + assert set(unset_fields) == (set(("header",)) & set(("name",))) + + +def test_get_task_tracking_info_rest_flattened(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = task_tracking_info.TaskTrackingInfo() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "providers/sample1/taskTrackingInfo/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = task_tracking_info.TaskTrackingInfo.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_task_tracking_info(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=providers/*/taskTrackingInfo/*}" % client.transport._host, + args[1], + ) + + +def test_get_task_tracking_info_rest_flattened_error(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_task_tracking_info( + delivery_api.GetTaskTrackingInfoRequest(), + name="name_value", + ) + + +def test_list_delivery_vehicles_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_delivery_vehicles + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_delivery_vehicles + ] = mock_rpc + + request = {} + client.list_delivery_vehicles(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_delivery_vehicles(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_delivery_vehicles_rest_required_fields( + request_type=delivery_api.ListDeliveryVehiclesRequest, +): + transport_class = transports.DeliveryServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_delivery_vehicles._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_delivery_vehicles._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "header", + "page_size", + "page_token", + "viewport", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = delivery_api.ListDeliveryVehiclesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = delivery_api.ListDeliveryVehiclesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_delivery_vehicles(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_delivery_vehicles_rest_unset_required_fields(): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_delivery_vehicles._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "header", + "pageSize", + "pageToken", + "viewport", + ) + ) + & set(("parent",)) + ) + + +def test_list_delivery_vehicles_rest_flattened(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = delivery_api.ListDeliveryVehiclesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "providers/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = delivery_api.ListDeliveryVehiclesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_delivery_vehicles(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=providers/*}/deliveryVehicles" % client.transport._host, + args[1], + ) + + +def test_list_delivery_vehicles_rest_flattened_error(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_delivery_vehicles( + delivery_api.ListDeliveryVehiclesRequest(), + parent="parent_value", + ) + + +def test_list_delivery_vehicles_rest_pager(transport: str = "rest"): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + delivery_api.ListDeliveryVehiclesResponse( + delivery_vehicles=[ + delivery_vehicles.DeliveryVehicle(), + delivery_vehicles.DeliveryVehicle(), + delivery_vehicles.DeliveryVehicle(), + ], + next_page_token="abc", + ), + delivery_api.ListDeliveryVehiclesResponse( + delivery_vehicles=[], + next_page_token="def", + ), + delivery_api.ListDeliveryVehiclesResponse( + delivery_vehicles=[ + delivery_vehicles.DeliveryVehicle(), + ], + next_page_token="ghi", + ), + delivery_api.ListDeliveryVehiclesResponse( + delivery_vehicles=[ + delivery_vehicles.DeliveryVehicle(), + delivery_vehicles.DeliveryVehicle(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + delivery_api.ListDeliveryVehiclesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "providers/sample1"} + + pager = client.list_delivery_vehicles(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, delivery_vehicles.DeliveryVehicle) for i in results) + + pages = list(client.list_delivery_vehicles(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DeliveryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DeliveryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeliveryServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DeliveryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeliveryServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeliveryServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DeliveryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeliveryServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DeliveryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DeliveryServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.DeliveryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.DeliveryServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeliveryServiceGrpcTransport, + transports.DeliveryServiceGrpcAsyncIOTransport, + transports.DeliveryServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = DeliveryServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_delivery_vehicle_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_delivery_vehicle), "__call__" + ) as call: + call.return_value = delivery_vehicles.DeliveryVehicle() + client.create_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.CreateDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_delivery_vehicle_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_delivery_vehicle), "__call__" + ) as call: + call.return_value = delivery_vehicles.DeliveryVehicle() + client.get_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_delivery_vehicle_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_delivery_vehicle), "__call__" + ) as call: + call.return_value = delivery_vehicles.DeliveryVehicle() + client.update_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.UpdateDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_tasks_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tasks), "__call__" + ) as call: + call.return_value = delivery_api.BatchCreateTasksResponse() + client.batch_create_tasks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.BatchCreateTasksRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_task_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_task), "__call__") as call: + call.return_value = tasks.Task() + client.create_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.CreateTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_task_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_task), "__call__") as call: + call.return_value = tasks.Task() + client.get_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_task_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_task), "__call__") as call: + call.return_value = tasks.Task() + client.update_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.UpdateTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_tasks_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: + call.return_value = delivery_api.ListTasksResponse() + client.list_tasks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.ListTasksRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_task_tracking_info_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_task_tracking_info), "__call__" + ) as call: + call.return_value = task_tracking_info.TaskTrackingInfo() + client.get_task_tracking_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetTaskTrackingInfoRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_delivery_vehicles_empty_call_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_delivery_vehicles), "__call__" + ) as call: + call.return_value = delivery_api.ListDeliveryVehiclesResponse() + client.list_delivery_vehicles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.ListDeliveryVehiclesRequest() + + assert args[0] == request_msg + + +def test_create_delivery_vehicle_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_delivery_vehicle), "__call__" + ) as call: + call.return_value = delivery_vehicles.DeliveryVehicle() + client.create_delivery_vehicle(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.CreateDeliveryVehicleRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_get_delivery_vehicle_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_delivery_vehicle), "__call__" + ) as call: + call.return_value = delivery_vehicles.DeliveryVehicle() + client.get_delivery_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetDeliveryVehicleRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_update_delivery_vehicle_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_delivery_vehicle), "__call__" + ) as call: + call.return_value = delivery_vehicles.DeliveryVehicle() + client.update_delivery_vehicle( + request={"delivery_vehicle": {"name": "providers/sample1"}} + ) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.UpdateDeliveryVehicleRequest( + **{"delivery_vehicle": {"name": "providers/sample1"}} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_batch_create_tasks_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tasks), "__call__" + ) as call: + call.return_value = delivery_api.BatchCreateTasksResponse() + client.batch_create_tasks(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.BatchCreateTasksRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_create_task_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_task), "__call__") as call: + call.return_value = tasks.Task() + client.create_task(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.CreateTaskRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_get_task_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_task), "__call__") as call: + call.return_value = tasks.Task() + client.get_task(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetTaskRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_update_task_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_task), "__call__") as call: + call.return_value = tasks.Task() + client.update_task(request={"task": {"name": "providers/sample1"}}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.UpdateTaskRequest( + **{"task": {"name": "providers/sample1"}} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_list_tasks_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: + call.return_value = delivery_api.ListTasksResponse() + client.list_tasks(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.ListTasksRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_get_task_tracking_info_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_task_tracking_info), "__call__" + ) as call: + call.return_value = task_tracking_info.TaskTrackingInfo() + client.get_task_tracking_info(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetTaskTrackingInfoRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_list_delivery_vehicles_routing_parameters_request_1_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_delivery_vehicles), "__call__" + ) as call: + call.return_value = delivery_api.ListDeliveryVehiclesResponse() + client.list_delivery_vehicles(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.ListDeliveryVehiclesRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_transport_kind_grpc_asyncio(): + transport = DeliveryServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_delivery_vehicle_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_delivery_vehicle), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + ) + await client.create_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.CreateDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_delivery_vehicle_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_delivery_vehicle), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + ) + await client.get_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_delivery_vehicle_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_delivery_vehicle), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + ) + await client.update_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.UpdateDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_create_tasks_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tasks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_api.BatchCreateTasksResponse() + ) + await client.batch_create_tasks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.BatchCreateTasksRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_task_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", + ) + ) + await client.create_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.CreateTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_task_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", + ) + ) + await client.get_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_task_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", + ) + ) + await client.update_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.UpdateTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_tasks_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_api.ListTasksResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_tasks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.ListTasksRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_task_tracking_info_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_task_tracking_info), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + task_tracking_info.TaskTrackingInfo( + name="name_value", + tracking_id="tracking_id_value", + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + ) + ) + await client.get_task_tracking_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetTaskTrackingInfoRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_delivery_vehicles_empty_call_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_delivery_vehicles), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_api.ListDeliveryVehiclesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_delivery_vehicles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.ListDeliveryVehiclesRequest() + + assert args[0] == request_msg + + +@pytest.mark.asyncio +async def test_create_delivery_vehicle_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_delivery_vehicle), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + ) + await client.create_delivery_vehicle(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.CreateDeliveryVehicleRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_get_delivery_vehicle_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_delivery_vehicle), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + ) + await client.get_delivery_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetDeliveryVehicleRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_update_delivery_vehicle_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_delivery_vehicle), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + ) + await client.update_delivery_vehicle( + request={"delivery_vehicle": {"name": "providers/sample1"}} + ) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.UpdateDeliveryVehicleRequest( + **{"delivery_vehicle": {"name": "providers/sample1"}} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_batch_create_tasks_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tasks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_api.BatchCreateTasksResponse() + ) + await client.batch_create_tasks(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.BatchCreateTasksRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_create_task_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", + ) + ) + await client.create_task(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.CreateTaskRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_get_task_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", + ) + ) + await client.get_task(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetTaskRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_update_task_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_task), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", + ) + ) + await client.update_task(request={"task": {"name": "providers/sample1"}}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.UpdateTaskRequest( + **{"task": {"name": "providers/sample1"}} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_list_tasks_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_api.ListTasksResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_tasks(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.ListTasksRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_get_task_tracking_info_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_task_tracking_info), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + task_tracking_info.TaskTrackingInfo( + name="name_value", + tracking_id="tracking_id_value", + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + ) + ) + await client.get_task_tracking_info(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetTaskTrackingInfoRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_list_delivery_vehicles_routing_parameters_request_1_grpc_asyncio(): + client = DeliveryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_delivery_vehicles), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + delivery_api.ListDeliveryVehiclesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_delivery_vehicles(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.ListDeliveryVehiclesRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_transport_kind_rest(): + transport = DeliveryServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_create_delivery_vehicle_rest_bad_request( + request_type=delivery_api.CreateDeliveryVehicleRequest, +): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) # send a request that will satisfy transcoding request_init = {"parent": "providers/sample1"} - request_init["task"] = { + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_delivery_vehicle(request) + + +@pytest.mark.parametrize( + "request_type", + [ + delivery_api.CreateDeliveryVehicleRequest, + dict, + ], +) +def test_create_delivery_vehicle_rest_call_success(request_type): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} + request_init["delivery_vehicle"] = { "name": "name_value", - "type_": 1, - "state": 1, - "task_outcome": 1, - "task_outcome_time": {"seconds": 751, "nanos": 543}, - "task_outcome_location": {"point": {"latitude": 0.86, "longitude": 0.971}}, - "task_outcome_location_source": 2, - "tracking_id": "tracking_id_value", - "delivery_vehicle_id": "delivery_vehicle_id_value", - "planned_location": {}, - "task_duration": {"seconds": 751, "nanos": 543}, - "target_time_window": {"start_time": {}, "end_time": {}}, - "journey_sharing_info": { - "remaining_vehicle_journey_segments": [ - { - "stop": { - "planned_location": {}, - "tasks": [ - { - "task_id": "task_id_value", - "task_duration": {}, - "target_time_window": {}, - } - ], - "state": 1, - }, - "driving_distance_meters": {"value": 541}, - "driving_duration": {}, - "path": {}, - } - ], - "last_location": { - "location": {}, - "horizontal_accuracy": {"value": 0.541}, - "latlng_accuracy": {}, - "heading": {}, - "bearing_accuracy": {}, - "heading_accuracy": {}, - "altitude": {}, - "vertical_accuracy": {}, - "altitude_accuracy": {}, - "speed_kmph": {}, - "speed": {}, - "speed_accuracy": {}, - "update_time": {}, - "server_time": {}, - "location_sensor": 1, - "is_road_snapped": {"value": True}, - "is_gps_sensor_enabled": {}, - "time_since_update": {}, - "num_stale_updates": {}, - "raw_location": {}, - "raw_location_time": {}, - "raw_location_sensor": 1, - "raw_location_accuracy": {}, - "supplemental_location": {}, - "supplemental_location_time": {}, - "supplemental_location_sensor": 1, - "supplemental_location_accuracy": {}, - "road_snapped": True, - }, - "last_location_snappable": True, - }, - "task_tracking_view_config": { - "route_polyline_points_visibility": { - "remaining_stop_count_threshold": 3219, - "duration_until_estimated_arrival_time_threshold": {}, - "remaining_driving_distance_meters_threshold": 4561, - "always": True, - "never": True, - }, - "estimated_arrival_time_visibility": {}, - "estimated_task_completion_time_visibility": {}, - "remaining_driving_distance_visibility": {}, - "remaining_stop_count_visibility": {}, - "vehicle_location_visibility": {}, + "last_location": { + "location": {"latitude": 0.86, "longitude": 0.971}, + "horizontal_accuracy": {"value": 0.541}, + "latlng_accuracy": {}, + "heading": {"value": 541}, + "bearing_accuracy": {}, + "heading_accuracy": {}, + "altitude": {}, + "vertical_accuracy": {}, + "altitude_accuracy": {}, + "speed_kmph": {}, + "speed": {}, + "speed_accuracy": {}, + "update_time": {"seconds": 751, "nanos": 543}, + "server_time": {}, + "location_sensor": 1, + "is_road_snapped": {"value": True}, + "is_gps_sensor_enabled": {}, + "time_since_update": {}, + "num_stale_updates": {}, + "raw_location": {}, + "raw_location_time": {}, + "raw_location_sensor": 1, + "raw_location_accuracy": {}, + "supplemental_location": {}, + "supplemental_location_time": {}, + "supplemental_location_sensor": 1, + "supplemental_location_accuracy": {}, + "road_snapped": True, }, + "navigation_status": 1, + "current_route_segment": b"current_route_segment_blob", + "current_route_segment_end_point": {}, + "remaining_distance_meters": {}, + "remaining_duration": {"seconds": 751, "nanos": 543}, + "remaining_vehicle_journey_segments": [ + { + "stop": { + "planned_location": {"point": {}}, + "tasks": [ + { + "task_id": "task_id_value", + "task_duration": {}, + "target_time_window": {"start_time": {}, "end_time": {}}, + } + ], + "state": 1, + }, + "driving_distance_meters": {}, + "driving_duration": {}, + "path": {}, + } + ], "attributes": [ { "key": "key_value", + "value": "value_value", "string_value": "string_value_value", "bool_value": True, "number_value": 0.1285, } ], + "type_": 1, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = delivery_api.CreateTaskRequest.meta.fields["task"] + test_field = delivery_api.CreateDeliveryVehicleRequest.meta.fields[ + "delivery_vehicle" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -6779,7 +7831,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["task"].items(): # pragma: NO COVER + for field, value in request_init["delivery_vehicle"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -6809,204 +7861,174 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["task"][field])): - del request_init["task"][field][i][subfield] + for i in range(0, len(request_init["delivery_vehicle"][field])): + del request_init["delivery_vehicle"][field][i][subfield] else: - del request_init["task"][field][subfield] + del request_init["delivery_vehicle"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tasks.Task( + return_value = delivery_vehicles.DeliveryVehicle( name="name_value", - type_=tasks.Task.Type.PICKUP, - state=tasks.Task.State.OPEN, - task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, - task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, - tracking_id="tracking_id_value", - delivery_vehicle_id="delivery_vehicle_id_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) + return_value = delivery_vehicles.DeliveryVehicle.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_task(request) + response = client.create_delivery_vehicle(request) # Establish that the response is the type that we expect. - assert isinstance(response, tasks.Task) + assert isinstance(response, delivery_vehicles.DeliveryVehicle) assert response.name == "name_value" - assert response.type_ == tasks.Task.Type.PICKUP - assert response.state == tasks.Task.State.OPEN - assert response.task_outcome == tasks.Task.TaskOutcome.SUCCEEDED assert ( - response.task_outcome_location_source - == tasks.Task.TaskOutcomeLocationSource.PROVIDER + response.navigation_status == common.DeliveryVehicleNavigationStatus.NO_GUIDANCE ) - assert response.tracking_id == "tracking_id_value" - assert response.delivery_vehicle_id == "delivery_vehicle_id_value" - - -def test_create_task_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + assert response.current_route_segment == b"current_route_segment_blob" + assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - # Ensure method has been cached - assert client._transport.create_task in client._transport._wrapped_methods +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_delivery_vehicle_rest_interceptors(null_interceptor): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeliveryServiceRestInterceptor(), + ) + client = DeliveryServiceClient(transport=transport) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "post_create_delivery_vehicle" + ) as post, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "pre_create_delivery_vehicle" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = delivery_api.CreateDeliveryVehicleRequest.pb( + delivery_api.CreateDeliveryVehicleRequest() ) - client._transport._wrapped_methods[client._transport.create_task] = mock_rpc - - request = {} - client.create_task(request) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = delivery_vehicles.DeliveryVehicle.to_json( + delivery_vehicles.DeliveryVehicle() + ) + req.return_value.content = return_value - client.create_task(request) + request = delivery_api.CreateDeliveryVehicleRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = delivery_vehicles.DeliveryVehicle() - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 + client.create_delivery_vehicle( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + pre.assert_called_once() + post.assert_called_once() -def test_create_task_rest_required_fields(request_type=delivery_api.CreateTaskRequest): - transport_class = transports.DeliveryServiceRestTransport - request_init = {} - request_init["parent"] = "" - request_init["task_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +def test_get_delivery_vehicle_rest_bad_request( + request_type=delivery_api.GetDeliveryVehicleRequest, +): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "providers/sample1/deliveryVehicles/sample2"} + request = request_type(**request_init) - # verify fields with default values are dropped - assert "taskId" not in jsonified_request - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_task._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "taskId" in jsonified_request - assert jsonified_request["taskId"] == request_init["task_id"] - - jsonified_request["parent"] = "parent_value" - jsonified_request["taskId"] = "task_id_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_task._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "header", - "task_id", - ) - ) - jsonified_request.update(unset_fields) + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_delivery_vehicle(request) - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "taskId" in jsonified_request - assert jsonified_request["taskId"] == "task_id_value" +@pytest.mark.parametrize( + "request_type", + [ + delivery_api.GetDeliveryVehicleRequest, + dict, + ], +) +def test_get_delivery_vehicle_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + + # send a request that will satisfy transcoding + request_init = {"name": "providers/sample1/deliveryVehicles/sample2"} request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = tasks.Task() # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.create_task(request) - - expected_params = [ - ( - "taskId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_create_task_rest_unset_required_fields(): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = delivery_vehicles.DeliveryVehicle.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_delivery_vehicle(request) - unset_fields = transport.create_task._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "header", - "taskId", - ) - ) - & set( - ( - "parent", - "taskId", - "task", - ) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, delivery_vehicles.DeliveryVehicle) + assert response.name == "name_value" + assert ( + response.navigation_status == common.DeliveryVehicleNavigationStatus.NO_GUIDANCE ) + assert response.current_route_segment == b"current_route_segment_blob" + assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_task_rest_interceptors(null_interceptor): +def test_get_delivery_vehicle_rest_interceptors(null_interceptor): transport = transports.DeliveryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -7014,18 +8036,21 @@ def test_create_task_rest_interceptors(null_interceptor): else transports.DeliveryServiceRestInterceptor(), ) client = DeliveryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_create_task" + transports.DeliveryServiceRestInterceptor, "post_get_delivery_vehicle" ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_create_task" + transports.DeliveryServiceRestInterceptor, "pre_get_delivery_vehicle" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = delivery_api.CreateTaskRequest.pb(delivery_api.CreateTaskRequest()) + pb_message = delivery_api.GetDeliveryVehicleRequest.pb( + delivery_api.GetDeliveryVehicleRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -7033,20 +8058,22 @@ def test_create_task_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = tasks.Task.to_json(tasks.Task()) + return_value = delivery_vehicles.DeliveryVehicle.to_json( + delivery_vehicles.DeliveryVehicle() + ) + req.return_value.content = return_value - request = delivery_api.CreateTaskRequest() + request = delivery_api.GetDeliveryVehicleRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = tasks.Task() + post.return_value = delivery_vehicles.DeliveryVehicle() - client.create_task( + client.get_delivery_vehicle( request, metadata=[ ("key", "val"), @@ -7058,16 +8085,16 @@ def test_create_task_rest_interceptors(null_interceptor): post.assert_called_once() -def test_create_task_rest_bad_request( - transport: str = "rest", request_type=delivery_api.CreateTaskRequest +def test_update_delivery_vehicle_rest_bad_request( + request_type=delivery_api.UpdateDeliveryVehicleRequest, ): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} + request_init = { + "delivery_vehicle": {"name": "providers/sample1/deliveryVehicles/sample2"} + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -7075,254 +8102,201 @@ def test_create_task_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_task(request) - - -def test_create_task_rest_flattened(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = tasks.Task() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "providers/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - task=tasks.Task(name="name_value"), - task_id="task_id_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.request = mock.Mock() req.return_value = response_value - - client.create_task(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=providers/*}/tasks" % client.transport._host, args[1] - ) - - -def test_create_task_rest_flattened_error(transport: str = "rest"): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_task( - delivery_api.CreateTaskRequest(), - parent="parent_value", - task=tasks.Task(name="name_value"), - task_id="task_id_value", - ) - - -def test_create_task_rest_error(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) + client.update_delivery_vehicle(request) @pytest.mark.parametrize( "request_type", [ - delivery_api.GetTaskRequest, + delivery_api.UpdateDeliveryVehicleRequest, dict, ], ) -def test_get_task_rest(request_type): +def test_update_delivery_vehicle_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "providers/sample1/tasks/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = tasks.Task( - name="name_value", - type_=tasks.Task.Type.PICKUP, - state=tasks.Task.State.OPEN, - task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, - task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, - tracking_id="tracking_id_value", - delivery_vehicle_id="delivery_vehicle_id_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_task(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, tasks.Task) - assert response.name == "name_value" - assert response.type_ == tasks.Task.Type.PICKUP - assert response.state == tasks.Task.State.OPEN - assert response.task_outcome == tasks.Task.TaskOutcome.SUCCEEDED - assert ( - response.task_outcome_location_source - == tasks.Task.TaskOutcomeLocationSource.PROVIDER - ) - assert response.tracking_id == "tracking_id_value" - assert response.delivery_vehicle_id == "delivery_vehicle_id_value" - - -def test_get_task_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_task in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.get_task] = mock_rpc - - request = {} - client.get_task(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_task(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - + request_init = { + "delivery_vehicle": {"name": "providers/sample1/deliveryVehicles/sample2"} + } + request_init["delivery_vehicle"] = { + "name": "providers/sample1/deliveryVehicles/sample2", + "last_location": { + "location": {"latitude": 0.86, "longitude": 0.971}, + "horizontal_accuracy": {"value": 0.541}, + "latlng_accuracy": {}, + "heading": {"value": 541}, + "bearing_accuracy": {}, + "heading_accuracy": {}, + "altitude": {}, + "vertical_accuracy": {}, + "altitude_accuracy": {}, + "speed_kmph": {}, + "speed": {}, + "speed_accuracy": {}, + "update_time": {"seconds": 751, "nanos": 543}, + "server_time": {}, + "location_sensor": 1, + "is_road_snapped": {"value": True}, + "is_gps_sensor_enabled": {}, + "time_since_update": {}, + "num_stale_updates": {}, + "raw_location": {}, + "raw_location_time": {}, + "raw_location_sensor": 1, + "raw_location_accuracy": {}, + "supplemental_location": {}, + "supplemental_location_time": {}, + "supplemental_location_sensor": 1, + "supplemental_location_accuracy": {}, + "road_snapped": True, + }, + "navigation_status": 1, + "current_route_segment": b"current_route_segment_blob", + "current_route_segment_end_point": {}, + "remaining_distance_meters": {}, + "remaining_duration": {"seconds": 751, "nanos": 543}, + "remaining_vehicle_journey_segments": [ + { + "stop": { + "planned_location": {"point": {}}, + "tasks": [ + { + "task_id": "task_id_value", + "task_duration": {}, + "target_time_window": {"start_time": {}, "end_time": {}}, + } + ], + "state": 1, + }, + "driving_distance_meters": {}, + "driving_duration": {}, + "path": {}, + } + ], + "attributes": [ + { + "key": "key_value", + "value": "value_value", + "string_value": "string_value_value", + "bool_value": True, + "number_value": 0.1285, + } + ], + "type_": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 -def test_get_task_rest_required_fields(request_type=delivery_api.GetTaskRequest): - transport_class = transports.DeliveryServiceRestTransport + # Determine if the message type is proto-plus or protobuf + test_field = delivery_api.UpdateDeliveryVehicleRequest.meta.fields[ + "delivery_vehicle" + ] - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - # verify fields with default values are dropped + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_task._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields - # verify required fields with default values are now present + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] - jsonified_request["name"] = "name_value" + subfields_not_in_runtime = [] - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_task._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("header",)) - jsonified_request.update(unset_fields) + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["delivery_vehicle"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["delivery_vehicle"][field])): + del request_init["delivery_vehicle"][field][i][subfield] + else: + del request_init["delivery_vehicle"][field][subfield] request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = tasks.Task() # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_task(request) + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = delivery_vehicles.DeliveryVehicle( + name="name_value", + navigation_status=common.DeliveryVehicleNavigationStatus.NO_GUIDANCE, + current_route_segment=b"current_route_segment_blob", + type_=delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO, + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = delivery_vehicles.DeliveryVehicle.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_delivery_vehicle(request) -def test_get_task_rest_unset_required_fields(): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials + # Establish that the response is the type that we expect. + assert isinstance(response, delivery_vehicles.DeliveryVehicle) + assert response.name == "name_value" + assert ( + response.navigation_status == common.DeliveryVehicleNavigationStatus.NO_GUIDANCE ) - - unset_fields = transport.get_task._get_unset_required_fields({}) - assert set(unset_fields) == (set(("header",)) & set(("name",))) + assert response.current_route_segment == b"current_route_segment_blob" + assert response.type_ == delivery_vehicles.DeliveryVehicle.DeliveryVehicleType.AUTO @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_task_rest_interceptors(null_interceptor): +def test_update_delivery_vehicle_rest_interceptors(null_interceptor): transport = transports.DeliveryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -7330,18 +8304,21 @@ def test_get_task_rest_interceptors(null_interceptor): else transports.DeliveryServiceRestInterceptor(), ) client = DeliveryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_get_task" + transports.DeliveryServiceRestInterceptor, "post_update_delivery_vehicle" ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_get_task" + transports.DeliveryServiceRestInterceptor, "pre_update_delivery_vehicle" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = delivery_api.GetTaskRequest.pb(delivery_api.GetTaskRequest()) + pb_message = delivery_api.UpdateDeliveryVehicleRequest.pb( + delivery_api.UpdateDeliveryVehicleRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -7349,20 +8326,22 @@ def test_get_task_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = tasks.Task.to_json(tasks.Task()) + return_value = delivery_vehicles.DeliveryVehicle.to_json( + delivery_vehicles.DeliveryVehicle() + ) + req.return_value.content = return_value - request = delivery_api.GetTaskRequest() + request = delivery_api.UpdateDeliveryVehicleRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = tasks.Task() + post.return_value = delivery_vehicles.DeliveryVehicle() - client.get_task( + client.update_delivery_vehicle( request, metadata=[ ("key", "val"), @@ -7374,16 +8353,14 @@ def test_get_task_rest_interceptors(null_interceptor): post.assert_called_once() -def test_get_task_rest_bad_request( - transport: str = "rest", request_type=delivery_api.GetTaskRequest +def test_batch_create_tasks_rest_bad_request( + request_type=delivery_api.BatchCreateTasksRequest, ): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"name": "providers/sample1/tasks/sample2"} + request_init = {"parent": "providers/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -7391,91 +8368,147 @@ def test_get_task_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value - client.get_task(request) + client.batch_create_tasks(request) -def test_get_task_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + delivery_api.BatchCreateTasksRequest, + dict, + ], +) +def test_batch_create_tasks_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = tasks.Task() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "providers/sample1/tasks/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + return_value = delivery_api.BatchCreateTasksResponse() # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) + return_value = delivery_api.BatchCreateTasksResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.batch_create_tasks(request) - client.get_task(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=providers/*/tasks/*}" % client.transport._host, args[1] - ) + # Establish that the response is the type that we expect. + assert isinstance(response, delivery_api.BatchCreateTasksResponse) -def test_get_task_rest_flattened_error(transport: str = "rest"): - client = DeliveryServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_tasks_rest_interceptors(null_interceptor): + transport = transports.DeliveryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.DeliveryServiceRestInterceptor(), ) + client = DeliveryServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "post_batch_create_tasks" + ) as post, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "pre_batch_create_tasks" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = delivery_api.BatchCreateTasksRequest.pb( + delivery_api.BatchCreateTasksRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = delivery_api.BatchCreateTasksResponse.to_json( + delivery_api.BatchCreateTasksResponse() + ) + req.return_value.content = return_value + + request = delivery_api.BatchCreateTasksRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = delivery_api.BatchCreateTasksResponse() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_task( - delivery_api.GetTaskRequest(), - name="name_value", + client.batch_create_tasks( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() + -def test_get_task_rest_error(): +def test_create_task_rest_bad_request(request_type=delivery_api.CreateTaskRequest): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_task(request) @pytest.mark.parametrize( "request_type", [ - delivery_api.UpdateTaskRequest, + delivery_api.CreateTaskRequest, dict, ], ) -def test_update_task_rest(request_type): +def test_create_task_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"task": {"name": "providers/sample1/tasks/sample2"}} + request_init = {"parent": "providers/sample1"} request_init["task"] = { - "name": "providers/sample1/tasks/sample2", + "name": "name_value", "type_": 1, "state": 1, "task_outcome": 1, @@ -7566,7 +8599,7 @@ def test_update_task_rest(request_type): # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = delivery_api.UpdateTaskRequest.meta.fields["task"] + test_field = delivery_api.CreateTaskRequest.meta.fields["task"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -7644,15 +8677,15 @@ def get_message_fields(field): ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = tasks.Task.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_task(request) + response = client.create_task(request) # Establish that the response is the type that we expect. assert isinstance(response, tasks.Task) @@ -7668,141 +8701,8 @@ def get_message_fields(field): assert response.delivery_vehicle_id == "delivery_vehicle_id_value" -def test_update_task_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_task in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.update_task] = mock_rpc - - request = {} - client.update_task(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_task(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_task_rest_required_fields(request_type=delivery_api.UpdateTaskRequest): - transport_class = transports.DeliveryServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_task._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_task._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "header", - "update_mask", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = tasks.Task() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.update_task(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_update_task_rest_unset_required_fields(): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.update_task._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "header", - "updateMask", - ) - ) - & set( - ( - "task", - "updateMask", - ) - ) - ) - - @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_task_rest_interceptors(null_interceptor): +def test_create_task_rest_interceptors(null_interceptor): transport = transports.DeliveryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -7810,317 +8710,129 @@ def test_update_task_rest_interceptors(null_interceptor): else transports.DeliveryServiceRestInterceptor(), ) client = DeliveryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_update_task" + transports.DeliveryServiceRestInterceptor, "post_create_task" ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_update_task" + transports.DeliveryServiceRestInterceptor, "pre_create_task" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = delivery_api.UpdateTaskRequest.pb(delivery_api.UpdateTaskRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = tasks.Task.to_json(tasks.Task()) - - request = delivery_api.UpdateTaskRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = tasks.Task() - - client.update_task( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_task_rest_bad_request( - transport: str = "rest", request_type=delivery_api.UpdateTaskRequest -): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"task": {"name": "providers/sample1/tasks/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_task(request) - - -def test_update_task_rest_flattened(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = tasks.Task() - - # get arguments that satisfy an http rule for this method - sample_request = {"task": {"name": "providers/sample1/tasks/sample2"}} - - # get truthy value for each flattened field - mock_args = dict( - task=tasks.Task(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) + pb_message = delivery_api.CreateTaskRequest.pb(delivery_api.CreateTaskRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = tasks.Task.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = tasks.Task.to_json(tasks.Task()) + req.return_value.content = return_value - client.update_task(**mock_args) + request = delivery_api.CreateTaskRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = tasks.Task() - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{task.name=providers/*/tasks/*}" % client.transport._host, args[1] + client.create_task( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - -def test_update_task_rest_flattened_error(transport: str = "rest"): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_task( - delivery_api.UpdateTaskRequest(), - task=tasks.Task(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + pre.assert_called_once() + post.assert_called_once() -def test_update_task_rest_error(): +def test_get_task_rest_bad_request(request_type=delivery_api.GetTaskRequest): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "providers/sample1/tasks/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_task(request) @pytest.mark.parametrize( "request_type", [ - delivery_api.ListTasksRequest, + delivery_api.GetTaskRequest, dict, ], ) -def test_list_tasks_rest(request_type): +def test_get_task_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} + request_init = {"name": "providers/sample1/tasks/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = delivery_api.ListTasksResponse( - next_page_token="next_page_token_value", - total_size=1086, + return_value = tasks.Task( + name="name_value", + type_=tasks.Task.Type.PICKUP, + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = delivery_api.ListTasksResponse.pb(return_value) + return_value = tasks.Task.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_tasks(request) + response = client.get_task(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListTasksPager) - assert response.next_page_token == "next_page_token_value" - assert response.total_size == 1086 - - -def test_list_tasks_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_tasks in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.list_tasks] = mock_rpc - - request = {} - client.list_tasks(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_tasks(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_tasks_rest_required_fields(request_type=delivery_api.ListTasksRequest): - transport_class = transports.DeliveryServiceRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_tasks._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_tasks._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "header", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = delivery_api.ListTasksResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = delivery_api.ListTasksResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.list_tasks(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_tasks_rest_unset_required_fields(): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_tasks._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "header", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) + assert isinstance(response, tasks.Task) + assert response.name == "name_value" + assert response.type_ == tasks.Task.Type.PICKUP + assert response.state == tasks.Task.State.OPEN + assert response.task_outcome == tasks.Task.TaskOutcome.SUCCEEDED + assert ( + response.task_outcome_location_source + == tasks.Task.TaskOutcomeLocationSource.PROVIDER ) + assert response.tracking_id == "tracking_id_value" + assert response.delivery_vehicle_id == "delivery_vehicle_id_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_tasks_rest_interceptors(null_interceptor): +def test_get_task_rest_interceptors(null_interceptor): transport = transports.DeliveryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -8128,18 +8840,19 @@ def test_list_tasks_rest_interceptors(null_interceptor): else transports.DeliveryServiceRestInterceptor(), ) client = DeliveryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_list_tasks" + transports.DeliveryServiceRestInterceptor, "post_get_task" ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_list_tasks" + transports.DeliveryServiceRestInterceptor, "pre_get_task" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = delivery_api.ListTasksRequest.pb(delivery_api.ListTasksRequest()) + pb_message = delivery_api.GetTaskRequest.pb(delivery_api.GetTaskRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -8147,22 +8860,20 @@ def test_list_tasks_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = delivery_api.ListTasksResponse.to_json( - delivery_api.ListTasksResponse() - ) + return_value = tasks.Task.to_json(tasks.Task()) + req.return_value.content = return_value - request = delivery_api.ListTasksRequest() + request = delivery_api.GetTaskRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = delivery_api.ListTasksResponse() + post.return_value = tasks.Task() - client.list_tasks( + client.get_task( request, metadata=[ ("key", "val"), @@ -8174,16 +8885,12 @@ def test_list_tasks_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_tasks_rest_bad_request( - transport: str = "rest", request_type=delivery_api.ListTasksRequest -): +def test_update_task_rest_bad_request(request_type=delivery_api.UpdateTaskRequest): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} + request_init = {"task": {"name": "providers/sample1/tasks/sample2"}} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -8191,303 +8898,342 @@ def test_list_tasks_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_tasks(request) - - -def test_list_tasks_rest_flattened(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = delivery_api.ListTasksResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "providers/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = delivery_api.ListTasksResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.request = mock.Mock() req.return_value = response_value - - client.list_tasks(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=providers/*}/tasks" % client.transport._host, args[1] - ) - - -def test_list_tasks_rest_flattened_error(transport: str = "rest"): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_tasks( - delivery_api.ListTasksRequest(), - parent="parent_value", - ) + client.update_task(request) -def test_list_tasks_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + delivery_api.UpdateTaskRequest, + dict, + ], +) +def test_update_task_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - delivery_api.ListTasksResponse( - tasks=[ - tasks.Task(), - tasks.Task(), - tasks.Task(), - ], - next_page_token="abc", - ), - delivery_api.ListTasksResponse( - tasks=[], - next_page_token="def", - ), - delivery_api.ListTasksResponse( - tasks=[ - tasks.Task(), - ], - next_page_token="ghi", - ), - delivery_api.ListTasksResponse( - tasks=[ - tasks.Task(), - tasks.Task(), - ], - ), - ) - # Two responses for two calls - response = response + response + # send a request that will satisfy transcoding + request_init = {"task": {"name": "providers/sample1/tasks/sample2"}} + request_init["task"] = { + "name": "providers/sample1/tasks/sample2", + "type_": 1, + "state": 1, + "task_outcome": 1, + "task_outcome_time": {"seconds": 751, "nanos": 543}, + "task_outcome_location": {"point": {"latitude": 0.86, "longitude": 0.971}}, + "task_outcome_location_source": 2, + "tracking_id": "tracking_id_value", + "delivery_vehicle_id": "delivery_vehicle_id_value", + "planned_location": {}, + "task_duration": {"seconds": 751, "nanos": 543}, + "target_time_window": {"start_time": {}, "end_time": {}}, + "journey_sharing_info": { + "remaining_vehicle_journey_segments": [ + { + "stop": { + "planned_location": {}, + "tasks": [ + { + "task_id": "task_id_value", + "task_duration": {}, + "target_time_window": {}, + } + ], + "state": 1, + }, + "driving_distance_meters": {"value": 541}, + "driving_duration": {}, + "path": {}, + } + ], + "last_location": { + "location": {}, + "horizontal_accuracy": {"value": 0.541}, + "latlng_accuracy": {}, + "heading": {}, + "bearing_accuracy": {}, + "heading_accuracy": {}, + "altitude": {}, + "vertical_accuracy": {}, + "altitude_accuracy": {}, + "speed_kmph": {}, + "speed": {}, + "speed_accuracy": {}, + "update_time": {}, + "server_time": {}, + "location_sensor": 1, + "is_road_snapped": {"value": True}, + "is_gps_sensor_enabled": {}, + "time_since_update": {}, + "num_stale_updates": {}, + "raw_location": {}, + "raw_location_time": {}, + "raw_location_sensor": 1, + "raw_location_accuracy": {}, + "supplemental_location": {}, + "supplemental_location_time": {}, + "supplemental_location_sensor": 1, + "supplemental_location_accuracy": {}, + "road_snapped": True, + }, + "last_location_snappable": True, + }, + "task_tracking_view_config": { + "route_polyline_points_visibility": { + "remaining_stop_count_threshold": 3219, + "duration_until_estimated_arrival_time_threshold": {}, + "remaining_driving_distance_meters_threshold": 4561, + "always": True, + "never": True, + }, + "estimated_arrival_time_visibility": {}, + "estimated_task_completion_time_visibility": {}, + "remaining_driving_distance_visibility": {}, + "remaining_stop_count_visibility": {}, + "vehicle_location_visibility": {}, + }, + "attributes": [ + { + "key": "key_value", + "string_value": "string_value_value", + "bool_value": True, + "number_value": 0.1285, + } + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 - # Wrap the values into proper Response objs - response = tuple(delivery_api.ListTasksResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Determine if the message type is proto-plus or protobuf + test_field = delivery_api.UpdateTaskRequest.meta.fields["task"] - sample_request = {"parent": "providers/sample1"} + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - pager = client.list_tasks(request=sample_request) + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, tasks.Task) for i in results) + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields - pages = list(client.list_tasks(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + subfields_not_in_runtime = [] -@pytest.mark.parametrize( - "request_type", - [ - delivery_api.GetTaskTrackingInfoRequest, - dict, - ], -) -def test_get_task_tracking_info_rest(request_type): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["task"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value - # send a request that will satisfy transcoding - request_init = {"name": "providers/sample1/taskTrackingInfo/sample2"} + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["task"][field])): + del request_init["task"][field][i][subfield] + else: + del request_init["task"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = task_tracking_info.TaskTrackingInfo( + return_value = tasks.Task( name="name_value", - tracking_id="tracking_id_value", + type_=tasks.Task.Type.PICKUP, state=tasks.Task.State.OPEN, task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, + task_outcome_location_source=tasks.Task.TaskOutcomeLocationSource.PROVIDER, + tracking_id="tracking_id_value", + delivery_vehicle_id="delivery_vehicle_id_value", ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = task_tracking_info.TaskTrackingInfo.pb(return_value) + return_value = tasks.Task.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_task_tracking_info(request) + response = client.update_task(request) # Establish that the response is the type that we expect. - assert isinstance(response, task_tracking_info.TaskTrackingInfo) + assert isinstance(response, tasks.Task) assert response.name == "name_value" - assert response.tracking_id == "tracking_id_value" + assert response.type_ == tasks.Task.Type.PICKUP assert response.state == tasks.Task.State.OPEN assert response.task_outcome == tasks.Task.TaskOutcome.SUCCEEDED + assert ( + response.task_outcome_location_source + == tasks.Task.TaskOutcomeLocationSource.PROVIDER + ) + assert response.tracking_id == "tracking_id_value" + assert response.delivery_vehicle_id == "delivery_vehicle_id_value" -def test_get_task_tracking_info_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.get_task_tracking_info - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.get_task_tracking_info - ] = mock_rpc - - request = {} - client.get_task_tracking_info(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_task_tracking_info(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_task_tracking_info_rest_required_fields( - request_type=delivery_api.GetTaskTrackingInfoRequest, -): - transport_class = transports.DeliveryServiceRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_task_rest_interceptors(null_interceptor): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeliveryServiceRestInterceptor(), ) + client = DeliveryServiceClient(transport=transport) - # verify fields with default values are dropped + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "post_update_task" + ) as post, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "pre_update_task" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = delivery_api.UpdateTaskRequest.pb(delivery_api.UpdateTaskRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_task_tracking_info._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = tasks.Task.to_json(tasks.Task()) + req.return_value.content = return_value - # verify required fields with default values are now present + request = delivery_api.UpdateTaskRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = tasks.Task() - jsonified_request["name"] = "name_value" + client.update_task( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_task_tracking_info._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("header",)) - jsonified_request.update(unset_fields) + pre.assert_called_once() + post.assert_called_once() - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_list_tasks_rest_bad_request(request_type=delivery_api.ListTasksRequest): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = task_tracking_info.TaskTrackingInfo() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_tasks(request) - # Convert return value to protobuf type - return_value = task_tracking_info.TaskTrackingInfo.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value +@pytest.mark.parametrize( + "request_type", + [ + delivery_api.ListTasksRequest, + dict, + ], +) +def test_list_tasks_rest_call_success(request_type): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - response = client.get_task_tracking_info(request) + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} + request = request_type(**request_init) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = delivery_api.ListTasksResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_get_task_tracking_info_rest_unset_required_fields(): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = delivery_api.ListTasksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_tasks(request) - unset_fields = transport.get_task_tracking_info._get_unset_required_fields({}) - assert set(unset_fields) == (set(("header",)) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTasksPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_task_tracking_info_rest_interceptors(null_interceptor): +def test_list_tasks_rest_interceptors(null_interceptor): transport = transports.DeliveryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -8495,20 +9241,19 @@ def test_get_task_tracking_info_rest_interceptors(null_interceptor): else transports.DeliveryServiceRestInterceptor(), ) client = DeliveryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "post_get_task_tracking_info" + transports.DeliveryServiceRestInterceptor, "post_list_tasks" ) as post, mock.patch.object( - transports.DeliveryServiceRestInterceptor, "pre_get_task_tracking_info" + transports.DeliveryServiceRestInterceptor, "pre_list_tasks" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = delivery_api.GetTaskTrackingInfoRequest.pb( - delivery_api.GetTaskTrackingInfoRequest() - ) + pb_message = delivery_api.ListTasksRequest.pb(delivery_api.ListTasksRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -8516,22 +9261,22 @@ def test_get_task_tracking_info_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = task_tracking_info.TaskTrackingInfo.to_json( - task_tracking_info.TaskTrackingInfo() + return_value = delivery_api.ListTasksResponse.to_json( + delivery_api.ListTasksResponse() ) + req.return_value.content = return_value - request = delivery_api.GetTaskTrackingInfoRequest() + request = delivery_api.ListTasksRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = task_tracking_info.TaskTrackingInfo() + post.return_value = delivery_api.ListTasksResponse() - client.get_task_tracking_info( + client.list_tasks( request, metadata=[ ("key", "val"), @@ -8544,13 +9289,11 @@ def test_get_task_tracking_info_rest_interceptors(null_interceptor): def test_get_task_tracking_info_rest_bad_request( - transport: str = "rest", request_type=delivery_api.GetTaskTrackingInfoRequest + request_type=delivery_api.GetTaskTrackingInfoRequest, ): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "providers/sample1/taskTrackingInfo/sample2"} request = request_type(**request_init) @@ -8560,260 +9303,181 @@ def test_get_task_tracking_info_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.get_task_tracking_info(request) -def test_get_task_tracking_info_rest_flattened(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = task_tracking_info.TaskTrackingInfo() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "providers/sample1/taskTrackingInfo/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = task_tracking_info.TaskTrackingInfo.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_task_tracking_info(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=providers/*/taskTrackingInfo/*}" % client.transport._host, - args[1], - ) - - -def test_get_task_tracking_info_rest_flattened_error(transport: str = "rest"): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_task_tracking_info( - delivery_api.GetTaskTrackingInfoRequest(), - name="name_value", - ) - - -def test_get_task_tracking_info_rest_error(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - @pytest.mark.parametrize( "request_type", [ - delivery_api.ListDeliveryVehiclesRequest, + delivery_api.GetTaskTrackingInfoRequest, dict, ], ) -def test_list_delivery_vehicles_rest(request_type): +def test_get_task_tracking_info_rest_call_success(request_type): client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} + request_init = {"name": "providers/sample1/taskTrackingInfo/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = delivery_api.ListDeliveryVehiclesResponse( - next_page_token="next_page_token_value", - total_size=1086, + return_value = task_tracking_info.TaskTrackingInfo( + name="name_value", + tracking_id="tracking_id_value", + state=tasks.Task.State.OPEN, + task_outcome=tasks.Task.TaskOutcome.SUCCEEDED, ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = delivery_api.ListDeliveryVehiclesResponse.pb(return_value) + return_value = task_tracking_info.TaskTrackingInfo.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_delivery_vehicles(request) + response = client.get_task_tracking_info(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDeliveryVehiclesPager) - assert response.next_page_token == "next_page_token_value" - assert response.total_size == 1086 - - -def test_list_delivery_vehicles_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.list_delivery_vehicles - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.list_delivery_vehicles - ] = mock_rpc - - request = {} - client.list_delivery_vehicles(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_delivery_vehicles(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - + assert isinstance(response, task_tracking_info.TaskTrackingInfo) + assert response.name == "name_value" + assert response.tracking_id == "tracking_id_value" + assert response.state == tasks.Task.State.OPEN + assert response.task_outcome == tasks.Task.TaskOutcome.SUCCEEDED -def test_list_delivery_vehicles_rest_required_fields( - request_type=delivery_api.ListDeliveryVehiclesRequest, -): - transport_class = transports.DeliveryServiceRestTransport - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_task_tracking_info_rest_interceptors(null_interceptor): + transport = transports.DeliveryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeliveryServiceRestInterceptor(), ) + client = DeliveryServiceClient(transport=transport) - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_delivery_vehicles._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_delivery_vehicles._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "header", - "page_size", - "page_token", - "viewport", + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "post_get_task_tracking_info" + ) as post, mock.patch.object( + transports.DeliveryServiceRestInterceptor, "pre_get_task_tracking_info" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = delivery_api.GetTaskTrackingInfoRequest.pb( + delivery_api.GetTaskTrackingInfoRequest() ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # Designate an appropriate value for the returned response. - return_value = delivery_api.ListDeliveryVehiclesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = task_tracking_info.TaskTrackingInfo.to_json( + task_tracking_info.TaskTrackingInfo() + ) + req.return_value.content = return_value - response_value = Response() - response_value.status_code = 200 + request = delivery_api.GetTaskTrackingInfoRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = task_tracking_info.TaskTrackingInfo() - # Convert return value to protobuf type - return_value = delivery_api.ListDeliveryVehiclesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + client.get_task_tracking_info( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + pre.assert_called_once() + post.assert_called_once() - response = client.list_delivery_vehicles(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params +def test_list_delivery_vehicles_rest_bad_request( + request_type=delivery_api.ListDeliveryVehiclesRequest, +): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_delivery_vehicles(request) -def test_list_delivery_vehicles_rest_unset_required_fields(): - transport = transports.DeliveryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials +@pytest.mark.parametrize( + "request_type", + [ + delivery_api.ListDeliveryVehiclesRequest, + dict, + ], +) +def test_list_delivery_vehicles_rest_call_success(request_type): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - unset_fields = transport.list_delivery_vehicles._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "header", - "pageSize", - "pageToken", - "viewport", - ) + # send a request that will satisfy transcoding + request_init = {"parent": "providers/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = delivery_api.ListDeliveryVehiclesResponse( + next_page_token="next_page_token_value", + total_size=1086, ) - & set(("parent",)) - ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = delivery_api.ListDeliveryVehiclesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_delivery_vehicles(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDeliveryVehiclesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -8825,6 +9489,7 @@ def test_list_delivery_vehicles_rest_interceptors(null_interceptor): else transports.DeliveryServiceRestInterceptor(), ) client = DeliveryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -8846,12 +9511,12 @@ def test_list_delivery_vehicles_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = delivery_api.ListDeliveryVehiclesResponse.to_json( + return_value = delivery_api.ListDeliveryVehiclesResponse.to_json( delivery_api.ListDeliveryVehiclesResponse() ) + req.return_value.content = return_value request = delivery_api.ListDeliveryVehiclesRequest() metadata = [ @@ -8873,253 +9538,481 @@ def test_list_delivery_vehicles_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_delivery_vehicles_rest_bad_request( - transport: str = "rest", request_type=delivery_api.ListDeliveryVehiclesRequest -): +def test_initialize_client_w_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_delivery_vehicle_empty_call_rest(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # send a request that will satisfy transcoding - request_init = {"parent": "providers/sample1"} - request = request_type(**request_init) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_delivery_vehicle), "__call__" + ) as call: + client.create_delivery_vehicle(request=None) - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_delivery_vehicles(request) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.CreateDeliveryVehicleRequest() + assert args[0] == request_msg -def test_list_delivery_vehicles_rest_flattened(): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_delivery_vehicle_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_delivery_vehicle), "__call__" + ) as call: + client.get_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_delivery_vehicle_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_delivery_vehicle), "__call__" + ) as call: + client.update_delivery_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.UpdateDeliveryVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_tasks_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tasks), "__call__" + ) as call: + client.batch_create_tasks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.BatchCreateTasksRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_task_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_task), "__call__") as call: + client.create_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.CreateTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_task_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_task), "__call__") as call: + client.get_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_task_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_task), "__call__") as call: + client.update_task(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.UpdateTaskRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_tasks_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: + client.list_tasks(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.ListTasksRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_task_tracking_info_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_task_tracking_info), "__call__" + ) as call: + client.get_task_tracking_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.GetTaskTrackingInfoRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_delivery_vehicles_empty_call_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_delivery_vehicles), "__call__" + ) as call: + client.list_delivery_vehicles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = delivery_api.ListDeliveryVehiclesRequest() + + assert args[0] == request_msg + + +def test_create_delivery_vehicle_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_delivery_vehicle), "__call__" + ) as call: + client.create_delivery_vehicle(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.CreateDeliveryVehicleRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_get_delivery_vehicle_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_delivery_vehicle), "__call__" + ) as call: + client.get_delivery_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetDeliveryVehicleRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_update_delivery_vehicle_routing_parameters_request_1_rest(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = delivery_api.ListDeliveryVehiclesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "providers/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_delivery_vehicle), "__call__" + ) as call: + client.update_delivery_vehicle( + request={"delivery_vehicle": {"name": "providers/sample1"}} ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = delivery_api.ListDeliveryVehiclesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.UpdateDeliveryVehicleRequest( + **{"delivery_vehicle": {"name": "providers/sample1"}} + ) - client.list_delivery_vehicles(**mock_args) + assert args[0] == request_msg - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=providers/*}/deliveryVehicles" % client.transport._host, - args[1], + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] ) -def test_list_delivery_vehicles_rest_flattened_error(transport: str = "rest"): +def test_batch_create_tasks_routing_parameters_request_1_rest(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_delivery_vehicles( - delivery_api.ListDeliveryVehiclesRequest(), - parent="parent_value", + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tasks), "__call__" + ) as call: + client.batch_create_tasks(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.BatchCreateTasksRequest( + **{"parent": "providers/sample1"} ) + assert args[0] == request_msg -def test_list_delivery_vehicles_rest_pager(transport: str = "rest"): + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_create_task_routing_parameters_request_1_rest(): client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - delivery_api.ListDeliveryVehiclesResponse( - delivery_vehicles=[ - delivery_vehicles.DeliveryVehicle(), - delivery_vehicles.DeliveryVehicle(), - delivery_vehicles.DeliveryVehicle(), - ], - next_page_token="abc", - ), - delivery_api.ListDeliveryVehiclesResponse( - delivery_vehicles=[], - next_page_token="def", - ), - delivery_api.ListDeliveryVehiclesResponse( - delivery_vehicles=[ - delivery_vehicles.DeliveryVehicle(), - ], - next_page_token="ghi", - ), - delivery_api.ListDeliveryVehiclesResponse( - delivery_vehicles=[ - delivery_vehicles.DeliveryVehicle(), - delivery_vehicles.DeliveryVehicle(), - ], - ), - ) - # Two responses for two calls - response = response + response + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_task), "__call__") as call: + client.create_task(request={"parent": "providers/sample1"}) - # Wrap the values into proper Response objs - response = tuple( - delivery_api.ListDeliveryVehiclesResponse.to_json(x) for x in response + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.CreateTaskRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - sample_request = {"parent": "providers/sample1"} - pager = client.list_delivery_vehicles(request=sample_request) +def test_get_task_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, delivery_vehicles.DeliveryVehicle) for i in results) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_task), "__call__") as call: + client.get_task(request={"name": "providers/sample1"}) - pages = list(client.list_delivery_vehicles(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetTaskRequest(**{"name": "providers/sample1"}) + assert args[0] == request_msg -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.DeliveryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.DeliveryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = DeliveryServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - # It is an error to provide an api_key and a transport instance. - transport = transports.DeliveryServiceGrpcTransport( +def test_update_task_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = DeliveryServiceClient( - client_options=options, - transport=transport, + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_task), "__call__") as call: + client.update_task(request={"task": {"name": "providers/sample1"}}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.UpdateTaskRequest( + **{"task": {"name": "providers/sample1"}} ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = DeliveryServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] ) - # It is an error to provide scopes and a transport instance. - transport = transports.DeliveryServiceGrpcTransport( + +def test_list_tasks_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = DeliveryServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tasks), "__call__") as call: + client.list_tasks(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.ListTasksRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] ) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.DeliveryServiceGrpcTransport( +def test_get_task_tracking_info_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = DeliveryServiceClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_task_tracking_info), "__call__" + ) as call: + client.get_task_tracking_info(request={"name": "providers/sample1"}) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.DeliveryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.GetTaskTrackingInfoRequest( + **{"name": "providers/sample1"} + ) - transport = transports.DeliveryServiceGrpcAsyncIOTransport( + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_list_delivery_vehicles_routing_parameters_request_1_rest(): + client = DeliveryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_delivery_vehicles), "__call__" + ) as call: + client.list_delivery_vehicles(request={"parent": "providers/sample1"}) -@pytest.mark.parametrize( - "transport_class", - [ - transports.DeliveryServiceGrpcTransport, - transports.DeliveryServiceGrpcAsyncIOTransport, - transports.DeliveryServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = delivery_api.ListDeliveryVehiclesRequest( + **{"parent": "providers/sample1"} + ) + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = DeliveryServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) def test_transport_grpc_default(): @@ -9776,36 +10669,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = DeliveryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = DeliveryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = DeliveryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/async_client.py b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/async_client.py index 2f9341d45df7..901f8da01f11 100644 --- a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/async_client.py +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/async_client.py @@ -318,11 +318,17 @@ async def sample_create_trip(): self._client._transport.create_trip ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -397,11 +403,17 @@ async def sample_get_trip(): # and friendly error handling. rpc = self._client._transport._wrapped_methods[self._client._transport.get_trip] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -472,11 +484,17 @@ async def sample_report_billable_trip(): self._client._transport.report_billable_trip ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -556,11 +574,17 @@ async def sample_search_trips(): self._client._transport.search_trips ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -648,11 +672,17 @@ async def sample_update_trip(): self._client._transport.update_trip ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/README.rst b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/README.rst new file mode 100644 index 000000000000..97675873407f --- /dev/null +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`TripServiceTransport` is the ABC for all transports. +- public child `TripServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `TripServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseTripServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `TripServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/grpc_asyncio.py b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/grpc_asyncio.py index 9082cbcda3a4..5be75436974d 100644 --- a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/grpc_asyncio.py +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/trip_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -373,7 +377,7 @@ def update_trip( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.create_trip: gapic_v1.method_async.wrap_method( + self.create_trip: self._wrap_method( self.create_trip, default_retry=retries.AsyncRetry( initial=1.0, @@ -387,7 +391,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.get_trip: gapic_v1.method_async.wrap_method( + self.get_trip: self._wrap_method( self.get_trip, default_retry=retries.AsyncRetry( initial=1.0, @@ -401,12 +405,12 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.report_billable_trip: gapic_v1.method_async.wrap_method( + self.report_billable_trip: self._wrap_method( self.report_billable_trip, default_timeout=None, client_info=client_info, ), - self.search_trips: gapic_v1.method_async.wrap_method( + self.search_trips: self._wrap_method( self.search_trips, default_retry=retries.AsyncRetry( initial=1.0, @@ -420,7 +424,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.update_trip: gapic_v1.method_async.wrap_method( + self.update_trip: self._wrap_method( self.update_trip, default_retry=retries.AsyncRetry( initial=1.0, @@ -436,8 +440,17 @@ def _prep_wrapped_messages(self, client_info): ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("TripServiceGrpcAsyncIOTransport",) diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/async_client.py b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/async_client.py index 19b447b14988..55f0e2fbbdb9 100644 --- a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/async_client.py +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/async_client.py @@ -349,11 +349,17 @@ async def sample_create_vehicle(): self._client._transport.create_vehicle ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -430,11 +436,17 @@ async def sample_get_vehicle(): self._client._transport.get_vehicle ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -528,11 +540,17 @@ async def sample_update_vehicle(): self._client._transport.update_vehicle ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -620,11 +638,17 @@ async def sample_update_vehicle_attributes(): self._client._transport.update_vehicle_attributes ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -708,11 +732,17 @@ async def sample_list_vehicles(): self._client._transport.list_vehicles ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() @@ -806,11 +836,17 @@ async def sample_search_vehicles(): self._client._transport.search_vehicles ] - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), - ) + header_params = {} + + routing_param_regex = re.compile("^(?Pproviders/[^/]+)$") + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("provider_id"): + header_params["provider_id"] = regex_match.group("provider_id") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) # Validate the universe domain. self._client._validate_universe_domain() diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/README.rst b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/README.rst new file mode 100644 index 000000000000..cab31a918dfd --- /dev/null +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`VehicleServiceTransport` is the ABC for all transports. +- public child `VehicleServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `VehicleServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseVehicleServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `VehicleServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/grpc_asyncio.py b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/grpc_asyncio.py index 28615e5f61e7..e22c75be1254 100644 --- a/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/grpc_asyncio.py +++ b/packages/google-maps-fleetengine/google/maps/fleetengine_v1/services/vehicle_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -459,7 +463,7 @@ def search_vehicles( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.create_vehicle: gapic_v1.method_async.wrap_method( + self.create_vehicle: self._wrap_method( self.create_vehicle, default_retry=retries.AsyncRetry( initial=1.0, @@ -473,7 +477,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.get_vehicle: gapic_v1.method_async.wrap_method( + self.get_vehicle: self._wrap_method( self.get_vehicle, default_retry=retries.AsyncRetry( initial=1.0, @@ -487,7 +491,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.update_vehicle: gapic_v1.method_async.wrap_method( + self.update_vehicle: self._wrap_method( self.update_vehicle, default_retry=retries.AsyncRetry( initial=1.0, @@ -501,7 +505,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.update_vehicle_attributes: gapic_v1.method_async.wrap_method( + self.update_vehicle_attributes: self._wrap_method( self.update_vehicle_attributes, default_retry=retries.AsyncRetry( initial=1.0, @@ -515,12 +519,12 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), - self.list_vehicles: gapic_v1.method_async.wrap_method( + self.list_vehicles: self._wrap_method( self.list_vehicles, default_timeout=None, client_info=client_info, ), - self.search_vehicles: gapic_v1.method_async.wrap_method( + self.search_vehicles: self._wrap_method( self.search_vehicles, default_retry=retries.AsyncRetry( initial=1.0, @@ -536,8 +540,17 @@ def _prep_wrapped_messages(self, client_info): ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("VehicleServiceGrpcAsyncIOTransport",) diff --git a/packages/google-maps-fleetengine/setup.py b/packages/google-maps-fleetengine/setup.py index 0b87b929373b..a133aad01d84 100644 --- a/packages/google-maps-fleetengine/setup.py +++ b/packages/google-maps-fleetengine/setup.py @@ -47,6 +47,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-geo-type >= 0.1.0, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-fleetengine" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -89,6 +90,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_trip_service.py b/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_trip_service.py index cfed72f2af3b..e753388e5c3d 100644 --- a/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_trip_service.py +++ b/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_trip_service.py @@ -24,8 +24,22 @@ import math +from google.api_core import api_core_version +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -37,11 +51,6 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore from google.type import latlng_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest from google.maps.fleetengine_v1.services.trip_service import ( TripServiceAsyncClient, @@ -58,10 +67,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1120,25 +1143,6 @@ def test_create_trip(request_type, transport: str = "grpc"): assert response.view == trips.TripView.SDK -def test_create_trip_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_trip), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.CreateTripRequest() - - def test_create_trip_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1204,37 +1208,6 @@ def test_create_trip_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_trip_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_trip), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - trips.Trip( - name="name_value", - vehicle_id="vehicle_id_value", - trip_status=trips.TripStatus.NEW, - trip_type=fleetengine.TripType.SHARED, - intermediate_destination_index=3187, - current_route_segment="current_route_segment_value", - number_of_passengers=2135, - last_location_snappable=True, - view=trips.TripView.SDK, - ) - ) - response = await client.create_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.CreateTripRequest() - - @pytest.mark.asyncio async def test_create_trip_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1243,7 +1216,7 @@ async def test_create_trip_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1282,7 +1255,7 @@ async def test_create_trip_async( transport: str = "grpc_asyncio", request_type=trip_api.CreateTripRequest ): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1332,30 +1305,6 @@ async def test_create_trip_async_from_dict(): await test_create_trip_async(request_type=dict) -def test_create_trip_routing_parameters(): - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = trip_api.CreateTripRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_trip), "__call__") as call: - call.return_value = trips.Trip() - client.create_trip(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -1408,25 +1357,6 @@ def test_get_trip(request_type, transport: str = "grpc"): assert response.view == trips.TripView.SDK -def test_get_trip_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_trip), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.GetTripRequest() - - def test_get_trip_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1490,44 +1420,13 @@ def test_get_trip_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_trip_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_trip), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - trips.Trip( - name="name_value", - vehicle_id="vehicle_id_value", - trip_status=trips.TripStatus.NEW, - trip_type=fleetengine.TripType.SHARED, - intermediate_destination_index=3187, - current_route_segment="current_route_segment_value", - number_of_passengers=2135, - last_location_snappable=True, - view=trips.TripView.SDK, - ) - ) - response = await client.get_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.GetTripRequest() - - @pytest.mark.asyncio async def test_get_trip_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1566,7 +1465,7 @@ async def test_get_trip_async( transport: str = "grpc_asyncio", request_type=trip_api.GetTripRequest ): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1616,30 +1515,6 @@ async def test_get_trip_async_from_dict(): await test_get_trip_async(request_type=dict) -def test_get_trip_routing_parameters(): - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = trip_api.GetTripRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_trip), "__call__") as call: - call.return_value = trips.Trip() - client.get_trip(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -1675,27 +1550,6 @@ def test_report_billable_trip(request_type, transport: str = "grpc"): assert response is None -def test_report_billable_trip_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.report_billable_trip), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.report_billable_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.ReportBillableTripRequest() - - def test_report_billable_trip_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1767,27 +1621,6 @@ def test_report_billable_trip_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_report_billable_trip_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.report_billable_trip), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.report_billable_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.ReportBillableTripRequest() - - @pytest.mark.asyncio async def test_report_billable_trip_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1796,7 +1629,7 @@ async def test_report_billable_trip_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1835,7 +1668,7 @@ async def test_report_billable_trip_async( transport: str = "grpc_asyncio", request_type=trip_api.ReportBillableTripRequest ): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1866,32 +1699,6 @@ async def test_report_billable_trip_async_from_dict(): await test_report_billable_trip_async(request_type=dict) -def test_report_billable_trip_routing_parameters(): - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = trip_api.ReportBillableTripRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.report_billable_trip), "__call__" - ) as call: - call.return_value = None - client.report_billable_trip(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -1928,25 +1735,6 @@ def test_search_trips(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_search_trips_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_trips), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.search_trips() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.SearchTripsRequest() - - def test_search_trips_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2014,29 +1802,6 @@ def test_search_trips_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_search_trips_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_trips), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - trip_api.SearchTripsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.search_trips() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.SearchTripsRequest() - - @pytest.mark.asyncio async def test_search_trips_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2045,7 +1810,7 @@ async def test_search_trips_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2084,7 +1849,7 @@ async def test_search_trips_async( transport: str = "grpc_asyncio", request_type=trip_api.SearchTripsRequest ): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2118,30 +1883,6 @@ async def test_search_trips_async_from_dict(): await test_search_trips_async(request_type=dict) -def test_search_trips_routing_parameters(): - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = trip_api.SearchTripsRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_trips), "__call__") as call: - call.return_value = trip_api.SearchTripsResponse() - client.search_trips(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_search_trips_pager(transport_name: str = "grpc"): client = TripServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2237,7 +1978,7 @@ def test_search_trips_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_search_trips_async_pager(): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2287,7 +2028,7 @@ async def test_search_trips_async_pager(): @pytest.mark.asyncio async def test_search_trips_async_pages(): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2385,46 +2126,27 @@ def test_update_trip(request_type, transport: str = "grpc"): assert response.view == trips.TripView.SDK -def test_update_trip_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. +def test_update_trip_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = TripServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = trip_api.UpdateTripRequest( + name="name_value", + ) + # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.update_trip), "__call__") as call: call.return_value.name = ( "foo" # operation_request.operation in compute client(s) expect a string. ) - client.update_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.UpdateTripRequest() - - -def test_update_trip_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = trip_api.UpdateTripRequest( - name="name_value", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_trip), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_trip(request=request) + client.update_trip(request=request) call.assert_called() _, args, _ = call.mock_calls[0] assert args[0] == trip_api.UpdateTripRequest( @@ -2467,37 +2189,6 @@ def test_update_trip_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_trip_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_trip), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - trips.Trip( - name="name_value", - vehicle_id="vehicle_id_value", - trip_status=trips.TripStatus.NEW, - trip_type=fleetengine.TripType.SHARED, - intermediate_destination_index=3187, - current_route_segment="current_route_segment_value", - number_of_passengers=2135, - last_location_snappable=True, - view=trips.TripView.SDK, - ) - ) - response = await client.update_trip() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == trip_api.UpdateTripRequest() - - @pytest.mark.asyncio async def test_update_trip_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2506,7 +2197,7 @@ async def test_update_trip_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2545,7 +2236,7 @@ async def test_update_trip_async( transport: str = "grpc_asyncio", request_type=trip_api.UpdateTripRequest ): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2595,30 +2286,6 @@ async def test_update_trip_async_from_dict(): await test_update_trip_async(request_type=dict) -def test_update_trip_routing_parameters(): - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = trip_api.UpdateTripRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_trip), "__call__") as call: - call.return_value = trips.Trip() - client.update_trip(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.TripServiceGrpcTransport( @@ -2710,17 +2377,594 @@ def test_transport_adc(transport_class): adc.assert_called_once() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - ], -) -def test_transport_kind(transport_name): - transport = TripServiceClient.get_transport_class(transport_name)( +def test_transport_kind_grpc(): + transport = TripServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_trip_empty_call_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_trip), "__call__") as call: + call.return_value = trips.Trip() + client.create_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.CreateTripRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_trip_empty_call_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_trip), "__call__") as call: + call.return_value = trips.Trip() + client.get_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.GetTripRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_report_billable_trip_empty_call_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.report_billable_trip), "__call__" + ) as call: + call.return_value = None + client.report_billable_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.ReportBillableTripRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_trips_empty_call_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_trips), "__call__") as call: + call.return_value = trip_api.SearchTripsResponse() + client.search_trips(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.SearchTripsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_trip_empty_call_grpc(): + client = TripServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_trip), "__call__") as call: + call.return_value = trips.Trip() + client.update_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.UpdateTripRequest() + + assert args[0] == request_msg + + +def test_create_trip_routing_parameters_request_1_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_trip), "__call__") as call: + call.return_value = trips.Trip() + client.create_trip(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.CreateTripRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_get_trip_routing_parameters_request_1_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_trip), "__call__") as call: + call.return_value = trips.Trip() + client.get_trip(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.GetTripRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_report_billable_trip_routing_parameters_request_1_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.report_billable_trip), "__call__" + ) as call: + call.return_value = None + client.report_billable_trip(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.ReportBillableTripRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_search_trips_routing_parameters_request_1_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_trips), "__call__") as call: + call.return_value = trip_api.SearchTripsResponse() + client.search_trips(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.SearchTripsRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_update_trip_routing_parameters_request_1_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_trip), "__call__") as call: + call.return_value = trips.Trip() + client.update_trip(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.UpdateTripRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_transport_kind_grpc_asyncio(): + transport = TripServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_trip_empty_call_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_trip), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trips.Trip( + name="name_value", + vehicle_id="vehicle_id_value", + trip_status=trips.TripStatus.NEW, + trip_type=fleetengine.TripType.SHARED, + intermediate_destination_index=3187, + current_route_segment="current_route_segment_value", + number_of_passengers=2135, + last_location_snappable=True, + view=trips.TripView.SDK, + ) + ) + await client.create_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.CreateTripRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_trip_empty_call_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_trip), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trips.Trip( + name="name_value", + vehicle_id="vehicle_id_value", + trip_status=trips.TripStatus.NEW, + trip_type=fleetengine.TripType.SHARED, + intermediate_destination_index=3187, + current_route_segment="current_route_segment_value", + number_of_passengers=2135, + last_location_snappable=True, + view=trips.TripView.SDK, + ) + ) + await client.get_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.GetTripRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_report_billable_trip_empty_call_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.report_billable_trip), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.report_billable_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.ReportBillableTripRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_trips_empty_call_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_trips), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trip_api.SearchTripsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.search_trips(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.SearchTripsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_trip_empty_call_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_trip), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trips.Trip( + name="name_value", + vehicle_id="vehicle_id_value", + trip_status=trips.TripStatus.NEW, + trip_type=fleetengine.TripType.SHARED, + intermediate_destination_index=3187, + current_route_segment="current_route_segment_value", + number_of_passengers=2135, + last_location_snappable=True, + view=trips.TripView.SDK, + ) + ) + await client.update_trip(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = trip_api.UpdateTripRequest() + + assert args[0] == request_msg + + +@pytest.mark.asyncio +async def test_create_trip_routing_parameters_request_1_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_trip), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trips.Trip( + name="name_value", + vehicle_id="vehicle_id_value", + trip_status=trips.TripStatus.NEW, + trip_type=fleetengine.TripType.SHARED, + intermediate_destination_index=3187, + current_route_segment="current_route_segment_value", + number_of_passengers=2135, + last_location_snappable=True, + view=trips.TripView.SDK, + ) + ) + await client.create_trip(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.CreateTripRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_get_trip_routing_parameters_request_1_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_trip), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trips.Trip( + name="name_value", + vehicle_id="vehicle_id_value", + trip_status=trips.TripStatus.NEW, + trip_type=fleetengine.TripType.SHARED, + intermediate_destination_index=3187, + current_route_segment="current_route_segment_value", + number_of_passengers=2135, + last_location_snappable=True, + view=trips.TripView.SDK, + ) + ) + await client.get_trip(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.GetTripRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_report_billable_trip_routing_parameters_request_1_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.report_billable_trip), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.report_billable_trip(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.ReportBillableTripRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_search_trips_routing_parameters_request_1_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_trips), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trip_api.SearchTripsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.search_trips(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.SearchTripsRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_update_trip_routing_parameters_request_1_grpc_asyncio(): + client = TripServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_trip), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + trips.Trip( + name="name_value", + vehicle_id="vehicle_id_value", + trip_status=trips.TripStatus.NEW, + trip_type=fleetengine.TripType.SHARED, + intermediate_destination_index=3187, + current_route_segment="current_route_segment_value", + number_of_passengers=2135, + last_location_snappable=True, + view=trips.TripView.SDK, + ) + ) + await client.update_trip(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = trip_api.UpdateTripRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) def test_transport_grpc_default(): @@ -3244,37 +3488,31 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = TripServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = TripServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = TripServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - def test_client_ctx(): transports = [ "grpc", diff --git a/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_vehicle_service.py b/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_vehicle_service.py index 8c3e7b0811ae..5d22d7a44674 100644 --- a/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_vehicle_service.py +++ b/packages/google-maps-fleetengine/tests/unit/gapic/fleetengine_v1/test_vehicle_service.py @@ -24,8 +24,22 @@ import math +from google.api_core import api_core_version +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -38,11 +52,6 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore from google.type import latlng_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest from google.maps.fleetengine_v1.services.vehicle_service import ( VehicleServiceAsyncClient, @@ -59,10 +68,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1156,25 +1179,6 @@ def test_create_vehicle(request_type, transport: str = "grpc"): assert response.navigation_status == fleetengine.NavigationStatus.NO_GUIDANCE -def test_create_vehicle_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.CreateVehicleRequest() - - def test_create_vehicle_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1240,36 +1244,6 @@ def test_create_vehicle_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_vehicle_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vehicles.Vehicle( - name="name_value", - vehicle_state=vehicles.VehicleState.OFFLINE, - supported_trip_types=[fleetengine.TripType.SHARED], - current_trips=["current_trips_value"], - maximum_capacity=1707, - current_route_segment="current_route_segment_value", - back_to_back_enabled=True, - navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, - ) - ) - response = await client.create_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.CreateVehicleRequest() - - @pytest.mark.asyncio async def test_create_vehicle_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1278,7 +1252,7 @@ async def test_create_vehicle_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1317,7 +1291,7 @@ async def test_create_vehicle_async( transport: str = "grpc_asyncio", request_type=vehicle_api.CreateVehicleRequest ): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1365,30 +1339,6 @@ async def test_create_vehicle_async_from_dict(): await test_create_vehicle_async(request_type=dict) -def test_create_vehicle_routing_parameters(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = vehicle_api.CreateVehicleRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: - call.return_value = vehicles.Vehicle() - client.create_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -1439,25 +1389,6 @@ def test_get_vehicle(request_type, transport: str = "grpc"): assert response.navigation_status == fleetengine.NavigationStatus.NO_GUIDANCE -def test_get_vehicle_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.GetVehicleRequest() - - def test_get_vehicle_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1521,36 +1452,6 @@ def test_get_vehicle_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_vehicle_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vehicles.Vehicle( - name="name_value", - vehicle_state=vehicles.VehicleState.OFFLINE, - supported_trip_types=[fleetengine.TripType.SHARED], - current_trips=["current_trips_value"], - maximum_capacity=1707, - current_route_segment="current_route_segment_value", - back_to_back_enabled=True, - navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, - ) - ) - response = await client.get_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.GetVehicleRequest() - - @pytest.mark.asyncio async def test_get_vehicle_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1559,7 +1460,7 @@ async def test_get_vehicle_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1598,7 +1499,7 @@ async def test_get_vehicle_async( transport: str = "grpc_asyncio", request_type=vehicle_api.GetVehicleRequest ): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1646,30 +1547,6 @@ async def test_get_vehicle_async_from_dict(): await test_get_vehicle_async(request_type=dict) -def test_get_vehicle_routing_parameters(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = vehicle_api.GetVehicleRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: - call.return_value = vehicles.Vehicle() - client.get_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -1720,25 +1597,6 @@ def test_update_vehicle(request_type, transport: str = "grpc"): assert response.navigation_status == fleetengine.NavigationStatus.NO_GUIDANCE -def test_update_vehicle_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.UpdateVehicleRequest() - - def test_update_vehicle_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1802,36 +1660,6 @@ def test_update_vehicle_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_vehicle_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vehicles.Vehicle( - name="name_value", - vehicle_state=vehicles.VehicleState.OFFLINE, - supported_trip_types=[fleetengine.TripType.SHARED], - current_trips=["current_trips_value"], - maximum_capacity=1707, - current_route_segment="current_route_segment_value", - back_to_back_enabled=True, - navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, - ) - ) - response = await client.update_vehicle() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.UpdateVehicleRequest() - - @pytest.mark.asyncio async def test_update_vehicle_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1840,7 +1668,7 @@ async def test_update_vehicle_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1879,7 +1707,7 @@ async def test_update_vehicle_async( transport: str = "grpc_asyncio", request_type=vehicle_api.UpdateVehicleRequest ): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1927,30 +1755,6 @@ async def test_update_vehicle_async_from_dict(): await test_update_vehicle_async(request_type=dict) -def test_update_vehicle_routing_parameters(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = vehicle_api.UpdateVehicleRequest(**{"name": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: - call.return_value = vehicles.Vehicle() - client.update_vehicle(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -1986,27 +1790,6 @@ def test_update_vehicle_attributes(request_type, transport: str = "grpc"): assert isinstance(response, vehicle_api.UpdateVehicleAttributesResponse) -def test_update_vehicle_attributes_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_vehicle_attributes), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_vehicle_attributes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.UpdateVehicleAttributesRequest() - - def test_update_vehicle_attributes_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2077,29 +1860,6 @@ def test_update_vehicle_attributes_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_vehicle_attributes_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_vehicle_attributes), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vehicle_api.UpdateVehicleAttributesResponse() - ) - response = await client.update_vehicle_attributes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.UpdateVehicleAttributesRequest() - - @pytest.mark.asyncio async def test_update_vehicle_attributes_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2108,7 +1868,7 @@ async def test_update_vehicle_attributes_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2148,7 +1908,7 @@ async def test_update_vehicle_attributes_async( request_type=vehicle_api.UpdateVehicleAttributesRequest, ): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2181,34 +1941,6 @@ async def test_update_vehicle_attributes_async_from_dict(): await test_update_vehicle_attributes_async(request_type=dict) -def test_update_vehicle_attributes_routing_parameters(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = vehicle_api.UpdateVehicleAttributesRequest( - **{"name": "providers/sample1"} - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_vehicle_attributes), "__call__" - ) as call: - call.return_value = vehicle_api.UpdateVehicleAttributesResponse() - client.update_vehicle_attributes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - @pytest.mark.parametrize( "request_type", [ @@ -2247,28 +1979,9 @@ def test_list_vehicles(request_type, transport: str = "grpc"): assert response.total_size == 1086 -def test_list_vehicles_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_vehicles() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.ListVehiclesRequest() - - -def test_list_vehicles_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. +def test_list_vehicles_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. client = VehicleServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="grpc", @@ -2333,30 +2046,6 @@ def test_list_vehicles_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_vehicles_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vehicle_api.ListVehiclesResponse( - next_page_token="next_page_token_value", - total_size=1086, - ) - ) - response = await client.list_vehicles() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.ListVehiclesRequest() - - @pytest.mark.asyncio async def test_list_vehicles_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2365,7 +2054,7 @@ async def test_list_vehicles_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2404,7 +2093,7 @@ async def test_list_vehicles_async( transport: str = "grpc_asyncio", request_type=vehicle_api.ListVehiclesRequest ): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2440,30 +2129,6 @@ async def test_list_vehicles_async_from_dict(): await test_list_vehicles_async(request_type=dict) -def test_list_vehicles_routing_parameters(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = vehicle_api.ListVehiclesRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: - call.return_value = vehicle_api.ListVehiclesResponse() - client.list_vehicles(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_list_vehicles_pager(transport_name: str = "grpc"): client = VehicleServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2559,7 +2224,7 @@ def test_list_vehicles_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_vehicles_async_pager(): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2609,7 +2274,7 @@ async def test_list_vehicles_async_pager(): @pytest.mark.asyncio async def test_list_vehicles_async_pages(): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2688,25 +2353,6 @@ def test_search_vehicles(request_type, transport: str = "grpc"): assert isinstance(response, vehicle_api.SearchVehiclesResponse) -def test_search_vehicles_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.search_vehicles() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.SearchVehiclesRequest() - - def test_search_vehicles_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2774,27 +2420,6 @@ def test_search_vehicles_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_search_vehicles_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - vehicle_api.SearchVehiclesResponse() - ) - response = await client.search_vehicles() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == vehicle_api.SearchVehiclesRequest() - - @pytest.mark.asyncio async def test_search_vehicles_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2803,7 +2428,7 @@ async def test_search_vehicles_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2842,7 +2467,7 @@ async def test_search_vehicles_async( transport: str = "grpc_asyncio", request_type=vehicle_api.SearchVehiclesRequest ): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2873,30 +2498,6 @@ async def test_search_vehicles_async_from_dict(): await test_search_vehicles_async(request_type=dict) -def test_search_vehicles_routing_parameters(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = vehicle_api.SearchVehiclesRequest(**{"parent": "providers/sample1"}) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: - call.return_value = vehicle_api.SearchVehiclesResponse() - client.search_vehicles(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - _, _, kw = call.mock_calls[0] - # This test doesn't assert anything useful. - assert kw["metadata"] - - def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.VehicleServiceGrpcTransport( @@ -2988,141 +2589,824 @@ def test_transport_adc(transport_class): adc.assert_called_once() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - ], -) -def test_transport_kind(transport_name): - transport = VehicleServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), +def test_transport_kind_grpc(): + transport = VehicleServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() ) - assert transport.kind == transport_name + assert transport.kind == "grpc" -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. +def test_initialize_client_w_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_vehicle_empty_call_grpc(): client = VehicleServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) - assert isinstance( - client.transport, - transports.VehicleServiceGrpcTransport, + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: + call.return_value = vehicles.Vehicle() + client.create_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.CreateVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_vehicle_empty_call_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: + call.return_value = vehicles.Vehicle() + client.get_vehicle(request=None) -def test_vehicle_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.VehicleServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.GetVehicleRequest() + assert args[0] == request_msg -def test_vehicle_service_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.maps.fleetengine_v1.services.vehicle_service.transports.VehicleServiceTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.VehicleServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "create_vehicle", - "get_vehicle", - "update_vehicle", - "update_vehicle_attributes", - "list_vehicles", - "search_vehicles", +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_vehicle_empty_call_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - with pytest.raises(NotImplementedError): - transport.close() + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: + call.return_value = vehicles.Vehicle() + client.update_vehicle(request=None) - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleRequest() + assert args[0] == request_msg -def test_vehicle_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_vehicle_attributes_empty_call_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.maps.fleetengine_v1.services.vehicle_service.transports.VehicleServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.VehicleServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) + type(client.transport.update_vehicle_attributes), "__call__" + ) as call: + call.return_value = vehicle_api.UpdateVehicleAttributesResponse() + client.update_vehicle_attributes(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleAttributesRequest() -def test_vehicle_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.maps.fleetengine_v1.services.vehicle_service.transports.VehicleServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.VehicleServiceTransport() - adc.assert_called_once() + assert args[0] == request_msg -def test_vehicle_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - VehicleServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id=None, - ) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_vehicles_empty_call_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: + call.return_value = vehicle_api.ListVehiclesResponse() + client.list_vehicles(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.VehicleServiceGrpcTransport, - transports.VehicleServiceGrpcAsyncIOTransport, - ], -) -def test_vehicle_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.ListVehiclesRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_class", + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_vehicles_empty_call_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: + call.return_value = vehicle_api.SearchVehiclesResponse() + client.search_vehicles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.SearchVehiclesRequest() + + assert args[0] == request_msg + + +def test_create_vehicle_routing_parameters_request_1_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: + call.return_value = vehicles.Vehicle() + client.create_vehicle(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.CreateVehicleRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_get_vehicle_routing_parameters_request_1_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: + call.return_value = vehicles.Vehicle() + client.get_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.GetVehicleRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_update_vehicle_routing_parameters_request_1_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: + call.return_value = vehicles.Vehicle() + client.update_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_update_vehicle_attributes_routing_parameters_request_1_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_vehicle_attributes), "__call__" + ) as call: + call.return_value = vehicle_api.UpdateVehicleAttributesResponse() + client.update_vehicle_attributes(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleAttributesRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_list_vehicles_routing_parameters_request_1_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: + call.return_value = vehicle_api.ListVehiclesResponse() + client.list_vehicles(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.ListVehiclesRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_search_vehicles_routing_parameters_request_1_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: + call.return_value = vehicle_api.SearchVehiclesResponse() + client.search_vehicles(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.SearchVehiclesRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_transport_kind_grpc_asyncio(): + transport = VehicleServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_vehicle_empty_call_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicles.Vehicle( + name="name_value", + vehicle_state=vehicles.VehicleState.OFFLINE, + supported_trip_types=[fleetengine.TripType.SHARED], + current_trips=["current_trips_value"], + maximum_capacity=1707, + current_route_segment="current_route_segment_value", + back_to_back_enabled=True, + navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, + ) + ) + await client.create_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.CreateVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_vehicle_empty_call_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicles.Vehicle( + name="name_value", + vehicle_state=vehicles.VehicleState.OFFLINE, + supported_trip_types=[fleetengine.TripType.SHARED], + current_trips=["current_trips_value"], + maximum_capacity=1707, + current_route_segment="current_route_segment_value", + back_to_back_enabled=True, + navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, + ) + ) + await client.get_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.GetVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_vehicle_empty_call_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicles.Vehicle( + name="name_value", + vehicle_state=vehicles.VehicleState.OFFLINE, + supported_trip_types=[fleetengine.TripType.SHARED], + current_trips=["current_trips_value"], + maximum_capacity=1707, + current_route_segment="current_route_segment_value", + back_to_back_enabled=True, + navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, + ) + ) + await client.update_vehicle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_vehicle_attributes_empty_call_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_vehicle_attributes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicle_api.UpdateVehicleAttributesResponse() + ) + await client.update_vehicle_attributes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleAttributesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_vehicles_empty_call_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicle_api.ListVehiclesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_vehicles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.ListVehiclesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_vehicles_empty_call_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicle_api.SearchVehiclesResponse() + ) + await client.search_vehicles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = vehicle_api.SearchVehiclesRequest() + + assert args[0] == request_msg + + +@pytest.mark.asyncio +async def test_create_vehicle_routing_parameters_request_1_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_vehicle), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicles.Vehicle( + name="name_value", + vehicle_state=vehicles.VehicleState.OFFLINE, + supported_trip_types=[fleetengine.TripType.SHARED], + current_trips=["current_trips_value"], + maximum_capacity=1707, + current_route_segment="current_route_segment_value", + back_to_back_enabled=True, + navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, + ) + ) + await client.create_vehicle(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.CreateVehicleRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_get_vehicle_routing_parameters_request_1_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_vehicle), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicles.Vehicle( + name="name_value", + vehicle_state=vehicles.VehicleState.OFFLINE, + supported_trip_types=[fleetengine.TripType.SHARED], + current_trips=["current_trips_value"], + maximum_capacity=1707, + current_route_segment="current_route_segment_value", + back_to_back_enabled=True, + navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, + ) + ) + await client.get_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.GetVehicleRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_update_vehicle_routing_parameters_request_1_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_vehicle), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicles.Vehicle( + name="name_value", + vehicle_state=vehicles.VehicleState.OFFLINE, + supported_trip_types=[fleetengine.TripType.SHARED], + current_trips=["current_trips_value"], + maximum_capacity=1707, + current_route_segment="current_route_segment_value", + back_to_back_enabled=True, + navigation_status=fleetengine.NavigationStatus.NO_GUIDANCE, + ) + ) + await client.update_vehicle(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleRequest(**{"name": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_update_vehicle_attributes_routing_parameters_request_1_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_vehicle_attributes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicle_api.UpdateVehicleAttributesResponse() + ) + await client.update_vehicle_attributes(request={"name": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.UpdateVehicleAttributesRequest( + **{"name": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_list_vehicles_routing_parameters_request_1_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_vehicles), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicle_api.ListVehiclesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + await client.list_vehicles(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.ListVehiclesRequest(**{"parent": "providers/sample1"}) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +@pytest.mark.asyncio +async def test_search_vehicles_routing_parameters_request_1_grpc_asyncio(): + client = VehicleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_vehicles), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + vehicle_api.SearchVehiclesResponse() + ) + await client.search_vehicles(request={"parent": "providers/sample1"}) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, kw = call.mock_calls[0] + request_msg = vehicle_api.SearchVehiclesRequest( + **{"parent": "providers/sample1"} + ) + + assert args[0] == request_msg + + expected_headers = {"provider_id": "providers/sample1"} + assert ( + gapic_v1.routing_header.to_grpc_metadata(expected_headers) in kw["metadata"] + ) + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.VehicleServiceGrpcTransport, + ) + + +def test_vehicle_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.VehicleServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_vehicle_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.maps.fleetengine_v1.services.vehicle_service.transports.VehicleServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.VehicleServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_vehicle", + "get_vehicle", + "update_vehicle", + "update_vehicle_attributes", + "list_vehicles", + "search_vehicles", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_vehicle_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.maps.fleetengine_v1.services.vehicle_service.transports.VehicleServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VehicleServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_vehicle_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.maps.fleetengine_v1.services.vehicle_service.transports.VehicleServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.VehicleServiceTransport() + adc.assert_called_once() + + +def test_vehicle_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + VehicleServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.VehicleServiceGrpcTransport, + transports.VehicleServiceGrpcAsyncIOTransport, + ], +) +def test_vehicle_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", [ transports.VehicleServiceGrpcTransport, transports.VehicleServiceGrpcAsyncIOTransport, @@ -3534,37 +3818,31 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = VehicleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = VehicleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = VehicleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - def test_client_ctx(): transports = [ "grpc", diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/README.rst b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/README.rst new file mode 100644 index 000000000000..cb6fbe0110ae --- /dev/null +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`MapsPlatformDatasetsTransport` is the ABC for all transports. +- public child `MapsPlatformDatasetsGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `MapsPlatformDatasetsGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseMapsPlatformDatasetsRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `MapsPlatformDatasetsRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py index 69e017ad9d1c..cfea955fdf05 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -229,6 +230,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -415,17 +419,17 @@ def delete_dataset( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.create_dataset: gapic_v1.method_async.wrap_method( + self.create_dataset: self._wrap_method( self.create_dataset, default_timeout=60.0, client_info=client_info, ), - self.update_dataset_metadata: gapic_v1.method_async.wrap_method( + self.update_dataset_metadata: self._wrap_method( self.update_dataset_metadata, default_timeout=60.0, client_info=client_info, ), - self.get_dataset: gapic_v1.method_async.wrap_method( + self.get_dataset: self._wrap_method( self.get_dataset, default_retry=retries.AsyncRetry( initial=1.0, @@ -439,7 +443,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.fetch_dataset_errors: gapic_v1.method_async.wrap_method( + self.fetch_dataset_errors: self._wrap_method( self.fetch_dataset_errors, default_retry=retries.AsyncRetry( initial=1.0, @@ -453,7 +457,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.list_datasets: gapic_v1.method_async.wrap_method( + self.list_datasets: self._wrap_method( self.list_datasets, default_retry=retries.AsyncRetry( initial=1.0, @@ -467,15 +471,24 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.delete_dataset: gapic_v1.method_async.wrap_method( + self.delete_dataset: self._wrap_method( self.delete_dataset, default_timeout=60.0, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("MapsPlatformDatasetsGrpcAsyncIOTransport",) diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py index eb6038688e07..b21eae08ff92 100644 --- a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest.py @@ -16,34 +16,30 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - -from google.protobuf import empty_pb2 # type: ignore - from google.maps.mapsplatformdatasets_v1.types import dataset from google.maps.mapsplatformdatasets_v1.types import dataset as gmm_dataset from google.maps.mapsplatformdatasets_v1.types import maps_platform_datasets from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import MapsPlatformDatasetsTransport +from .rest_base import _BaseMapsPlatformDatasetsRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, @@ -252,8 +248,8 @@ class MapsPlatformDatasetsRestStub: _interceptor: MapsPlatformDatasetsRestInterceptor -class MapsPlatformDatasetsRestTransport(MapsPlatformDatasetsTransport): - """REST backend transport for MapsPlatformDatasets. +class MapsPlatformDatasetsRestTransport(_BaseMapsPlatformDatasetsRestTransport): + """REST backend synchronous transport for MapsPlatformDatasets. Service definition for the Maps Platform Datasets API. @@ -262,7 +258,6 @@ class MapsPlatformDatasetsRestTransport(MapsPlatformDatasetsTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -316,21 +311,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -341,19 +327,35 @@ def __init__( self._interceptor = interceptor or MapsPlatformDatasetsRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateDataset(MapsPlatformDatasetsRestStub): + class _CreateDataset( + _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset, + MapsPlatformDatasetsRestStub, + ): def __hash__(self): - return hash("CreateDataset") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("MapsPlatformDatasetsRestTransport.CreateDataset") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -381,45 +383,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*}/datasets", - "body": "dataset", - }, - ] + http_options = ( + _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_http_options() + ) request, metadata = self._interceptor.pre_create_dataset(request, metadata) - pb_request = maps_platform_datasets.CreateDatasetRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = MapsPlatformDatasetsRestTransport._CreateDataset._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -435,19 +424,34 @@ def __call__( resp = self._interceptor.post_create_dataset(resp) return resp - class _DeleteDataset(MapsPlatformDatasetsRestStub): + class _DeleteDataset( + _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset, + MapsPlatformDatasetsRestStub, + ): def __hash__(self): - return hash("DeleteDataset") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("MapsPlatformDatasetsRestTransport.DeleteDataset") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -469,38 +473,27 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1/{name=projects/*/datasets/*}", - }, - ] + http_options = ( + _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset._get_http_options() + ) request, metadata = self._interceptor.pre_delete_dataset(request, metadata) - pb_request = maps_platform_datasets.DeleteDatasetRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = MapsPlatformDatasetsRestTransport._DeleteDataset._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -508,19 +501,34 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _FetchDatasetErrors(MapsPlatformDatasetsRestStub): + class _FetchDatasetErrors( + _BaseMapsPlatformDatasetsRestTransport._BaseFetchDatasetErrors, + MapsPlatformDatasetsRestStub, + ): def __hash__(self): - return hash("FetchDatasetErrors") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("MapsPlatformDatasetsRestTransport.FetchDatasetErrors") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -549,40 +557,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{dataset=projects/*/datasets/*}:fetchDatasetErrors", - }, - ] + http_options = ( + _BaseMapsPlatformDatasetsRestTransport._BaseFetchDatasetErrors._get_http_options() + ) request, metadata = self._interceptor.pre_fetch_dataset_errors( request, metadata ) - pb_request = maps_platform_datasets.FetchDatasetErrorsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseFetchDatasetErrors._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseMapsPlatformDatasetsRestTransport._BaseFetchDatasetErrors._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + MapsPlatformDatasetsRestTransport._FetchDatasetErrors._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -598,19 +597,34 @@ def __call__( resp = self._interceptor.post_fetch_dataset_errors(resp) return resp - class _GetDataset(MapsPlatformDatasetsRestStub): + class _GetDataset( + _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset, + MapsPlatformDatasetsRestStub, + ): def __hash__(self): - return hash("GetDataset") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("MapsPlatformDatasetsRestTransport.GetDataset") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -638,38 +652,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=projects/*/datasets/*}", - }, - ] + http_options = ( + _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset._get_http_options() + ) request, metadata = self._interceptor.pre_get_dataset(request, metadata) - pb_request = maps_platform_datasets.GetDatasetRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = MapsPlatformDatasetsRestTransport._GetDataset._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -685,19 +688,34 @@ def __call__( resp = self._interceptor.post_get_dataset(resp) return resp - class _ListDatasets(MapsPlatformDatasetsRestStub): + class _ListDatasets( + _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets, + MapsPlatformDatasetsRestStub, + ): def __hash__(self): - return hash("ListDatasets") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("MapsPlatformDatasetsRestTransport.ListDatasets") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -724,38 +742,27 @@ def __call__( Response object of ListDatasets. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=projects/*}/datasets", - }, - ] + http_options = ( + _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets._get_http_options() + ) request, metadata = self._interceptor.pre_list_datasets(request, metadata) - pb_request = maps_platform_datasets.ListDatasetsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = MapsPlatformDatasetsRestTransport._ListDatasets._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -771,19 +778,35 @@ def __call__( resp = self._interceptor.post_list_datasets(resp) return resp - class _UpdateDatasetMetadata(MapsPlatformDatasetsRestStub): + class _UpdateDatasetMetadata( + _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata, + MapsPlatformDatasetsRestStub, + ): def __hash__(self): - return hash("UpdateDatasetMetadata") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("MapsPlatformDatasetsRestTransport.UpdateDatasetMetadata") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -812,47 +835,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{dataset.name=projects/*/datasets/*}", - "body": "dataset", - }, - ] + http_options = ( + _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata._get_http_options() + ) request, metadata = self._interceptor.pre_update_dataset_metadata( request, metadata ) - pb_request = maps_platform_datasets.UpdateDatasetMetadataRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + MapsPlatformDatasetsRestTransport._UpdateDatasetMetadata._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest_base.py b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest_base.py new file mode 100644 index 000000000000..3cd36b933332 --- /dev/null +++ b/packages/google-maps-mapsplatformdatasets/google/maps/mapsplatformdatasets_v1/services/maps_platform_datasets/transports/rest_base.py @@ -0,0 +1,396 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.maps.mapsplatformdatasets_v1.types import dataset +from google.maps.mapsplatformdatasets_v1.types import dataset as gmm_dataset +from google.maps.mapsplatformdatasets_v1.types import maps_platform_datasets + +from .base import DEFAULT_CLIENT_INFO, MapsPlatformDatasetsTransport + + +class _BaseMapsPlatformDatasetsRestTransport(MapsPlatformDatasetsTransport): + """Base REST backend transport for MapsPlatformDatasets. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "mapsplatformdatasets.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'mapsplatformdatasets.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateDataset: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*}/datasets", + "body": "dataset", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = maps_platform_datasets.CreateDatasetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMapsPlatformDatasetsRestTransport._BaseCreateDataset._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteDataset: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/datasets/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = maps_platform_datasets.DeleteDatasetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMapsPlatformDatasetsRestTransport._BaseDeleteDataset._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseFetchDatasetErrors: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{dataset=projects/*/datasets/*}:fetchDatasetErrors", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = maps_platform_datasets.FetchDatasetErrorsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMapsPlatformDatasetsRestTransport._BaseFetchDatasetErrors._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDataset: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/datasets/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = maps_platform_datasets.GetDatasetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMapsPlatformDatasetsRestTransport._BaseGetDataset._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDatasets: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*}/datasets", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = maps_platform_datasets.ListDatasetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMapsPlatformDatasetsRestTransport._BaseListDatasets._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateDatasetMetadata: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{dataset.name=projects/*/datasets/*}", + "body": "dataset", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = maps_platform_datasets.UpdateDatasetMetadataRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMapsPlatformDatasetsRestTransport._BaseUpdateDatasetMetadata._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseMapsPlatformDatasetsRestTransport",) diff --git a/packages/google-maps-mapsplatformdatasets/setup.py b/packages/google-maps-mapsplatformdatasets/setup.py index b7c29c768e07..abf8c5a3ecd3 100644 --- a/packages/google-maps-mapsplatformdatasets/setup.py +++ b/packages/google-maps-mapsplatformdatasets/setup.py @@ -48,6 +48,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-mapsplatformdatasets" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -90,6 +91,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py b/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py index c731c88871b4..ad2d239b6593 100644 --- a/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py +++ b/packages/google-maps-mapsplatformdatasets/tests/unit/gapic/mapsplatformdatasets_v1/test_maps_platform_datasets.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,16 +52,8 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.maps.mapsplatformdatasets_v1.services.maps_platform_datasets import ( MapsPlatformDatasetsAsyncClient, @@ -58,10 +67,24 @@ from google.maps.mapsplatformdatasets_v1.types import maps_platform_datasets +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1237,25 +1260,6 @@ def test_create_dataset(request_type, transport: str = "grpc"): assert response.version_description == "version_description_value" -def test_create_dataset_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_dataset() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.CreateDatasetRequest() - - def test_create_dataset_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1319,34 +1323,6 @@ def test_create_dataset_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_dataset_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gmm_dataset.Dataset( - name="name_value", - display_name="display_name_value", - description="description_value", - version_id="version_id_value", - usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], - version_description="version_description_value", - ) - ) - response = await client.create_dataset() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.CreateDatasetRequest() - - @pytest.mark.asyncio async def test_create_dataset_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1355,7 +1331,7 @@ async def test_create_dataset_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1395,7 +1371,7 @@ async def test_create_dataset_async( request_type=maps_platform_datasets.CreateDatasetRequest, ): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1471,7 +1447,7 @@ def test_create_dataset_field_headers(): @pytest.mark.asyncio async def test_create_dataset_field_headers_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1544,7 +1520,7 @@ def test_create_dataset_flattened_error(): @pytest.mark.asyncio async def test_create_dataset_flattened_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1575,7 +1551,7 @@ async def test_create_dataset_flattened_async(): @pytest.mark.asyncio async def test_create_dataset_flattened_error_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1636,27 +1612,6 @@ def test_update_dataset_metadata(request_type, transport: str = "grpc"): assert response.version_description == "version_description_value" -def test_update_dataset_metadata_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_dataset_metadata), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_dataset_metadata() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.UpdateDatasetMetadataRequest() - - def test_update_dataset_metadata_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1723,36 +1678,6 @@ def test_update_dataset_metadata_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_dataset_metadata_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_dataset_metadata), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gmm_dataset.Dataset( - name="name_value", - display_name="display_name_value", - description="description_value", - version_id="version_id_value", - usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], - version_description="version_description_value", - ) - ) - response = await client.update_dataset_metadata() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.UpdateDatasetMetadataRequest() - - @pytest.mark.asyncio async def test_update_dataset_metadata_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1761,7 +1686,7 @@ async def test_update_dataset_metadata_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1801,7 +1726,7 @@ async def test_update_dataset_metadata_async( request_type=maps_platform_datasets.UpdateDatasetMetadataRequest, ): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1881,7 +1806,7 @@ def test_update_dataset_metadata_field_headers(): @pytest.mark.asyncio async def test_update_dataset_metadata_field_headers_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1958,7 +1883,7 @@ def test_update_dataset_metadata_flattened_error(): @pytest.mark.asyncio async def test_update_dataset_metadata_flattened_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1991,7 +1916,7 @@ async def test_update_dataset_metadata_flattened_async(): @pytest.mark.asyncio async def test_update_dataset_metadata_flattened_error_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2050,25 +1975,6 @@ def test_get_dataset(request_type, transport: str = "grpc"): assert response.version_description == "version_description_value" -def test_get_dataset_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_dataset() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.GetDatasetRequest() - - def test_get_dataset_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2132,34 +2038,6 @@ def test_get_dataset_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_dataset_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - dataset.Dataset( - name="name_value", - display_name="display_name_value", - description="description_value", - version_id="version_id_value", - usage=[dataset.Usage.USAGE_DATA_DRIVEN_STYLING], - version_description="version_description_value", - ) - ) - response = await client.get_dataset() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.GetDatasetRequest() - - @pytest.mark.asyncio async def test_get_dataset_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2168,7 +2046,7 @@ async def test_get_dataset_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2208,7 +2086,7 @@ async def test_get_dataset_async( request_type=maps_platform_datasets.GetDatasetRequest, ): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2284,7 +2162,7 @@ def test_get_dataset_field_headers(): @pytest.mark.asyncio async def test_get_dataset_field_headers_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2352,7 +2230,7 @@ def test_get_dataset_flattened_error(): @pytest.mark.asyncio async def test_get_dataset_flattened_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2379,7 +2257,7 @@ async def test_get_dataset_flattened_async(): @pytest.mark.asyncio async def test_get_dataset_flattened_error_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2429,27 +2307,6 @@ def test_fetch_dataset_errors(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_fetch_dataset_errors_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.fetch_dataset_errors), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.fetch_dataset_errors() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.FetchDatasetErrorsRequest() - - def test_fetch_dataset_errors_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2521,31 +2378,6 @@ def test_fetch_dataset_errors_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_fetch_dataset_errors_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.fetch_dataset_errors), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - maps_platform_datasets.FetchDatasetErrorsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.fetch_dataset_errors() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.FetchDatasetErrorsRequest() - - @pytest.mark.asyncio async def test_fetch_dataset_errors_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2554,7 +2386,7 @@ async def test_fetch_dataset_errors_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2594,7 +2426,7 @@ async def test_fetch_dataset_errors_async( request_type=maps_platform_datasets.FetchDatasetErrorsRequest, ): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2664,7 +2496,7 @@ def test_fetch_dataset_errors_field_headers(): @pytest.mark.asyncio async def test_fetch_dataset_errors_field_headers_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2738,7 +2570,7 @@ def test_fetch_dataset_errors_flattened_error(): @pytest.mark.asyncio async def test_fetch_dataset_errors_flattened_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2769,7 +2601,7 @@ async def test_fetch_dataset_errors_flattened_async(): @pytest.mark.asyncio async def test_fetch_dataset_errors_flattened_error_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2883,7 +2715,7 @@ def test_fetch_dataset_errors_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_fetch_dataset_errors_async_pager(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2935,7 +2767,7 @@ async def test_fetch_dataset_errors_async_pager(): @pytest.mark.asyncio async def test_fetch_dataset_errors_async_pages(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3019,25 +2851,6 @@ def test_list_datasets(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_datasets_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_datasets() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.ListDatasetsRequest() - - def test_list_datasets_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3105,29 +2918,6 @@ def test_list_datasets_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_datasets_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - maps_platform_datasets.ListDatasetsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_datasets() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.ListDatasetsRequest() - - @pytest.mark.asyncio async def test_list_datasets_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -3136,7 +2926,7 @@ async def test_list_datasets_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3176,7 +2966,7 @@ async def test_list_datasets_async( request_type=maps_platform_datasets.ListDatasetsRequest, ): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3242,7 +3032,7 @@ def test_list_datasets_field_headers(): @pytest.mark.asyncio async def test_list_datasets_field_headers_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3312,7 +3102,7 @@ def test_list_datasets_flattened_error(): @pytest.mark.asyncio async def test_list_datasets_flattened_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3341,7 +3131,7 @@ async def test_list_datasets_flattened_async(): @pytest.mark.asyncio async def test_list_datasets_flattened_error_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3451,7 +3241,7 @@ def test_list_datasets_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_datasets_async_pager(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3501,7 +3291,7 @@ async def test_list_datasets_async_pager(): @pytest.mark.asyncio async def test_list_datasets_async_pages(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3580,25 +3370,6 @@ def test_delete_dataset(request_type, transport: str = "grpc"): assert response is None -def test_delete_dataset_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_dataset() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.DeleteDatasetRequest() - - def test_delete_dataset_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3662,25 +3433,6 @@ def test_delete_dataset_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_dataset_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_dataset() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == maps_platform_datasets.DeleteDatasetRequest() - - @pytest.mark.asyncio async def test_delete_dataset_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -3689,7 +3441,7 @@ async def test_delete_dataset_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3729,7 +3481,7 @@ async def test_delete_dataset_async( request_type=maps_platform_datasets.DeleteDatasetRequest, ): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3790,7 +3542,7 @@ def test_delete_dataset_field_headers(): @pytest.mark.asyncio async def test_delete_dataset_field_headers_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3858,7 +3610,7 @@ def test_delete_dataset_flattened_error(): @pytest.mark.asyncio async def test_delete_dataset_flattened_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3885,7 +3637,7 @@ async def test_delete_dataset_flattened_async(): @pytest.mark.asyncio async def test_delete_dataset_flattened_error_async(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3897,137 +3649,6 @@ async def test_delete_dataset_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - maps_platform_datasets.CreateDatasetRequest, - dict, - ], -) -def test_create_dataset_rest(request_type): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request_init["dataset"] = { - "name": "name_value", - "display_name": "display_name_value", - "description": "description_value", - "version_id": "version_id_value", - "usage": [1], - "local_file_source": {"filename": "filename_value", "file_format": 1}, - "gcs_source": {"input_uri": "input_uri_value", "file_format": 1}, - "status": {"state": 1, "error_message": "error_message_value"}, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "version_create_time": {}, - "version_description": "version_description_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = maps_platform_datasets.CreateDatasetRequest.meta.fields["dataset"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["dataset"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["dataset"][field])): - del request_init["dataset"][field][i][subfield] - else: - del request_init["dataset"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gmm_dataset.Dataset( - name="name_value", - display_name="display_name_value", - description="description_value", - version_id="version_id_value", - usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], - version_description="version_description_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gmm_dataset.Dataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_dataset(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, gmm_dataset.Dataset) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.version_id == "version_id_value" - assert response.usage == [gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING] - assert response.version_description == "version_description_value" - - def test_create_dataset_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4156,85 +3777,6 @@ def test_create_dataset_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_dataset_rest_interceptors(null_interceptor): - transport = transports.MapsPlatformDatasetsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.MapsPlatformDatasetsRestInterceptor(), - ) - client = MapsPlatformDatasetsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "post_create_dataset" - ) as post, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "pre_create_dataset" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = maps_platform_datasets.CreateDatasetRequest.pb( - maps_platform_datasets.CreateDatasetRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = gmm_dataset.Dataset.to_json(gmm_dataset.Dataset()) - - request = maps_platform_datasets.CreateDatasetRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = gmm_dataset.Dataset() - - client.create_dataset( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_dataset_rest_bad_request( - transport: str = "rest", request_type=maps_platform_datasets.CreateDatasetRequest -): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_dataset(request) - - def test_create_dataset_rest_flattened(): client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4292,163 +3834,24 @@ def test_create_dataset_rest_flattened_error(transport: str = "rest"): ) -def test_create_dataset_rest_error(): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_dataset_metadata_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - maps_platform_datasets.UpdateDatasetMetadataRequest, - dict, - ], -) -def test_update_dataset_metadata_rest(request_type): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"dataset": {"name": "projects/sample1/datasets/sample2"}} - request_init["dataset"] = { - "name": "projects/sample1/datasets/sample2", - "display_name": "display_name_value", - "description": "description_value", - "version_id": "version_id_value", - "usage": [1], - "local_file_source": {"filename": "filename_value", "file_format": 1}, - "gcs_source": {"input_uri": "input_uri_value", "file_format": 1}, - "status": {"state": 1, "error_message": "error_message_value"}, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "version_create_time": {}, - "version_description": "version_description_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = maps_platform_datasets.UpdateDatasetMetadataRequest.meta.fields[ - "dataset" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["dataset"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["dataset"][field])): - del request_init["dataset"][field][i][subfield] - else: - del request_init["dataset"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gmm_dataset.Dataset( - name="name_value", - display_name="display_name_value", - description="description_value", - version_id="version_id_value", - usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], - version_description="version_description_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gmm_dataset.Dataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_dataset_metadata(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, gmm_dataset.Dataset) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.version_id == "version_id_value" - assert response.usage == [gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING] - assert response.version_description == "version_description_value" - - -def test_update_dataset_metadata_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.update_dataset_metadata - in client._transport._wrapped_methods - ) + # Ensure method has been cached + assert ( + client._transport.update_dataset_metadata + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -4553,86 +3956,6 @@ def test_update_dataset_metadata_rest_unset_required_fields(): assert set(unset_fields) == (set(("updateMask",)) & set(("dataset",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_dataset_metadata_rest_interceptors(null_interceptor): - transport = transports.MapsPlatformDatasetsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.MapsPlatformDatasetsRestInterceptor(), - ) - client = MapsPlatformDatasetsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "post_update_dataset_metadata" - ) as post, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "pre_update_dataset_metadata" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = maps_platform_datasets.UpdateDatasetMetadataRequest.pb( - maps_platform_datasets.UpdateDatasetMetadataRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = gmm_dataset.Dataset.to_json(gmm_dataset.Dataset()) - - request = maps_platform_datasets.UpdateDatasetMetadataRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = gmm_dataset.Dataset() - - client.update_dataset_metadata( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_dataset_metadata_rest_bad_request( - transport: str = "rest", - request_type=maps_platform_datasets.UpdateDatasetMetadataRequest, -): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"dataset": {"name": "projects/sample1/datasets/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_dataset_metadata(request) - - def test_update_dataset_metadata_rest_flattened(): client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4691,84 +4014,28 @@ def test_update_dataset_metadata_rest_flattened_error(transport: str = "rest"): ) -def test_update_dataset_metadata_rest_error(): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - +def test_get_dataset_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -@pytest.mark.parametrize( - "request_type", - [ - maps_platform_datasets.GetDatasetRequest, - dict, - ], -) -def test_get_dataset_rest(request_type): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/datasets/sample2"} - request = request_type(**request_init) + # Ensure method has been cached + assert client._transport.get_dataset in client._transport._wrapped_methods - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = dataset.Dataset( - name="name_value", - display_name="display_name_value", - description="description_value", - version_id="version_id_value", - usage=[dataset.Usage.USAGE_DATA_DRIVEN_STYLING], - version_description="version_description_value", + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = dataset.Dataset.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_dataset(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, dataset.Dataset) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.version_id == "version_id_value" - assert response.usage == [dataset.Usage.USAGE_DATA_DRIVEN_STYLING] - assert response.version_description == "version_description_value" - - -def test_get_dataset_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_dataset in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.get_dataset] = mock_rpc + client._transport._wrapped_methods[client._transport.get_dataset] = mock_rpc request = {} client.get_dataset(request) @@ -4866,85 +4133,6 @@ def test_get_dataset_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_dataset_rest_interceptors(null_interceptor): - transport = transports.MapsPlatformDatasetsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.MapsPlatformDatasetsRestInterceptor(), - ) - client = MapsPlatformDatasetsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "post_get_dataset" - ) as post, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "pre_get_dataset" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = maps_platform_datasets.GetDatasetRequest.pb( - maps_platform_datasets.GetDatasetRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = dataset.Dataset.to_json(dataset.Dataset()) - - request = maps_platform_datasets.GetDatasetRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = dataset.Dataset() - - client.get_dataset( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_dataset_rest_bad_request( - transport: str = "rest", request_type=maps_platform_datasets.GetDatasetRequest -): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/datasets/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_dataset(request) - - def test_get_dataset_rest_flattened(): client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5000,54 +4188,6 @@ def test_get_dataset_rest_flattened_error(transport: str = "rest"): ) -def test_get_dataset_rest_error(): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - maps_platform_datasets.FetchDatasetErrorsRequest, - dict, - ], -) -def test_fetch_dataset_errors_rest(request_type): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"dataset": "projects/sample1/datasets/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = maps_platform_datasets.FetchDatasetErrorsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = maps_platform_datasets.FetchDatasetErrorsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.fetch_dataset_errors(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.FetchDatasetErrorsPager) - assert response.next_page_token == "next_page_token_value" - - def test_fetch_dataset_errors_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5188,90 +4328,6 @@ def test_fetch_dataset_errors_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_fetch_dataset_errors_rest_interceptors(null_interceptor): - transport = transports.MapsPlatformDatasetsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.MapsPlatformDatasetsRestInterceptor(), - ) - client = MapsPlatformDatasetsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "post_fetch_dataset_errors" - ) as post, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "pre_fetch_dataset_errors" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = maps_platform_datasets.FetchDatasetErrorsRequest.pb( - maps_platform_datasets.FetchDatasetErrorsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - maps_platform_datasets.FetchDatasetErrorsResponse.to_json( - maps_platform_datasets.FetchDatasetErrorsResponse() - ) - ) - - request = maps_platform_datasets.FetchDatasetErrorsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = maps_platform_datasets.FetchDatasetErrorsResponse() - - client.fetch_dataset_errors( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_fetch_dataset_errors_rest_bad_request( - transport: str = "rest", - request_type=maps_platform_datasets.FetchDatasetErrorsRequest, -): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"dataset": "projects/sample1/datasets/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.fetch_dataset_errors(request) - - def test_fetch_dataset_errors_rest_flattened(): client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5395,46 +4451,6 @@ def test_fetch_dataset_errors_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - maps_platform_datasets.ListDatasetsRequest, - dict, - ], -) -def test_list_datasets_rest(request_type): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = maps_platform_datasets.ListDatasetsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = maps_platform_datasets.ListDatasetsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_datasets(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDatasetsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_datasets_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5571,87 +4587,6 @@ def test_list_datasets_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_datasets_rest_interceptors(null_interceptor): - transport = transports.MapsPlatformDatasetsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.MapsPlatformDatasetsRestInterceptor(), - ) - client = MapsPlatformDatasetsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "post_list_datasets" - ) as post, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "pre_list_datasets" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = maps_platform_datasets.ListDatasetsRequest.pb( - maps_platform_datasets.ListDatasetsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = maps_platform_datasets.ListDatasetsResponse.to_json( - maps_platform_datasets.ListDatasetsResponse() - ) - - request = maps_platform_datasets.ListDatasetsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = maps_platform_datasets.ListDatasetsResponse() - - client.list_datasets( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_datasets_rest_bad_request( - transport: str = "rest", request_type=maps_platform_datasets.ListDatasetsRequest -): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_datasets(request) - - def test_list_datasets_rest_flattened(): client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5770,41 +4705,6 @@ def test_list_datasets_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - maps_platform_datasets.DeleteDatasetRequest, - dict, - ], -) -def test_delete_dataset_rest(request_type): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/datasets/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_dataset(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_dataset_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5921,25 +4821,1253 @@ def test_delete_dataset_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_dataset_rest_interceptors(null_interceptor): - transport = transports.MapsPlatformDatasetsRestTransport( +def test_delete_dataset_rest_flattened(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/datasets/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_dataset(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/datasets/*}" % client.transport._host, args[1] + ) + + +def test_delete_dataset_rest_flattened_error(transport: str = "rest"): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_dataset( + maps_platform_datasets.DeleteDatasetRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MapsPlatformDatasetsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MapsPlatformDatasetsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MapsPlatformDatasetsClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MapsPlatformDatasetsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MapsPlatformDatasetsClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MapsPlatformDatasetsClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MapsPlatformDatasetsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MapsPlatformDatasetsClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MapsPlatformDatasetsGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.MapsPlatformDatasetsRestInterceptor(), ) client = MapsPlatformDatasetsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.MapsPlatformDatasetsRestInterceptor, "pre_delete_dataset" + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.MapsPlatformDatasetsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.MapsPlatformDatasetsGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MapsPlatformDatasetsGrpcTransport, + transports.MapsPlatformDatasetsGrpcAsyncIOTransport, + transports.MapsPlatformDatasetsRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = MapsPlatformDatasetsClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_dataset_empty_call_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + call.return_value = gmm_dataset.Dataset() + client.create_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.CreateDatasetRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_dataset_metadata_empty_call_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_dataset_metadata), "__call__" + ) as call: + call.return_value = gmm_dataset.Dataset() + client.update_dataset_metadata(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.UpdateDatasetMetadataRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_dataset_empty_call_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + call.return_value = dataset.Dataset() + client.get_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.GetDatasetRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_fetch_dataset_errors_empty_call_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.fetch_dataset_errors), "__call__" + ) as call: + call.return_value = maps_platform_datasets.FetchDatasetErrorsResponse() + client.fetch_dataset_errors(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.FetchDatasetErrorsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_datasets_empty_call_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + call.return_value = maps_platform_datasets.ListDatasetsResponse() + client.list_datasets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.ListDatasetsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_dataset_empty_call_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + call.return_value = None + client.delete_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.DeleteDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = MapsPlatformDatasetsAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_dataset_empty_call_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gmm_dataset.Dataset( + name="name_value", + display_name="display_name_value", + description="description_value", + version_id="version_id_value", + usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], + version_description="version_description_value", + ) + ) + await client.create_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.CreateDatasetRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_dataset_metadata_empty_call_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_dataset_metadata), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gmm_dataset.Dataset( + name="name_value", + display_name="display_name_value", + description="description_value", + version_id="version_id_value", + usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], + version_description="version_description_value", + ) + ) + await client.update_dataset_metadata(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.UpdateDatasetMetadataRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_dataset_empty_call_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + dataset.Dataset( + name="name_value", + display_name="display_name_value", + description="description_value", + version_id="version_id_value", + usage=[dataset.Usage.USAGE_DATA_DRIVEN_STYLING], + version_description="version_description_value", + ) + ) + await client.get_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.GetDatasetRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_fetch_dataset_errors_empty_call_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.fetch_dataset_errors), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + maps_platform_datasets.FetchDatasetErrorsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.fetch_dataset_errors(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.FetchDatasetErrorsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_datasets_empty_call_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + maps_platform_datasets.ListDatasetsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_datasets(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.ListDatasetsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_dataset_empty_call_grpc_asyncio(): + client = MapsPlatformDatasetsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.DeleteDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = MapsPlatformDatasetsClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_create_dataset_rest_bad_request( + request_type=maps_platform_datasets.CreateDatasetRequest, +): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_dataset(request) + + +@pytest.mark.parametrize( + "request_type", + [ + maps_platform_datasets.CreateDatasetRequest, + dict, + ], +) +def test_create_dataset_rest_call_success(request_type): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request_init["dataset"] = { + "name": "name_value", + "display_name": "display_name_value", + "description": "description_value", + "version_id": "version_id_value", + "usage": [1], + "local_file_source": {"filename": "filename_value", "file_format": 1}, + "gcs_source": {"input_uri": "input_uri_value", "file_format": 1}, + "status": {"state": 1, "error_message": "error_message_value"}, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "version_create_time": {}, + "version_description": "version_description_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = maps_platform_datasets.CreateDatasetRequest.meta.fields["dataset"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["dataset"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["dataset"][field])): + del request_init["dataset"][field][i][subfield] + else: + del request_init["dataset"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gmm_dataset.Dataset( + name="name_value", + display_name="display_name_value", + description="description_value", + version_id="version_id_value", + usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], + version_description="version_description_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gmm_dataset.Dataset.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_dataset(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gmm_dataset.Dataset) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.version_id == "version_id_value" + assert response.usage == [gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING] + assert response.version_description == "version_description_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_dataset_rest_interceptors(null_interceptor): + transport = transports.MapsPlatformDatasetsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MapsPlatformDatasetsRestInterceptor(), + ) + client = MapsPlatformDatasetsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "post_create_dataset" + ) as post, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "pre_create_dataset" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = maps_platform_datasets.CreateDatasetRequest.pb( + maps_platform_datasets.CreateDatasetRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = gmm_dataset.Dataset.to_json(gmm_dataset.Dataset()) + req.return_value.content = return_value + + request = maps_platform_datasets.CreateDatasetRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gmm_dataset.Dataset() + + client.create_dataset( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_dataset_metadata_rest_bad_request( + request_type=maps_platform_datasets.UpdateDatasetMetadataRequest, +): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"dataset": {"name": "projects/sample1/datasets/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_dataset_metadata(request) + + +@pytest.mark.parametrize( + "request_type", + [ + maps_platform_datasets.UpdateDatasetMetadataRequest, + dict, + ], +) +def test_update_dataset_metadata_rest_call_success(request_type): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"dataset": {"name": "projects/sample1/datasets/sample2"}} + request_init["dataset"] = { + "name": "projects/sample1/datasets/sample2", + "display_name": "display_name_value", + "description": "description_value", + "version_id": "version_id_value", + "usage": [1], + "local_file_source": {"filename": "filename_value", "file_format": 1}, + "gcs_source": {"input_uri": "input_uri_value", "file_format": 1}, + "status": {"state": 1, "error_message": "error_message_value"}, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "version_create_time": {}, + "version_description": "version_description_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = maps_platform_datasets.UpdateDatasetMetadataRequest.meta.fields[ + "dataset" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["dataset"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["dataset"][field])): + del request_init["dataset"][field][i][subfield] + else: + del request_init["dataset"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gmm_dataset.Dataset( + name="name_value", + display_name="display_name_value", + description="description_value", + version_id="version_id_value", + usage=[gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING], + version_description="version_description_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gmm_dataset.Dataset.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_dataset_metadata(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gmm_dataset.Dataset) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.version_id == "version_id_value" + assert response.usage == [gmm_dataset.Usage.USAGE_DATA_DRIVEN_STYLING] + assert response.version_description == "version_description_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_dataset_metadata_rest_interceptors(null_interceptor): + transport = transports.MapsPlatformDatasetsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MapsPlatformDatasetsRestInterceptor(), + ) + client = MapsPlatformDatasetsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "post_update_dataset_metadata" + ) as post, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "pre_update_dataset_metadata" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = maps_platform_datasets.UpdateDatasetMetadataRequest.pb( + maps_platform_datasets.UpdateDatasetMetadataRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = gmm_dataset.Dataset.to_json(gmm_dataset.Dataset()) + req.return_value.content = return_value + + request = maps_platform_datasets.UpdateDatasetMetadataRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gmm_dataset.Dataset() + + client.update_dataset_metadata( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_dataset_rest_bad_request( + request_type=maps_platform_datasets.GetDatasetRequest, +): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/datasets/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_dataset(request) + + +@pytest.mark.parametrize( + "request_type", + [ + maps_platform_datasets.GetDatasetRequest, + dict, + ], +) +def test_get_dataset_rest_call_success(request_type): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/datasets/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = dataset.Dataset( + name="name_value", + display_name="display_name_value", + description="description_value", + version_id="version_id_value", + usage=[dataset.Usage.USAGE_DATA_DRIVEN_STYLING], + version_description="version_description_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = dataset.Dataset.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_dataset(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, dataset.Dataset) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.version_id == "version_id_value" + assert response.usage == [dataset.Usage.USAGE_DATA_DRIVEN_STYLING] + assert response.version_description == "version_description_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_dataset_rest_interceptors(null_interceptor): + transport = transports.MapsPlatformDatasetsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MapsPlatformDatasetsRestInterceptor(), + ) + client = MapsPlatformDatasetsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "post_get_dataset" + ) as post, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "pre_get_dataset" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = maps_platform_datasets.GetDatasetRequest.pb( + maps_platform_datasets.GetDatasetRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = dataset.Dataset.to_json(dataset.Dataset()) + req.return_value.content = return_value + + request = maps_platform_datasets.GetDatasetRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = dataset.Dataset() + + client.get_dataset( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_fetch_dataset_errors_rest_bad_request( + request_type=maps_platform_datasets.FetchDatasetErrorsRequest, +): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"dataset": "projects/sample1/datasets/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.fetch_dataset_errors(request) + + +@pytest.mark.parametrize( + "request_type", + [ + maps_platform_datasets.FetchDatasetErrorsRequest, + dict, + ], +) +def test_fetch_dataset_errors_rest_call_success(request_type): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"dataset": "projects/sample1/datasets/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = maps_platform_datasets.FetchDatasetErrorsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = maps_platform_datasets.FetchDatasetErrorsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.fetch_dataset_errors(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.FetchDatasetErrorsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_fetch_dataset_errors_rest_interceptors(null_interceptor): + transport = transports.MapsPlatformDatasetsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MapsPlatformDatasetsRestInterceptor(), + ) + client = MapsPlatformDatasetsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "post_fetch_dataset_errors" + ) as post, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "pre_fetch_dataset_errors" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = maps_platform_datasets.FetchDatasetErrorsRequest.pb( + maps_platform_datasets.FetchDatasetErrorsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = maps_platform_datasets.FetchDatasetErrorsResponse.to_json( + maps_platform_datasets.FetchDatasetErrorsResponse() + ) + req.return_value.content = return_value + + request = maps_platform_datasets.FetchDatasetErrorsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = maps_platform_datasets.FetchDatasetErrorsResponse() + + client.fetch_dataset_errors( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_datasets_rest_bad_request( + request_type=maps_platform_datasets.ListDatasetsRequest, +): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_datasets(request) + + +@pytest.mark.parametrize( + "request_type", + [ + maps_platform_datasets.ListDatasetsRequest, + dict, + ], +) +def test_list_datasets_rest_call_success(request_type): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = maps_platform_datasets.ListDatasetsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = maps_platform_datasets.ListDatasetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_datasets(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDatasetsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_datasets_rest_interceptors(null_interceptor): + transport = transports.MapsPlatformDatasetsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MapsPlatformDatasetsRestInterceptor(), + ) + client = MapsPlatformDatasetsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "post_list_datasets" + ) as post, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "pre_list_datasets" ) as pre: pre.assert_not_called() - pb_message = maps_platform_datasets.DeleteDatasetRequest.pb( - maps_platform_datasets.DeleteDatasetRequest() + post.assert_not_called() + pb_message = maps_platform_datasets.ListDatasetsRequest.pb( + maps_platform_datasets.ListDatasetsRequest() ) transcode.return_value = { "method": "post", @@ -5948,18 +6076,22 @@ def test_delete_dataset_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = maps_platform_datasets.ListDatasetsResponse.to_json( + maps_platform_datasets.ListDatasetsResponse() + ) + req.return_value.content = return_value - request = maps_platform_datasets.DeleteDatasetRequest() + request = maps_platform_datasets.ListDatasetsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = maps_platform_datasets.ListDatasetsResponse() - client.delete_dataset( + client.list_datasets( request, metadata=[ ("key", "val"), @@ -5968,16 +6100,15 @@ def test_delete_dataset_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_delete_dataset_rest_bad_request( - transport: str = "rest", request_type=maps_platform_datasets.DeleteDatasetRequest + request_type=maps_platform_datasets.DeleteDatasetRequest, ): client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "projects/sample1/datasets/sample2"} request = request_type(**request_init) @@ -5987,176 +6118,226 @@ def test_delete_dataset_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.delete_dataset(request) -def test_delete_dataset_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + maps_platform_datasets.DeleteDatasetRequest, + dict, + ], +) +def test_delete_dataset_rest_call_success(request_type): client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/datasets/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/datasets/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_dataset(request) - client.delete_dataset(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/datasets/*}" % client.transport._host, args[1] - ) + # Establish that the response is the type that we expect. + assert response is None -def test_delete_dataset_rest_flattened_error(transport: str = "rest"): - client = MapsPlatformDatasetsClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_dataset_rest_interceptors(null_interceptor): + transport = transports.MapsPlatformDatasetsRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.MapsPlatformDatasetsRestInterceptor(), ) + client = MapsPlatformDatasetsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MapsPlatformDatasetsRestInterceptor, "pre_delete_dataset" + ) as pre: + pre.assert_not_called() + pb_message = maps_platform_datasets.DeleteDatasetRequest.pb( + maps_platform_datasets.DeleteDatasetRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = maps_platform_datasets.DeleteDatasetRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.delete_dataset( - maps_platform_datasets.DeleteDatasetRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + -def test_delete_dataset_rest_error(): +def test_initialize_client_w_rest(): client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.MapsPlatformDatasetsGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_dataset_empty_call_rest(): + client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.MapsPlatformDatasetsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = MapsPlatformDatasetsClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_dataset), "__call__") as call: + client.create_dataset(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.MapsPlatformDatasetsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = MapsPlatformDatasetsClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.CreateDatasetRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = MapsPlatformDatasetsClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.MapsPlatformDatasetsGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_dataset_metadata_empty_call_rest(): + client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = MapsPlatformDatasetsClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_dataset_metadata), "__call__" + ) as call: + client.update_dataset_metadata(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.UpdateDatasetMetadataRequest() -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.MapsPlatformDatasetsGrpcTransport( + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_dataset_empty_call_rest(): + client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = MapsPlatformDatasetsClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_dataset), "__call__") as call: + client.get_dataset(request=None) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.MapsPlatformDatasetsGrpcTransport( + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.GetDatasetRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_fetch_dataset_errors_empty_call_rest(): + client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - transport = transports.MapsPlatformDatasetsGrpcAsyncIOTransport( + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.fetch_dataset_errors), "__call__" + ) as call: + client.fetch_dataset_errors(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.FetchDatasetErrorsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_datasets_empty_call_rest(): + client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_datasets), "__call__") as call: + client.list_datasets(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.MapsPlatformDatasetsGrpcTransport, - transports.MapsPlatformDatasetsGrpcAsyncIOTransport, - transports.MapsPlatformDatasetsRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.ListDatasetsRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = MapsPlatformDatasetsClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_dataset_empty_call_rest(): + client = MapsPlatformDatasetsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_dataset), "__call__") as call: + client.delete_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = maps_platform_datasets.DeleteDatasetRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -6753,36 +6934,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = MapsPlatformDatasetsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = MapsPlatformDatasetsClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = MapsPlatformDatasetsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-maps-places/google/maps/places/gapic_version.py b/packages/google-maps-places/google/maps/places/gapic_version.py index 3c51a1157647..558c8aab67c5 100644 --- a/packages/google-maps-places/google/maps/places/gapic_version.py +++ b/packages/google-maps-places/google/maps/places/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.18" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-places/google/maps/places_v1/gapic_version.py b/packages/google-maps-places/google/maps/places_v1/gapic_version.py index 3c51a1157647..558c8aab67c5 100644 --- a/packages/google-maps-places/google/maps/places_v1/gapic_version.py +++ b/packages/google-maps-places/google/maps/places_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.18" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/transports/README.rst b/packages/google-maps-places/google/maps/places_v1/services/places/transports/README.rst new file mode 100644 index 000000000000..954b9149d54e --- /dev/null +++ b/packages/google-maps-places/google/maps/places_v1/services/places/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`PlacesTransport` is the ABC for all transports. +- public child `PlacesGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `PlacesGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BasePlacesRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `PlacesRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py b/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py index 8a771c6f5b74..060a9e4f5f0e 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -230,6 +231,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -386,35 +390,44 @@ def autocomplete_places( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.search_nearby: gapic_v1.method_async.wrap_method( + self.search_nearby: self._wrap_method( self.search_nearby, default_timeout=None, client_info=client_info, ), - self.search_text: gapic_v1.method_async.wrap_method( + self.search_text: self._wrap_method( self.search_text, default_timeout=None, client_info=client_info, ), - self.get_photo_media: gapic_v1.method_async.wrap_method( + self.get_photo_media: self._wrap_method( self.get_photo_media, default_timeout=None, client_info=client_info, ), - self.get_place: gapic_v1.method_async.wrap_method( + self.get_place: self._wrap_method( self.get_place, default_timeout=None, client_info=client_info, ), - self.autocomplete_places: gapic_v1.method_async.wrap_method( + self.autocomplete_places: self._wrap_method( self.autocomplete_places, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("PlacesGrpcAsyncIOTransport",) diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py b/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py index eec6f2cdf9e3..89d6b4f90d0c 100644 --- a/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py +++ b/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.maps.places_v1.types import place, places_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BasePlacesRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.maps.places_v1.types import place, places_service - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import PlacesTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -230,8 +227,8 @@ class PlacesRestStub: _interceptor: PlacesRestInterceptor -class PlacesRestTransport(PlacesTransport): - """REST backend transport for Places. +class PlacesRestTransport(_BasePlacesRestTransport): + """REST backend synchronous transport for Places. Service definition for the Places API. Note: every request (except for Autocomplete requests) requires a field mask set outside of the @@ -244,7 +241,6 @@ class PlacesRestTransport(PlacesTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -298,21 +294,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -323,19 +310,34 @@ def __init__( self._interceptor = interceptor or PlacesRestInterceptor() self._prep_wrapped_messages(client_info) - class _AutocompletePlaces(PlacesRestStub): + class _AutocompletePlaces( + _BasePlacesRestTransport._BaseAutocompletePlaces, PlacesRestStub + ): def __hash__(self): - return hash("AutocompletePlaces") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PlacesRestTransport.AutocompletePlaces") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -363,47 +365,38 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/places:autocomplete", - "body": "*", - }, - ] + http_options = ( + _BasePlacesRestTransport._BaseAutocompletePlaces._get_http_options() + ) request, metadata = self._interceptor.pre_autocomplete_places( request, metadata ) - pb_request = places_service.AutocompletePlacesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BasePlacesRestTransport._BaseAutocompletePlaces._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = ( + _BasePlacesRestTransport._BaseAutocompletePlaces._get_request_body_json( + transcoded_request + ) ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BasePlacesRestTransport._BaseAutocompletePlaces._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = PlacesRestTransport._AutocompletePlaces._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -419,19 +412,31 @@ def __call__( resp = self._interceptor.post_autocomplete_places(resp) return resp - class _GetPhotoMedia(PlacesRestStub): + class _GetPhotoMedia(_BasePlacesRestTransport._BaseGetPhotoMedia, PlacesRestStub): def __hash__(self): - return hash("GetPhotoMedia") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PlacesRestTransport.GetPhotoMedia") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -458,38 +463,31 @@ def __call__( A photo media from Places API. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=places/*/photos/*/media}", - }, - ] + http_options = ( + _BasePlacesRestTransport._BaseGetPhotoMedia._get_http_options() + ) request, metadata = self._interceptor.pre_get_photo_media(request, metadata) - pb_request = places_service.GetPhotoMediaRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BasePlacesRestTransport._BaseGetPhotoMedia._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BasePlacesRestTransport._BaseGetPhotoMedia._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = PlacesRestTransport._GetPhotoMedia._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -505,19 +503,31 @@ def __call__( resp = self._interceptor.post_get_photo_media(resp) return resp - class _GetPlace(PlacesRestStub): + class _GetPlace(_BasePlacesRestTransport._BaseGetPlace, PlacesRestStub): def __hash__(self): - return hash("GetPlace") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PlacesRestTransport.GetPlace") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -546,38 +556,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=places/*}", - }, - ] + http_options = _BasePlacesRestTransport._BaseGetPlace._get_http_options() request, metadata = self._interceptor.pre_get_place(request, metadata) - pb_request = places_service.GetPlaceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BasePlacesRestTransport._BaseGetPlace._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BasePlacesRestTransport._BaseGetPlace._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = PlacesRestTransport._GetPlace._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -593,19 +594,32 @@ def __call__( resp = self._interceptor.post_get_place(resp) return resp - class _SearchNearby(PlacesRestStub): + class _SearchNearby(_BasePlacesRestTransport._BaseSearchNearby, PlacesRestStub): def __hash__(self): - return hash("SearchNearby") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PlacesRestTransport.SearchNearby") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -631,45 +645,36 @@ def __call__( Response proto for Search Nearby. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/places:searchNearby", - "body": "*", - }, - ] + http_options = ( + _BasePlacesRestTransport._BaseSearchNearby._get_http_options() + ) request, metadata = self._interceptor.pre_search_nearby(request, metadata) - pb_request = places_service.SearchNearbyRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BasePlacesRestTransport._BaseSearchNearby._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BasePlacesRestTransport._BaseSearchNearby._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BasePlacesRestTransport._BaseSearchNearby._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = PlacesRestTransport._SearchNearby._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -685,19 +690,32 @@ def __call__( resp = self._interceptor.post_search_nearby(resp) return resp - class _SearchText(PlacesRestStub): + class _SearchText(_BasePlacesRestTransport._BaseSearchText, PlacesRestStub): def __hash__(self): - return hash("SearchText") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PlacesRestTransport.SearchText") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -723,45 +741,34 @@ def __call__( Response proto for SearchText. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/places:searchText", - "body": "*", - }, - ] + http_options = _BasePlacesRestTransport._BaseSearchText._get_http_options() request, metadata = self._interceptor.pre_search_text(request, metadata) - pb_request = places_service.SearchTextRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BasePlacesRestTransport._BaseSearchText._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BasePlacesRestTransport._BaseSearchText._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BasePlacesRestTransport._BaseSearchText._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = PlacesRestTransport._SearchText._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest_base.py b/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest_base.py new file mode 100644 index 000000000000..80a7db462bf9 --- /dev/null +++ b/packages/google-maps-places/google/maps/places_v1/services/places/transports/rest_base.py @@ -0,0 +1,356 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.maps.places_v1.types import place, places_service + +from .base import DEFAULT_CLIENT_INFO, PlacesTransport + + +class _BasePlacesRestTransport(PlacesTransport): + """Base REST backend transport for Places. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "places.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'places.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseAutocompletePlaces: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/places:autocomplete", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = places_service.AutocompletePlacesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacesRestTransport._BaseAutocompletePlaces._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetPhotoMedia: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=places/*/photos/*/media}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = places_service.GetPhotoMediaRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacesRestTransport._BaseGetPhotoMedia._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetPlace: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=places/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = places_service.GetPlaceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacesRestTransport._BaseGetPlace._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseSearchNearby: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/places:searchNearby", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = places_service.SearchNearbyRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacesRestTransport._BaseSearchNearby._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseSearchText: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/places:searchText", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = places_service.SearchTextRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacesRestTransport._BaseSearchText._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BasePlacesRestTransport",) diff --git a/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json b/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json index e9caf90c3929..74eb224b30a6 100644 --- a/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json +++ b/packages/google-maps-places/samples/generated_samples/snippet_metadata_google.maps.places.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-places", - "version": "0.1.18" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-maps-places/setup.py b/packages/google-maps-places/setup.py index 77540957bbe5..aaee7a4dc2df 100644 --- a/packages/google-maps-places/setup.py +++ b/packages/google-maps-places/setup.py @@ -47,6 +47,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-geo-type >= 0.1.0, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-places" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -89,6 +90,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py b/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py index c7fa3af8519d..71d288094892 100644 --- a/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py +++ b/packages/google-maps-places/tests/unit/gapic/places_v1/test_places.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,16 +52,8 @@ from google.auth.exceptions import MutualTLSChannelError from google.geo.type.types import viewport from google.oauth2 import service_account -from google.protobuf import json_format from google.type import latlng_pb2 # type: ignore from google.type import localized_text_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.maps.places_v1.services.places import ( PlacesAsyncClient, @@ -68,10 +77,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1098,25 +1121,6 @@ def test_search_nearby(request_type, transport: str = "grpc"): assert isinstance(response, places_service.SearchNearbyResponse) -def test_search_nearby_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_nearby), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.search_nearby() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.SearchNearbyRequest() - - def test_search_nearby_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1182,27 +1186,6 @@ def test_search_nearby_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_search_nearby_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_nearby), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - places_service.SearchNearbyResponse() - ) - response = await client.search_nearby() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.SearchNearbyRequest() - - @pytest.mark.asyncio async def test_search_nearby_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1211,7 +1194,7 @@ async def test_search_nearby_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1250,7 +1233,7 @@ async def test_search_nearby_async( transport: str = "grpc_asyncio", request_type=places_service.SearchNearbyRequest ): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1314,25 +1297,6 @@ def test_search_text(request_type, transport: str = "grpc"): assert isinstance(response, places_service.SearchTextResponse) -def test_search_text_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_text), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.search_text() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.SearchTextRequest() - - def test_search_text_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1402,27 +1366,6 @@ def test_search_text_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_search_text_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search_text), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - places_service.SearchTextResponse() - ) - response = await client.search_text() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.SearchTextRequest() - - @pytest.mark.asyncio async def test_search_text_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1431,7 +1374,7 @@ async def test_search_text_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1470,7 +1413,7 @@ async def test_search_text_async( transport: str = "grpc_asyncio", request_type=places_service.SearchTextRequest ): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1539,25 +1482,6 @@ def test_get_photo_media(request_type, transport: str = "grpc"): assert response.photo_uri == "photo_uri_value" -def test_get_photo_media_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_photo_media), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_photo_media() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.GetPhotoMediaRequest() - - def test_get_photo_media_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1621,30 +1545,6 @@ def test_get_photo_media_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_photo_media_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_photo_media), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - places_service.PhotoMedia( - name="name_value", - photo_uri="photo_uri_value", - ) - ) - response = await client.get_photo_media() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.GetPhotoMediaRequest() - - @pytest.mark.asyncio async def test_get_photo_media_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1653,7 +1553,7 @@ async def test_get_photo_media_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1692,7 +1592,7 @@ async def test_get_photo_media_async( transport: str = "grpc_asyncio", request_type=places_service.GetPhotoMediaRequest ): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1760,7 +1660,7 @@ def test_get_photo_media_field_headers(): @pytest.mark.asyncio async def test_get_photo_media_field_headers_async(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1830,7 +1730,7 @@ def test_get_photo_media_flattened_error(): @pytest.mark.asyncio async def test_get_photo_media_flattened_async(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1859,7 +1759,7 @@ async def test_get_photo_media_flattened_async(): @pytest.mark.asyncio async def test_get_photo_media_flattened_error_async(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1987,25 +1887,6 @@ def test_get_place(request_type, transport: str = "grpc"): assert response.good_for_watching_sports is True -def test_get_place_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_place), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_place() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.GetPlaceRequest() - - def test_get_place_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2075,76 +1956,13 @@ def test_get_place_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_place_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_place), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - place.Place( - name="name_value", - id="id_value", - types=["types_value"], - primary_type="primary_type_value", - national_phone_number="national_phone_number_value", - international_phone_number="international_phone_number_value", - formatted_address="formatted_address_value", - short_formatted_address="short_formatted_address_value", - rating=0.645, - google_maps_uri="google_maps_uri_value", - website_uri="website_uri_value", - utc_offset_minutes=1942, - adr_format_address="adr_format_address_value", - business_status=place.Place.BusinessStatus.OPERATIONAL, - price_level=place.PriceLevel.PRICE_LEVEL_FREE, - user_rating_count=1835, - icon_mask_base_uri="icon_mask_base_uri_value", - icon_background_color="icon_background_color_value", - takeout=True, - delivery=True, - dine_in=True, - curbside_pickup=True, - reservable=True, - serves_breakfast=True, - serves_lunch=True, - serves_dinner=True, - serves_beer=True, - serves_wine=True, - serves_brunch=True, - serves_vegetarian_food=True, - outdoor_seating=True, - live_music=True, - menu_for_children=True, - serves_cocktails=True, - serves_dessert=True, - serves_coffee=True, - good_for_children=True, - allows_dogs=True, - restroom=True, - good_for_groups=True, - good_for_watching_sports=True, - ) - ) - response = await client.get_place() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.GetPlaceRequest() - - @pytest.mark.asyncio async def test_get_place_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2183,7 +2001,7 @@ async def test_get_place_async( transport: str = "grpc_asyncio", request_type=places_service.GetPlaceRequest ): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2329,7 +2147,7 @@ def test_get_place_field_headers(): @pytest.mark.asyncio async def test_get_place_field_headers_async(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2397,7 +2215,7 @@ def test_get_place_flattened_error(): @pytest.mark.asyncio async def test_get_place_flattened_async(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2424,7 +2242,7 @@ async def test_get_place_flattened_async(): @pytest.mark.asyncio async def test_get_place_flattened_error_async(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2471,27 +2289,6 @@ def test_autocomplete_places(request_type, transport: str = "grpc"): assert isinstance(response, places_service.AutocompletePlacesResponse) -def test_autocomplete_places_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.autocomplete_places), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.autocomplete_places() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.AutocompletePlacesRequest() - - def test_autocomplete_places_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2567,29 +2364,6 @@ def test_autocomplete_places_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_autocomplete_places_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.autocomplete_places), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - places_service.AutocompletePlacesResponse() - ) - response = await client.autocomplete_places() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == places_service.AutocompletePlacesRequest() - - @pytest.mark.asyncio async def test_autocomplete_places_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2598,7 +2372,7 @@ async def test_autocomplete_places_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2638,7 +2412,7 @@ async def test_autocomplete_places_async( request_type=places_service.AutocompletePlacesRequest, ): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2671,43 +2445,6 @@ async def test_autocomplete_places_async_from_dict(): await test_autocomplete_places_async(request_type=dict) -@pytest.mark.parametrize( - "request_type", - [ - places_service.SearchNearbyRequest, - dict, - ], -) -def test_search_nearby_rest(request_type): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = places_service.SearchNearbyResponse() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = places_service.SearchNearbyResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.search_nearby(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, places_service.SearchNearbyResponse) - - def test_search_nearby_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2823,128 +2560,6 @@ def test_search_nearby_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("locationRestriction",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_search_nearby_rest_interceptors(null_interceptor): - transport = transports.PlacesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), - ) - client = PlacesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.PlacesRestInterceptor, "post_search_nearby" - ) as post, mock.patch.object( - transports.PlacesRestInterceptor, "pre_search_nearby" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = places_service.SearchNearbyRequest.pb( - places_service.SearchNearbyRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = places_service.SearchNearbyResponse.to_json( - places_service.SearchNearbyResponse() - ) - - request = places_service.SearchNearbyRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = places_service.SearchNearbyResponse() - - client.search_nearby( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_search_nearby_rest_bad_request( - transport: str = "rest", request_type=places_service.SearchNearbyRequest -): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.search_nearby(request) - - -def test_search_nearby_rest_error(): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - places_service.SearchTextRequest, - dict, - ], -) -def test_search_text_rest(request_type): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = places_service.SearchTextResponse() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = places_service.SearchTextResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.search_text(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, places_service.SearchTextResponse) - - def test_search_text_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3065,133 +2680,6 @@ def test_search_text_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("textQuery",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_search_text_rest_interceptors(null_interceptor): - transport = transports.PlacesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), - ) - client = PlacesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.PlacesRestInterceptor, "post_search_text" - ) as post, mock.patch.object( - transports.PlacesRestInterceptor, "pre_search_text" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = places_service.SearchTextRequest.pb( - places_service.SearchTextRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = places_service.SearchTextResponse.to_json( - places_service.SearchTextResponse() - ) - - request = places_service.SearchTextRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = places_service.SearchTextResponse() - - client.search_text( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_search_text_rest_bad_request( - transport: str = "rest", request_type=places_service.SearchTextRequest -): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.search_text(request) - - -def test_search_text_rest_error(): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - places_service.GetPhotoMediaRequest, - dict, - ], -) -def test_get_photo_media_rest(request_type): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "places/sample1/photos/sample2/media"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = places_service.PhotoMedia( - name="name_value", - photo_uri="photo_uri_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = places_service.PhotoMedia.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_photo_media(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, places_service.PhotoMedia) - assert response.name == "name_value" - assert response.photo_uri == "photo_uri_value" - - def test_get_photo_media_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3328,85 +2816,6 @@ def test_get_photo_media_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_photo_media_rest_interceptors(null_interceptor): - transport = transports.PlacesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), - ) - client = PlacesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.PlacesRestInterceptor, "post_get_photo_media" - ) as post, mock.patch.object( - transports.PlacesRestInterceptor, "pre_get_photo_media" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = places_service.GetPhotoMediaRequest.pb( - places_service.GetPhotoMediaRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = places_service.PhotoMedia.to_json( - places_service.PhotoMedia() - ) - - request = places_service.GetPhotoMediaRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = places_service.PhotoMedia() - - client.get_photo_media( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_photo_media_rest_bad_request( - transport: str = "rest", request_type=places_service.GetPhotoMediaRequest -): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "places/sample1/photos/sample2/media"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_photo_media(request) - - def test_get_photo_media_rest_flattened(): client = PlacesClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3462,132 +2871,6 @@ def test_get_photo_media_rest_flattened_error(transport: str = "rest"): ) -def test_get_photo_media_rest_error(): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - places_service.GetPlaceRequest, - dict, - ], -) -def test_get_place_rest(request_type): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "places/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = place.Place( - name="name_value", - id="id_value", - types=["types_value"], - primary_type="primary_type_value", - national_phone_number="national_phone_number_value", - international_phone_number="international_phone_number_value", - formatted_address="formatted_address_value", - short_formatted_address="short_formatted_address_value", - rating=0.645, - google_maps_uri="google_maps_uri_value", - website_uri="website_uri_value", - utc_offset_minutes=1942, - adr_format_address="adr_format_address_value", - business_status=place.Place.BusinessStatus.OPERATIONAL, - price_level=place.PriceLevel.PRICE_LEVEL_FREE, - user_rating_count=1835, - icon_mask_base_uri="icon_mask_base_uri_value", - icon_background_color="icon_background_color_value", - takeout=True, - delivery=True, - dine_in=True, - curbside_pickup=True, - reservable=True, - serves_breakfast=True, - serves_lunch=True, - serves_dinner=True, - serves_beer=True, - serves_wine=True, - serves_brunch=True, - serves_vegetarian_food=True, - outdoor_seating=True, - live_music=True, - menu_for_children=True, - serves_cocktails=True, - serves_dessert=True, - serves_coffee=True, - good_for_children=True, - allows_dogs=True, - restroom=True, - good_for_groups=True, - good_for_watching_sports=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = place.Place.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_place(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, place.Place) - assert response.name == "name_value" - assert response.id == "id_value" - assert response.types == ["types_value"] - assert response.primary_type == "primary_type_value" - assert response.national_phone_number == "national_phone_number_value" - assert response.international_phone_number == "international_phone_number_value" - assert response.formatted_address == "formatted_address_value" - assert response.short_formatted_address == "short_formatted_address_value" - assert math.isclose(response.rating, 0.645, rel_tol=1e-6) - assert response.google_maps_uri == "google_maps_uri_value" - assert response.website_uri == "website_uri_value" - assert response.utc_offset_minutes == 1942 - assert response.adr_format_address == "adr_format_address_value" - assert response.business_status == place.Place.BusinessStatus.OPERATIONAL - assert response.price_level == place.PriceLevel.PRICE_LEVEL_FREE - assert response.user_rating_count == 1835 - assert response.icon_mask_base_uri == "icon_mask_base_uri_value" - assert response.icon_background_color == "icon_background_color_value" - assert response.takeout is True - assert response.delivery is True - assert response.dine_in is True - assert response.curbside_pickup is True - assert response.reservable is True - assert response.serves_breakfast is True - assert response.serves_lunch is True - assert response.serves_dinner is True - assert response.serves_beer is True - assert response.serves_wine is True - assert response.serves_brunch is True - assert response.serves_vegetarian_food is True - assert response.outdoor_seating is True - assert response.live_music is True - assert response.menu_for_children is True - assert response.serves_cocktails is True - assert response.serves_dessert is True - assert response.serves_coffee is True - assert response.good_for_children is True - assert response.allows_dogs is True - assert response.restroom is True - assert response.good_for_groups is True - assert response.good_for_watching_sports is True - - def test_get_place_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3722,109 +3005,34 @@ def test_get_place_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_place_rest_interceptors(null_interceptor): - transport = transports.PlacesRestTransport( +def test_get_place_rest_flattened(): + client = PlacesClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), + transport="rest", ) - client = PlacesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.PlacesRestInterceptor, "post_get_place" - ) as post, mock.patch.object( - transports.PlacesRestInterceptor, "pre_get_place" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = places_service.GetPlaceRequest.pb(places_service.GetPlaceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = place.Place.to_json(place.Place()) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = place.Place() - request = places_service.GetPlaceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = place.Place() + # get arguments that satisfy an http rule for this method + sample_request = {"name": "places/sample1"} - client.get_place( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) + mock_args.update(sample_request) - pre.assert_called_once() - post.assert_called_once() - - -def test_get_place_rest_bad_request( - transport: str = "rest", request_type=places_service.GetPlaceRequest -): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "places/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_place(request) - - -def test_get_place_rest_flattened(): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = place.Place() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "places/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = place.Place.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = place.Place.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value client.get_place(**mock_args) @@ -3852,49 +3060,6 @@ def test_get_place_rest_flattened_error(transport: str = "rest"): ) -def test_get_place_rest_error(): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - places_service.AutocompletePlacesRequest, - dict, - ], -) -def test_autocomplete_places_rest(request_type): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = places_service.AutocompletePlacesResponse() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = places_service.AutocompletePlacesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.autocomplete_places(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, places_service.AutocompletePlacesResponse) - - def test_autocomplete_places_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3957,66 +3122,1074 @@ def test_autocomplete_places_rest_required_fields( # verify required fields with default values are now present - jsonified_request["input"] = "input_value" + jsonified_request["input"] = "input_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).autocomplete_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "input" in jsonified_request + assert jsonified_request["input"] == "input_value" + + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = places_service.AutocompletePlacesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = places_service.AutocompletePlacesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.autocomplete_places(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_autocomplete_places_rest_unset_required_fields(): + transport = transports.PlacesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.autocomplete_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("input",))) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PlacesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PlacesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PlacesClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PlacesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PlacesClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PlacesClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PlacesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PlacesClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PlacesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PlacesClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PlacesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PlacesGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PlacesGrpcTransport, + transports.PlacesGrpcAsyncIOTransport, + transports.PlacesRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = PlacesClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_nearby_empty_call_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_nearby), "__call__") as call: + call.return_value = places_service.SearchNearbyResponse() + client.search_nearby(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.SearchNearbyRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_text_empty_call_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_text), "__call__") as call: + call.return_value = places_service.SearchTextResponse() + client.search_text(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.SearchTextRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_photo_media_empty_call_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_photo_media), "__call__") as call: + call.return_value = places_service.PhotoMedia() + client.get_photo_media(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.GetPhotoMediaRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_place_empty_call_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_place), "__call__") as call: + call.return_value = place.Place() + client.get_place(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.GetPlaceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_autocomplete_places_empty_call_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.autocomplete_places), "__call__" + ) as call: + call.return_value = places_service.AutocompletePlacesResponse() + client.autocomplete_places(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.AutocompletePlacesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = PlacesAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = PlacesAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_nearby_empty_call_grpc_asyncio(): + client = PlacesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_nearby), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + places_service.SearchNearbyResponse() + ) + await client.search_nearby(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.SearchNearbyRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_text_empty_call_grpc_asyncio(): + client = PlacesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_text), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + places_service.SearchTextResponse() + ) + await client.search_text(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.SearchTextRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_photo_media_empty_call_grpc_asyncio(): + client = PlacesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_photo_media), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + places_service.PhotoMedia( + name="name_value", + photo_uri="photo_uri_value", + ) + ) + await client.get_photo_media(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.GetPhotoMediaRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_place_empty_call_grpc_asyncio(): + client = PlacesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_place), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + place.Place( + name="name_value", + id="id_value", + types=["types_value"], + primary_type="primary_type_value", + national_phone_number="national_phone_number_value", + international_phone_number="international_phone_number_value", + formatted_address="formatted_address_value", + short_formatted_address="short_formatted_address_value", + rating=0.645, + google_maps_uri="google_maps_uri_value", + website_uri="website_uri_value", + utc_offset_minutes=1942, + adr_format_address="adr_format_address_value", + business_status=place.Place.BusinessStatus.OPERATIONAL, + price_level=place.PriceLevel.PRICE_LEVEL_FREE, + user_rating_count=1835, + icon_mask_base_uri="icon_mask_base_uri_value", + icon_background_color="icon_background_color_value", + takeout=True, + delivery=True, + dine_in=True, + curbside_pickup=True, + reservable=True, + serves_breakfast=True, + serves_lunch=True, + serves_dinner=True, + serves_beer=True, + serves_wine=True, + serves_brunch=True, + serves_vegetarian_food=True, + outdoor_seating=True, + live_music=True, + menu_for_children=True, + serves_cocktails=True, + serves_dessert=True, + serves_coffee=True, + good_for_children=True, + allows_dogs=True, + restroom=True, + good_for_groups=True, + good_for_watching_sports=True, + ) + ) + await client.get_place(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.GetPlaceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_autocomplete_places_empty_call_grpc_asyncio(): + client = PlacesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.autocomplete_places), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + places_service.AutocompletePlacesResponse() + ) + await client.autocomplete_places(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.AutocompletePlacesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = PlacesClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_search_nearby_rest_bad_request( + request_type=places_service.SearchNearbyRequest, +): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.search_nearby(request) + + +@pytest.mark.parametrize( + "request_type", + [ + places_service.SearchNearbyRequest, + dict, + ], +) +def test_search_nearby_rest_call_success(request_type): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = places_service.SearchNearbyResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = places_service.SearchNearbyResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.search_nearby(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, places_service.SearchNearbyResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_nearby_rest_interceptors(null_interceptor): + transport = transports.PlacesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), + ) + client = PlacesClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacesRestInterceptor, "post_search_nearby" + ) as post, mock.patch.object( + transports.PlacesRestInterceptor, "pre_search_nearby" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = places_service.SearchNearbyRequest.pb( + places_service.SearchNearbyRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = places_service.SearchNearbyResponse.to_json( + places_service.SearchNearbyResponse() + ) + req.return_value.content = return_value + + request = places_service.SearchNearbyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = places_service.SearchNearbyResponse() + + client.search_nearby( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_search_text_rest_bad_request(request_type=places_service.SearchTextRequest): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.search_text(request) + + +@pytest.mark.parametrize( + "request_type", + [ + places_service.SearchTextRequest, + dict, + ], +) +def test_search_text_rest_call_success(request_type): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = places_service.SearchTextResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = places_service.SearchTextResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.search_text(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, places_service.SearchTextResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_text_rest_interceptors(null_interceptor): + transport = transports.PlacesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), + ) + client = PlacesClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacesRestInterceptor, "post_search_text" + ) as post, mock.patch.object( + transports.PlacesRestInterceptor, "pre_search_text" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = places_service.SearchTextRequest.pb( + places_service.SearchTextRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = places_service.SearchTextResponse.to_json( + places_service.SearchTextResponse() + ) + req.return_value.content = return_value + + request = places_service.SearchTextRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = places_service.SearchTextResponse() + + client.search_text( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_photo_media_rest_bad_request( + request_type=places_service.GetPhotoMediaRequest, +): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "places/sample1/photos/sample2/media"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_photo_media(request) + + +@pytest.mark.parametrize( + "request_type", + [ + places_service.GetPhotoMediaRequest, + dict, + ], +) +def test_get_photo_media_rest_call_success(request_type): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "places/sample1/photos/sample2/media"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = places_service.PhotoMedia( + name="name_value", + photo_uri="photo_uri_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = places_service.PhotoMedia.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_photo_media(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, places_service.PhotoMedia) + assert response.name == "name_value" + assert response.photo_uri == "photo_uri_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_photo_media_rest_interceptors(null_interceptor): + transport = transports.PlacesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), + ) + client = PlacesClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacesRestInterceptor, "post_get_photo_media" + ) as post, mock.patch.object( + transports.PlacesRestInterceptor, "pre_get_photo_media" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = places_service.GetPhotoMediaRequest.pb( + places_service.GetPhotoMediaRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = places_service.PhotoMedia.to_json(places_service.PhotoMedia()) + req.return_value.content = return_value + + request = places_service.GetPhotoMediaRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = places_service.PhotoMedia() + + client.get_photo_media( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_place_rest_bad_request(request_type=places_service.GetPlaceRequest): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "places/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_place(request) + + +@pytest.mark.parametrize( + "request_type", + [ + places_service.GetPlaceRequest, + dict, + ], +) +def test_get_place_rest_call_success(request_type): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "places/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = place.Place( + name="name_value", + id="id_value", + types=["types_value"], + primary_type="primary_type_value", + national_phone_number="national_phone_number_value", + international_phone_number="international_phone_number_value", + formatted_address="formatted_address_value", + short_formatted_address="short_formatted_address_value", + rating=0.645, + google_maps_uri="google_maps_uri_value", + website_uri="website_uri_value", + utc_offset_minutes=1942, + adr_format_address="adr_format_address_value", + business_status=place.Place.BusinessStatus.OPERATIONAL, + price_level=place.PriceLevel.PRICE_LEVEL_FREE, + user_rating_count=1835, + icon_mask_base_uri="icon_mask_base_uri_value", + icon_background_color="icon_background_color_value", + takeout=True, + delivery=True, + dine_in=True, + curbside_pickup=True, + reservable=True, + serves_breakfast=True, + serves_lunch=True, + serves_dinner=True, + serves_beer=True, + serves_wine=True, + serves_brunch=True, + serves_vegetarian_food=True, + outdoor_seating=True, + live_music=True, + menu_for_children=True, + serves_cocktails=True, + serves_dessert=True, + serves_coffee=True, + good_for_children=True, + allows_dogs=True, + restroom=True, + good_for_groups=True, + good_for_watching_sports=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = place.Place.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_place(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, place.Place) + assert response.name == "name_value" + assert response.id == "id_value" + assert response.types == ["types_value"] + assert response.primary_type == "primary_type_value" + assert response.national_phone_number == "national_phone_number_value" + assert response.international_phone_number == "international_phone_number_value" + assert response.formatted_address == "formatted_address_value" + assert response.short_formatted_address == "short_formatted_address_value" + assert math.isclose(response.rating, 0.645, rel_tol=1e-6) + assert response.google_maps_uri == "google_maps_uri_value" + assert response.website_uri == "website_uri_value" + assert response.utc_offset_minutes == 1942 + assert response.adr_format_address == "adr_format_address_value" + assert response.business_status == place.Place.BusinessStatus.OPERATIONAL + assert response.price_level == place.PriceLevel.PRICE_LEVEL_FREE + assert response.user_rating_count == 1835 + assert response.icon_mask_base_uri == "icon_mask_base_uri_value" + assert response.icon_background_color == "icon_background_color_value" + assert response.takeout is True + assert response.delivery is True + assert response.dine_in is True + assert response.curbside_pickup is True + assert response.reservable is True + assert response.serves_breakfast is True + assert response.serves_lunch is True + assert response.serves_dinner is True + assert response.serves_beer is True + assert response.serves_wine is True + assert response.serves_brunch is True + assert response.serves_vegetarian_food is True + assert response.outdoor_seating is True + assert response.live_music is True + assert response.menu_for_children is True + assert response.serves_cocktails is True + assert response.serves_dessert is True + assert response.serves_coffee is True + assert response.good_for_children is True + assert response.allows_dogs is True + assert response.restroom is True + assert response.good_for_groups is True + assert response.good_for_watching_sports is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_place_rest_interceptors(null_interceptor): + transport = transports.PlacesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), + ) + client = PlacesClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacesRestInterceptor, "post_get_place" + ) as post, mock.patch.object( + transports.PlacesRestInterceptor, "pre_get_place" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = places_service.GetPlaceRequest.pb(places_service.GetPlaceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = place.Place.to_json(place.Place()) + req.return_value.content = return_value + + request = places_service.GetPlaceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = place.Place() + + client.get_place( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).autocomplete_places._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + pre.assert_called_once() + post.assert_called_once() - # verify required fields with non-default values are left alone - assert "input" in jsonified_request - assert jsonified_request["input"] == "input_value" +def test_autocomplete_places_rest_bad_request( + request_type=places_service.AutocompletePlacesRequest, +): client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {} request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = places_service.AutocompletePlacesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.autocomplete_places(request) - # Convert return value to protobuf type - return_value = places_service.AutocompletePlacesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value +@pytest.mark.parametrize( + "request_type", + [ + places_service.AutocompletePlacesRequest, + dict, + ], +) +def test_autocomplete_places_rest_call_success(request_type): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - response = client.autocomplete_places(request) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = places_service.AutocompletePlacesResponse() + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_autocomplete_places_rest_unset_required_fields(): - transport = transports.PlacesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = places_service.AutocompletePlacesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.autocomplete_places(request) - unset_fields = transport.autocomplete_places._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("input",))) + # Establish that the response is the type that we expect. + assert isinstance(response, places_service.AutocompletePlacesResponse) @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -4026,6 +4199,7 @@ def test_autocomplete_places_rest_interceptors(null_interceptor): interceptor=None if null_interceptor else transports.PlacesRestInterceptor(), ) client = PlacesClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -4047,12 +4221,12 @@ def test_autocomplete_places_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = places_service.AutocompletePlacesResponse.to_json( + return_value = places_service.AutocompletePlacesResponse.to_json( places_service.AutocompletePlacesResponse() ) + req.return_value.content = return_value request = places_service.AutocompletePlacesRequest() metadata = [ @@ -4074,140 +4248,113 @@ def test_autocomplete_places_rest_interceptors(null_interceptor): post.assert_called_once() -def test_autocomplete_places_rest_bad_request( - transport: str = "rest", request_type=places_service.AutocompletePlacesRequest -): +def test_initialize_client_w_rest(): client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.autocomplete_places(request) + assert client is not None -def test_autocomplete_places_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_nearby_empty_call_rest(): client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_nearby), "__call__") as call: + client.search_nearby(request=None) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.PlacesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.SearchNearbyRequest() - # It is an error to provide a credentials file and a transport instance. - transport = transports.PlacesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PlacesClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + assert args[0] == request_msg - # It is an error to provide an api_key and a transport instance. - transport = transports.PlacesGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_text_empty_call_rest(): + client = PlacesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PlacesClient( - client_options=options, - transport=transport, - ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PlacesClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search_text), "__call__") as call: + client.search_text(request=None) - # It is an error to provide scopes and a transport instance. - transport = transports.PlacesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PlacesClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.SearchTextRequest() + assert args[0] == request_msg -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.PlacesGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_photo_media_empty_call_rest(): + client = PlacesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = PlacesClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_photo_media), "__call__") as call: + client.get_photo_media(request=None) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.PlacesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.GetPhotoMediaRequest() - transport = transports.PlacesGrpcAsyncIOTransport( + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_place_empty_call_rest(): + client = PlacesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_place), "__call__") as call: + client.get_place(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.PlacesGrpcTransport, - transports.PlacesGrpcAsyncIOTransport, - transports.PlacesRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.GetPlaceRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = PlacesClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_autocomplete_places_empty_call_rest(): + client = PlacesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.autocomplete_places), "__call__" + ) as call: + client.autocomplete_places(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = places_service.AutocompletePlacesRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4853,36 +5000,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = PlacesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = PlacesClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = PlacesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py index 937ede8823ef..558c8aab67c5 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.4" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py index 73dc5e7358cc..d8ad78e46e99 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/async_client.py @@ -558,11 +558,7 @@ async def get_operation( # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.get_operation, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] # Certain fields should be provided within the metadata header; # add these here. diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py index 93b71fd86ac4..7cd2e3ac409b 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/client.py @@ -971,11 +971,7 @@ def get_operation( # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. - rpc = gapic_v1.method.wrap_method( - self._transport.get_operation, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) + rpc = self._transport._wrapped_methods[self._transport.get_operation] # Certain fields should be provided within the metadata header; # add these here. diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/README.rst b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/README.rst new file mode 100644 index 000000000000..777c90bfd2dd --- /dev/null +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`RouteOptimizationTransport` is the ABC for all transports. +- public child `RouteOptimizationGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `RouteOptimizationGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseRouteOptimizationRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `RouteOptimizationRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/base.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/base.py index c71fce73f9c7..b92dde20b511 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/base.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/base.py @@ -148,6 +148,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), } def close(self): diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py index 285c3188cd2e..36b86ca20bae 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -250,6 +251,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -378,7 +382,7 @@ def batch_optimize_tours( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.optimize_tours: gapic_v1.method_async.wrap_method( + self.optimize_tours: self._wrap_method( self.optimize_tours, default_retry=retries.AsyncRetry( initial=1.0, @@ -392,16 +396,30 @@ def _prep_wrapped_messages(self, client_info): default_timeout=3600.0, client_info=client_info, ), - self.batch_optimize_tours: gapic_v1.method_async.wrap_method( + self.batch_optimize_tours: self._wrap_method( self.batch_optimize_tours, default_timeout=None, client_info=client_info, ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + @property def get_operation( self, diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py index b92db0e9f025..3d43a8a44ba4 100644 --- a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py @@ -16,39 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import ( - gapic_v1, - operations_v1, - path_template, - rest_helpers, - rest_streaming, -) +from google.api_core import gapic_v1, operations_v1, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.maps.routeoptimization_v1.types import route_optimization_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseRouteOptimizationRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.longrunning import operations_pb2 # type: ignore - -from google.maps.routeoptimization_v1.types import route_optimization_service - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import RouteOptimizationTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -174,8 +164,8 @@ class RouteOptimizationRestStub: _interceptor: RouteOptimizationRestInterceptor -class RouteOptimizationRestTransport(RouteOptimizationTransport): - """REST backend transport for RouteOptimization. +class RouteOptimizationRestTransport(_BaseRouteOptimizationRestTransport): + """REST backend synchronous transport for RouteOptimization. A service for optimizing vehicle tours. @@ -206,7 +196,6 @@ class RouteOptimizationRestTransport(RouteOptimizationTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -260,21 +249,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -320,19 +300,35 @@ def operations_client(self) -> operations_v1.AbstractOperationsClient: # Return the client from cache. return self._operations_client - class _BatchOptimizeTours(RouteOptimizationRestStub): + class _BatchOptimizeTours( + _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours, + RouteOptimizationRestStub, + ): def __hash__(self): - return hash("BatchOptimizeTours") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RouteOptimizationRestTransport.BatchOptimizeTours") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -367,54 +363,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}:batchOptimizeTours", - "body": "*", - }, - { - "method": "post", - "uri": "/v1/{parent=projects/*}:batchOptimizeTours", - "body": "*", - }, - ] + http_options = ( + _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours._get_http_options() + ) request, metadata = self._interceptor.pre_batch_optimize_tours( request, metadata ) - pb_request = route_optimization_service.BatchOptimizeToursRequest.pb( - request + transcoded_request = _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RouteOptimizationRestTransport._BatchOptimizeTours._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -428,19 +404,35 @@ def __call__( resp = self._interceptor.post_batch_optimize_tours(resp) return resp - class _OptimizeTours(RouteOptimizationRestStub): + class _OptimizeTours( + _BaseRouteOptimizationRestTransport._BaseOptimizeTours, + RouteOptimizationRestStub, + ): def __hash__(self): - return hash("OptimizeTours") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RouteOptimizationRestTransport.OptimizeTours") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -474,50 +466,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}:optimizeTours", - "body": "*", - }, - { - "method": "post", - "uri": "/v1/{parent=projects/*}:optimizeTours", - "body": "*", - }, - ] + http_options = ( + _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_http_options() + ) request, metadata = self._interceptor.pre_optimize_tours(request, metadata) - pb_request = route_optimization_service.OptimizeToursRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RouteOptimizationRestTransport._OptimizeTours._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -558,7 +532,34 @@ def optimize_tours( def get_operation(self): return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore - class _GetOperation(RouteOptimizationRestStub): + class _GetOperation( + _BaseRouteOptimizationRestTransport._BaseGetOperation, RouteOptimizationRestStub + ): + def __hash__(self): + return hash("RouteOptimizationRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + def __call__( self, request: operations_pb2.GetOperationRequest, @@ -582,32 +583,27 @@ def __call__( operations_pb2.Operation: Response from GetOperation method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/operations/*}", - }, - ] - + http_options = ( + _BaseRouteOptimizationRestTransport._BaseGetOperation._get_http_options() + ) request, metadata = self._interceptor.pre_get_operation(request, metadata) - request_kwargs = json_format.MessageToDict(request) - transcoded_request = path_template.transcode(http_options, **request_kwargs) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseRouteOptimizationRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads(json.dumps(transcoded_request["query_params"])) + query_params = _BaseRouteOptimizationRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params), + response = RouteOptimizationRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -615,8 +611,9 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + content = response.content.decode("utf-8") resp = operations_pb2.Operation() - resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = json_format.Parse(content, resp) resp = self._interceptor.post_get_operation(resp) return resp diff --git a/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest_base.py b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest_base.py new file mode 100644 index 000000000000..a1f86809d2ab --- /dev/null +++ b/packages/google-maps-routeoptimization/google/maps/routeoptimization_v1/services/route_optimization/transports/rest_base.py @@ -0,0 +1,243 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.maps.routeoptimization_v1.types import route_optimization_service + +from .base import DEFAULT_CLIENT_INFO, RouteOptimizationTransport + + +class _BaseRouteOptimizationRestTransport(RouteOptimizationTransport): + """Base REST backend transport for RouteOptimization. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "routeoptimization.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'routeoptimization.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchOptimizeTours: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}:batchOptimizeTours", + "body": "*", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*}:batchOptimizeTours", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = route_optimization_service.BatchOptimizeToursRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRouteOptimizationRestTransport._BaseBatchOptimizeTours._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseOptimizeTours: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}:optimizeTours", + "body": "*", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*}:optimizeTours", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = route_optimization_service.OptimizeToursRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRouteOptimizationRestTransport._BaseOptimizeTours._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseRouteOptimizationRestTransport",) diff --git a/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json b/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json index b41aa32bfdd8..c329d83ca2a2 100644 --- a/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json +++ b/packages/google-maps-routeoptimization/samples/generated_samples/snippet_metadata_google.maps.routeoptimization.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-maps-routeoptimization", - "version": "0.1.4" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-maps-routeoptimization/setup.py b/packages/google-maps-routeoptimization/setup.py index c3720d5cd1c0..a3013c482fa0 100644 --- a/packages/google-maps-routeoptimization/setup.py +++ b/packages/google-maps-routeoptimization/setup.py @@ -48,6 +48,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-routeoptimization" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -90,6 +91,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py b/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py index 019f424b2345..6457ac729fd0 100644 --- a/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py +++ b/packages/google-maps-routeoptimization/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py @@ -22,10 +22,27 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import ( future, gapic_v1, @@ -35,7 +52,7 @@ operations_v1, path_template, ) -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import operation_async # type: ignore from google.api_core import retry as retries @@ -45,16 +62,8 @@ from google.longrunning import operations_pb2 # type: ignore from google.oauth2 import service_account from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.type import latlng_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.maps.routeoptimization_v1.services.route_optimization import ( RouteOptimizationAsyncClient, @@ -64,10 +73,24 @@ from google.maps.routeoptimization_v1.types import route_optimization_service +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1203,25 +1226,6 @@ def test_optimize_tours(request_type, transport: str = "grpc"): assert response.request_label == "request_label_value" -def test_optimize_tours_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.optimize_tours), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.optimize_tours() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == route_optimization_service.OptimizeToursRequest() - - def test_optimize_tours_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1287,29 +1291,6 @@ def test_optimize_tours_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_optimize_tours_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.optimize_tours), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - route_optimization_service.OptimizeToursResponse( - request_label="request_label_value", - ) - ) - response = await client.optimize_tours() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == route_optimization_service.OptimizeToursRequest() - - @pytest.mark.asyncio async def test_optimize_tours_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1318,7 +1299,7 @@ async def test_optimize_tours_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1358,7 +1339,7 @@ async def test_optimize_tours_async( request_type=route_optimization_service.OptimizeToursRequest, ): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1424,7 +1405,7 @@ def test_optimize_tours_field_headers(): @pytest.mark.asyncio async def test_optimize_tours_field_headers_async(): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1488,27 +1469,6 @@ def test_batch_optimize_tours(request_type, transport: str = "grpc"): assert isinstance(response, future.Future) -def test_batch_optimize_tours_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_optimize_tours), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.batch_optimize_tours() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == route_optimization_service.BatchOptimizeToursRequest() - - def test_batch_optimize_tours_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1583,29 +1543,6 @@ def test_batch_optimize_tours_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_batch_optimize_tours_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_optimize_tours), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - response = await client.batch_optimize_tours() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == route_optimization_service.BatchOptimizeToursRequest() - - @pytest.mark.asyncio async def test_batch_optimize_tours_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1614,7 +1551,7 @@ async def test_batch_optimize_tours_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1659,7 +1596,7 @@ async def test_batch_optimize_tours_async( request_type=route_optimization_service.BatchOptimizeToursRequest, ): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1726,7 +1663,7 @@ def test_batch_optimize_tours_field_headers(): @pytest.mark.asyncio async def test_batch_optimize_tours_field_headers_async(): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1757,46 +1694,6 @@ async def test_batch_optimize_tours_field_headers_async(): ) in kw["metadata"] -@pytest.mark.parametrize( - "request_type", - [ - route_optimization_service.OptimizeToursRequest, - dict, - ], -) -def test_optimize_tours_rest(request_type): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = route_optimization_service.OptimizeToursResponse( - request_label="request_label_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = route_optimization_service.OptimizeToursResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.optimize_tours(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, route_optimization_service.OptimizeToursResponse) - assert response.request_label == "request_label_value" - - def test_optimize_tours_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1919,131 +1816,6 @@ def test_optimize_tours_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("parent",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_optimize_tours_rest_interceptors(null_interceptor): - transport = transports.RouteOptimizationRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RouteOptimizationRestInterceptor(), - ) - client = RouteOptimizationClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RouteOptimizationRestInterceptor, "post_optimize_tours" - ) as post, mock.patch.object( - transports.RouteOptimizationRestInterceptor, "pre_optimize_tours" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = route_optimization_service.OptimizeToursRequest.pb( - route_optimization_service.OptimizeToursRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - route_optimization_service.OptimizeToursResponse.to_json( - route_optimization_service.OptimizeToursResponse() - ) - ) - - request = route_optimization_service.OptimizeToursRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = route_optimization_service.OptimizeToursResponse() - - client.optimize_tours( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_optimize_tours_rest_bad_request( - transport: str = "rest", - request_type=route_optimization_service.OptimizeToursRequest, -): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.optimize_tours(request) - - -def test_optimize_tours_rest_error(): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - route_optimization_service.BatchOptimizeToursRequest, - dict, - ], -) -def test_batch_optimize_tours_rest(request_type): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.batch_optimize_tours(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - def test_batch_optimize_tours_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2177,15 +1949,419 @@ def test_batch_optimize_tours_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_batch_optimize_tours_rest_interceptors(null_interceptor): - transport = transports.RouteOptimizationRestTransport( +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.RouteOptimizationGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.RouteOptimizationGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RouteOptimizationClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.RouteOptimizationGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RouteOptimizationClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RouteOptimizationClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.RouteOptimizationGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RouteOptimizationClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.RouteOptimizationGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = RouteOptimizationClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.RouteOptimizationGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.RouteOptimizationGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RouteOptimizationGrpcTransport, + transports.RouteOptimizationGrpcAsyncIOTransport, + transports.RouteOptimizationRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = RouteOptimizationClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_optimize_tours_empty_call_grpc(): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.optimize_tours), "__call__") as call: + call.return_value = route_optimization_service.OptimizeToursResponse() + client.optimize_tours(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_optimization_service.OptimizeToursRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_optimize_tours_empty_call_grpc(): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_optimize_tours), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.batch_optimize_tours(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_optimization_service.BatchOptimizeToursRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = RouteOptimizationAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = RouteOptimizationAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_optimize_tours_empty_call_grpc_asyncio(): + client = RouteOptimizationAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.optimize_tours), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + route_optimization_service.OptimizeToursResponse( + request_label="request_label_value", + ) + ) + await client.optimize_tours(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_optimization_service.OptimizeToursRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_optimize_tours_empty_call_grpc_asyncio(): + client = RouteOptimizationAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_optimize_tours), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.batch_optimize_tours(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_optimization_service.BatchOptimizeToursRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = RouteOptimizationClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_optimize_tours_rest_bad_request( + request_type=route_optimization_service.OptimizeToursRequest, +): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.optimize_tours(request) + + +@pytest.mark.parametrize( + "request_type", + [ + route_optimization_service.OptimizeToursRequest, + dict, + ], +) +def test_optimize_tours_rest_call_success(request_type): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = route_optimization_service.OptimizeToursResponse( + request_label="request_label_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = route_optimization_service.OptimizeToursResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.optimize_tours(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, route_optimization_service.OptimizeToursResponse) + assert response.request_label == "request_label_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_optimize_tours_rest_interceptors(null_interceptor): + transport = transports.RouteOptimizationRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.RouteOptimizationRestInterceptor(), ) client = RouteOptimizationClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RouteOptimizationRestInterceptor, "post_optimize_tours" + ) as post, mock.patch.object( + transports.RouteOptimizationRestInterceptor, "pre_optimize_tours" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = route_optimization_service.OptimizeToursRequest.pb( + route_optimization_service.OptimizeToursRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = route_optimization_service.OptimizeToursResponse.to_json( + route_optimization_service.OptimizeToursResponse() + ) + req.return_value.content = return_value + + request = route_optimization_service.OptimizeToursRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = route_optimization_service.OptimizeToursResponse() + + client.optimize_tours( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_optimize_tours_rest_bad_request( + request_type=route_optimization_service.BatchOptimizeToursRequest, +): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.batch_optimize_tours(request) + + +@pytest.mark.parametrize( + "request_type", + [ + route_optimization_service.BatchOptimizeToursRequest, + dict, + ], +) +def test_batch_optimize_tours_rest_call_success(request_type): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.batch_optimize_tours(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_optimize_tours_rest_interceptors(null_interceptor): + transport = transports.RouteOptimizationRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RouteOptimizationRestInterceptor(), + ) + client = RouteOptimizationClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2209,12 +2385,10 @@ def test_batch_optimize_tours_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value request = route_optimization_service.BatchOptimizeToursRequest() metadata = [ @@ -2236,18 +2410,17 @@ def test_batch_optimize_tours_rest_interceptors(null_interceptor): post.assert_called_once() -def test_batch_optimize_tours_rest_bad_request( - transport: str = "rest", - request_type=route_optimization_service.BatchOptimizeToursRequest, +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, ): client = RouteOptimizationClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. with mock.patch.object(Session, "request") as req, pytest.raises( @@ -2255,122 +2428,112 @@ def test_batch_optimize_tours_rest_bad_request( ): # Wrap the value into a proper Response obj response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.batch_optimize_tours(request) + client.get_operation(request) -def test_batch_optimize_tours_rest_error(): +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.RouteOptimizationGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") - # It is an error to provide a credentials file and a transport instance. - transport = transports.RouteOptimizationGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = RouteOptimizationClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + req.return_value = response_value - # It is an error to provide an api_key and a transport instance. - transport = transports.RouteOptimizationGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = RouteOptimizationClient( - client_options=options, - transport=transport, - ) + response = client.get_operation(request) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = RouteOptimizationClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) - # It is an error to provide scopes and a transport instance. - transport = transports.RouteOptimizationGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + +def test_initialize_client_w_rest(): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - with pytest.raises(ValueError): - client = RouteOptimizationClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + assert client is not None -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.RouteOptimizationGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_optimize_tours_empty_call_rest(): + client = RouteOptimizationClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = RouteOptimizationClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.optimize_tours), "__call__") as call: + client.optimize_tours(request=None) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.RouteOptimizationGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_optimization_service.OptimizeToursRequest() - transport = transports.RouteOptimizationGrpcAsyncIOTransport( + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_optimize_tours_empty_call_rest(): + client = RouteOptimizationClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_optimize_tours), "__call__" + ) as call: + client.batch_optimize_tours(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.RouteOptimizationGrpcTransport, - transports.RouteOptimizationGrpcAsyncIOTransport, - transports.RouteOptimizationRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = route_optimization_service.BatchOptimizeToursRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = RouteOptimizationClient.get_transport_class(transport_name)( + +def test_route_optimization_rest_lro_client(): + client = RouteOptimizationClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have an api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, ) - assert transport.kind == transport_name + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client def test_transport_grpc_default(): @@ -2609,23 +2772,6 @@ def test_route_optimization_http_transport_client_cert_source_for_mtls(): mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) -def test_route_optimization_rest_lro_client(): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.AbstractOperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - @pytest.mark.parametrize( "transport_name", [ @@ -2983,78 +3129,6 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) -@pytest.mark.asyncio -async def test_transport_close_async(): - client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" - ) as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_get_operation_rest_bad_request( - transport: str = "rest", request_type=operations_pb2.GetOperationRequest -): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - request = request_type() - request = json_format.ParseDict( - {"name": "projects/sample1/locations/sample2/operations/sample3"}, request - ) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_operation(request) - - -@pytest.mark.parametrize( - "request_type", - [ - operations_pb2.GetOperationRequest, - dict, - ], -) -def test_get_operation_rest(request_type): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} - request = request_type(**request_init) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_operation(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, operations_pb2.Operation) - - def test_get_operation(transport: str = "grpc"): client = RouteOptimizationClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3082,7 +3156,7 @@ def test_get_operation(transport: str = "grpc"): @pytest.mark.asyncio async def test_get_operation_async(transport: str = "grpc_asyncio"): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3137,7 +3211,7 @@ def test_get_operation_field_headers(): @pytest.mark.asyncio async def test_get_operation_field_headers_async(): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3184,7 +3258,7 @@ def test_get_operation_from_dict(): @pytest.mark.asyncio async def test_get_operation_from_dict_async(): client = RouteOptimizationAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.get_operation), "__call__") as call: @@ -3200,22 +3274,41 @@ async def test_get_operation_from_dict_async(): call.assert_called() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } +def test_transport_close_grpc(): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() - for transport, close_name in transports.items(): - client = RouteOptimizationClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = RouteOptimizationAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = RouteOptimizationClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/README.rst b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/README.rst new file mode 100644 index 000000000000..ece3f327f1db --- /dev/null +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`RoutesTransport` is the ABC for all transports. +- public child `RoutesGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `RoutesGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseRoutesRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `RoutesRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py index 25f70c19904b..53f4300794cc 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -372,20 +376,29 @@ def compute_route_matrix( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.compute_routes: gapic_v1.method_async.wrap_method( + self.compute_routes: self._wrap_method( self.compute_routes, default_timeout=None, client_info=client_info, ), - self.compute_route_matrix: gapic_v1.method_async.wrap_method( + self.compute_route_matrix: self._wrap_method( self.compute_route_matrix, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("RoutesGrpcAsyncIOTransport",) diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py index 08b286734e99..53044250a575 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.maps.routing_v2.types import routes_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseRoutesRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.maps.routing_v2.types import routes_service - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import RoutesTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -139,8 +136,8 @@ class RoutesRestStub: _interceptor: RoutesRestInterceptor -class RoutesRestTransport(RoutesTransport): - """REST backend transport for Routes. +class RoutesRestTransport(_BaseRoutesRestTransport): + """REST backend synchronous transport for Routes. The Routes API. @@ -149,7 +146,6 @@ class RoutesRestTransport(RoutesTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -203,21 +199,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -228,19 +215,35 @@ def __init__( self._interceptor = interceptor or RoutesRestInterceptor() self._prep_wrapped_messages(client_info) - class _ComputeRouteMatrix(RoutesRestStub): + class _ComputeRouteMatrix( + _BaseRoutesRestTransport._BaseComputeRouteMatrix, RoutesRestStub + ): def __hash__(self): - return hash("ComputeRouteMatrix") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RoutesRestTransport.ComputeRouteMatrix") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + stream=True, + ) + return response def __call__( self, @@ -270,47 +273,38 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/distanceMatrix/v2:computeRouteMatrix", - "body": "*", - }, - ] + http_options = ( + _BaseRoutesRestTransport._BaseComputeRouteMatrix._get_http_options() + ) request, metadata = self._interceptor.pre_compute_route_matrix( request, metadata ) - pb_request = routes_service.ComputeRouteMatrixRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseRoutesRestTransport._BaseComputeRouteMatrix._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = ( + _BaseRoutesRestTransport._BaseComputeRouteMatrix._get_request_body_json( + transcoded_request + ) ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseRoutesRestTransport._BaseComputeRouteMatrix._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RoutesRestTransport._ComputeRouteMatrix._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -325,19 +319,32 @@ def __call__( resp = self._interceptor.post_compute_route_matrix(resp) return resp - class _ComputeRoutes(RoutesRestStub): + class _ComputeRoutes(_BaseRoutesRestTransport._BaseComputeRoutes, RoutesRestStub): def __hash__(self): - return hash("ComputeRoutes") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RoutesRestTransport.ComputeRoutes") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -363,45 +370,36 @@ def __call__( ComputeRoutes the response message. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/directions/v2:computeRoutes", - "body": "*", - }, - ] + http_options = ( + _BaseRoutesRestTransport._BaseComputeRoutes._get_http_options() + ) request, metadata = self._interceptor.pre_compute_routes(request, metadata) - pb_request = routes_service.ComputeRoutesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseRoutesRestTransport._BaseComputeRoutes._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseRoutesRestTransport._BaseComputeRoutes._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseRoutesRestTransport._BaseComputeRoutes._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RoutesRestTransport._ComputeRoutes._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest_base.py b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest_base.py new file mode 100644 index 000000000000..aca441e52a4d --- /dev/null +++ b/packages/google-maps-routing/google/maps/routing_v2/services/routes/transports/rest_base.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.maps.routing_v2.types import routes_service + +from .base import DEFAULT_CLIENT_INFO, RoutesTransport + + +class _BaseRoutesRestTransport(RoutesTransport): + """Base REST backend transport for Routes. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "routes.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'routes.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseComputeRouteMatrix: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/distanceMatrix/v2:computeRouteMatrix", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = routes_service.ComputeRouteMatrixRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRoutesRestTransport._BaseComputeRouteMatrix._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseComputeRoutes: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/directions/v2:computeRoutes", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = routes_service.ComputeRoutesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRoutesRestTransport._BaseComputeRoutes._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseRoutesRestTransport",) diff --git a/packages/google-maps-routing/google/maps/routing_v2/types/toll_passes.py b/packages/google-maps-routing/google/maps/routing_v2/types/toll_passes.py index 57edad22a37d..db2a0615cd62 100644 --- a/packages/google-maps-routing/google/maps/routing_v2/types/toll_passes.py +++ b/packages/google-maps-routing/google/maps/routing_v2/types/toll_passes.py @@ -85,6 +85,7 @@ class TollPass(proto.Enum): E-card provided by multiple banks used to pay for tolls. All e-cards via banks are charged the same so only one enum value is needed. E.g. + - Bank Mandiri https://www.bankmandiri.co.id/e-money - BCA https://www.bca.co.id/flazz diff --git a/packages/google-maps-routing/scripts/client-post-processing/doc-formatting.yaml b/packages/google-maps-routing/scripts/client-post-processing/doc-formatting.yaml new file mode 120000 index 000000000000..6e0991666f97 --- /dev/null +++ b/packages/google-maps-routing/scripts/client-post-processing/doc-formatting.yaml @@ -0,0 +1 @@ +../../../../scripts/client-post-processing/doc-formatting.yaml \ No newline at end of file diff --git a/packages/google-maps-routing/setup.py b/packages/google-maps-routing/setup.py index c35fa0f98964..34ba7f2de872 100644 --- a/packages/google-maps-routing/setup.py +++ b/packages/google-maps-routing/setup.py @@ -47,6 +47,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-geo-type >= 0.1.0, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-routing" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -89,6 +90,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py b/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py index 8f1804aabaf4..cb10af4bc981 100644 --- a/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py +++ b/packages/google-maps-routing/tests/unit/gapic/routing_v2/test_routes.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,18 +52,10 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore from google.type import latlng_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.maps.routing_v2.services.routes import ( RoutesAsyncClient, @@ -73,10 +82,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1103,25 +1126,6 @@ def test_compute_routes(request_type, transport: str = "grpc"): assert isinstance(response, routes_service.ComputeRoutesResponse) -def test_compute_routes_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.compute_routes), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.compute_routes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == routes_service.ComputeRoutesRequest() - - def test_compute_routes_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1187,27 +1191,6 @@ def test_compute_routes_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_compute_routes_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.compute_routes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - routes_service.ComputeRoutesResponse() - ) - response = await client.compute_routes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == routes_service.ComputeRoutesRequest() - - @pytest.mark.asyncio async def test_compute_routes_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1216,7 +1199,7 @@ async def test_compute_routes_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1255,7 +1238,7 @@ async def test_compute_routes_async( transport: str = "grpc_asyncio", request_type=routes_service.ComputeRoutesRequest ): client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1322,27 +1305,6 @@ def test_compute_route_matrix(request_type, transport: str = "grpc"): assert isinstance(message, routes_service.RouteMatrixElement) -def test_compute_route_matrix_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.compute_route_matrix), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.compute_route_matrix() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == routes_service.ComputeRouteMatrixRequest() - - def test_compute_route_matrix_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1414,30 +1376,6 @@ def test_compute_route_matrix_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_compute_route_matrix_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.compute_route_matrix), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) - call.return_value.read = mock.AsyncMock( - side_effect=[routes_service.RouteMatrixElement()] - ) - response = await client.compute_route_matrix() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == routes_service.ComputeRouteMatrixRequest() - - @pytest.mark.asyncio async def test_compute_route_matrix_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1446,7 +1384,7 @@ async def test_compute_route_matrix_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1486,7 +1424,7 @@ async def test_compute_route_matrix_async( request_type=routes_service.ComputeRouteMatrixRequest, ): client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1521,43 +1459,6 @@ async def test_compute_route_matrix_async_from_dict(): await test_compute_route_matrix_async(request_type=dict) -@pytest.mark.parametrize( - "request_type", - [ - routes_service.ComputeRoutesRequest, - dict, - ], -) -def test_compute_routes_rest(request_type): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = routes_service.ComputeRoutesResponse() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = routes_service.ComputeRoutesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.compute_routes(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, routes_service.ComputeRoutesResponse) - - def test_compute_routes_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1681,144 +1582,6 @@ def test_compute_routes_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_compute_routes_rest_interceptors(null_interceptor): - transport = transports.RoutesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.RoutesRestInterceptor(), - ) - client = RoutesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RoutesRestInterceptor, "post_compute_routes" - ) as post, mock.patch.object( - transports.RoutesRestInterceptor, "pre_compute_routes" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = routes_service.ComputeRoutesRequest.pb( - routes_service.ComputeRoutesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = routes_service.ComputeRoutesResponse.to_json( - routes_service.ComputeRoutesResponse() - ) - - request = routes_service.ComputeRoutesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = routes_service.ComputeRoutesResponse() - - client.compute_routes( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_compute_routes_rest_bad_request( - transport: str = "rest", request_type=routes_service.ComputeRoutesRequest -): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.compute_routes(request) - - -def test_compute_routes_rest_error(): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - routes_service.ComputeRouteMatrixRequest, - dict, - ], -) -def test_compute_route_matrix_rest(request_type): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = routes_service.RouteMatrixElement( - origin_index=1279, - destination_index=1817, - condition=routes_service.RouteMatrixElementCondition.ROUTE_EXISTS, - distance_meters=1594, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = routes_service.RouteMatrixElement.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - json_return_value = "[{}]".format(json_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - with mock.patch.object(response_value, "iter_content") as iter_content: - iter_content.return_value = iter(json_return_value) - response = client.compute_route_matrix(request) - - assert isinstance(response, Iterable) - response = next(response) - - # Establish that the response is the type that we expect. - assert isinstance(response, routes_service.RouteMatrixElement) - assert response.origin_index == 1279 - assert response.destination_index == 1817 - assert response.condition == routes_service.RouteMatrixElementCondition.ROUTE_EXISTS - assert response.distance_meters == 1594 - - def test_compute_route_matrix_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1949,92 +1712,6 @@ def test_compute_route_matrix_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_compute_route_matrix_rest_interceptors(null_interceptor): - transport = transports.RoutesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.RoutesRestInterceptor(), - ) - client = RoutesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RoutesRestInterceptor, "post_compute_route_matrix" - ) as post, mock.patch.object( - transports.RoutesRestInterceptor, "pre_compute_route_matrix" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = routes_service.ComputeRouteMatrixRequest.pb( - routes_service.ComputeRouteMatrixRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = routes_service.RouteMatrixElement.to_json( - routes_service.RouteMatrixElement() - ) - req.return_value._content = "[{}]".format(req.return_value._content) - - request = routes_service.ComputeRouteMatrixRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = routes_service.RouteMatrixElement() - - client.compute_route_matrix( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_compute_route_matrix_rest_bad_request( - transport: str = "rest", request_type=routes_service.ComputeRouteMatrixRequest -): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.compute_route_matrix(request) - - -def test_compute_route_matrix_rest_error(): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.RoutesGrpcTransport( @@ -2127,18 +1804,430 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = RoutesClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_compute_routes_empty_call_grpc(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.compute_routes), "__call__") as call: + call.return_value = routes_service.ComputeRoutesResponse() + client.compute_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = routes_service.ComputeRoutesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_compute_route_matrix_empty_call_grpc(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.compute_route_matrix), "__call__" + ) as call: + call.return_value = iter([routes_service.RouteMatrixElement()]) + client.compute_route_matrix(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = routes_service.ComputeRouteMatrixRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = RoutesAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = RoutesAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_compute_routes_empty_call_grpc_asyncio(): + client = RoutesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.compute_routes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + routes_service.ComputeRoutesResponse() + ) + await client.compute_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = routes_service.ComputeRoutesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_compute_route_matrix_empty_call_grpc_asyncio(): + client = RoutesAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.compute_route_matrix), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[routes_service.RouteMatrixElement()] + ) + await client.compute_route_matrix(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = routes_service.ComputeRouteMatrixRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = RoutesClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_compute_routes_rest_bad_request( + request_type=routes_service.ComputeRoutesRequest, +): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.compute_routes(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + routes_service.ComputeRoutesRequest, + dict, + ], +) +def test_compute_routes_rest_call_success(request_type): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = routes_service.ComputeRoutesResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = routes_service.ComputeRoutesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.compute_routes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, routes_service.ComputeRoutesResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_compute_routes_rest_interceptors(null_interceptor): + transport = transports.RoutesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.RoutesRestInterceptor(), + ) + client = RoutesClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RoutesRestInterceptor, "post_compute_routes" + ) as post, mock.patch.object( + transports.RoutesRestInterceptor, "pre_compute_routes" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = routes_service.ComputeRoutesRequest.pb( + routes_service.ComputeRoutesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = routes_service.ComputeRoutesResponse.to_json( + routes_service.ComputeRoutesResponse() + ) + req.return_value.content = return_value + + request = routes_service.ComputeRoutesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = routes_service.ComputeRoutesResponse() + + client.compute_routes( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_compute_route_matrix_rest_bad_request( + request_type=routes_service.ComputeRouteMatrixRequest, +): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.compute_route_matrix(request) + + +@pytest.mark.parametrize( + "request_type", + [ + routes_service.ComputeRouteMatrixRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = RoutesClient.get_transport_class(transport_name)( +def test_compute_route_matrix_rest_call_success(request_type): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = routes_service.RouteMatrixElement( + origin_index=1279, + destination_index=1817, + condition=routes_service.RouteMatrixElementCondition.ROUTE_EXISTS, + distance_meters=1594, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = routes_service.RouteMatrixElement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + json_return_value = "[{}]".format(json_return_value) + response_value.iter_content = mock.Mock(return_value=iter(json_return_value)) + req.return_value = response_value + response = client.compute_route_matrix(request) + + assert isinstance(response, Iterable) + response = next(response) + + # Establish that the response is the type that we expect. + assert isinstance(response, routes_service.RouteMatrixElement) + assert response.origin_index == 1279 + assert response.destination_index == 1817 + assert response.condition == routes_service.RouteMatrixElementCondition.ROUTE_EXISTS + assert response.distance_meters == 1594 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_compute_route_matrix_rest_interceptors(null_interceptor): + transport = transports.RoutesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.RoutesRestInterceptor(), + ) + client = RoutesClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RoutesRestInterceptor, "post_compute_route_matrix" + ) as post, mock.patch.object( + transports.RoutesRestInterceptor, "pre_compute_route_matrix" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = routes_service.ComputeRouteMatrixRequest.pb( + routes_service.ComputeRouteMatrixRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = routes_service.RouteMatrixElement.to_json( + routes_service.RouteMatrixElement() + ) + req.return_value.iter_content = mock.Mock(return_value=iter(return_value)) + + request = routes_service.ComputeRouteMatrixRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = routes_service.RouteMatrixElement() + + client.compute_route_matrix( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_compute_routes_empty_call_rest(): + client = RoutesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.compute_routes), "__call__") as call: + client.compute_routes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = routes_service.ComputeRoutesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_compute_route_matrix_empty_call_rest(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.compute_route_matrix), "__call__" + ) as call: + client.compute_route_matrix(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = routes_service.ComputeRouteMatrixRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2683,36 +2772,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = RoutesAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = RoutesClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = RoutesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/README.rst b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/README.rst new file mode 100644 index 000000000000..9860e8dc616e --- /dev/null +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`SolarTransport` is the ABC for all transports. +- public child `SolarGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `SolarGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseSolarRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `SolarRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py index cb8e903a3cde..920b24e85628 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -331,7 +335,7 @@ def get_geo_tiff( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.find_closest_building_insights: gapic_v1.method_async.wrap_method( + self.find_closest_building_insights: self._wrap_method( self.find_closest_building_insights, default_retry=retries.AsyncRetry( initial=1.0, @@ -345,7 +349,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.get_data_layers: gapic_v1.method_async.wrap_method( + self.get_data_layers: self._wrap_method( self.get_data_layers, default_retry=retries.AsyncRetry( initial=1.0, @@ -359,7 +363,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.get_geo_tiff: gapic_v1.method_async.wrap_method( + self.get_geo_tiff: self._wrap_method( self.get_geo_tiff, default_retry=retries.AsyncRetry( initial=1.0, @@ -375,8 +379,17 @@ def _prep_wrapped_messages(self, client_info): ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("SolarGrpcAsyncIOTransport",) diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py index bfd035ae4c53..4078f5ec3f23 100644 --- a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming +from google.api import httpbody_pb2 # type: ignore from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.maps.solar_v1.types import solar_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseSolarRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.api import httpbody_pb2 # type: ignore - -from google.maps.solar_v1.types import solar_service - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import SolarTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -174,8 +170,8 @@ class SolarRestStub: _interceptor: SolarRestInterceptor -class SolarRestTransport(SolarTransport): - """REST backend transport for Solar. +class SolarRestTransport(_BaseSolarRestTransport): + """REST backend synchronous transport for Solar. Service definition for the Solar API. @@ -184,7 +180,6 @@ class SolarRestTransport(SolarTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -238,21 +233,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -263,21 +249,33 @@ def __init__( self._interceptor = interceptor or SolarRestInterceptor() self._prep_wrapped_messages(client_info) - class _FindClosestBuildingInsights(SolarRestStub): + class _FindClosestBuildingInsights( + _BaseSolarRestTransport._BaseFindClosestBuildingInsights, SolarRestStub + ): def __hash__(self): - return hash("FindClosestBuildingInsights") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "location": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("SolarRestTransport.FindClosestBuildingInsights") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -309,40 +307,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/buildingInsights:findClosest", - }, - ] + http_options = ( + _BaseSolarRestTransport._BaseFindClosestBuildingInsights._get_http_options() + ) request, metadata = self._interceptor.pre_find_closest_building_insights( request, metadata ) - pb_request = solar_service.FindClosestBuildingInsightsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseSolarRestTransport._BaseFindClosestBuildingInsights._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseSolarRestTransport._BaseFindClosestBuildingInsights._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = SolarRestTransport._FindClosestBuildingInsights._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -358,22 +345,31 @@ def __call__( resp = self._interceptor.post_find_closest_building_insights(resp) return resp - class _GetDataLayers(SolarRestStub): + class _GetDataLayers(_BaseSolarRestTransport._BaseGetDataLayers, SolarRestStub): def __hash__(self): - return hash("GetDataLayers") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "location": {}, - "radiusMeters": 0.0, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("SolarRestTransport.GetDataLayers") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -411,38 +407,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/dataLayers:get", - }, - ] + http_options = ( + _BaseSolarRestTransport._BaseGetDataLayers._get_http_options() + ) request, metadata = self._interceptor.pre_get_data_layers(request, metadata) - pb_request = solar_service.GetDataLayersRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseSolarRestTransport._BaseGetDataLayers._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseSolarRestTransport._BaseGetDataLayers._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = SolarRestTransport._GetDataLayers._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -458,21 +447,31 @@ def __call__( resp = self._interceptor.post_get_data_layers(resp) return resp - class _GetGeoTiff(SolarRestStub): + class _GetGeoTiff(_BaseSolarRestTransport._BaseGetGeoTiff, SolarRestStub): def __hash__(self): - return hash("GetGeoTiff") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "id": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("SolarRestTransport.GetGeoTiff") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -547,38 +546,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/geoTiff:get", - }, - ] + http_options = _BaseSolarRestTransport._BaseGetGeoTiff._get_http_options() request, metadata = self._interceptor.pre_get_geo_tiff(request, metadata) - pb_request = solar_service.GetGeoTiffRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseSolarRestTransport._BaseGetGeoTiff._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseSolarRestTransport._BaseGetGeoTiff._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = SolarRestTransport._GetGeoTiff._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest_base.py b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest_base.py new file mode 100644 index 000000000000..4b5a35c8c4e7 --- /dev/null +++ b/packages/google-maps-solar/google/maps/solar_v1/services/solar/transports/rest_base.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api import httpbody_pb2 # type: ignore +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.maps.solar_v1.types import solar_service + +from .base import DEFAULT_CLIENT_INFO, SolarTransport + + +class _BaseSolarRestTransport(SolarTransport): + """Base REST backend transport for Solar. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "solar.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'solar.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseFindClosestBuildingInsights: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "location": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/buildingInsights:findClosest", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = solar_service.FindClosestBuildingInsightsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSolarRestTransport._BaseFindClosestBuildingInsights._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDataLayers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "location": {}, + "radiusMeters": 0.0, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/dataLayers:get", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = solar_service.GetDataLayersRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSolarRestTransport._BaseGetDataLayers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGeoTiff: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "id": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/geoTiff:get", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = solar_service.GetGeoTiffRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSolarRestTransport._BaseGetGeoTiff._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseSolarRestTransport",) diff --git a/packages/google-maps-solar/setup.py b/packages/google-maps-solar/setup.py index d39a442fd709..a517dc74f4b4 100644 --- a/packages/google-maps-solar/setup.py +++ b/packages/google-maps-solar/setup.py @@ -46,6 +46,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-solar" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -88,6 +89,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py b/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py index 9306930f7bd8..695e3082c0b5 100644 --- a/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py +++ b/packages/google-maps-solar/tests/unit/gapic/solar_v1/test_solar.py @@ -22,13 +22,30 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api import httpbody_pb2 # type: ignore from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -36,16 +53,8 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import any_pb2 # type: ignore -from google.protobuf import json_format from google.type import date_pb2 # type: ignore from google.type import latlng_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.maps.solar_v1.services.solar import ( SolarAsyncClient, @@ -55,10 +64,24 @@ from google.maps.solar_v1.types import solar_service +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1096,27 +1119,6 @@ def test_find_closest_building_insights(request_type, transport: str = "grpc"): assert response.imagery_quality == solar_service.ImageryQuality.HIGH -def test_find_closest_building_insights_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.find_closest_building_insights), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.find_closest_building_insights() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == solar_service.FindClosestBuildingInsightsRequest() - - def test_find_closest_building_insights_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1183,36 +1185,6 @@ def test_find_closest_building_insights_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_find_closest_building_insights_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.find_closest_building_insights), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - solar_service.BuildingInsights( - name="name_value", - postal_code="postal_code_value", - administrative_area="administrative_area_value", - statistical_area="statistical_area_value", - region_code="region_code_value", - imagery_quality=solar_service.ImageryQuality.HIGH, - ) - ) - response = await client.find_closest_building_insights() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == solar_service.FindClosestBuildingInsightsRequest() - - @pytest.mark.asyncio async def test_find_closest_building_insights_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1221,7 +1193,7 @@ async def test_find_closest_building_insights_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1261,7 +1233,7 @@ async def test_find_closest_building_insights_async( request_type=solar_service.FindClosestBuildingInsightsRequest, ): client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1355,25 +1327,6 @@ def test_get_data_layers(request_type, transport: str = "grpc"): assert response.imagery_quality == solar_service.ImageryQuality.HIGH -def test_get_data_layers_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_data_layers), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_data_layers() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == solar_service.GetDataLayersRequest() - - def test_get_data_layers_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1433,35 +1386,6 @@ def test_get_data_layers_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_data_layers_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_data_layers), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - solar_service.DataLayers( - dsm_url="dsm_url_value", - rgb_url="rgb_url_value", - mask_url="mask_url_value", - annual_flux_url="annual_flux_url_value", - monthly_flux_url="monthly_flux_url_value", - hourly_shade_urls=["hourly_shade_urls_value"], - imagery_quality=solar_service.ImageryQuality.HIGH, - ) - ) - response = await client.get_data_layers() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == solar_service.GetDataLayersRequest() - - @pytest.mark.asyncio async def test_get_data_layers_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1470,7 +1394,7 @@ async def test_get_data_layers_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1509,7 +1433,7 @@ async def test_get_data_layers_async( transport: str = "grpc_asyncio", request_type=solar_service.GetDataLayersRequest ): client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1593,25 +1517,6 @@ def test_get_geo_tiff(request_type, transport: str = "grpc"): assert response.data == b"data_blob" -def test_get_geo_tiff_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_geo_tiff), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_geo_tiff() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == solar_service.GetGeoTiffRequest() - - def test_get_geo_tiff_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1675,30 +1580,6 @@ def test_get_geo_tiff_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_geo_tiff_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_geo_tiff), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - httpbody_pb2.HttpBody( - content_type="content_type_value", - data=b"data_blob", - ) - ) - response = await client.get_geo_tiff() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == solar_service.GetGeoTiffRequest() - - @pytest.mark.asyncio async def test_get_geo_tiff_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1707,7 +1588,7 @@ async def test_get_geo_tiff_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1746,7 +1627,7 @@ async def test_get_geo_tiff_async( transport: str = "grpc_asyncio", request_type=solar_service.GetGeoTiffRequest ): client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1782,56 +1663,6 @@ async def test_get_geo_tiff_async_from_dict(): await test_get_geo_tiff_async(request_type=dict) -@pytest.mark.parametrize( - "request_type", - [ - solar_service.FindClosestBuildingInsightsRequest, - dict, - ], -) -def test_find_closest_building_insights_rest(request_type): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = solar_service.BuildingInsights( - name="name_value", - postal_code="postal_code_value", - administrative_area="administrative_area_value", - statistical_area="statistical_area_value", - region_code="region_code_value", - imagery_quality=solar_service.ImageryQuality.HIGH, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = solar_service.BuildingInsights.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.find_closest_building_insights(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, solar_service.BuildingInsights) - assert response.name == "name_value" - assert response.postal_code == "postal_code_value" - assert response.administrative_area == "administrative_area_value" - assert response.statistical_area == "statistical_area_value" - assert response.region_code == "region_code_value" - assert response.imagery_quality == solar_service.ImageryQuality.HIGH - - def test_find_closest_building_insights_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1970,166 +1801,28 @@ def test_find_closest_building_insights_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_find_closest_building_insights_rest_interceptors(null_interceptor): - transport = transports.SolarRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.SolarRestInterceptor(), - ) - client = SolarClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.SolarRestInterceptor, "post_find_closest_building_insights" - ) as post, mock.patch.object( - transports.SolarRestInterceptor, "pre_find_closest_building_insights" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = solar_service.FindClosestBuildingInsightsRequest.pb( - solar_service.FindClosestBuildingInsightsRequest() +def test_get_data_layers_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = solar_service.BuildingInsights.to_json( - solar_service.BuildingInsights() - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - request = solar_service.FindClosestBuildingInsightsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = solar_service.BuildingInsights() + # Ensure method has been cached + assert client._transport.get_data_layers in client._transport._wrapped_methods - client.find_closest_building_insights( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_find_closest_building_insights_rest_bad_request( - transport: str = "rest", - request_type=solar_service.FindClosestBuildingInsightsRequest, -): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.find_closest_building_insights(request) - - -def test_find_closest_building_insights_rest_error(): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - solar_service.GetDataLayersRequest, - dict, - ], -) -def test_get_data_layers_rest(request_type): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = solar_service.DataLayers( - dsm_url="dsm_url_value", - rgb_url="rgb_url_value", - mask_url="mask_url_value", - annual_flux_url="annual_flux_url_value", - monthly_flux_url="monthly_flux_url_value", - hourly_shade_urls=["hourly_shade_urls_value"], - imagery_quality=solar_service.ImageryQuality.HIGH, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = solar_service.DataLayers.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_data_layers(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, solar_service.DataLayers) - assert response.dsm_url == "dsm_url_value" - assert response.rgb_url == "rgb_url_value" - assert response.mask_url == "mask_url_value" - assert response.annual_flux_url == "annual_flux_url_value" - assert response.monthly_flux_url == "monthly_flux_url_value" - assert response.hourly_shade_urls == ["hourly_shade_urls_value"] - assert response.imagery_quality == solar_service.ImageryQuality.HIGH - - -def test_get_data_layers_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_data_layers in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.get_data_layers] = mock_rpc + client._transport._wrapped_methods[client._transport.get_data_layers] = mock_rpc request = {} client.get_data_layers(request) @@ -2264,131 +1957,6 @@ def test_get_data_layers_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_data_layers_rest_interceptors(null_interceptor): - transport = transports.SolarRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.SolarRestInterceptor(), - ) - client = SolarClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.SolarRestInterceptor, "post_get_data_layers" - ) as post, mock.patch.object( - transports.SolarRestInterceptor, "pre_get_data_layers" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = solar_service.GetDataLayersRequest.pb( - solar_service.GetDataLayersRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = solar_service.DataLayers.to_json( - solar_service.DataLayers() - ) - - request = solar_service.GetDataLayersRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = solar_service.DataLayers() - - client.get_data_layers( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_data_layers_rest_bad_request( - transport: str = "rest", request_type=solar_service.GetDataLayersRequest -): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_data_layers(request) - - -def test_get_data_layers_rest_error(): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - solar_service.GetGeoTiffRequest, - dict, - ], -) -def test_get_geo_tiff_rest(request_type): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = httpbody_pb2.HttpBody( - content_type="content_type_value", - data=b"data_blob", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_geo_tiff(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, httpbody_pb2.HttpBody) - assert response.content_type == "content_type_value" - assert response.data == b"data_blob" - - def test_get_geo_tiff_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2508,35 +2076,527 @@ def test_get_geo_tiff_rest_required_fields( assert expected_params == actual_params -def test_get_geo_tiff_rest_unset_required_fields(): - transport = transports.SolarRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) +def test_get_geo_tiff_rest_unset_required_fields(): + transport = transports.SolarRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_geo_tiff._get_unset_required_fields({}) + assert set(unset_fields) == (set(("id",)) & set(("id",))) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SolarGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SolarGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SolarClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SolarGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SolarClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SolarClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SolarGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SolarClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SolarGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SolarClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SolarGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SolarGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SolarGrpcTransport, + transports.SolarGrpcAsyncIOTransport, + transports.SolarRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = SolarClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_find_closest_building_insights_empty_call_grpc(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.find_closest_building_insights), "__call__" + ) as call: + call.return_value = solar_service.BuildingInsights() + client.find_closest_building_insights(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.FindClosestBuildingInsightsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_data_layers_empty_call_grpc(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_layers), "__call__") as call: + call.return_value = solar_service.DataLayers() + client.get_data_layers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.GetDataLayersRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_geo_tiff_empty_call_grpc(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_geo_tiff), "__call__") as call: + call.return_value = httpbody_pb2.HttpBody() + client.get_geo_tiff(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.GetGeoTiffRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = SolarAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = SolarAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_find_closest_building_insights_empty_call_grpc_asyncio(): + client = SolarAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.find_closest_building_insights), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + solar_service.BuildingInsights( + name="name_value", + postal_code="postal_code_value", + administrative_area="administrative_area_value", + statistical_area="statistical_area_value", + region_code="region_code_value", + imagery_quality=solar_service.ImageryQuality.HIGH, + ) + ) + await client.find_closest_building_insights(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.FindClosestBuildingInsightsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_data_layers_empty_call_grpc_asyncio(): + client = SolarAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_layers), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + solar_service.DataLayers( + dsm_url="dsm_url_value", + rgb_url="rgb_url_value", + mask_url="mask_url_value", + annual_flux_url="annual_flux_url_value", + monthly_flux_url="monthly_flux_url_value", + hourly_shade_urls=["hourly_shade_urls_value"], + imagery_quality=solar_service.ImageryQuality.HIGH, + ) + ) + await client.get_data_layers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.GetDataLayersRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_geo_tiff_empty_call_grpc_asyncio(): + client = SolarAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_geo_tiff), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + httpbody_pb2.HttpBody( + content_type="content_type_value", + data=b"data_blob", + ) + ) + await client.get_geo_tiff(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.GetGeoTiffRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = SolarClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_find_closest_building_insights_rest_bad_request( + request_type=solar_service.FindClosestBuildingInsightsRequest, +): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.find_closest_building_insights(request) + + +@pytest.mark.parametrize( + "request_type", + [ + solar_service.FindClosestBuildingInsightsRequest, + dict, + ], +) +def test_find_closest_building_insights_rest_call_success(request_type): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = solar_service.BuildingInsights( + name="name_value", + postal_code="postal_code_value", + administrative_area="administrative_area_value", + statistical_area="statistical_area_value", + region_code="region_code_value", + imagery_quality=solar_service.ImageryQuality.HIGH, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = solar_service.BuildingInsights.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.find_closest_building_insights(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, solar_service.BuildingInsights) + assert response.name == "name_value" + assert response.postal_code == "postal_code_value" + assert response.administrative_area == "administrative_area_value" + assert response.statistical_area == "statistical_area_value" + assert response.region_code == "region_code_value" + assert response.imagery_quality == solar_service.ImageryQuality.HIGH + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_find_closest_building_insights_rest_interceptors(null_interceptor): + transport = transports.SolarRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.SolarRestInterceptor(), + ) + client = SolarClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SolarRestInterceptor, "post_find_closest_building_insights" + ) as post, mock.patch.object( + transports.SolarRestInterceptor, "pre_find_closest_building_insights" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = solar_service.FindClosestBuildingInsightsRequest.pb( + solar_service.FindClosestBuildingInsightsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = solar_service.BuildingInsights.to_json( + solar_service.BuildingInsights() + ) + req.return_value.content = return_value + + request = solar_service.FindClosestBuildingInsightsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = solar_service.BuildingInsights() + + client.find_closest_building_insights( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_data_layers_rest_bad_request( + request_type=solar_service.GetDataLayersRequest, +): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_data_layers(request) + + +@pytest.mark.parametrize( + "request_type", + [ + solar_service.GetDataLayersRequest, + dict, + ], +) +def test_get_data_layers_rest_call_success(request_type): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = solar_service.DataLayers( + dsm_url="dsm_url_value", + rgb_url="rgb_url_value", + mask_url="mask_url_value", + annual_flux_url="annual_flux_url_value", + monthly_flux_url="monthly_flux_url_value", + hourly_shade_urls=["hourly_shade_urls_value"], + imagery_quality=solar_service.ImageryQuality.HIGH, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 - unset_fields = transport.get_geo_tiff._get_unset_required_fields({}) - assert set(unset_fields) == (set(("id",)) & set(("id",))) + # Convert return value to protobuf type + return_value = solar_service.DataLayers.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_data_layers(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, solar_service.DataLayers) + assert response.dsm_url == "dsm_url_value" + assert response.rgb_url == "rgb_url_value" + assert response.mask_url == "mask_url_value" + assert response.annual_flux_url == "annual_flux_url_value" + assert response.monthly_flux_url == "monthly_flux_url_value" + assert response.hourly_shade_urls == ["hourly_shade_urls_value"] + assert response.imagery_quality == solar_service.ImageryQuality.HIGH @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_geo_tiff_rest_interceptors(null_interceptor): +def test_get_data_layers_rest_interceptors(null_interceptor): transport = transports.SolarRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.SolarRestInterceptor(), ) client = SolarClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.SolarRestInterceptor, "post_get_geo_tiff" + transports.SolarRestInterceptor, "post_get_data_layers" ) as post, mock.patch.object( - transports.SolarRestInterceptor, "pre_get_geo_tiff" + transports.SolarRestInterceptor, "pre_get_data_layers" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = solar_service.GetGeoTiffRequest.pb( - solar_service.GetGeoTiffRequest() + pb_message = solar_service.GetDataLayersRequest.pb( + solar_service.GetDataLayersRequest() ) transcode.return_value = { "method": "post", @@ -2545,20 +2605,20 @@ def test_get_geo_tiff_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson(httpbody_pb2.HttpBody()) + return_value = solar_service.DataLayers.to_json(solar_service.DataLayers()) + req.return_value.content = return_value - request = solar_service.GetGeoTiffRequest() + request = solar_service.GetDataLayersRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = httpbody_pb2.HttpBody() + post.return_value = solar_service.DataLayers() - client.get_geo_tiff( + client.get_data_layers( request, metadata=[ ("key", "val"), @@ -2570,14 +2630,10 @@ def test_get_geo_tiff_rest_interceptors(null_interceptor): post.assert_called_once() -def test_get_geo_tiff_rest_bad_request( - transport: str = "rest", request_type=solar_service.GetGeoTiffRequest -): +def test_get_geo_tiff_rest_bad_request(request_type=solar_service.GetGeoTiffRequest): client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {} request = request_type(**request_init) @@ -2587,123 +2643,174 @@ def test_get_geo_tiff_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.get_geo_tiff(request) -def test_get_geo_tiff_rest_error(): +@pytest.mark.parametrize( + "request_type", + [ + solar_service.GetGeoTiffRequest, + dict, + ], +) +def test_get_geo_tiff_rest_call_success(request_type): client = SolarClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.SolarGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = httpbody_pb2.HttpBody( + content_type="content_type_value", + data=b"data_blob", ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.SolarGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SolarClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_geo_tiff(request) - # It is an error to provide an api_key and a transport instance. - transport = transports.SolarGrpcTransport( + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == "content_type_value" + assert response.data == b"data_blob" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_geo_tiff_rest_interceptors(null_interceptor): + transport = transports.SolarRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.SolarRestInterceptor(), ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = SolarClient( - client_options=options, - transport=transport, - ) + client = SolarClient(transport=transport) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = SolarClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SolarRestInterceptor, "post_get_geo_tiff" + ) as post, mock.patch.object( + transports.SolarRestInterceptor, "pre_get_geo_tiff" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = solar_service.GetGeoTiffRequest.pb( + solar_service.GetGeoTiffRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # It is an error to provide scopes and a transport instance. - transport = transports.SolarGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SolarClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = json_format.MessageToJson(httpbody_pb2.HttpBody()) + req.return_value.content = return_value + + request = solar_service.GetGeoTiffRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = httpbody_pb2.HttpBody() + + client.get_geo_tiff( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() + -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.SolarGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), +def test_initialize_client_w_rest(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - client = SolarClient(transport=transport) - assert client.transport is transport + assert client is not None -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.SolarGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_find_closest_building_insights_empty_call_rest(): + client = SolarClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - transport = transports.SolarGrpcAsyncIOTransport( + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.find_closest_building_insights), "__call__" + ) as call: + client.find_closest_building_insights(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.FindClosestBuildingInsightsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_data_layers_empty_call_rest(): + client = SolarClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_layers), "__call__") as call: + client.get_data_layers(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.SolarGrpcTransport, - transports.SolarGrpcAsyncIOTransport, - transports.SolarRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.GetDataLayersRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = SolarClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_geo_tiff_empty_call_rest(): + client = SolarClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_geo_tiff), "__call__") as call: + client.get_geo_tiff(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = solar_service.GetGeoTiffRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3248,36 +3355,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = SolarAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = SolarClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = SolarClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-css/google/shopping/css/gapic_version.py b/packages/google-shopping-css/google/shopping/css/gapic_version.py index ec8d212c9160..558c8aab67c5 100644 --- a/packages/google-shopping-css/google/shopping/css/gapic_version.py +++ b/packages/google-shopping-css/google/shopping/css/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.8" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-css/google/shopping/css_v1/gapic_version.py b/packages/google-shopping-css/google/shopping/css_v1/gapic_version.py index ec8d212c9160..558c8aab67c5 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/gapic_version.py +++ b/packages/google-shopping-css/google/shopping/css_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.8" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/README.rst b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/README.rst new file mode 100644 index 000000000000..309b49e65c3e --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AccountLabelsServiceTransport` is the ABC for all transports. +- public child `AccountLabelsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AccountLabelsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAccountLabelsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AccountLabelsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/grpc_asyncio.py b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/grpc_asyncio.py index a643471588e6..cf2c05d3337b 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -358,7 +362,7 @@ def delete_account_label( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.list_account_labels: gapic_v1.method_async.wrap_method( + self.list_account_labels: self._wrap_method( self.list_account_labels, default_retry=retries.AsyncRetry( initial=1.0, @@ -372,25 +376,34 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.create_account_label: gapic_v1.method_async.wrap_method( + self.create_account_label: self._wrap_method( self.create_account_label, default_timeout=60.0, client_info=client_info, ), - self.update_account_label: gapic_v1.method_async.wrap_method( + self.update_account_label: self._wrap_method( self.update_account_label, default_timeout=60.0, client_info=client_info, ), - self.delete_account_label: gapic_v1.method_async.wrap_method( + self.delete_account_label: self._wrap_method( self.delete_account_label, default_timeout=60.0, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("AccountLabelsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest.py b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest.py index 86e5a531afeb..e3e5f46eb7b1 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.css_v1.types import accounts_labels + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAccountLabelsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.css_v1.types import accounts_labels - -from .base import AccountLabelsServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -188,8 +184,8 @@ class AccountLabelsServiceRestStub: _interceptor: AccountLabelsServiceRestInterceptor -class AccountLabelsServiceRestTransport(AccountLabelsServiceTransport): - """REST backend transport for AccountLabelsService. +class AccountLabelsServiceRestTransport(_BaseAccountLabelsServiceRestTransport): + """REST backend synchronous transport for AccountLabelsService. Manages Merchant Center and CSS accounts labels. @@ -198,7 +194,6 @@ class AccountLabelsServiceRestTransport(AccountLabelsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -252,21 +247,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -277,19 +263,35 @@ def __init__( self._interceptor = interceptor or AccountLabelsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateAccountLabel(AccountLabelsServiceRestStub): + class _CreateAccountLabel( + _BaseAccountLabelsServiceRestTransport._BaseCreateAccountLabel, + AccountLabelsServiceRestStub, + ): def __hash__(self): - return hash("CreateAccountLabel") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountLabelsServiceRestTransport.CreateAccountLabel") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -318,47 +320,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=accounts/*}/labels", - "body": "account_label", - }, - ] + http_options = ( + _BaseAccountLabelsServiceRestTransport._BaseCreateAccountLabel._get_http_options() + ) request, metadata = self._interceptor.pre_create_account_label( request, metadata ) - pb_request = accounts_labels.CreateAccountLabelRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAccountLabelsServiceRestTransport._BaseCreateAccountLabel._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAccountLabelsServiceRestTransport._BaseCreateAccountLabel._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountLabelsServiceRestTransport._BaseCreateAccountLabel._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + AccountLabelsServiceRestTransport._CreateAccountLabel._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -374,19 +365,34 @@ def __call__( resp = self._interceptor.post_create_account_label(resp) return resp - class _DeleteAccountLabel(AccountLabelsServiceRestStub): + class _DeleteAccountLabel( + _BaseAccountLabelsServiceRestTransport._BaseDeleteAccountLabel, + AccountLabelsServiceRestStub, + ): def __hash__(self): - return hash("DeleteAccountLabel") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountLabelsServiceRestTransport.DeleteAccountLabel") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -409,40 +415,31 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1/{name=accounts/*/labels/*}", - }, - ] + http_options = ( + _BaseAccountLabelsServiceRestTransport._BaseDeleteAccountLabel._get_http_options() + ) request, metadata = self._interceptor.pre_delete_account_label( request, metadata ) - pb_request = accounts_labels.DeleteAccountLabelRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountLabelsServiceRestTransport._BaseDeleteAccountLabel._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountLabelsServiceRestTransport._BaseDeleteAccountLabel._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + AccountLabelsServiceRestTransport._DeleteAccountLabel._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -450,19 +447,34 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _ListAccountLabels(AccountLabelsServiceRestStub): + class _ListAccountLabels( + _BaseAccountLabelsServiceRestTransport._BaseListAccountLabels, + AccountLabelsServiceRestStub, + ): def __hash__(self): - return hash("ListAccountLabels") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountLabelsServiceRestTransport.ListAccountLabels") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -488,40 +500,31 @@ def __call__( Response message for the ``ListAccountLabels`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=accounts/*}/labels", - }, - ] + http_options = ( + _BaseAccountLabelsServiceRestTransport._BaseListAccountLabels._get_http_options() + ) request, metadata = self._interceptor.pre_list_account_labels( request, metadata ) - pb_request = accounts_labels.ListAccountLabelsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountLabelsServiceRestTransport._BaseListAccountLabels._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountLabelsServiceRestTransport._BaseListAccountLabels._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + AccountLabelsServiceRestTransport._ListAccountLabels._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -537,19 +540,35 @@ def __call__( resp = self._interceptor.post_list_account_labels(resp) return resp - class _UpdateAccountLabel(AccountLabelsServiceRestStub): + class _UpdateAccountLabel( + _BaseAccountLabelsServiceRestTransport._BaseUpdateAccountLabel, + AccountLabelsServiceRestStub, + ): def __hash__(self): - return hash("UpdateAccountLabel") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountLabelsServiceRestTransport.UpdateAccountLabel") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -577,47 +596,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{account_label.name=accounts/*/labels/*}", - "body": "account_label", - }, - ] + http_options = ( + _BaseAccountLabelsServiceRestTransport._BaseUpdateAccountLabel._get_http_options() + ) request, metadata = self._interceptor.pre_update_account_label( request, metadata ) - pb_request = accounts_labels.UpdateAccountLabelRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAccountLabelsServiceRestTransport._BaseUpdateAccountLabel._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAccountLabelsServiceRestTransport._BaseUpdateAccountLabel._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountLabelsServiceRestTransport._BaseUpdateAccountLabel._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + AccountLabelsServiceRestTransport._UpdateAccountLabel._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest_base.py b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest_base.py new file mode 100644 index 000000000000..820dd90a6c7d --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/account_labels_service/transports/rest_base.py @@ -0,0 +1,300 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.css_v1.types import accounts_labels + +from .base import DEFAULT_CLIENT_INFO, AccountLabelsServiceTransport + + +class _BaseAccountLabelsServiceRestTransport(AccountLabelsServiceTransport): + """Base REST backend transport for AccountLabelsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "css.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'css.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateAccountLabel: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=accounts/*}/labels", + "body": "account_label", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts_labels.CreateAccountLabelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountLabelsServiceRestTransport._BaseCreateAccountLabel._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteAccountLabel: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=accounts/*/labels/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts_labels.DeleteAccountLabelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountLabelsServiceRestTransport._BaseDeleteAccountLabel._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAccountLabels: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=accounts/*}/labels", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts_labels.ListAccountLabelsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountLabelsServiceRestTransport._BaseListAccountLabels._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateAccountLabel: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{account_label.name=accounts/*/labels/*}", + "body": "account_label", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts_labels.UpdateAccountLabelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountLabelsServiceRestTransport._BaseUpdateAccountLabel._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAccountLabelsServiceRestTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/README.rst b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/README.rst new file mode 100644 index 000000000000..feb9cc900a04 --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AccountsServiceTransport` is the ABC for all transports. +- public child `AccountsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AccountsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAccountsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AccountsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/grpc_asyncio.py b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/grpc_asyncio.py index 8afc86222777..6fd4ab3905f0 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -325,7 +329,7 @@ def update_labels( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.list_child_accounts: gapic_v1.method_async.wrap_method( + self.list_child_accounts: self._wrap_method( self.list_child_accounts, default_retry=retries.AsyncRetry( initial=1.0, @@ -339,7 +343,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.get_account: gapic_v1.method_async.wrap_method( + self.get_account: self._wrap_method( self.get_account, default_retry=retries.AsyncRetry( initial=1.0, @@ -353,15 +357,24 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.update_labels: gapic_v1.method_async.wrap_method( + self.update_labels: self._wrap_method( self.update_labels, default_timeout=60.0, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("AccountsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest.py b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest.py index ed97c2fc5b94..47fe6d1876d5 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.css_v1.types import accounts + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAccountsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.css_v1.types import accounts - -from .base import AccountsServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -164,8 +161,8 @@ class AccountsServiceRestStub: _interceptor: AccountsServiceRestInterceptor -class AccountsServiceRestTransport(AccountsServiceTransport): - """REST backend transport for AccountsService. +class AccountsServiceRestTransport(_BaseAccountsServiceRestTransport): + """REST backend synchronous transport for AccountsService. Service for managing CSS/MC account information. @@ -174,7 +171,6 @@ class AccountsServiceRestTransport(AccountsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -228,21 +224,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -253,19 +240,33 @@ def __init__( self._interceptor = interceptor or AccountsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetAccount(AccountsServiceRestStub): + class _GetAccount( + _BaseAccountsServiceRestTransport._BaseGetAccount, AccountsServiceRestStub + ): def __hash__(self): - return hash("GetAccount") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.GetAccount") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -291,38 +292,27 @@ def __call__( Information about CSS/MC account. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=accounts/*}", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseGetAccount._get_http_options() + ) request, metadata = self._interceptor.pre_get_account(request, metadata) - pb_request = accounts.GetAccountRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountsServiceRestTransport._BaseGetAccount._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseGetAccount._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountsServiceRestTransport._GetAccount._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -338,19 +328,34 @@ def __call__( resp = self._interceptor.post_get_account(resp) return resp - class _ListChildAccounts(AccountsServiceRestStub): + class _ListChildAccounts( + _BaseAccountsServiceRestTransport._BaseListChildAccounts, + AccountsServiceRestStub, + ): def __hash__(self): - return hash("ListChildAccounts") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.ListChildAccounts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -377,40 +382,29 @@ def __call__( Response message for the ``ListChildAccounts`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=accounts/*}:listChildAccounts", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseListChildAccounts._get_http_options() + ) request, metadata = self._interceptor.pre_list_child_accounts( request, metadata ) - pb_request = accounts.ListChildAccountsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountsServiceRestTransport._BaseListChildAccounts._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseListChildAccounts._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountsServiceRestTransport._ListChildAccounts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -426,19 +420,34 @@ def __call__( resp = self._interceptor.post_list_child_accounts(resp) return resp - class _UpdateLabels(AccountsServiceRestStub): + class _UpdateLabels( + _BaseAccountsServiceRestTransport._BaseUpdateLabels, AccountsServiceRestStub + ): def __hash__(self): - return hash("UpdateLabels") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.UpdateLabels") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -464,45 +473,32 @@ def __call__( Information about CSS/MC account. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{name=accounts/*}:updateLabels", - "body": "*", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseUpdateLabels._get_http_options() + ) request, metadata = self._interceptor.pre_update_labels(request, metadata) - pb_request = accounts.UpdateAccountLabelsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAccountsServiceRestTransport._BaseUpdateLabels._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAccountsServiceRestTransport._BaseUpdateLabels._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseUpdateLabels._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = AccountsServiceRestTransport._UpdateLabels._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest_base.py b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest_base.py new file mode 100644 index 000000000000..33b723ea76fb --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/accounts_service/transports/rest_base.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.css_v1.types import accounts + +from .base import DEFAULT_CLIENT_INFO, AccountsServiceTransport + + +class _BaseAccountsServiceRestTransport(AccountsServiceTransport): + """Base REST backend transport for AccountsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "css.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'css.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetAccount: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=accounts/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.GetAccountRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseGetAccount._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListChildAccounts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=accounts/*}:listChildAccounts", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.ListChildAccountsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseListChildAccounts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateLabels: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=accounts/*}:updateLabels", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.UpdateAccountLabelsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseUpdateLabels._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAccountsServiceRestTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/README.rst b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/README.rst new file mode 100644 index 000000000000..271828b42261 --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CssProductInputsServiceTransport` is the ABC for all transports. +- public child `CssProductInputsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CssProductInputsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCssProductInputsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CssProductInputsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/grpc_asyncio.py b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/grpc_asyncio.py index 0ed5e836c82b..bc09141cc86e 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -310,20 +314,29 @@ def delete_css_product_input( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.insert_css_product_input: gapic_v1.method_async.wrap_method( + self.insert_css_product_input: self._wrap_method( self.insert_css_product_input, default_timeout=60.0, client_info=client_info, ), - self.delete_css_product_input: gapic_v1.method_async.wrap_method( + self.delete_css_product_input: self._wrap_method( self.delete_css_product_input, default_timeout=60.0, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("CssProductInputsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest.py b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest.py index 48061418b567..fb538000acde 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.css_v1.types import css_product_inputs + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseCssProductInputsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.css_v1.types import css_product_inputs - -from .base import CssProductInputsServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -130,8 +126,8 @@ class CssProductInputsServiceRestStub: _interceptor: CssProductInputsServiceRestInterceptor -class CssProductInputsServiceRestTransport(CssProductInputsServiceTransport): - """REST backend transport for CssProductInputsService. +class CssProductInputsServiceRestTransport(_BaseCssProductInputsServiceRestTransport): + """REST backend synchronous transport for CssProductInputsService. Service to use CssProductInput resource. This service helps to insert/update/delete CSS Products. @@ -141,7 +137,6 @@ class CssProductInputsServiceRestTransport(CssProductInputsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -195,21 +190,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -220,19 +206,34 @@ def __init__( self._interceptor = interceptor or CssProductInputsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _DeleteCssProductInput(CssProductInputsServiceRestStub): + class _DeleteCssProductInput( + _BaseCssProductInputsServiceRestTransport._BaseDeleteCssProductInput, + CssProductInputsServiceRestStub, + ): def __hash__(self): - return hash("DeleteCssProductInput") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("CssProductInputsServiceRestTransport.DeleteCssProductInput") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -255,40 +256,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1/{name=accounts/*/cssProductInputs/*}", - }, - ] + http_options = ( + _BaseCssProductInputsServiceRestTransport._BaseDeleteCssProductInput._get_http_options() + ) request, metadata = self._interceptor.pre_delete_css_product_input( request, metadata ) - pb_request = css_product_inputs.DeleteCssProductInputRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseCssProductInputsServiceRestTransport._BaseDeleteCssProductInput._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseCssProductInputsServiceRestTransport._BaseDeleteCssProductInput._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = CssProductInputsServiceRestTransport._DeleteCssProductInput._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -296,21 +286,35 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _InsertCssProductInput(CssProductInputsServiceRestStub): + class _InsertCssProductInput( + _BaseCssProductInputsServiceRestTransport._BaseInsertCssProductInput, + CssProductInputsServiceRestStub, + ): def __hash__(self): - return hash("InsertCssProductInput") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "feedId": 0, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("CssProductInputsServiceRestTransport.InsertCssProductInput") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -342,47 +346,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=accounts/*}/cssProductInputs:insert", - "body": "css_product_input", - }, - ] + http_options = ( + _BaseCssProductInputsServiceRestTransport._BaseInsertCssProductInput._get_http_options() + ) request, metadata = self._interceptor.pre_insert_css_product_input( request, metadata ) - pb_request = css_product_inputs.InsertCssProductInputRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseCssProductInputsServiceRestTransport._BaseInsertCssProductInput._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseCssProductInputsServiceRestTransport._BaseInsertCssProductInput._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseCssProductInputsServiceRestTransport._BaseInsertCssProductInput._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = CssProductInputsServiceRestTransport._InsertCssProductInput._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest_base.py b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest_base.py new file mode 100644 index 000000000000..5f6befc77bd3 --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_product_inputs_service/transports/rest_base.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.css_v1.types import css_product_inputs + +from .base import DEFAULT_CLIENT_INFO, CssProductInputsServiceTransport + + +class _BaseCssProductInputsServiceRestTransport(CssProductInputsServiceTransport): + """Base REST backend transport for CssProductInputsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "css.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'css.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseDeleteCssProductInput: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=accounts/*/cssProductInputs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = css_product_inputs.DeleteCssProductInputRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCssProductInputsServiceRestTransport._BaseDeleteCssProductInput._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertCssProductInput: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "feedId": 0, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=accounts/*}/cssProductInputs:insert", + "body": "css_product_input", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = css_product_inputs.InsertCssProductInputRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCssProductInputsServiceRestTransport._BaseInsertCssProductInput._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseCssProductInputsServiceRestTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/README.rst b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/README.rst new file mode 100644 index 000000000000..fd1f37fc1bca --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CssProductsServiceTransport` is the ABC for all transports. +- public child `CssProductsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CssProductsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCssProductsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CssProductsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/grpc_asyncio.py b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/grpc_asyncio.py index d425f519b64f..5ae2aefa9b75 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -309,7 +313,7 @@ def list_css_products( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_css_product: gapic_v1.method_async.wrap_method( + self.get_css_product: self._wrap_method( self.get_css_product, default_retry=retries.AsyncRetry( initial=1.0, @@ -323,7 +327,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=60.0, client_info=client_info, ), - self.list_css_products: gapic_v1.method_async.wrap_method( + self.list_css_products: self._wrap_method( self.list_css_products, default_retry=retries.AsyncRetry( initial=1.0, @@ -339,8 +343,17 @@ def _prep_wrapped_messages(self, client_info): ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("CssProductsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest.py b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest.py index ffa599d2a576..bb4e55782c03 100644 --- a/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest.py +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.css_v1.types import css_products + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseCssProductsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.css_v1.types import css_products - -from .base import CssProductsServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -139,8 +136,8 @@ class CssProductsServiceRestStub: _interceptor: CssProductsServiceRestInterceptor -class CssProductsServiceRestTransport(CssProductsServiceTransport): - """REST backend transport for CssProductsService. +class CssProductsServiceRestTransport(_BaseCssProductsServiceRestTransport): + """REST backend synchronous transport for CssProductsService. Service for doing get and list on Css Products(a.k.a Aggregate Offers internally). @@ -150,7 +147,6 @@ class CssProductsServiceRestTransport(CssProductsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -204,21 +200,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -229,19 +216,34 @@ def __init__( self._interceptor = interceptor or CssProductsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetCssProduct(CssProductsServiceRestStub): + class _GetCssProduct( + _BaseCssProductsServiceRestTransport._BaseGetCssProduct, + CssProductsServiceRestStub, + ): def __hash__(self): - return hash("GetCssProduct") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("CssProductsServiceRestTransport.GetCssProduct") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -269,38 +271,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=accounts/*/cssProducts/*}", - }, - ] + http_options = ( + _BaseCssProductsServiceRestTransport._BaseGetCssProduct._get_http_options() + ) request, metadata = self._interceptor.pre_get_css_product(request, metadata) - pb_request = css_products.GetCssProductRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseCssProductsServiceRestTransport._BaseGetCssProduct._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseCssProductsServiceRestTransport._BaseGetCssProduct._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = CssProductsServiceRestTransport._GetCssProduct._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -316,19 +307,34 @@ def __call__( resp = self._interceptor.post_get_css_product(resp) return resp - class _ListCssProducts(CssProductsServiceRestStub): + class _ListCssProducts( + _BaseCssProductsServiceRestTransport._BaseListCssProducts, + CssProductsServiceRestStub, + ): def __hash__(self): - return hash("ListCssProducts") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("CssProductsServiceRestTransport.ListCssProducts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -357,40 +363,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=accounts/*}/cssProducts", - }, - ] + http_options = ( + _BaseCssProductsServiceRestTransport._BaseListCssProducts._get_http_options() + ) request, metadata = self._interceptor.pre_list_css_products( request, metadata ) - pb_request = css_products.ListCssProductsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseCssProductsServiceRestTransport._BaseListCssProducts._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseCssProductsServiceRestTransport._BaseListCssProducts._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = CssProductsServiceRestTransport._ListCssProducts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest_base.py b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest_base.py new file mode 100644 index 000000000000..8b5f2eb39007 --- /dev/null +++ b/packages/google-shopping-css/google/shopping/css_v1/services/css_products_service/transports/rest_base.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.css_v1.types import css_products + +from .base import DEFAULT_CLIENT_INFO, CssProductsServiceTransport + + +class _BaseCssProductsServiceRestTransport(CssProductsServiceTransport): + """Base REST backend transport for CssProductsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "css.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'css.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetCssProduct: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=accounts/*/cssProducts/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = css_products.GetCssProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCssProductsServiceRestTransport._BaseGetCssProduct._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListCssProducts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=accounts/*}/cssProducts", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = css_products.ListCssProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCssProductsServiceRestTransport._BaseListCssProducts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseCssProductsServiceRestTransport",) diff --git a/packages/google-shopping-css/samples/generated_samples/snippet_metadata_google.shopping.css.v1.json b/packages/google-shopping-css/samples/generated_samples/snippet_metadata_google.shopping.css.v1.json index 301d93f4bbc4..5b682921bee5 100644 --- a/packages/google-shopping-css/samples/generated_samples/snippet_metadata_google.shopping.css.v1.json +++ b/packages/google-shopping-css/samples/generated_samples/snippet_metadata_google.shopping.css.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-css", - "version": "0.1.8" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-shopping-css/setup.py b/packages/google-shopping-css/setup.py index 86cceb75fb83..ab352792bba2 100644 --- a/packages/google-shopping-css/setup.py +++ b/packages/google-shopping-css/setup.py @@ -47,6 +47,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-css" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -89,6 +90,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_account_labels_service.py b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_account_labels_service.py index 8e827d965701..50d137f2065d 100644 --- a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_account_labels_service.py +++ b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_account_labels_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.css_v1.services.account_labels_service import ( AccountLabelsServiceAsyncClient, AccountLabelsServiceClient, @@ -52,10 +61,24 @@ from google.shopping.css_v1.types import accounts_labels +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1223,27 +1246,6 @@ def test_list_account_labels(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_account_labels_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_account_labels), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_account_labels() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.ListAccountLabelsRequest() - - def test_list_account_labels_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1315,31 +1317,6 @@ def test_list_account_labels_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_account_labels_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_account_labels), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts_labels.ListAccountLabelsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_account_labels() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.ListAccountLabelsRequest() - - @pytest.mark.asyncio async def test_list_account_labels_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1348,7 +1325,7 @@ async def test_list_account_labels_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1388,7 +1365,7 @@ async def test_list_account_labels_async( request_type=accounts_labels.ListAccountLabelsRequest, ): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1458,7 +1435,7 @@ def test_list_account_labels_field_headers(): @pytest.mark.asyncio async def test_list_account_labels_field_headers_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1532,7 +1509,7 @@ def test_list_account_labels_flattened_error(): @pytest.mark.asyncio async def test_list_account_labels_flattened_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1563,7 +1540,7 @@ async def test_list_account_labels_flattened_async(): @pytest.mark.asyncio async def test_list_account_labels_flattened_error_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1677,7 +1654,7 @@ def test_list_account_labels_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_account_labels_async_pager(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1729,7 +1706,7 @@ async def test_list_account_labels_async_pager(): @pytest.mark.asyncio async def test_list_account_labels_async_pages(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1825,27 +1802,6 @@ def test_create_account_label(request_type, transport: str = "grpc"): assert response.label_type == accounts_labels.AccountLabel.LabelType.MANUAL -def test_create_account_label_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_account_label), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_account_label() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.CreateAccountLabelRequest() - - def test_create_account_label_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1915,36 +1871,6 @@ def test_create_account_label_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_account_label_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_account_label), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts_labels.AccountLabel( - name="name_value", - label_id=812, - account_id=1049, - display_name="display_name_value", - description="description_value", - label_type=accounts_labels.AccountLabel.LabelType.MANUAL, - ) - ) - response = await client.create_account_label() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.CreateAccountLabelRequest() - - @pytest.mark.asyncio async def test_create_account_label_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1953,7 +1879,7 @@ async def test_create_account_label_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1993,7 +1919,7 @@ async def test_create_account_label_async( request_type=accounts_labels.CreateAccountLabelRequest, ): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2073,7 +1999,7 @@ def test_create_account_label_field_headers(): @pytest.mark.asyncio async def test_create_account_label_field_headers_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2152,7 +2078,7 @@ def test_create_account_label_flattened_error(): @pytest.mark.asyncio async def test_create_account_label_flattened_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2187,7 +2113,7 @@ async def test_create_account_label_flattened_async(): @pytest.mark.asyncio async def test_create_account_label_flattened_error_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2248,27 +2174,6 @@ def test_update_account_label(request_type, transport: str = "grpc"): assert response.label_type == accounts_labels.AccountLabel.LabelType.MANUAL -def test_update_account_label_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_account_label), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_account_label() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.UpdateAccountLabelRequest() - - def test_update_account_label_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2334,36 +2239,6 @@ def test_update_account_label_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_account_label_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_account_label), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts_labels.AccountLabel( - name="name_value", - label_id=812, - account_id=1049, - display_name="display_name_value", - description="description_value", - label_type=accounts_labels.AccountLabel.LabelType.MANUAL, - ) - ) - response = await client.update_account_label() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.UpdateAccountLabelRequest() - - @pytest.mark.asyncio async def test_update_account_label_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2372,7 +2247,7 @@ async def test_update_account_label_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2412,7 +2287,7 @@ async def test_update_account_label_async( request_type=accounts_labels.UpdateAccountLabelRequest, ): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2492,7 +2367,7 @@ def test_update_account_label_field_headers(): @pytest.mark.asyncio async def test_update_account_label_field_headers_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2566,7 +2441,7 @@ def test_update_account_label_flattened_error(): @pytest.mark.asyncio async def test_update_account_label_flattened_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2597,7 +2472,7 @@ async def test_update_account_label_flattened_async(): @pytest.mark.asyncio async def test_update_account_label_flattened_error_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2644,27 +2519,6 @@ def test_delete_account_label(request_type, transport: str = "grpc"): assert response is None -def test_delete_account_label_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_account_label), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_account_label() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.DeleteAccountLabelRequest() - - def test_delete_account_label_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2734,27 +2588,6 @@ def test_delete_account_label_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_account_label_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_account_label), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_account_label() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts_labels.DeleteAccountLabelRequest() - - @pytest.mark.asyncio async def test_delete_account_label_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2763,7 +2596,7 @@ async def test_delete_account_label_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2803,7 +2636,7 @@ async def test_delete_account_label_async( request_type=accounts_labels.DeleteAccountLabelRequest, ): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2868,7 +2701,7 @@ def test_delete_account_label_field_headers(): @pytest.mark.asyncio async def test_delete_account_label_field_headers_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2940,7 +2773,7 @@ def test_delete_account_label_flattened_error(): @pytest.mark.asyncio async def test_delete_account_label_flattened_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2969,7 +2802,7 @@ async def test_delete_account_label_flattened_async(): @pytest.mark.asyncio async def test_delete_account_label_flattened_error_async(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2981,46 +2814,6 @@ async def test_delete_account_label_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - accounts_labels.ListAccountLabelsRequest, - dict, - ], -) -def test_list_account_labels_rest(request_type): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts_labels.ListAccountLabelsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts_labels.ListAccountLabelsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_account_labels(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAccountLabelsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_account_labels_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3159,91 +2952,10 @@ def test_list_account_labels_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_account_labels_rest_interceptors(null_interceptor): - transport = transports.AccountLabelsServiceRestTransport( +def test_list_account_labels_rest_flattened(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountLabelsServiceRestInterceptor(), - ) - client = AccountLabelsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "post_list_account_labels" - ) as post, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "pre_list_account_labels" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts_labels.ListAccountLabelsRequest.pb( - accounts_labels.ListAccountLabelsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts_labels.ListAccountLabelsResponse.to_json( - accounts_labels.ListAccountLabelsResponse() - ) - - request = accounts_labels.ListAccountLabelsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts_labels.ListAccountLabelsResponse() - - client.list_account_labels( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_account_labels_rest_bad_request( - transport: str = "rest", request_type=accounts_labels.ListAccountLabelsRequest -): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_account_labels(request) - - -def test_list_account_labels_rest_flattened(): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="rest", ) # Mock the http request call within the method and fake a response. @@ -3358,131 +3070,6 @@ def test_list_account_labels_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - accounts_labels.CreateAccountLabelRequest, - dict, - ], -) -def test_create_account_label_rest(request_type): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["account_label"] = { - "name": "name_value", - "label_id": 812, - "account_id": 1049, - "display_name": "display_name_value", - "description": "description_value", - "label_type": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = accounts_labels.CreateAccountLabelRequest.meta.fields["account_label"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["account_label"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["account_label"][field])): - del request_init["account_label"][field][i][subfield] - else: - del request_init["account_label"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts_labels.AccountLabel( - name="name_value", - label_id=812, - account_id=1049, - display_name="display_name_value", - description="description_value", - label_type=accounts_labels.AccountLabel.LabelType.MANUAL, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts_labels.AccountLabel.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_account_label(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts_labels.AccountLabel) - assert response.name == "name_value" - assert response.label_id == 812 - assert response.account_id == 1049 - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.label_type == accounts_labels.AccountLabel.LabelType.MANUAL - - def test_create_account_label_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3615,118 +3202,37 @@ def test_create_account_label_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_account_label_rest_interceptors(null_interceptor): - transport = transports.AccountLabelsServiceRestTransport( +def test_create_account_label_rest_flattened(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountLabelsServiceRestInterceptor(), + transport="rest", ) - client = AccountLabelsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "post_create_account_label" - ) as post, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "pre_create_account_label" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts_labels.CreateAccountLabelRequest.pb( - accounts_labels.CreateAccountLabelRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts_labels.AccountLabel.to_json( - accounts_labels.AccountLabel() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts_labels.AccountLabel() - request = accounts_labels.CreateAccountLabelRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts_labels.AccountLabel() + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} - client.create_account_label( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + account_label=accounts_labels.AccountLabel(name="name_value"), ) + mock_args.update(sample_request) - pre.assert_called_once() - post.assert_called_once() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = accounts_labels.AccountLabel.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value - -def test_create_account_label_rest_bad_request( - transport: str = "rest", request_type=accounts_labels.CreateAccountLabelRequest -): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_account_label(request) - - -def test_create_account_label_rest_flattened(): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts_labels.AccountLabel() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - account_label=accounts_labels.AccountLabel(name="name_value"), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts_labels.AccountLabel.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.create_account_label(**mock_args) + client.create_account_label(**mock_args) # Establish that the underlying call was made with the expected # request object values. @@ -3753,137 +3259,6 @@ def test_create_account_label_rest_flattened_error(transport: str = "rest"): ) -def test_create_account_label_rest_error(): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - accounts_labels.UpdateAccountLabelRequest, - dict, - ], -) -def test_update_account_label_rest(request_type): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"account_label": {"name": "accounts/sample1/labels/sample2"}} - request_init["account_label"] = { - "name": "accounts/sample1/labels/sample2", - "label_id": 812, - "account_id": 1049, - "display_name": "display_name_value", - "description": "description_value", - "label_type": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = accounts_labels.UpdateAccountLabelRequest.meta.fields["account_label"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["account_label"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["account_label"][field])): - del request_init["account_label"][field][i][subfield] - else: - del request_init["account_label"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts_labels.AccountLabel( - name="name_value", - label_id=812, - account_id=1049, - display_name="display_name_value", - description="description_value", - label_type=accounts_labels.AccountLabel.LabelType.MANUAL, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts_labels.AccountLabel.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_account_label(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts_labels.AccountLabel) - assert response.name == "name_value" - assert response.label_id == 812 - assert response.account_id == 1049 - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.label_type == accounts_labels.AccountLabel.LabelType.MANUAL - - def test_update_account_label_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4003,106 +3378,25 @@ def test_update_account_label_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("accountLabel",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_account_label_rest_interceptors(null_interceptor): - transport = transports.AccountLabelsServiceRestTransport( +def test_update_account_label_rest_flattened(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountLabelsServiceRestInterceptor(), + transport="rest", ) - client = AccountLabelsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "post_update_account_label" - ) as post, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "pre_update_account_label" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts_labels.UpdateAccountLabelRequest.pb( - accounts_labels.UpdateAccountLabelRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts_labels.AccountLabel.to_json( - accounts_labels.AccountLabel() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts_labels.AccountLabel() - request = accounts_labels.UpdateAccountLabelRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts_labels.AccountLabel() + # get arguments that satisfy an http rule for this method + sample_request = {"account_label": {"name": "accounts/sample1/labels/sample2"}} - client.update_account_label( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + account_label=accounts_labels.AccountLabel(name="name_value"), ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_account_label_rest_bad_request( - transport: str = "rest", request_type=accounts_labels.UpdateAccountLabelRequest -): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"account_label": {"name": "accounts/sample1/labels/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_account_label(request) - - -def test_update_account_label_rest_flattened(): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts_labels.AccountLabel() - - # get arguments that satisfy an http rule for this method - sample_request = {"account_label": {"name": "accounts/sample1/labels/sample2"}} - - # get truthy value for each flattened field - mock_args = dict( - account_label=accounts_labels.AccountLabel(name="name_value"), - ) - mock_args.update(sample_request) + mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() @@ -4140,47 +3434,6 @@ def test_update_account_label_rest_flattened_error(transport: str = "rest"): ) -def test_update_account_label_rest_error(): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - accounts_labels.DeleteAccountLabelRequest, - dict, - ], -) -def test_delete_account_label_rest(request_type): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/labels/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_account_label(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_account_label_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4301,8 +3554,877 @@ def test_delete_account_label_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) +def test_delete_account_label_rest_flattened(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/labels/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_account_label(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=accounts/*/labels/*}" % client.transport._host, args[1] + ) + + +def test_delete_account_label_rest_flattened_error(transport: str = "rest"): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_account_label( + accounts_labels.DeleteAccountLabelRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AccountLabelsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AccountLabelsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountLabelsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AccountLabelsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountLabelsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountLabelsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AccountLabelsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountLabelsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountLabelsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AccountLabelsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountLabelsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AccountLabelsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AccountLabelsServiceGrpcTransport, + transports.AccountLabelsServiceGrpcAsyncIOTransport, + transports.AccountLabelsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = AccountLabelsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_account_labels_empty_call_grpc(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_account_labels), "__call__" + ) as call: + call.return_value = accounts_labels.ListAccountLabelsResponse() + client.list_account_labels(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.ListAccountLabelsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_account_label_empty_call_grpc(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_account_label), "__call__" + ) as call: + call.return_value = accounts_labels.AccountLabel() + client.create_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.CreateAccountLabelRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_account_label_empty_call_grpc(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_account_label), "__call__" + ) as call: + call.return_value = accounts_labels.AccountLabel() + client.update_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.UpdateAccountLabelRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_account_label_empty_call_grpc(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_account_label), "__call__" + ) as call: + call.return_value = None + client.delete_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.DeleteAccountLabelRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AccountLabelsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AccountLabelsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_account_labels_empty_call_grpc_asyncio(): + client = AccountLabelsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_account_labels), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts_labels.ListAccountLabelsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_account_labels(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.ListAccountLabelsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_account_label_empty_call_grpc_asyncio(): + client = AccountLabelsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_account_label), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts_labels.AccountLabel( + name="name_value", + label_id=812, + account_id=1049, + display_name="display_name_value", + description="description_value", + label_type=accounts_labels.AccountLabel.LabelType.MANUAL, + ) + ) + await client.create_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.CreateAccountLabelRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_account_label_empty_call_grpc_asyncio(): + client = AccountLabelsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_account_label), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts_labels.AccountLabel( + name="name_value", + label_id=812, + account_id=1049, + display_name="display_name_value", + description="description_value", + label_type=accounts_labels.AccountLabel.LabelType.MANUAL, + ) + ) + await client.update_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.UpdateAccountLabelRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_account_label_empty_call_grpc_asyncio(): + client = AccountLabelsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_account_label), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.DeleteAccountLabelRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AccountLabelsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_account_labels_rest_bad_request( + request_type=accounts_labels.ListAccountLabelsRequest, +): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_account_labels(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts_labels.ListAccountLabelsRequest, + dict, + ], +) +def test_list_account_labels_rest_call_success(request_type): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts_labels.ListAccountLabelsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts_labels.ListAccountLabelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_account_labels(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAccountLabelsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_account_labels_rest_interceptors(null_interceptor): + transport = transports.AccountLabelsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountLabelsServiceRestInterceptor(), + ) + client = AccountLabelsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountLabelsServiceRestInterceptor, "post_list_account_labels" + ) as post, mock.patch.object( + transports.AccountLabelsServiceRestInterceptor, "pre_list_account_labels" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts_labels.ListAccountLabelsRequest.pb( + accounts_labels.ListAccountLabelsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts_labels.ListAccountLabelsResponse.to_json( + accounts_labels.ListAccountLabelsResponse() + ) + req.return_value.content = return_value + + request = accounts_labels.ListAccountLabelsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts_labels.ListAccountLabelsResponse() + + client.list_account_labels( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_account_label_rest_bad_request( + request_type=accounts_labels.CreateAccountLabelRequest, +): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_account_label(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts_labels.CreateAccountLabelRequest, + dict, + ], +) +def test_create_account_label_rest_call_success(request_type): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["account_label"] = { + "name": "name_value", + "label_id": 812, + "account_id": 1049, + "display_name": "display_name_value", + "description": "description_value", + "label_type": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = accounts_labels.CreateAccountLabelRequest.meta.fields["account_label"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["account_label"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["account_label"][field])): + del request_init["account_label"][field][i][subfield] + else: + del request_init["account_label"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts_labels.AccountLabel( + name="name_value", + label_id=812, + account_id=1049, + display_name="display_name_value", + description="description_value", + label_type=accounts_labels.AccountLabel.LabelType.MANUAL, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts_labels.AccountLabel.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_account_label(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, accounts_labels.AccountLabel) + assert response.name == "name_value" + assert response.label_id == 812 + assert response.account_id == 1049 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.label_type == accounts_labels.AccountLabel.LabelType.MANUAL + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_account_label_rest_interceptors(null_interceptor): + transport = transports.AccountLabelsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountLabelsServiceRestInterceptor(), + ) + client = AccountLabelsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountLabelsServiceRestInterceptor, "post_create_account_label" + ) as post, mock.patch.object( + transports.AccountLabelsServiceRestInterceptor, "pre_create_account_label" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts_labels.CreateAccountLabelRequest.pb( + accounts_labels.CreateAccountLabelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts_labels.AccountLabel.to_json( + accounts_labels.AccountLabel() + ) + req.return_value.content = return_value + + request = accounts_labels.CreateAccountLabelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts_labels.AccountLabel() + + client.create_account_label( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_account_label_rest_bad_request( + request_type=accounts_labels.UpdateAccountLabelRequest, +): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"account_label": {"name": "accounts/sample1/labels/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_account_label(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts_labels.UpdateAccountLabelRequest, + dict, + ], +) +def test_update_account_label_rest_call_success(request_type): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"account_label": {"name": "accounts/sample1/labels/sample2"}} + request_init["account_label"] = { + "name": "accounts/sample1/labels/sample2", + "label_id": 812, + "account_id": 1049, + "display_name": "display_name_value", + "description": "description_value", + "label_type": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = accounts_labels.UpdateAccountLabelRequest.meta.fields["account_label"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["account_label"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["account_label"][field])): + del request_init["account_label"][field][i][subfield] + else: + del request_init["account_label"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts_labels.AccountLabel( + name="name_value", + label_id=812, + account_id=1049, + display_name="display_name_value", + description="description_value", + label_type=accounts_labels.AccountLabel.LabelType.MANUAL, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts_labels.AccountLabel.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_account_label(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, accounts_labels.AccountLabel) + assert response.name == "name_value" + assert response.label_id == 812 + assert response.account_id == 1049 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.label_type == accounts_labels.AccountLabel.LabelType.MANUAL + + @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_account_label_rest_interceptors(null_interceptor): +def test_update_account_label_rest_interceptors(null_interceptor): transport = transports.AccountLabelsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -4310,16 +4432,20 @@ def test_delete_account_label_rest_interceptors(null_interceptor): else transports.AccountLabelsServiceRestInterceptor(), ) client = AccountLabelsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.AccountLabelsServiceRestInterceptor, "pre_delete_account_label" + transports.AccountLabelsServiceRestInterceptor, "post_update_account_label" + ) as post, mock.patch.object( + transports.AccountLabelsServiceRestInterceptor, "pre_update_account_label" ) as pre: pre.assert_not_called() - pb_message = accounts_labels.DeleteAccountLabelRequest.pb( - accounts_labels.DeleteAccountLabelRequest() + post.assert_not_called() + pb_message = accounts_labels.UpdateAccountLabelRequest.pb( + accounts_labels.UpdateAccountLabelRequest() ) transcode.return_value = { "method": "post", @@ -4328,18 +4454,22 @@ def test_delete_account_label_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = accounts_labels.AccountLabel.to_json( + accounts_labels.AccountLabel() + ) + req.return_value.content = return_value - request = accounts_labels.DeleteAccountLabelRequest() + request = accounts_labels.UpdateAccountLabelRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = accounts_labels.AccountLabel() - client.delete_account_label( + client.update_account_label( request, metadata=[ ("key", "val"), @@ -4348,16 +4478,15 @@ def test_delete_account_label_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_delete_account_label_rest_bad_request( - transport: str = "rest", request_type=accounts_labels.DeleteAccountLabelRequest + request_type=accounts_labels.DeleteAccountLabelRequest, ): client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1/labels/sample2"} request = request_type(**request_init) @@ -4367,176 +4496,190 @@ def test_delete_account_label_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.delete_account_label(request) -def test_delete_account_label_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + accounts_labels.DeleteAccountLabelRequest, + dict, + ], +) +def test_delete_account_label_rest_call_success(request_type): client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/labels/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/labels/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_account_label(request) - client.delete_account_label(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=accounts/*/labels/*}" % client.transport._host, args[1] - ) + # Establish that the response is the type that we expect. + assert response is None -def test_delete_account_label_rest_flattened_error(transport: str = "rest"): - client = AccountLabelsServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_account_label_rest_interceptors(null_interceptor): + transport = transports.AccountLabelsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.AccountLabelsServiceRestInterceptor(), ) + client = AccountLabelsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountLabelsServiceRestInterceptor, "pre_delete_account_label" + ) as pre: + pre.assert_not_called() + pb_message = accounts_labels.DeleteAccountLabelRequest.pb( + accounts_labels.DeleteAccountLabelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = accounts_labels.DeleteAccountLabelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.delete_account_label( - accounts_labels.DeleteAccountLabelRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + -def test_delete_account_label_rest_error(): +def test_initialize_client_w_rest(): client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.AccountLabelsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_account_labels_empty_call_rest(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.AccountLabelsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AccountLabelsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_account_labels), "__call__" + ) as call: + client.list_account_labels(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.AccountLabelsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountLabelsServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.ListAccountLabelsRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountLabelsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.AccountLabelsServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_account_label_empty_call_rest(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountLabelsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_account_label), "__call__" + ) as call: + client.create_account_label(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountLabelsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = AccountLabelsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.CreateAccountLabelRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountLabelsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.AccountLabelsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_account_label_empty_call_rest(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_account_label), "__call__" + ) as call: + client.update_account_label(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.AccountLabelsServiceGrpcTransport, - transports.AccountLabelsServiceGrpcAsyncIOTransport, - transports.AccountLabelsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.UpdateAccountLabelRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = AccountLabelsServiceClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_account_label_empty_call_rest(): + client = AccountLabelsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_account_label), "__call__" + ) as call: + client.delete_account_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts_labels.DeleteAccountLabelRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -5123,36 +5266,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = AccountLabelsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = AccountLabelsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = AccountLabelsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_accounts_service.py b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_accounts_service.py index b5e69b9df20c..bbdd3ea3cb27 100644 --- a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_accounts_service.py +++ b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_accounts_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.css_v1.services.accounts_service import ( AccountsServiceAsyncClient, AccountsServiceClient, @@ -52,10 +61,24 @@ from google.shopping.css_v1.types import accounts +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1179,27 +1202,6 @@ def test_list_child_accounts(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_child_accounts_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_child_accounts), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_child_accounts() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.ListChildAccountsRequest() - - def test_list_child_accounts_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1273,31 +1275,6 @@ def test_list_child_accounts_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_child_accounts_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_child_accounts), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.ListChildAccountsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_child_accounts() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.ListChildAccountsRequest() - - @pytest.mark.asyncio async def test_list_child_accounts_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1306,7 +1283,7 @@ async def test_list_child_accounts_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1345,7 +1322,7 @@ async def test_list_child_accounts_async( transport: str = "grpc_asyncio", request_type=accounts.ListChildAccountsRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1415,7 +1392,7 @@ def test_list_child_accounts_field_headers(): @pytest.mark.asyncio async def test_list_child_accounts_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1489,7 +1466,7 @@ def test_list_child_accounts_flattened_error(): @pytest.mark.asyncio async def test_list_child_accounts_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1520,7 +1497,7 @@ async def test_list_child_accounts_flattened_async(): @pytest.mark.asyncio async def test_list_child_accounts_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1634,7 +1611,7 @@ def test_list_child_accounts_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_child_accounts_async_pager(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1686,7 +1663,7 @@ async def test_list_child_accounts_async_pager(): @pytest.mark.asyncio async def test_list_child_accounts_async_pages(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1784,25 +1761,6 @@ def test_get_account(request_type, transport: str = "grpc"): assert response.account_type == accounts.Account.AccountType.CSS_GROUP -def test_get_account_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_account), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.GetAccountRequest() - - def test_get_account_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1868,36 +1826,6 @@ def test_get_account_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_account_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_account), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.Account( - name="name_value", - full_name="full_name_value", - display_name="display_name_value", - homepage_uri="homepage_uri_value", - parent="parent_value", - label_ids=[927], - automatic_label_ids=[1989], - account_type=accounts.Account.AccountType.CSS_GROUP, - ) - ) - response = await client.get_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.GetAccountRequest() - - @pytest.mark.asyncio async def test_get_account_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1906,7 +1834,7 @@ async def test_get_account_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1945,7 +1873,7 @@ async def test_get_account_async( transport: str = "grpc_asyncio", request_type=accounts.GetAccountRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2025,7 +1953,7 @@ def test_get_account_field_headers(): @pytest.mark.asyncio async def test_get_account_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2093,7 +2021,7 @@ def test_get_account_flattened_error(): @pytest.mark.asyncio async def test_get_account_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2120,7 +2048,7 @@ async def test_get_account_flattened_async(): @pytest.mark.asyncio async def test_get_account_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2182,25 +2110,6 @@ def test_update_labels(request_type, transport: str = "grpc"): assert response.account_type == accounts.Account.AccountType.CSS_GROUP -def test_update_labels_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_labels), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_labels() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.UpdateAccountLabelsRequest() - - def test_update_labels_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2266,36 +2175,6 @@ def test_update_labels_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_labels_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_labels), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.Account( - name="name_value", - full_name="full_name_value", - display_name="display_name_value", - homepage_uri="homepage_uri_value", - parent="parent_value", - label_ids=[927], - automatic_label_ids=[1989], - account_type=accounts.Account.AccountType.CSS_GROUP, - ) - ) - response = await client.update_labels() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.UpdateAccountLabelsRequest() - - @pytest.mark.asyncio async def test_update_labels_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2304,7 +2183,7 @@ async def test_update_labels_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2343,7 +2222,7 @@ async def test_update_labels_async( transport: str = "grpc_asyncio", request_type=accounts.UpdateAccountLabelsRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2423,7 +2302,7 @@ def test_update_labels_field_headers(): @pytest.mark.asyncio async def test_update_labels_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2491,7 +2370,7 @@ def test_update_labels_flattened_error(): @pytest.mark.asyncio async def test_update_labels_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2518,7 +2397,7 @@ async def test_update_labels_flattened_async(): @pytest.mark.asyncio async def test_update_labels_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2530,46 +2409,6 @@ async def test_update_labels_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - accounts.ListChildAccountsRequest, - dict, - ], -) -def test_list_child_accounts_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.ListChildAccountsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.ListChildAccountsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_child_accounts(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListChildAccountsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_child_accounts_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2712,106 +2551,25 @@ def test_list_child_accounts_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_child_accounts_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( +def test_list_child_accounts_rest_flattened(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), + transport="rest", ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_list_child_accounts" - ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_list_child_accounts" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts.ListChildAccountsRequest.pb( - accounts.ListChildAccountsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.ListChildAccountsResponse.to_json( - accounts.ListChildAccountsResponse() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.ListChildAccountsResponse() - request = accounts.ListChildAccountsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts.ListChildAccountsResponse() + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} - client.list_child_accounts( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_child_accounts_rest_bad_request( - transport: str = "rest", request_type=accounts.ListChildAccountsRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_child_accounts(request) - - -def test_list_child_accounts_rest_flattened(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.ListChildAccountsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) + mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() @@ -2912,60 +2670,6 @@ def test_list_child_accounts_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - accounts.GetAccountRequest, - dict, - ], -) -def test_get_account_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.Account( - name="name_value", - full_name="full_name_value", - display_name="display_name_value", - homepage_uri="homepage_uri_value", - parent="parent_value", - label_ids=[927], - automatic_label_ids=[1989], - account_type=accounts.Account.AccountType.CSS_GROUP, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.Account.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_account(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts.Account) - assert response.name == "name_value" - assert response.full_name == "full_name_value" - assert response.display_name == "display_name_value" - assert response.homepage_uri == "homepage_uri_value" - assert response.parent == "parent_value" - assert response.label_ids == [927] - assert response.automatic_label_ids == [1989] - assert response.account_type == accounts.Account.AccountType.CSS_GROUP - - def test_get_account_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3085,83 +2789,6 @@ def test_get_account_rest_unset_required_fields(): assert set(unset_fields) == (set(("parent",)) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_account_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), - ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_get_account" - ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_get_account" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts.GetAccountRequest.pb(accounts.GetAccountRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.Account.to_json(accounts.Account()) - - request = accounts.GetAccountRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts.Account() - - client.get_account( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_account_rest_bad_request( - transport: str = "rest", request_type=accounts.GetAccountRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_account(request) - - def test_get_account_rest_flattened(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3217,66 +2844,6 @@ def test_get_account_rest_flattened_error(transport: str = "rest"): ) -def test_get_account_rest_error(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - accounts.UpdateAccountLabelsRequest, - dict, - ], -) -def test_update_labels_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.Account( - name="name_value", - full_name="full_name_value", - display_name="display_name_value", - homepage_uri="homepage_uri_value", - parent="parent_value", - label_ids=[927], - automatic_label_ids=[1989], - account_type=accounts.Account.AccountType.CSS_GROUP, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.Account.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_labels(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts.Account) - assert response.name == "name_value" - assert response.full_name == "full_name_value" - assert response.display_name == "display_name_value" - assert response.homepage_uri == "homepage_uri_value" - assert response.parent == "parent_value" - assert response.label_ids == [927] - assert response.automatic_label_ids == [1989] - assert response.account_type == accounts.Account.AccountType.CSS_GROUP - - def test_update_labels_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3397,8 +2964,548 @@ def test_update_labels_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) +def test_update_labels_rest_flattened(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.Account() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = accounts.Account.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_labels(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=accounts/*}:updateLabels" % client.transport._host, args[1] + ) + + +def test_update_labels_rest_flattened_error(transport: str = "rest"): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_labels( + accounts.UpdateAccountLabelsRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AccountsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AccountsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AccountsServiceGrpcTransport, + transports.AccountsServiceGrpcAsyncIOTransport, + transports.AccountsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = AccountsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_child_accounts_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_child_accounts), "__call__" + ) as call: + call.return_value = accounts.ListChildAccountsResponse() + client.list_child_accounts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListChildAccountsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_account_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account), "__call__") as call: + call.return_value = accounts.Account() + client.get_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.GetAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_labels_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_labels), "__call__") as call: + call.return_value = accounts.Account() + client.update_labels(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.UpdateAccountLabelsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AccountsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_child_accounts_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_child_accounts), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.ListChildAccountsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_child_accounts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListChildAccountsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_account_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.Account( + name="name_value", + full_name="full_name_value", + display_name="display_name_value", + homepage_uri="homepage_uri_value", + parent="parent_value", + label_ids=[927], + automatic_label_ids=[1989], + account_type=accounts.Account.AccountType.CSS_GROUP, + ) + ) + await client.get_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.GetAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_labels_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_labels), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.Account( + name="name_value", + full_name="full_name_value", + display_name="display_name_value", + homepage_uri="homepage_uri_value", + parent="parent_value", + label_ids=[927], + automatic_label_ids=[1989], + account_type=accounts.Account.AccountType.CSS_GROUP, + ) + ) + await client.update_labels(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.UpdateAccountLabelsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AccountsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_child_accounts_rest_bad_request( + request_type=accounts.ListChildAccountsRequest, +): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_child_accounts(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.ListChildAccountsRequest, + dict, + ], +) +def test_list_child_accounts_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.ListChildAccountsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.ListChildAccountsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_child_accounts(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListChildAccountsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_child_accounts_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), + ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "post_list_child_accounts" + ) as post, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_list_child_accounts" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts.ListChildAccountsRequest.pb( + accounts.ListChildAccountsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts.ListChildAccountsResponse.to_json( + accounts.ListChildAccountsResponse() + ) + req.return_value.content = return_value + + request = accounts.ListChildAccountsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts.ListChildAccountsResponse() + + client.list_child_accounts( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_account_rest_bad_request(request_type=accounts.GetAccountRequest): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_account(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.GetAccountRequest, + dict, + ], +) +def test_get_account_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.Account( + name="name_value", + full_name="full_name_value", + display_name="display_name_value", + homepage_uri="homepage_uri_value", + parent="parent_value", + label_ids=[927], + automatic_label_ids=[1989], + account_type=accounts.Account.AccountType.CSS_GROUP, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.Account.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_account(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, accounts.Account) + assert response.name == "name_value" + assert response.full_name == "full_name_value" + assert response.display_name == "display_name_value" + assert response.homepage_uri == "homepage_uri_value" + assert response.parent == "parent_value" + assert response.label_ids == [927] + assert response.automatic_label_ids == [1989] + assert response.account_type == accounts.Account.AccountType.CSS_GROUP + + @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_labels_rest_interceptors(null_interceptor): +def test_get_account_rest_interceptors(null_interceptor): transport = transports.AccountsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -3406,20 +3513,19 @@ def test_update_labels_rest_interceptors(null_interceptor): else transports.AccountsServiceRestInterceptor(), ) client = AccountsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_update_labels" + transports.AccountsServiceRestInterceptor, "post_get_account" ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_update_labels" + transports.AccountsServiceRestInterceptor, "pre_get_account" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = accounts.UpdateAccountLabelsRequest.pb( - accounts.UpdateAccountLabelsRequest() - ) + pb_message = accounts.GetAccountRequest.pb(accounts.GetAccountRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -3427,12 +3533,12 @@ def test_update_labels_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.Account.to_json(accounts.Account()) + return_value = accounts.Account.to_json(accounts.Account()) + req.return_value.content = return_value - request = accounts.UpdateAccountLabelsRequest() + request = accounts.GetAccountRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -3440,7 +3546,7 @@ def test_update_labels_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = accounts.Account() - client.update_labels( + client.get_account( request, metadata=[ ("key", "val"), @@ -3453,13 +3559,11 @@ def test_update_labels_rest_interceptors(null_interceptor): def test_update_labels_rest_bad_request( - transport: str = "rest", request_type=accounts.UpdateAccountLabelsRequest + request_type=accounts.UpdateAccountLabelsRequest, ): client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1"} request = request_type(**request_init) @@ -3469,178 +3573,191 @@ def test_update_labels_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.update_labels(request) -def test_update_labels_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + accounts.UpdateAccountLabelsRequest, + dict, + ], +) +def test_update_labels_rest_call_success(request_type): client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = accounts.Account() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( + return_value = accounts.Account( name="name_value", + full_name="full_name_value", + display_name="display_name_value", + homepage_uri="homepage_uri_value", + parent="parent_value", + label_ids=[927], + automatic_label_ids=[1989], + account_type=accounts.Account.AccountType.CSS_GROUP, ) - mock_args.update(sample_request) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = accounts.Account.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.update_labels(request) - client.update_labels(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=accounts/*}:updateLabels" % client.transport._host, args[1] - ) + # Establish that the response is the type that we expect. + assert isinstance(response, accounts.Account) + assert response.name == "name_value" + assert response.full_name == "full_name_value" + assert response.display_name == "display_name_value" + assert response.homepage_uri == "homepage_uri_value" + assert response.parent == "parent_value" + assert response.label_ids == [927] + assert response.automatic_label_ids == [1989] + assert response.account_type == accounts.Account.AccountType.CSS_GROUP -def test_update_labels_rest_flattened_error(transport: str = "rest"): - client = AccountsServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_labels_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "post_update_labels" + ) as post, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_update_labels" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts.UpdateAccountLabelsRequest.pb( + accounts.UpdateAccountLabelsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts.Account.to_json(accounts.Account()) + req.return_value.content = return_value + + request = accounts.UpdateAccountLabelsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts.Account() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.update_labels( - accounts.UpdateAccountLabelsRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() -def test_update_labels_rest_error(): + +def test_initialize_client_w_rest(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.AccountsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_child_accounts_empty_call_rest(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_child_accounts), "__call__" + ) as call: + client.list_child_accounts(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListChildAccountsRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.AccountsServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_account_empty_call_rest(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account), "__call__") as call: + client.get_account(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = AccountsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.GetAccountRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.AccountsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_labels_empty_call_rest(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.AccountsServiceGrpcTransport, - transports.AccountsServiceGrpcAsyncIOTransport, - transports.AccountsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_labels), "__call__") as call: + client.update_labels(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.UpdateAccountLabelsRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = AccountsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4218,36 +4335,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_product_inputs_service.py b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_product_inputs_service.py index 44cee9034e03..f985762cdb9b 100644 --- a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_product_inputs_service.py +++ b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_product_inputs_service.py @@ -22,28 +22,37 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.css_v1.services.css_product_inputs_service import ( CssProductInputsServiceAsyncClient, @@ -53,10 +62,24 @@ from google.shopping.css_v1.types import css_product_common, css_product_inputs +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1236,27 +1259,6 @@ def test_insert_css_product_input(request_type, transport: str = "grpc"): assert response.feed_label == "feed_label_value" -def test_insert_css_product_input_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_css_product_input), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_css_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_product_inputs.InsertCssProductInputRequest() - - def test_insert_css_product_input_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1327,35 +1329,6 @@ def test_insert_css_product_input_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_css_product_input_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_css_product_input), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - css_product_inputs.CssProductInput( - name="name_value", - final_name="final_name_value", - raw_provided_id="raw_provided_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - ) - ) - response = await client.insert_css_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_product_inputs.InsertCssProductInputRequest() - - @pytest.mark.asyncio async def test_insert_css_product_input_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1364,7 +1337,7 @@ async def test_insert_css_product_input_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1404,7 +1377,7 @@ async def test_insert_css_product_input_async( request_type=css_product_inputs.InsertCssProductInputRequest, ): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1482,7 +1455,7 @@ def test_insert_css_product_input_field_headers(): @pytest.mark.asyncio async def test_insert_css_product_input_field_headers_async(): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1548,27 +1521,6 @@ def test_delete_css_product_input(request_type, transport: str = "grpc"): assert response is None -def test_delete_css_product_input_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_css_product_input), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_css_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_product_inputs.DeleteCssProductInputRequest() - - def test_delete_css_product_input_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1639,27 +1591,6 @@ def test_delete_css_product_input_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_css_product_input_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_css_product_input), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_css_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_product_inputs.DeleteCssProductInputRequest() - - @pytest.mark.asyncio async def test_delete_css_product_input_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1668,7 +1599,7 @@ async def test_delete_css_product_input_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1708,7 +1639,7 @@ async def test_delete_css_product_input_async( request_type=css_product_inputs.DeleteCssProductInputRequest, ): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1773,7 +1704,7 @@ def test_delete_css_product_input_field_headers(): @pytest.mark.asyncio async def test_delete_css_product_input_field_headers_async(): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1845,7 +1776,7 @@ def test_delete_css_product_input_flattened_error(): @pytest.mark.asyncio async def test_delete_css_product_input_flattened_async(): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1874,7 +1805,7 @@ async def test_delete_css_product_input_flattened_async(): @pytest.mark.asyncio async def test_delete_css_product_input_flattened_error_async(): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1886,244 +1817,39 @@ async def test_delete_css_product_input_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - css_product_inputs.InsertCssProductInputRequest, - dict, - ], -) -def test_insert_css_product_input_rest(request_type): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +def test_insert_css_product_input_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["css_product_input"] = { - "name": "name_value", - "final_name": "final_name_value", - "raw_provided_id": "raw_provided_id_value", - "content_language": "content_language_value", - "feed_label": "feed_label_value", - "freshness_time": {"seconds": 751, "nanos": 543}, - "attributes": { - "cpp_link": "cpp_link_value", - "cpp_mobile_link": "cpp_mobile_link_value", - "cpp_ads_redirect": "cpp_ads_redirect_value", - "low_price": { - "amount_micros": 1408, - "currency_code": "currency_code_value", - }, - "high_price": {}, - "number_of_offers": 1697, - "headline_offer_condition": "headline_offer_condition_value", - "headline_offer_price": {}, - "headline_offer_link": "headline_offer_link_value", - "headline_offer_mobile_link": "headline_offer_mobile_link_value", - "headline_offer_shipping_price": {}, - "title": "title_value", - "image_link": "image_link_value", - "additional_image_links": [ - "additional_image_links_value1", - "additional_image_links_value2", - ], - "description": "description_value", - "brand": "brand_value", - "mpn": "mpn_value", - "gtin": "gtin_value", - "product_types": ["product_types_value1", "product_types_value2"], - "google_product_category": "google_product_category_value", - "adult": True, - "multipack": 970, - "is_bundle": True, - "age_group": "age_group_value", - "color": "color_value", - "gender": "gender_value", - "material": "material_value", - "pattern": "pattern_value", - "size": "size_value", - "size_system": "size_system_value", - "size_types": ["size_types_value1", "size_types_value2"], - "item_group_id": "item_group_id_value", - "product_details": [ - { - "section_name": "section_name_value", - "attribute_name": "attribute_name_value", - "attribute_value": "attribute_value_value", - } - ], - "product_weight": {"value": 0.541, "unit": "unit_value"}, - "product_length": {"value": 0.541, "unit": "unit_value"}, - "product_width": {}, - "product_height": {}, - "product_highlights": [ - "product_highlights_value1", - "product_highlights_value2", - ], - "certifications": [ - { - "name": "name_value", - "authority": "authority_value", - "code": "code_value", - } - ], - "expiration_date": {}, - "included_destinations": [ - "included_destinations_value1", - "included_destinations_value2", - ], - "excluded_destinations": [ - "excluded_destinations_value1", - "excluded_destinations_value2", - ], - "pause": "pause_value", - "custom_label_0": "custom_label_0_value", - "custom_label_1": "custom_label_1_value", - "custom_label_2": "custom_label_2_value", - "custom_label_3": "custom_label_3_value", - "custom_label_4": "custom_label_4_value", - }, - "custom_attributes": [ - {"name": "name_value", "value": "value_value", "group_values": {}} - ], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Determine if the message type is proto-plus or protobuf - test_field = css_product_inputs.InsertCssProductInputRequest.meta.fields[ - "css_product_input" - ] + # Ensure method has been cached + assert ( + client._transport.insert_css_product_input + in client._transport._wrapped_methods + ) - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.insert_css_product_input + ] = mock_rpc - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + request = {} + client.insert_css_product_input(request) - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["css_product_input"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["css_product_input"][field])): - del request_init["css_product_input"][field][i][subfield] - else: - del request_init["css_product_input"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = css_product_inputs.CssProductInput( - name="name_value", - final_name="final_name_value", - raw_provided_id="raw_provided_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = css_product_inputs.CssProductInput.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_css_product_input(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, css_product_inputs.CssProductInput) - assert response.name == "name_value" - assert response.final_name == "final_name_value" - assert response.raw_provided_id == "raw_provided_id_value" - assert response.content_language == "content_language_value" - assert response.feed_label == "feed_label_value" - - -def test_insert_css_product_input_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.insert_css_product_input - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.insert_css_product_input - ] = mock_rpc - - request = {} - client.insert_css_product_input(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 client.insert_css_product_input(request) @@ -2240,131 +1966,6 @@ def test_insert_css_product_input_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_css_product_input_rest_interceptors(null_interceptor): - transport = transports.CssProductInputsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.CssProductInputsServiceRestInterceptor(), - ) - client = CssProductInputsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.CssProductInputsServiceRestInterceptor, - "post_insert_css_product_input", - ) as post, mock.patch.object( - transports.CssProductInputsServiceRestInterceptor, - "pre_insert_css_product_input", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = css_product_inputs.InsertCssProductInputRequest.pb( - css_product_inputs.InsertCssProductInputRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = css_product_inputs.CssProductInput.to_json( - css_product_inputs.CssProductInput() - ) - - request = css_product_inputs.InsertCssProductInputRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = css_product_inputs.CssProductInput() - - client.insert_css_product_input( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_insert_css_product_input_rest_bad_request( - transport: str = "rest", - request_type=css_product_inputs.InsertCssProductInputRequest, -): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_css_product_input(request) - - -def test_insert_css_product_input_rest_error(): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - css_product_inputs.DeleteCssProductInputRequest, - dict, - ], -) -def test_delete_css_product_input_rest(request_type): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/cssProductInputs/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_css_product_input(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_css_product_input_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2484,12 +2085,525 @@ def test_delete_css_product_input_rest_unset_required_fields(): credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_css_product_input._get_unset_required_fields({}) - assert set(unset_fields) == (set(("supplementalFeedId",)) & set(("name",))) + unset_fields = transport.delete_css_product_input._get_unset_required_fields({}) + assert set(unset_fields) == (set(("supplementalFeedId",)) & set(("name",))) + + +def test_delete_css_product_input_rest_flattened(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/cssProductInputs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_css_product_input(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=accounts/*/cssProductInputs/*}" % client.transport._host, + args[1], + ) + + +def test_delete_css_product_input_rest_flattened_error(transport: str = "rest"): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_css_product_input( + css_product_inputs.DeleteCssProductInputRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CssProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CssProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CssProductInputsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CssProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CssProductInputsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CssProductInputsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CssProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CssProductInputsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CssProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CssProductInputsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CssProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CssProductInputsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CssProductInputsServiceGrpcTransport, + transports.CssProductInputsServiceGrpcAsyncIOTransport, + transports.CssProductInputsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = CssProductInputsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_css_product_input_empty_call_grpc(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_css_product_input), "__call__" + ) as call: + call.return_value = css_product_inputs.CssProductInput() + client.insert_css_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_product_inputs.InsertCssProductInputRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_css_product_input_empty_call_grpc(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_css_product_input), "__call__" + ) as call: + call.return_value = None + client.delete_css_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_product_inputs.DeleteCssProductInputRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = CssProductInputsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = CssProductInputsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_css_product_input_empty_call_grpc_asyncio(): + client = CssProductInputsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_css_product_input), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + css_product_inputs.CssProductInput( + name="name_value", + final_name="final_name_value", + raw_provided_id="raw_provided_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + ) + ) + await client.insert_css_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_product_inputs.InsertCssProductInputRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_css_product_input_empty_call_grpc_asyncio(): + client = CssProductInputsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_css_product_input), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_css_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_product_inputs.DeleteCssProductInputRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = CssProductInputsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_insert_css_product_input_rest_bad_request( + request_type=css_product_inputs.InsertCssProductInputRequest, +): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_css_product_input(request) + + +@pytest.mark.parametrize( + "request_type", + [ + css_product_inputs.InsertCssProductInputRequest, + dict, + ], +) +def test_insert_css_product_input_rest_call_success(request_type): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["css_product_input"] = { + "name": "name_value", + "final_name": "final_name_value", + "raw_provided_id": "raw_provided_id_value", + "content_language": "content_language_value", + "feed_label": "feed_label_value", + "freshness_time": {"seconds": 751, "nanos": 543}, + "attributes": { + "cpp_link": "cpp_link_value", + "cpp_mobile_link": "cpp_mobile_link_value", + "cpp_ads_redirect": "cpp_ads_redirect_value", + "low_price": { + "amount_micros": 1408, + "currency_code": "currency_code_value", + }, + "high_price": {}, + "number_of_offers": 1697, + "headline_offer_condition": "headline_offer_condition_value", + "headline_offer_price": {}, + "headline_offer_link": "headline_offer_link_value", + "headline_offer_mobile_link": "headline_offer_mobile_link_value", + "headline_offer_shipping_price": {}, + "title": "title_value", + "image_link": "image_link_value", + "additional_image_links": [ + "additional_image_links_value1", + "additional_image_links_value2", + ], + "description": "description_value", + "brand": "brand_value", + "mpn": "mpn_value", + "gtin": "gtin_value", + "product_types": ["product_types_value1", "product_types_value2"], + "google_product_category": "google_product_category_value", + "adult": True, + "multipack": 970, + "is_bundle": True, + "age_group": "age_group_value", + "color": "color_value", + "gender": "gender_value", + "material": "material_value", + "pattern": "pattern_value", + "size": "size_value", + "size_system": "size_system_value", + "size_types": ["size_types_value1", "size_types_value2"], + "item_group_id": "item_group_id_value", + "product_details": [ + { + "section_name": "section_name_value", + "attribute_name": "attribute_name_value", + "attribute_value": "attribute_value_value", + } + ], + "product_weight": {"value": 0.541, "unit": "unit_value"}, + "product_length": {"value": 0.541, "unit": "unit_value"}, + "product_width": {}, + "product_height": {}, + "product_highlights": [ + "product_highlights_value1", + "product_highlights_value2", + ], + "certifications": [ + { + "name": "name_value", + "authority": "authority_value", + "code": "code_value", + } + ], + "expiration_date": {}, + "included_destinations": [ + "included_destinations_value1", + "included_destinations_value2", + ], + "excluded_destinations": [ + "excluded_destinations_value1", + "excluded_destinations_value2", + ], + "pause": "pause_value", + "custom_label_0": "custom_label_0_value", + "custom_label_1": "custom_label_1_value", + "custom_label_2": "custom_label_2_value", + "custom_label_3": "custom_label_3_value", + "custom_label_4": "custom_label_4_value", + }, + "custom_attributes": [ + {"name": "name_value", "value": "value_value", "group_values": {}} + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = css_product_inputs.InsertCssProductInputRequest.meta.fields[ + "css_product_input" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["css_product_input"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["css_product_input"][field])): + del request_init["css_product_input"][field][i][subfield] + else: + del request_init["css_product_input"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = css_product_inputs.CssProductInput( + name="name_value", + final_name="final_name_value", + raw_provided_id="raw_provided_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = css_product_inputs.CssProductInput.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_css_product_input(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, css_product_inputs.CssProductInput) + assert response.name == "name_value" + assert response.final_name == "final_name_value" + assert response.raw_provided_id == "raw_provided_id_value" + assert response.content_language == "content_language_value" + assert response.feed_label == "feed_label_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_css_product_input_rest_interceptors(null_interceptor): +def test_insert_css_product_input_rest_interceptors(null_interceptor): transport = transports.CssProductInputsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -2497,17 +2611,22 @@ def test_delete_css_product_input_rest_interceptors(null_interceptor): else transports.CssProductInputsServiceRestInterceptor(), ) client = CssProductInputsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( transports.CssProductInputsServiceRestInterceptor, - "pre_delete_css_product_input", + "post_insert_css_product_input", + ) as post, mock.patch.object( + transports.CssProductInputsServiceRestInterceptor, + "pre_insert_css_product_input", ) as pre: pre.assert_not_called() - pb_message = css_product_inputs.DeleteCssProductInputRequest.pb( - css_product_inputs.DeleteCssProductInputRequest() + post.assert_not_called() + pb_message = css_product_inputs.InsertCssProductInputRequest.pb( + css_product_inputs.InsertCssProductInputRequest() ) transcode.return_value = { "method": "post", @@ -2516,18 +2635,22 @@ def test_delete_css_product_input_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = css_product_inputs.CssProductInput.to_json( + css_product_inputs.CssProductInput() + ) + req.return_value.content = return_value - request = css_product_inputs.DeleteCssProductInputRequest() + request = css_product_inputs.InsertCssProductInputRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = css_product_inputs.CssProductInput() - client.delete_css_product_input( + client.insert_css_product_input( request, metadata=[ ("key", "val"), @@ -2536,17 +2659,15 @@ def test_delete_css_product_input_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_delete_css_product_input_rest_bad_request( - transport: str = "rest", request_type=css_product_inputs.DeleteCssProductInputRequest, ): client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1/cssProductInputs/sample2"} request = request_type(**request_init) @@ -2556,177 +2677,147 @@ def test_delete_css_product_input_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.delete_css_product_input(request) -def test_delete_css_product_input_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + css_product_inputs.DeleteCssProductInputRequest, + dict, + ], +) +def test_delete_css_product_input_rest_call_success(request_type): client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/cssProductInputs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/cssProductInputs/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_css_product_input(request) - client.delete_css_product_input(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=accounts/*/cssProductInputs/*}" % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert response is None -def test_delete_css_product_input_rest_flattened_error(transport: str = "rest"): - client = CssProductInputsServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_css_product_input_rest_interceptors(null_interceptor): + transport = transports.CssProductInputsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.CssProductInputsServiceRestInterceptor(), ) + client = CssProductInputsServiceClient(transport=transport) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_css_product_input( - css_product_inputs.DeleteCssProductInputRequest(), - name="name_value", + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CssProductInputsServiceRestInterceptor, + "pre_delete_css_product_input", + ) as pre: + pre.assert_not_called() + pb_message = css_product_inputs.DeleteCssProductInputRequest.pb( + css_product_inputs.DeleteCssProductInputRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + req.return_value = mock.Mock() + req.return_value.status_code = 200 -def test_delete_css_product_input_rest_error(): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - + request = css_product_inputs.DeleteCssProductInputRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.CssProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + client.delete_css_product_input( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.CssProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CssProductInputsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + pre.assert_called_once() - # It is an error to provide an api_key and a transport instance. - transport = transports.CssProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + +def test_initialize_client_w_rest(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CssProductInputsServiceClient( - client_options=options, - transport=transport, - ) + assert client is not None - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = CssProductInputsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - # It is an error to provide scopes and a transport instance. - transport = transports.CssProductInputsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_css_product_input_empty_call_rest(): + client = CssProductInputsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = CssProductInputsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_css_product_input), "__call__" + ) as call: + client.insert_css_product_input(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.CssProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = CssProductInputsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_product_inputs.InsertCssProductInputRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.CssProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.CssProductInputsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_css_product_input_empty_call_rest(): + client = CssProductInputsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.CssProductInputsServiceGrpcTransport, - transports.CssProductInputsServiceGrpcAsyncIOTransport, - transports.CssProductInputsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_css_product_input), "__call__" + ) as call: + client.delete_css_product_input(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_product_inputs.DeleteCssProductInputRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = CssProductInputsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3309,36 +3400,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = CssProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = CssProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = CssProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_products_service.py b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_products_service.py index 093bbfb35ea4..abceede615c5 100644 --- a/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_products_service.py +++ b/packages/google-shopping-css/tests/unit/gapic/css_v1/test_css_products_service.py @@ -22,20 +22,12 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format -from google.shopping.type.types import types import grpc from grpc.experimental import aio from proto.marshal.rules import wrappers @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.shopping.type.types import types + from google.shopping.css_v1.services.css_products_service import ( CssProductsServiceAsyncClient, CssProductsServiceClient, @@ -53,10 +62,24 @@ from google.shopping.css_v1.types import css_product_common, css_products +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1202,25 +1225,6 @@ def test_get_css_product(request_type, transport: str = "grpc"): assert response.feed_label == "feed_label_value" -def test_get_css_product_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_css_product), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_css_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_products.GetCssProductRequest() - - def test_get_css_product_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1284,32 +1288,6 @@ def test_get_css_product_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_css_product_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_css_product), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - css_products.CssProduct( - name="name_value", - raw_provided_id="raw_provided_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - ) - ) - response = await client.get_css_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_products.GetCssProductRequest() - - @pytest.mark.asyncio async def test_get_css_product_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1318,7 +1296,7 @@ async def test_get_css_product_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1357,7 +1335,7 @@ async def test_get_css_product_async( transport: str = "grpc_asyncio", request_type=css_products.GetCssProductRequest ): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1429,7 +1407,7 @@ def test_get_css_product_field_headers(): @pytest.mark.asyncio async def test_get_css_product_field_headers_async(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1499,7 +1477,7 @@ def test_get_css_product_flattened_error(): @pytest.mark.asyncio async def test_get_css_product_flattened_async(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1528,7 +1506,7 @@ async def test_get_css_product_flattened_async(): @pytest.mark.asyncio async def test_get_css_product_flattened_error_async(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1578,27 +1556,6 @@ def test_list_css_products(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_css_products_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_css_products), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_css_products() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_products.ListCssProductsRequest() - - def test_list_css_products_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1668,31 +1625,6 @@ def test_list_css_products_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_css_products_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_css_products), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - css_products.ListCssProductsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_css_products() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == css_products.ListCssProductsRequest() - - @pytest.mark.asyncio async def test_list_css_products_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1701,7 +1633,7 @@ async def test_list_css_products_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1740,7 +1672,7 @@ async def test_list_css_products_async( transport: str = "grpc_asyncio", request_type=css_products.ListCssProductsRequest ): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1810,7 +1742,7 @@ def test_list_css_products_field_headers(): @pytest.mark.asyncio async def test_list_css_products_field_headers_async(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1884,7 +1816,7 @@ def test_list_css_products_flattened_error(): @pytest.mark.asyncio async def test_list_css_products_flattened_async(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1915,7 +1847,7 @@ async def test_list_css_products_flattened_async(): @pytest.mark.asyncio async def test_list_css_products_flattened_error_async(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2029,7 +1961,7 @@ def test_list_css_products_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_css_products_async_pager(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2081,7 +2013,7 @@ async def test_list_css_products_async_pager(): @pytest.mark.asyncio async def test_list_css_products_async_pages(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2129,52 +2061,6 @@ async def test_list_css_products_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - css_products.GetCssProductRequest, - dict, - ], -) -def test_get_css_product_rest(request_type): - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/cssProducts/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = css_products.CssProduct( - name="name_value", - raw_provided_id="raw_provided_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = css_products.CssProduct.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_css_product(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, css_products.CssProduct) - assert response.name == "name_value" - assert response.raw_provided_id == "raw_provided_id_value" - assert response.content_language == "content_language_value" - assert response.feed_label == "feed_label_value" - - def test_get_css_product_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2294,87 +2180,6 @@ def test_get_css_product_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_css_product_rest_interceptors(null_interceptor): - transport = transports.CssProductsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.CssProductsServiceRestInterceptor(), - ) - client = CssProductsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.CssProductsServiceRestInterceptor, "post_get_css_product" - ) as post, mock.patch.object( - transports.CssProductsServiceRestInterceptor, "pre_get_css_product" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = css_products.GetCssProductRequest.pb( - css_products.GetCssProductRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = css_products.CssProduct.to_json( - css_products.CssProduct() - ) - - request = css_products.GetCssProductRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = css_products.CssProduct() - - client.get_css_product( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_css_product_rest_bad_request( - transport: str = "rest", request_type=css_products.GetCssProductRequest -): - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/cssProducts/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_css_product(request) - - def test_get_css_product_rest_flattened(): client = CssProductsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2430,67 +2235,21 @@ def test_get_css_product_rest_flattened_error(transport: str = "rest"): ) -def test_get_css_product_rest_error(): - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_list_css_products_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - css_products.ListCssProductsRequest, - dict, - ], -) -def test_list_css_products_rest(request_type): - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = css_products.ListCssProductsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = css_products.ListCssProductsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_css_products(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListCssProductsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_css_products_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_css_products in client._transport._wrapped_methods + # Ensure method has been cached + assert client._transport.list_css_products in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -2612,87 +2371,6 @@ def test_list_css_products_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_css_products_rest_interceptors(null_interceptor): - transport = transports.CssProductsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.CssProductsServiceRestInterceptor(), - ) - client = CssProductsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.CssProductsServiceRestInterceptor, "post_list_css_products" - ) as post, mock.patch.object( - transports.CssProductsServiceRestInterceptor, "pre_list_css_products" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = css_products.ListCssProductsRequest.pb( - css_products.ListCssProductsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = css_products.ListCssProductsResponse.to_json( - css_products.ListCssProductsResponse() - ) - - request = css_products.ListCssProductsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = css_products.ListCssProductsResponse() - - client.list_css_products( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_css_products_rest_bad_request( - transport: str = "rest", request_type=css_products.ListCssProductsRequest -): - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_css_products(request) - - def test_list_css_products_rest_flattened(): client = CssProductsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2903,18 +2581,437 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = CssProductsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_css_product_empty_call_grpc(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_css_product), "__call__") as call: + call.return_value = css_products.CssProduct() + client.get_css_product(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_products.GetCssProductRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_css_products_empty_call_grpc(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_css_products), "__call__" + ) as call: + call.return_value = css_products.ListCssProductsResponse() + client.list_css_products(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_products.ListCssProductsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = CssProductsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = CssProductsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_css_product_empty_call_grpc_asyncio(): + client = CssProductsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_css_product), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + css_products.CssProduct( + name="name_value", + raw_provided_id="raw_provided_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + ) + ) + await client.get_css_product(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_products.GetCssProductRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_css_products_empty_call_grpc_asyncio(): + client = CssProductsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_css_products), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + css_products.ListCssProductsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_css_products(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_products.ListCssProductsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = CssProductsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_css_product_rest_bad_request( + request_type=css_products.GetCssProductRequest, +): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/cssProducts/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_css_product(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + css_products.GetCssProductRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = CssProductsServiceClient.get_transport_class(transport_name)( +def test_get_css_product_rest_call_success(request_type): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/cssProducts/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = css_products.CssProduct( + name="name_value", + raw_provided_id="raw_provided_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = css_products.CssProduct.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_css_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, css_products.CssProduct) + assert response.name == "name_value" + assert response.raw_provided_id == "raw_provided_id_value" + assert response.content_language == "content_language_value" + assert response.feed_label == "feed_label_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_css_product_rest_interceptors(null_interceptor): + transport = transports.CssProductsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CssProductsServiceRestInterceptor(), ) - assert transport.kind == transport_name + client = CssProductsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CssProductsServiceRestInterceptor, "post_get_css_product" + ) as post, mock.patch.object( + transports.CssProductsServiceRestInterceptor, "pre_get_css_product" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = css_products.GetCssProductRequest.pb( + css_products.GetCssProductRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = css_products.CssProduct.to_json(css_products.CssProduct()) + req.return_value.content = return_value + + request = css_products.GetCssProductRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = css_products.CssProduct() + + client.get_css_product( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_css_products_rest_bad_request( + request_type=css_products.ListCssProductsRequest, +): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_css_products(request) + + +@pytest.mark.parametrize( + "request_type", + [ + css_products.ListCssProductsRequest, + dict, + ], +) +def test_list_css_products_rest_call_success(request_type): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = css_products.ListCssProductsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = css_products.ListCssProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_css_products(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCssProductsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_css_products_rest_interceptors(null_interceptor): + transport = transports.CssProductsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CssProductsServiceRestInterceptor(), + ) + client = CssProductsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CssProductsServiceRestInterceptor, "post_list_css_products" + ) as post, mock.patch.object( + transports.CssProductsServiceRestInterceptor, "pre_list_css_products" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = css_products.ListCssProductsRequest.pb( + css_products.ListCssProductsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = css_products.ListCssProductsResponse.to_json( + css_products.ListCssProductsResponse() + ) + req.return_value.content = return_value + + request = css_products.ListCssProductsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = css_products.ListCssProductsResponse() + + client.list_css_products( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_css_product_empty_call_rest(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_css_product), "__call__") as call: + client.get_css_product(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_products.GetCssProductRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_css_products_empty_call_rest(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_css_products), "__call__" + ) as call: + client.list_css_products(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = css_products.ListCssProductsRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3493,36 +3590,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = CssProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = CssProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = CssProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py index 364164ddb134..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py index 364164ddb134..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.2.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/README.rst new file mode 100644 index 000000000000..c03ba991127e --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AccountIssueServiceTransport` is the ABC for all transports. +- public child `AccountIssueServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AccountIssueServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAccountIssueServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AccountIssueServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py index 25e1588f4bb4..240f7523f536 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -271,15 +275,24 @@ def list_account_issues( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.list_account_issues: gapic_v1.method_async.wrap_method( + self.list_account_issues: self._wrap_method( self.list_account_issues, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("AccountIssueServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py index c62775d22a36..b6c6b38c64a0 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import accountissue + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAccountIssueServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import accountissue - -from .base import AccountIssueServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -108,8 +105,8 @@ class AccountIssueServiceRestStub: _interceptor: AccountIssueServiceRestInterceptor -class AccountIssueServiceRestTransport(AccountIssueServiceTransport): - """REST backend transport for AccountIssueService. +class AccountIssueServiceRestTransport(_BaseAccountIssueServiceRestTransport): + """REST backend synchronous transport for AccountIssueService. Service to support ``AccountIssueService`` API. @@ -118,7 +115,6 @@ class AccountIssueServiceRestTransport(AccountIssueServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -172,21 +168,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -197,19 +184,34 @@ def __init__( self._interceptor = interceptor or AccountIssueServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _ListAccountIssues(AccountIssueServiceRestStub): + class _ListAccountIssues( + _BaseAccountIssueServiceRestTransport._BaseListAccountIssues, + AccountIssueServiceRestStub, + ): def __hash__(self): - return hash("ListAccountIssues") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountIssueServiceRestTransport.ListAccountIssues") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -235,40 +237,31 @@ def __call__( Response message for the ``ListAccountIssues`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/issues", - }, - ] + http_options = ( + _BaseAccountIssueServiceRestTransport._BaseListAccountIssues._get_http_options() + ) request, metadata = self._interceptor.pre_list_account_issues( request, metadata ) - pb_request = accountissue.ListAccountIssuesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountIssueServiceRestTransport._BaseListAccountIssues._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountIssueServiceRestTransport._BaseListAccountIssues._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + AccountIssueServiceRestTransport._ListAccountIssues._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest_base.py new file mode 100644 index 000000000000..ed128bb70bdb --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_issue_service/transports/rest_base.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import accountissue + +from .base import DEFAULT_CLIENT_INFO, AccountIssueServiceTransport + + +class _BaseAccountIssueServiceRestTransport(AccountIssueServiceTransport): + """Base REST backend transport for AccountIssueService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseListAccountIssues: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/issues", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accountissue.ListAccountIssuesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountIssueServiceRestTransport._BaseListAccountIssues._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAccountIssueServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/README.rst new file mode 100644 index 000000000000..2af3997395a2 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AccountTaxServiceTransport` is the ABC for all transports. +- public child `AccountTaxServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AccountTaxServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAccountTaxServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AccountTaxServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py index a0965e05d70a..620cf2c12ae6 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -233,6 +234,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -338,25 +342,34 @@ def update_account_tax( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_account_tax: gapic_v1.method_async.wrap_method( + self.get_account_tax: self._wrap_method( self.get_account_tax, default_timeout=None, client_info=client_info, ), - self.list_account_tax: gapic_v1.method_async.wrap_method( + self.list_account_tax: self._wrap_method( self.list_account_tax, default_timeout=None, client_info=client_info, ), - self.update_account_tax: gapic_v1.method_async.wrap_method( + self.update_account_tax: self._wrap_method( self.update_account_tax, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("AccountTaxServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py index 3a254f06599d..985fa95d6269 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest.py @@ -16,33 +16,30 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - from google.shopping.merchant_accounts_v1beta.types import ( account_tax as gsma_account_tax, ) from google.shopping.merchant_accounts_v1beta.types import account_tax -from .base import AccountTaxServiceTransport from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAccountTaxServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, @@ -173,8 +170,8 @@ class AccountTaxServiceRestStub: _interceptor: AccountTaxServiceRestInterceptor -class AccountTaxServiceRestTransport(AccountTaxServiceTransport): - """REST backend transport for AccountTaxService. +class AccountTaxServiceRestTransport(_BaseAccountTaxServiceRestTransport): + """REST backend synchronous transport for AccountTaxService. Manages account level tax setting data. @@ -187,7 +184,6 @@ class AccountTaxServiceRestTransport(AccountTaxServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -241,21 +237,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -266,19 +253,34 @@ def __init__( self._interceptor = interceptor or AccountTaxServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetAccountTax(AccountTaxServiceRestStub): + class _GetAccountTax( + _BaseAccountTaxServiceRestTransport._BaseGetAccountTax, + AccountTaxServiceRestStub, + ): def __hash__(self): - return hash("GetAccountTax") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountTaxServiceRestTransport.GetAccountTax") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -307,38 +309,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/accounttax/*}", - }, - ] + http_options = ( + _BaseAccountTaxServiceRestTransport._BaseGetAccountTax._get_http_options() + ) request, metadata = self._interceptor.pre_get_account_tax(request, metadata) - pb_request = account_tax.GetAccountTaxRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountTaxServiceRestTransport._BaseGetAccountTax._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountTaxServiceRestTransport._BaseGetAccountTax._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountTaxServiceRestTransport._GetAccountTax._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -354,19 +345,34 @@ def __call__( resp = self._interceptor.post_get_account_tax(resp) return resp - class _ListAccountTax(AccountTaxServiceRestStub): + class _ListAccountTax( + _BaseAccountTaxServiceRestTransport._BaseListAccountTax, + AccountTaxServiceRestStub, + ): def __hash__(self): - return hash("ListAccountTax") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountTaxServiceRestTransport.ListAccountTax") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -400,40 +406,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/accounttax", - }, - ] + http_options = ( + _BaseAccountTaxServiceRestTransport._BaseListAccountTax._get_http_options() + ) request, metadata = self._interceptor.pre_list_account_tax( request, metadata ) - pb_request = account_tax.ListAccountTaxRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountTaxServiceRestTransport._BaseListAccountTax._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountTaxServiceRestTransport._BaseListAccountTax._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountTaxServiceRestTransport._ListAccountTax._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -449,19 +444,35 @@ def __call__( resp = self._interceptor.post_list_account_tax(resp) return resp - class _UpdateAccountTax(AccountTaxServiceRestStub): + class _UpdateAccountTax( + _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax, + AccountTaxServiceRestStub, + ): def __hash__(self): - return hash("UpdateAccountTax") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountTaxServiceRestTransport.UpdateAccountTax") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -490,47 +501,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{account_tax.name=accounts/*/accounttax/*}", - "body": "account_tax", - }, - ] + http_options = ( + _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax._get_http_options() + ) request, metadata = self._interceptor.pre_update_account_tax( request, metadata ) - pb_request = gsma_account_tax.UpdateAccountTaxRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = AccountTaxServiceRestTransport._UpdateAccountTax._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest_base.py new file mode 100644 index 000000000000..b940bd9885aa --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/account_tax_service/transports/rest_base.py @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import ( + account_tax as gsma_account_tax, +) +from google.shopping.merchant_accounts_v1beta.types import account_tax + +from .base import DEFAULT_CLIENT_INFO, AccountTaxServiceTransport + + +class _BaseAccountTaxServiceRestTransport(AccountTaxServiceTransport): + """Base REST backend transport for AccountTaxService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetAccountTax: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/accounttax/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = account_tax.GetAccountTaxRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountTaxServiceRestTransport._BaseGetAccountTax._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAccountTax: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/accounttax", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = account_tax.ListAccountTaxRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountTaxServiceRestTransport._BaseListAccountTax._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateAccountTax: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{account_tax.name=accounts/*/accounttax/*}", + "body": "account_tax", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gsma_account_tax.UpdateAccountTaxRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountTaxServiceRestTransport._BaseUpdateAccountTax._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAccountTaxServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/README.rst new file mode 100644 index 000000000000..feb9cc900a04 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AccountsServiceTransport` is the ABC for all transports. +- public child `AccountsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AccountsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAccountsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AccountsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py index a90a29d80462..1e3d872aa0b2 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -428,40 +432,49 @@ def list_sub_accounts( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_account: gapic_v1.method_async.wrap_method( + self.get_account: self._wrap_method( self.get_account, default_timeout=None, client_info=client_info, ), - self.create_and_configure_account: gapic_v1.method_async.wrap_method( + self.create_and_configure_account: self._wrap_method( self.create_and_configure_account, default_timeout=None, client_info=client_info, ), - self.delete_account: gapic_v1.method_async.wrap_method( + self.delete_account: self._wrap_method( self.delete_account, default_timeout=None, client_info=client_info, ), - self.update_account: gapic_v1.method_async.wrap_method( + self.update_account: self._wrap_method( self.update_account, default_timeout=None, client_info=client_info, ), - self.list_accounts: gapic_v1.method_async.wrap_method( + self.list_accounts: self._wrap_method( self.list_accounts, default_timeout=None, client_info=client_info, ), - self.list_sub_accounts: gapic_v1.method_async.wrap_method( + self.list_sub_accounts: self._wrap_method( self.list_sub_accounts, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("AccountsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py index 30b38720cf32..928ae4a3e37e 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import accounts + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAccountsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_accounts_v1beta.types import accounts - -from .base import AccountsServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -242,8 +238,8 @@ class AccountsServiceRestStub: _interceptor: AccountsServiceRestInterceptor -class AccountsServiceRestTransport(AccountsServiceTransport): - """REST backend transport for AccountsService. +class AccountsServiceRestTransport(_BaseAccountsServiceRestTransport): + """REST backend synchronous transport for AccountsService. Service to support Accounts API. @@ -252,7 +248,6 @@ class AccountsServiceRestTransport(AccountsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -306,21 +301,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -331,19 +317,35 @@ def __init__( self._interceptor = interceptor or AccountsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateAndConfigureAccount(AccountsServiceRestStub): + class _CreateAndConfigureAccount( + _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount, + AccountsServiceRestStub, + ): def __hash__(self): - return hash("CreateAndConfigureAccount") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.CreateAndConfigureAccount") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -371,47 +373,36 @@ def __call__( An account. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/accounts:createAndConfigure", - "body": "*", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount._get_http_options() + ) request, metadata = self._interceptor.pre_create_and_configure_account( request, metadata ) - pb_request = accounts.CreateAndConfigureAccountRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + AccountsServiceRestTransport._CreateAndConfigureAccount._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -427,19 +418,33 @@ def __call__( resp = self._interceptor.post_create_and_configure_account(resp) return resp - class _DeleteAccount(AccountsServiceRestStub): + class _DeleteAccount( + _BaseAccountsServiceRestTransport._BaseDeleteAccount, AccountsServiceRestStub + ): def __hash__(self): - return hash("DeleteAccount") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.DeleteAccount") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -461,38 +466,27 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/accounts/v1beta/{name=accounts/*}", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseDeleteAccount._get_http_options() + ) request, metadata = self._interceptor.pre_delete_account(request, metadata) - pb_request = accounts.DeleteAccountRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountsServiceRestTransport._BaseDeleteAccount._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseDeleteAccount._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountsServiceRestTransport._DeleteAccount._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -500,19 +494,33 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetAccount(AccountsServiceRestStub): + class _GetAccount( + _BaseAccountsServiceRestTransport._BaseGetAccount, AccountsServiceRestStub + ): def __hash__(self): - return hash("GetAccount") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.GetAccount") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -538,38 +546,27 @@ def __call__( An account. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*}", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseGetAccount._get_http_options() + ) request, metadata = self._interceptor.pre_get_account(request, metadata) - pb_request = accounts.GetAccountRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountsServiceRestTransport._BaseGetAccount._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseGetAccount._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountsServiceRestTransport._GetAccount._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -585,9 +582,33 @@ def __call__( resp = self._interceptor.post_get_account(resp) return resp - class _ListAccounts(AccountsServiceRestStub): + class _ListAccounts( + _BaseAccountsServiceRestTransport._BaseListAccounts, AccountsServiceRestStub + ): def __hash__(self): - return hash("ListAccounts") + return hash("AccountsServiceRestTransport.ListAccounts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -613,37 +634,27 @@ def __call__( Response message for the ``ListAccounts`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/accounts", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseListAccounts._get_http_options() + ) request, metadata = self._interceptor.pre_list_accounts(request, metadata) - pb_request = accounts.ListAccountsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountsServiceRestTransport._BaseListAccounts._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseListAccounts._get_query_params_json( + transcoded_request ) - query_params["$alt"] = "json;enum-encoding=int" - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountsServiceRestTransport._ListAccounts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -659,19 +670,33 @@ def __call__( resp = self._interceptor.post_list_accounts(resp) return resp - class _ListSubAccounts(AccountsServiceRestStub): + class _ListSubAccounts( + _BaseAccountsServiceRestTransport._BaseListSubAccounts, AccountsServiceRestStub + ): def __hash__(self): - return hash("ListSubAccounts") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.ListSubAccounts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -697,40 +722,29 @@ def __call__( Response message for the ``ListSubAccounts`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{provider=accounts/*}:listSubaccounts", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseListSubAccounts._get_http_options() + ) request, metadata = self._interceptor.pre_list_sub_accounts( request, metadata ) - pb_request = accounts.ListSubAccountsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAccountsServiceRestTransport._BaseListSubAccounts._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseListSubAccounts._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = AccountsServiceRestTransport._ListSubAccounts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -746,21 +760,34 @@ def __call__( resp = self._interceptor.post_list_sub_accounts(resp) return resp - class _UpdateAccount(AccountsServiceRestStub): + class _UpdateAccount( + _BaseAccountsServiceRestTransport._BaseUpdateAccount, AccountsServiceRestStub + ): def __hash__(self): - return hash("UpdateAccount") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AccountsServiceRestTransport.UpdateAccount") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -786,45 +813,32 @@ def __call__( An account. """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{account.name=accounts/*}", - "body": "account", - }, - ] + http_options = ( + _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_http_options() + ) request, metadata = self._interceptor.pre_update_account(request, metadata) - pb_request = accounts.UpdateAccountRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = AccountsServiceRestTransport._UpdateAccount._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest_base.py new file mode 100644 index 000000000000..b4645467d045 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/accounts_service/transports/rest_base.py @@ -0,0 +1,381 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import accounts + +from .base import DEFAULT_CLIENT_INFO, AccountsServiceTransport + + +class _BaseAccountsServiceRestTransport(AccountsServiceTransport): + """Base REST backend transport for AccountsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateAndConfigureAccount: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/accounts:createAndConfigure", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.CreateAndConfigureAccountRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseCreateAndConfigureAccount._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteAccount: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/accounts/v1beta/{name=accounts/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.DeleteAccountRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseDeleteAccount._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetAccount: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.GetAccountRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseGetAccount._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAccounts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/accounts", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.ListAccountsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListSubAccounts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{provider=accounts/*}:listSubaccounts", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.ListSubAccountsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseListSubAccounts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateAccount: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{account.name=accounts/*}", + "body": "account", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = accounts.UpdateAccountRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAccountsServiceRestTransport._BaseUpdateAccount._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAccountsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/README.rst new file mode 100644 index 000000000000..54f64d66d215 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AutofeedSettingsServiceTransport` is the ABC for all transports. +- public child `AutofeedSettingsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AutofeedSettingsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAutofeedSettingsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AutofeedSettingsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py index 99364a401b73..8a3be82e594e 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -301,20 +305,29 @@ def update_autofeed_settings( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_autofeed_settings: gapic_v1.method_async.wrap_method( + self.get_autofeed_settings: self._wrap_method( self.get_autofeed_settings, default_timeout=None, client_info=client_info, ), - self.update_autofeed_settings: gapic_v1.method_async.wrap_method( + self.update_autofeed_settings: self._wrap_method( self.update_autofeed_settings, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("AutofeedSettingsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py index 57aff5878d5f..d24313bb2f19 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import autofeedsettings + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAutofeedSettingsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import autofeedsettings - -from .base import AutofeedSettingsServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -141,8 +138,8 @@ class AutofeedSettingsServiceRestStub: _interceptor: AutofeedSettingsServiceRestInterceptor -class AutofeedSettingsServiceRestTransport(AutofeedSettingsServiceTransport): - """REST backend transport for AutofeedSettingsService. +class AutofeedSettingsServiceRestTransport(_BaseAutofeedSettingsServiceRestTransport): + """REST backend synchronous transport for AutofeedSettingsService. Service to support `autofeed `__ @@ -153,7 +150,6 @@ class AutofeedSettingsServiceRestTransport(AutofeedSettingsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -207,21 +203,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -232,19 +219,34 @@ def __init__( self._interceptor = interceptor or AutofeedSettingsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetAutofeedSettings(AutofeedSettingsServiceRestStub): + class _GetAutofeedSettings( + _BaseAutofeedSettingsServiceRestTransport._BaseGetAutofeedSettings, + AutofeedSettingsServiceRestStub, + ): def __hash__(self): - return hash("GetAutofeedSettings") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AutofeedSettingsServiceRestTransport.GetAutofeedSettings") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -273,40 +275,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/autofeedSettings}", - }, - ] + http_options = ( + _BaseAutofeedSettingsServiceRestTransport._BaseGetAutofeedSettings._get_http_options() + ) request, metadata = self._interceptor.pre_get_autofeed_settings( request, metadata ) - pb_request = autofeedsettings.GetAutofeedSettingsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseAutofeedSettingsServiceRestTransport._BaseGetAutofeedSettings._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAutofeedSettingsServiceRestTransport._BaseGetAutofeedSettings._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + AutofeedSettingsServiceRestTransport._GetAutofeedSettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -322,21 +315,35 @@ def __call__( resp = self._interceptor.post_get_autofeed_settings(resp) return resp - class _UpdateAutofeedSettings(AutofeedSettingsServiceRestStub): + class _UpdateAutofeedSettings( + _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings, + AutofeedSettingsServiceRestStub, + ): def __hash__(self): - return hash("UpdateAutofeedSettings") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("AutofeedSettingsServiceRestTransport.UpdateAutofeedSettings") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -366,47 +373,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{autofeed_settings.name=accounts/*/autofeedSettings}", - "body": "autofeed_settings", - }, - ] + http_options = ( + _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings._get_http_options() + ) request, metadata = self._interceptor.pre_update_autofeed_settings( request, metadata ) - pb_request = autofeedsettings.UpdateAutofeedSettingsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = AutofeedSettingsServiceRestTransport._UpdateAutofeedSettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest_base.py new file mode 100644 index 000000000000..9324187c4fe8 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/autofeed_settings_service/transports/rest_base.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import autofeedsettings + +from .base import DEFAULT_CLIENT_INFO, AutofeedSettingsServiceTransport + + +class _BaseAutofeedSettingsServiceRestTransport(AutofeedSettingsServiceTransport): + """Base REST backend transport for AutofeedSettingsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetAutofeedSettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/autofeedSettings}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = autofeedsettings.GetAutofeedSettingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAutofeedSettingsServiceRestTransport._BaseGetAutofeedSettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateAutofeedSettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{autofeed_settings.name=accounts/*/autofeedSettings}", + "body": "autofeed_settings", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = autofeedsettings.UpdateAutofeedSettingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAutofeedSettingsServiceRestTransport._BaseUpdateAutofeedSettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseAutofeedSettingsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/README.rst new file mode 100644 index 000000000000..55db4f093f62 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`BusinessIdentityServiceTransport` is the ABC for all transports. +- public child `BusinessIdentityServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `BusinessIdentityServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseBusinessIdentityServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `BusinessIdentityServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py index c3720ff6f6e5..cef1a65f4404 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -302,20 +306,29 @@ def update_business_identity( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_business_identity: gapic_v1.method_async.wrap_method( + self.get_business_identity: self._wrap_method( self.get_business_identity, default_timeout=None, client_info=client_info, ), - self.update_business_identity: gapic_v1.method_async.wrap_method( + self.update_business_identity: self._wrap_method( self.update_business_identity, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("BusinessIdentityServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py index 09662fb5d730..4f276d1b7029 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import businessidentity + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseBusinessIdentityServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import businessidentity - -from .base import BusinessIdentityServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -141,8 +138,8 @@ class BusinessIdentityServiceRestStub: _interceptor: BusinessIdentityServiceRestInterceptor -class BusinessIdentityServiceRestTransport(BusinessIdentityServiceTransport): - """REST backend transport for BusinessIdentityService. +class BusinessIdentityServiceRestTransport(_BaseBusinessIdentityServiceRestTransport): + """REST backend synchronous transport for BusinessIdentityService. Service to support `business identity `__ @@ -153,7 +150,6 @@ class BusinessIdentityServiceRestTransport(BusinessIdentityServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -207,21 +203,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -232,19 +219,34 @@ def __init__( self._interceptor = interceptor or BusinessIdentityServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetBusinessIdentity(BusinessIdentityServiceRestStub): + class _GetBusinessIdentity( + _BaseBusinessIdentityServiceRestTransport._BaseGetBusinessIdentity, + BusinessIdentityServiceRestStub, + ): def __hash__(self): - return hash("GetBusinessIdentity") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("BusinessIdentityServiceRestTransport.GetBusinessIdentity") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -272,40 +274,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/businessIdentity}", - }, - ] + http_options = ( + _BaseBusinessIdentityServiceRestTransport._BaseGetBusinessIdentity._get_http_options() + ) request, metadata = self._interceptor.pre_get_business_identity( request, metadata ) - pb_request = businessidentity.GetBusinessIdentityRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseBusinessIdentityServiceRestTransport._BaseGetBusinessIdentity._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseBusinessIdentityServiceRestTransport._BaseGetBusinessIdentity._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + BusinessIdentityServiceRestTransport._GetBusinessIdentity._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -321,21 +314,35 @@ def __call__( resp = self._interceptor.post_get_business_identity(resp) return resp - class _UpdateBusinessIdentity(BusinessIdentityServiceRestStub): + class _UpdateBusinessIdentity( + _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity, + BusinessIdentityServiceRestStub, + ): def __hash__(self): - return hash("UpdateBusinessIdentity") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("BusinessIdentityServiceRestTransport.UpdateBusinessIdentity") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -364,47 +371,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{business_identity.name=accounts/*/businessIdentity}", - "body": "business_identity", - }, - ] + http_options = ( + _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity._get_http_options() + ) request, metadata = self._interceptor.pre_update_business_identity( request, metadata ) - pb_request = businessidentity.UpdateBusinessIdentityRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = BusinessIdentityServiceRestTransport._UpdateBusinessIdentity._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest_base.py new file mode 100644 index 000000000000..cb7dec179dba --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_identity_service/transports/rest_base.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import businessidentity + +from .base import DEFAULT_CLIENT_INFO, BusinessIdentityServiceTransport + + +class _BaseBusinessIdentityServiceRestTransport(BusinessIdentityServiceTransport): + """Base REST backend transport for BusinessIdentityService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetBusinessIdentity: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/businessIdentity}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = businessidentity.GetBusinessIdentityRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBusinessIdentityServiceRestTransport._BaseGetBusinessIdentity._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateBusinessIdentity: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{business_identity.name=accounts/*/businessIdentity}", + "body": "business_identity", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = businessidentity.UpdateBusinessIdentityRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBusinessIdentityServiceRestTransport._BaseUpdateBusinessIdentity._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseBusinessIdentityServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/README.rst new file mode 100644 index 000000000000..1024050406f9 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`BusinessInfoServiceTransport` is the ABC for all transports. +- public child `BusinessInfoServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `BusinessInfoServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseBusinessInfoServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `BusinessInfoServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py index 1819c7775728..e1c608c2ad30 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -298,20 +302,29 @@ def update_business_info( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_business_info: gapic_v1.method_async.wrap_method( + self.get_business_info: self._wrap_method( self.get_business_info, default_timeout=None, client_info=client_info, ), - self.update_business_info: gapic_v1.method_async.wrap_method( + self.update_business_info: self._wrap_method( self.update_business_info, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("BusinessInfoServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py index 9b95f0f8188a..40b25eebeefa 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import businessinfo + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseBusinessInfoServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import businessinfo - -from .base import BusinessInfoServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -139,8 +136,8 @@ class BusinessInfoServiceRestStub: _interceptor: BusinessInfoServiceRestInterceptor -class BusinessInfoServiceRestTransport(BusinessInfoServiceTransport): - """REST backend transport for BusinessInfoService. +class BusinessInfoServiceRestTransport(_BaseBusinessInfoServiceRestTransport): + """REST backend synchronous transport for BusinessInfoService. Service to support business info API. @@ -149,7 +146,6 @@ class BusinessInfoServiceRestTransport(BusinessInfoServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -203,21 +199,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -228,19 +215,34 @@ def __init__( self._interceptor = interceptor or BusinessInfoServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetBusinessInfo(BusinessInfoServiceRestStub): + class _GetBusinessInfo( + _BaseBusinessInfoServiceRestTransport._BaseGetBusinessInfo, + BusinessInfoServiceRestStub, + ): def __hash__(self): - return hash("GetBusinessInfo") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("BusinessInfoServiceRestTransport.GetBusinessInfo") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -268,40 +270,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/businessInfo}", - }, - ] + http_options = ( + _BaseBusinessInfoServiceRestTransport._BaseGetBusinessInfo._get_http_options() + ) request, metadata = self._interceptor.pre_get_business_info( request, metadata ) - pb_request = businessinfo.GetBusinessInfoRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseBusinessInfoServiceRestTransport._BaseGetBusinessInfo._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseBusinessInfoServiceRestTransport._BaseGetBusinessInfo._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = BusinessInfoServiceRestTransport._GetBusinessInfo._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -317,21 +308,35 @@ def __call__( resp = self._interceptor.post_get_business_info(resp) return resp - class _UpdateBusinessInfo(BusinessInfoServiceRestStub): + class _UpdateBusinessInfo( + _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo, + BusinessInfoServiceRestStub, + ): def __hash__(self): - return hash("UpdateBusinessInfo") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("BusinessInfoServiceRestTransport.UpdateBusinessInfo") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -359,47 +364,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{business_info.name=accounts/*/businessInfo}", - "body": "business_info", - }, - ] + http_options = ( + _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo._get_http_options() + ) request, metadata = self._interceptor.pre_update_business_info( request, metadata ) - pb_request = businessinfo.UpdateBusinessInfoRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + BusinessInfoServiceRestTransport._UpdateBusinessInfo._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest_base.py new file mode 100644 index 000000000000..fa99d3ab3827 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/business_info_service/transports/rest_base.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import businessinfo + +from .base import DEFAULT_CLIENT_INFO, BusinessInfoServiceTransport + + +class _BaseBusinessInfoServiceRestTransport(BusinessInfoServiceTransport): + """Base REST backend transport for BusinessInfoService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetBusinessInfo: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/businessInfo}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = businessinfo.GetBusinessInfoRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBusinessInfoServiceRestTransport._BaseGetBusinessInfo._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateBusinessInfo: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{business_info.name=accounts/*/businessInfo}", + "body": "business_info", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = businessinfo.UpdateBusinessInfoRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBusinessInfoServiceRestTransport._BaseUpdateBusinessInfo._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseBusinessInfoServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py index 570799bb8e27..024febb291db 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py @@ -287,7 +287,7 @@ async def get_email_preferences( r"""Returns the email preferences for a Merchant Center account user. - Use the ``name=accounts/*/users/me/emailPreferences`` alias to get + Use the `name=accounts/*/users/me/emailPreferences` alias to get preferences for the authenticated user. .. code-block:: python @@ -411,7 +411,7 @@ async def update_email_preferences( It is invalid for updates to specify an UNCONFIRMED opt-in status value. - Use the ``name=accounts/*/users/me/emailPreferences`` alias to + Use the `name=accounts/*/users/me/emailPreferences` alias to update preferences for the authenticated user. .. code-block:: python diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py index d1a194f82f4b..9d1b566afaee 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py @@ -702,7 +702,7 @@ def get_email_preferences( r"""Returns the email preferences for a Merchant Center account user. - Use the ``name=accounts/*/users/me/emailPreferences`` alias to get + Use the `name=accounts/*/users/me/emailPreferences` alias to get preferences for the authenticated user. .. code-block:: python @@ -823,7 +823,7 @@ def update_email_preferences( It is invalid for updates to specify an UNCONFIRMED opt-in status value. - Use the ``name=accounts/*/users/me/emailPreferences`` alias to + Use the `name=accounts/*/users/me/emailPreferences` alias to update preferences for the authenticated user. .. code-block:: python diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/README.rst new file mode 100644 index 000000000000..210db60dee0d --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`EmailPreferencesServiceTransport` is the ABC for all transports. +- public child `EmailPreferencesServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `EmailPreferencesServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseEmailPreferencesServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `EmailPreferencesServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py index 568ca9dd5a6e..79b98addeaa5 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py @@ -248,7 +248,7 @@ def get_email_preferences( Returns the email preferences for a Merchant Center account user. - Use the name=accounts/*/users/me/emailPreferences alias to get + Use the `name=accounts/*/users/me/emailPreferences` alias to get preferences for the authenticated user. Returns: @@ -288,7 +288,7 @@ def update_email_preferences( It is invalid for updates to specify an UNCONFIRMED opt-in status value. - Use the name=accounts/*/users/me/emailPreferences alias to + Use the `name=accounts/*/users/me/emailPreferences` alias to update preferences for the authenticated user. Returns: diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py index afd5cc75f670..650ebee527de 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -229,6 +230,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -253,7 +257,7 @@ def get_email_preferences( Returns the email preferences for a Merchant Center account user. - Use the name=accounts/*/users/me/emailPreferences alias to get + Use the `name=accounts/*/users/me/emailPreferences` alias to get preferences for the authenticated user. Returns: @@ -293,7 +297,7 @@ def update_email_preferences( It is invalid for updates to specify an UNCONFIRMED opt-in status value. - Use the name=accounts/*/users/me/emailPreferences alias to + Use the `name=accounts/*/users/me/emailPreferences` alias to update preferences for the authenticated user. Returns: @@ -317,20 +321,29 @@ def update_email_preferences( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_email_preferences: gapic_v1.method_async.wrap_method( + self.get_email_preferences: self._wrap_method( self.get_email_preferences, default_timeout=None, client_info=client_info, ), - self.update_email_preferences: gapic_v1.method_async.wrap_method( + self.update_email_preferences: self._wrap_method( self.update_email_preferences, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("EmailPreferencesServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py index fddae29de426..bc42e6fca75f 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import emailpreferences + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseEmailPreferencesServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import emailpreferences - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import EmailPreferencesServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -141,8 +138,8 @@ class EmailPreferencesServiceRestStub: _interceptor: EmailPreferencesServiceRestInterceptor -class EmailPreferencesServiceRestTransport(EmailPreferencesServiceTransport): - """REST backend transport for EmailPreferencesService. +class EmailPreferencesServiceRestTransport(_BaseEmailPreferencesServiceRestTransport): + """REST backend synchronous transport for EmailPreferencesService. Service to support the ``EmailPreferences`` API. @@ -154,7 +151,6 @@ class EmailPreferencesServiceRestTransport(EmailPreferencesServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -208,21 +204,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -233,19 +220,34 @@ def __init__( self._interceptor = interceptor or EmailPreferencesServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetEmailPreferences(EmailPreferencesServiceRestStub): + class _GetEmailPreferences( + _BaseEmailPreferencesServiceRestTransport._BaseGetEmailPreferences, + EmailPreferencesServiceRestStub, + ): def __hash__(self): - return hash("GetEmailPreferences") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("EmailPreferencesServiceRestTransport.GetEmailPreferences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -277,40 +279,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/users/*/emailPreferences}", - }, - ] + http_options = ( + _BaseEmailPreferencesServiceRestTransport._BaseGetEmailPreferences._get_http_options() + ) request, metadata = self._interceptor.pre_get_email_preferences( request, metadata ) - pb_request = emailpreferences.GetEmailPreferencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseEmailPreferencesServiceRestTransport._BaseGetEmailPreferences._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseEmailPreferencesServiceRestTransport._BaseGetEmailPreferences._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + EmailPreferencesServiceRestTransport._GetEmailPreferences._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -326,21 +319,35 @@ def __call__( resp = self._interceptor.post_get_email_preferences(resp) return resp - class _UpdateEmailPreferences(EmailPreferencesServiceRestStub): + class _UpdateEmailPreferences( + _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences, + EmailPreferencesServiceRestStub, + ): def __hash__(self): - return hash("UpdateEmailPreferences") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("EmailPreferencesServiceRestTransport.UpdateEmailPreferences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -372,47 +379,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{email_preferences.name=accounts/*/users/*/emailPreferences}", - "body": "email_preferences", - }, - ] + http_options = ( + _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences._get_http_options() + ) request, metadata = self._interceptor.pre_update_email_preferences( request, metadata ) - pb_request = emailpreferences.UpdateEmailPreferencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = EmailPreferencesServiceRestTransport._UpdateEmailPreferences._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest_base.py new file mode 100644 index 000000000000..bafadd133449 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/rest_base.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import emailpreferences + +from .base import DEFAULT_CLIENT_INFO, EmailPreferencesServiceTransport + + +class _BaseEmailPreferencesServiceRestTransport(EmailPreferencesServiceTransport): + """Base REST backend transport for EmailPreferencesService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetEmailPreferences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/users/*/emailPreferences}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = emailpreferences.GetEmailPreferencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseEmailPreferencesServiceRestTransport._BaseGetEmailPreferences._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateEmailPreferences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{email_preferences.name=accounts/*/users/*/emailPreferences}", + "body": "email_preferences", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = emailpreferences.UpdateEmailPreferencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseEmailPreferencesServiceRestTransport._BaseUpdateEmailPreferences._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseEmailPreferencesServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/README.rst new file mode 100644 index 000000000000..8c0def729b79 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`HomepageServiceTransport` is the ABC for all transports. +- public child `HomepageServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `HomepageServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseHomepageServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `HomepageServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py index bdb5bbe81077..b6a09e6a7af3 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -362,30 +366,39 @@ def unclaim_homepage( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_homepage: gapic_v1.method_async.wrap_method( + self.get_homepage: self._wrap_method( self.get_homepage, default_timeout=None, client_info=client_info, ), - self.update_homepage: gapic_v1.method_async.wrap_method( + self.update_homepage: self._wrap_method( self.update_homepage, default_timeout=None, client_info=client_info, ), - self.claim_homepage: gapic_v1.method_async.wrap_method( + self.claim_homepage: self._wrap_method( self.claim_homepage, default_timeout=None, client_info=client_info, ), - self.unclaim_homepage: gapic_v1.method_async.wrap_method( + self.unclaim_homepage: self._wrap_method( self.unclaim_homepage, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("HomepageServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py index 2aba51fd6733..15a92ae52f30 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest.py @@ -16,32 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import homepage as gsma_homepage +from google.shopping.merchant_accounts_v1beta.types import homepage + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseHomepageServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import homepage as gsma_homepage -from google.shopping.merchant_accounts_v1beta.types import homepage - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import HomepageServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -194,8 +191,8 @@ class HomepageServiceRestStub: _interceptor: HomepageServiceRestInterceptor -class HomepageServiceRestTransport(HomepageServiceTransport): - """REST backend transport for HomepageService. +class HomepageServiceRestTransport(_BaseHomepageServiceRestTransport): + """REST backend synchronous transport for HomepageService. Service to support an API for a store's homepage. @@ -204,7 +201,6 @@ class HomepageServiceRestTransport(HomepageServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -258,21 +254,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -283,19 +270,34 @@ def __init__( self._interceptor = interceptor or HomepageServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _ClaimHomepage(HomepageServiceRestStub): + class _ClaimHomepage( + _BaseHomepageServiceRestTransport._BaseClaimHomepage, HomepageServiceRestStub + ): def __hash__(self): - return hash("ClaimHomepage") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("HomepageServiceRestTransport.ClaimHomepage") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -321,45 +323,32 @@ def __call__( A store's homepage. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{name=accounts/*/homepage}:claim", - "body": "*", - }, - ] + http_options = ( + _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_http_options() + ) request, metadata = self._interceptor.pre_claim_homepage(request, metadata) - pb_request = homepage.ClaimHomepageRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = HomepageServiceRestTransport._ClaimHomepage._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -375,19 +364,33 @@ def __call__( resp = self._interceptor.post_claim_homepage(resp) return resp - class _GetHomepage(HomepageServiceRestStub): + class _GetHomepage( + _BaseHomepageServiceRestTransport._BaseGetHomepage, HomepageServiceRestStub + ): def __hash__(self): - return hash("GetHomepage") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("HomepageServiceRestTransport.GetHomepage") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -413,38 +416,27 @@ def __call__( A store's homepage. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/homepage}", - }, - ] + http_options = ( + _BaseHomepageServiceRestTransport._BaseGetHomepage._get_http_options() + ) request, metadata = self._interceptor.pre_get_homepage(request, metadata) - pb_request = homepage.GetHomepageRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseHomepageServiceRestTransport._BaseGetHomepage._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseHomepageServiceRestTransport._BaseGetHomepage._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = HomepageServiceRestTransport._GetHomepage._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -460,19 +452,34 @@ def __call__( resp = self._interceptor.post_get_homepage(resp) return resp - class _UnclaimHomepage(HomepageServiceRestStub): + class _UnclaimHomepage( + _BaseHomepageServiceRestTransport._BaseUnclaimHomepage, HomepageServiceRestStub + ): def __hash__(self): - return hash("UnclaimHomepage") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("HomepageServiceRestTransport.UnclaimHomepage") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -498,47 +505,34 @@ def __call__( A store's homepage. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{name=accounts/*/homepage}:unclaim", - "body": "*", - }, - ] + http_options = ( + _BaseHomepageServiceRestTransport._BaseUnclaimHomepage._get_http_options() + ) request, metadata = self._interceptor.pre_unclaim_homepage( request, metadata ) - pb_request = homepage.UnclaimHomepageRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseHomepageServiceRestTransport._BaseUnclaimHomepage._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseHomepageServiceRestTransport._BaseUnclaimHomepage._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseHomepageServiceRestTransport._BaseUnclaimHomepage._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = HomepageServiceRestTransport._UnclaimHomepage._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -554,21 +548,34 @@ def __call__( resp = self._interceptor.post_unclaim_homepage(resp) return resp - class _UpdateHomepage(HomepageServiceRestStub): + class _UpdateHomepage( + _BaseHomepageServiceRestTransport._BaseUpdateHomepage, HomepageServiceRestStub + ): def __hash__(self): - return hash("UpdateHomepage") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("HomepageServiceRestTransport.UpdateHomepage") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -594,45 +601,32 @@ def __call__( A store's homepage. """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{homepage.name=accounts/*/homepage}", - "body": "homepage", - }, - ] + http_options = ( + _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_http_options() + ) request, metadata = self._interceptor.pre_update_homepage(request, metadata) - pb_request = gsma_homepage.UpdateHomepageRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = HomepageServiceRestTransport._UpdateHomepage._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest_base.py new file mode 100644 index 000000000000..7473e2094323 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/homepage_service/transports/rest_base.py @@ -0,0 +1,312 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import homepage as gsma_homepage +from google.shopping.merchant_accounts_v1beta.types import homepage + +from .base import DEFAULT_CLIENT_INFO, HomepageServiceTransport + + +class _BaseHomepageServiceRestTransport(HomepageServiceTransport): + """Base REST backend transport for HomepageService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseClaimHomepage: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{name=accounts/*/homepage}:claim", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = homepage.ClaimHomepageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHomepageServiceRestTransport._BaseClaimHomepage._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetHomepage: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/homepage}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = homepage.GetHomepageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHomepageServiceRestTransport._BaseGetHomepage._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUnclaimHomepage: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{name=accounts/*/homepage}:unclaim", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = homepage.UnclaimHomepageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHomepageServiceRestTransport._BaseUnclaimHomepage._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateHomepage: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{homepage.name=accounts/*/homepage}", + "body": "homepage", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gsma_homepage.UpdateHomepageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseHomepageServiceRestTransport._BaseUpdateHomepage._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseHomepageServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py index edfee0c82f58..8806d4a0a30f 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py @@ -55,10 +55,10 @@ class OnlineReturnPolicyServiceAsyncClient: """The service facilitates the management of a merchant's remorse return policy configuration, encompassing return policies for both - ads and free listings programs. This API defines the following resource model: - ----------------------------------------------------------------------------- + ads and free listings - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] + programs. This API defines the following resource model: + - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] """ _client: OnlineReturnPolicyServiceClient diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py index 690860b09d70..d27af3eaa3f6 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py @@ -99,10 +99,10 @@ def get_transport_class( class OnlineReturnPolicyServiceClient(metaclass=OnlineReturnPolicyServiceClientMeta): """The service facilitates the management of a merchant's remorse return policy configuration, encompassing return policies for both - ads and free listings programs. This API defines the following resource model: - ----------------------------------------------------------------------------- + ads and free listings - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] + programs. This API defines the following resource model: + - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] """ @staticmethod diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/README.rst new file mode 100644 index 000000000000..a6e34721a621 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`OnlineReturnPolicyServiceTransport` is the ABC for all transports. +- public child `OnlineReturnPolicyServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `OnlineReturnPolicyServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseOnlineReturnPolicyServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `OnlineReturnPolicyServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py index dea6fb91c35a..a8d881201cc9 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py @@ -35,9 +35,7 @@ class OnlineReturnPolicyServiceGrpcTransport(OnlineReturnPolicyServiceTransport) ads and free listings programs. This API defines the following resource model: - -------------------------------------------------------- - - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] + - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py index 043a6612628a..1b0f450584ee 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -38,9 +39,7 @@ class OnlineReturnPolicyServiceGrpcAsyncIOTransport(OnlineReturnPolicyServiceTra ads and free listings programs. This API defines the following resource model: - -------------------------------------------------------- - - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] + - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] This class defines the same methods as the primary client, so the primary client can load the underlying transport implementation @@ -233,6 +232,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -306,20 +308,29 @@ def list_online_return_policies( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_online_return_policy: gapic_v1.method_async.wrap_method( + self.get_online_return_policy: self._wrap_method( self.get_online_return_policy, default_timeout=None, client_info=client_info, ), - self.list_online_return_policies: gapic_v1.method_async.wrap_method( + self.list_online_return_policies: self._wrap_method( self.list_online_return_policies, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("OnlineReturnPolicyServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py index 662b5c93e797..e65c3b752bd3 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import online_return_policy + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseOnlineReturnPolicyServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import online_return_policy - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import OnlineReturnPolicyServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -143,8 +140,10 @@ class OnlineReturnPolicyServiceRestStub: _interceptor: OnlineReturnPolicyServiceRestInterceptor -class OnlineReturnPolicyServiceRestTransport(OnlineReturnPolicyServiceTransport): - """REST backend transport for OnlineReturnPolicyService. +class OnlineReturnPolicyServiceRestTransport( + _BaseOnlineReturnPolicyServiceRestTransport +): + """REST backend synchronous transport for OnlineReturnPolicyService. The service facilitates the management of a merchant's remorse return policy configuration, encompassing return policies for both @@ -160,7 +159,6 @@ class OnlineReturnPolicyServiceRestTransport(OnlineReturnPolicyServiceTransport) and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -214,21 +212,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -239,19 +228,34 @@ def __init__( self._interceptor = interceptor or OnlineReturnPolicyServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetOnlineReturnPolicy(OnlineReturnPolicyServiceRestStub): + class _GetOnlineReturnPolicy( + _BaseOnlineReturnPolicyServiceRestTransport._BaseGetOnlineReturnPolicy, + OnlineReturnPolicyServiceRestStub, + ): def __hash__(self): - return hash("GetOnlineReturnPolicy") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("OnlineReturnPolicyServiceRestTransport.GetOnlineReturnPolicy") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -282,40 +286,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/onlineReturnPolicies/*}", - }, - ] + http_options = ( + _BaseOnlineReturnPolicyServiceRestTransport._BaseGetOnlineReturnPolicy._get_http_options() + ) request, metadata = self._interceptor.pre_get_online_return_policy( request, metadata ) - pb_request = online_return_policy.GetOnlineReturnPolicyRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseOnlineReturnPolicyServiceRestTransport._BaseGetOnlineReturnPolicy._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseOnlineReturnPolicyServiceRestTransport._BaseGetOnlineReturnPolicy._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = OnlineReturnPolicyServiceRestTransport._GetOnlineReturnPolicy._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -331,19 +324,36 @@ def __call__( resp = self._interceptor.post_get_online_return_policy(resp) return resp - class _ListOnlineReturnPolicies(OnlineReturnPolicyServiceRestStub): + class _ListOnlineReturnPolicies( + _BaseOnlineReturnPolicyServiceRestTransport._BaseListOnlineReturnPolicies, + OnlineReturnPolicyServiceRestStub, + ): def __hash__(self): - return hash("ListOnlineReturnPolicies") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "OnlineReturnPolicyServiceRestTransport.ListOnlineReturnPolicies" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -373,42 +383,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/onlineReturnPolicies", - }, - ] + http_options = ( + _BaseOnlineReturnPolicyServiceRestTransport._BaseListOnlineReturnPolicies._get_http_options() + ) request, metadata = self._interceptor.pre_list_online_return_policies( request, metadata ) - pb_request = online_return_policy.ListOnlineReturnPoliciesRequest.pb( - request + transcoded_request = _BaseOnlineReturnPolicyServiceRestTransport._BaseListOnlineReturnPolicies._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseOnlineReturnPolicyServiceRestTransport._BaseListOnlineReturnPolicies._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = OnlineReturnPolicyServiceRestTransport._ListOnlineReturnPolicies._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest_base.py new file mode 100644 index 000000000000..850bc42f1d11 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/rest_base.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import online_return_policy + +from .base import DEFAULT_CLIENT_INFO, OnlineReturnPolicyServiceTransport + + +class _BaseOnlineReturnPolicyServiceRestTransport(OnlineReturnPolicyServiceTransport): + """Base REST backend transport for OnlineReturnPolicyService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetOnlineReturnPolicy: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/onlineReturnPolicies/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = online_return_policy.GetOnlineReturnPolicyRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOnlineReturnPolicyServiceRestTransport._BaseGetOnlineReturnPolicy._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListOnlineReturnPolicies: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/onlineReturnPolicies", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = online_return_policy.ListOnlineReturnPoliciesRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseOnlineReturnPolicyServiceRestTransport._BaseListOnlineReturnPolicies._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseOnlineReturnPolicyServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/README.rst new file mode 100644 index 000000000000..b36d6af5aeda --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ProgramsServiceTransport` is the ABC for all transports. +- public child `ProgramsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ProgramsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseProgramsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ProgramsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py index b76fa8eed9ec..aac76bd3629b 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -236,6 +237,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -360,30 +364,39 @@ def disable_program( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_program: gapic_v1.method_async.wrap_method( + self.get_program: self._wrap_method( self.get_program, default_timeout=None, client_info=client_info, ), - self.list_programs: gapic_v1.method_async.wrap_method( + self.list_programs: self._wrap_method( self.list_programs, default_timeout=None, client_info=client_info, ), - self.enable_program: gapic_v1.method_async.wrap_method( + self.enable_program: self._wrap_method( self.enable_program, default_timeout=None, client_info=client_info, ), - self.disable_program: gapic_v1.method_async.wrap_method( + self.disable_program: self._wrap_method( self.disable_program, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("ProgramsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py index 717744840799..332e16772f4a 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import programs + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseProgramsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import programs - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import ProgramsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -191,8 +188,8 @@ class ProgramsServiceRestStub: _interceptor: ProgramsServiceRestInterceptor -class ProgramsServiceRestTransport(ProgramsServiceTransport): - """REST backend transport for ProgramsService. +class ProgramsServiceRestTransport(_BaseProgramsServiceRestTransport): + """REST backend synchronous transport for ProgramsService. Service for program management. @@ -211,7 +208,6 @@ class ProgramsServiceRestTransport(ProgramsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -265,21 +261,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -290,19 +277,34 @@ def __init__( self._interceptor = interceptor or ProgramsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _DisableProgram(ProgramsServiceRestStub): + class _DisableProgram( + _BaseProgramsServiceRestTransport._BaseDisableProgram, ProgramsServiceRestStub + ): def __hash__(self): - return hash("DisableProgram") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProgramsServiceRestTransport.DisableProgram") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -338,45 +340,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{name=accounts/*/programs/*}:disable", - "body": "*", - }, - ] + http_options = ( + _BaseProgramsServiceRestTransport._BaseDisableProgram._get_http_options() + ) request, metadata = self._interceptor.pre_disable_program(request, metadata) - pb_request = programs.DisableProgramRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseProgramsServiceRestTransport._BaseDisableProgram._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseProgramsServiceRestTransport._BaseDisableProgram._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProgramsServiceRestTransport._BaseDisableProgram._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ProgramsServiceRestTransport._DisableProgram._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -392,19 +381,34 @@ def __call__( resp = self._interceptor.post_disable_program(resp) return resp - class _EnableProgram(ProgramsServiceRestStub): + class _EnableProgram( + _BaseProgramsServiceRestTransport._BaseEnableProgram, ProgramsServiceRestStub + ): def __hash__(self): - return hash("EnableProgram") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProgramsServiceRestTransport.EnableProgram") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -440,45 +444,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{name=accounts/*/programs/*}:enable", - "body": "*", - }, - ] + http_options = ( + _BaseProgramsServiceRestTransport._BaseEnableProgram._get_http_options() + ) request, metadata = self._interceptor.pre_enable_program(request, metadata) - pb_request = programs.EnableProgramRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseProgramsServiceRestTransport._BaseEnableProgram._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseProgramsServiceRestTransport._BaseEnableProgram._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProgramsServiceRestTransport._BaseEnableProgram._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ProgramsServiceRestTransport._EnableProgram._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -494,19 +485,33 @@ def __call__( resp = self._interceptor.post_enable_program(resp) return resp - class _GetProgram(ProgramsServiceRestStub): + class _GetProgram( + _BaseProgramsServiceRestTransport._BaseGetProgram, ProgramsServiceRestStub + ): def __hash__(self): - return hash("GetProgram") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProgramsServiceRestTransport.GetProgram") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -542,38 +547,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/programs/*}", - }, - ] + http_options = ( + _BaseProgramsServiceRestTransport._BaseGetProgram._get_http_options() + ) request, metadata = self._interceptor.pre_get_program(request, metadata) - pb_request = programs.GetProgramRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseProgramsServiceRestTransport._BaseGetProgram._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProgramsServiceRestTransport._BaseGetProgram._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ProgramsServiceRestTransport._GetProgram._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -589,19 +583,33 @@ def __call__( resp = self._interceptor.post_get_program(resp) return resp - class _ListPrograms(ProgramsServiceRestStub): + class _ListPrograms( + _BaseProgramsServiceRestTransport._BaseListPrograms, ProgramsServiceRestStub + ): def __hash__(self): - return hash("ListPrograms") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProgramsServiceRestTransport.ListPrograms") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -630,38 +638,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/programs", - }, - ] + http_options = ( + _BaseProgramsServiceRestTransport._BaseListPrograms._get_http_options() + ) request, metadata = self._interceptor.pre_list_programs(request, metadata) - pb_request = programs.ListProgramsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseProgramsServiceRestTransport._BaseListPrograms._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProgramsServiceRestTransport._BaseListPrograms._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ProgramsServiceRestTransport._ListPrograms._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest_base.py new file mode 100644 index 000000000000..41b5f767b600 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/programs_service/transports/rest_base.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import programs + +from .base import DEFAULT_CLIENT_INFO, ProgramsServiceTransport + + +class _BaseProgramsServiceRestTransport(ProgramsServiceTransport): + """Base REST backend transport for ProgramsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseDisableProgram: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{name=accounts/*/programs/*}:disable", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = programs.DisableProgramRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProgramsServiceRestTransport._BaseDisableProgram._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseEnableProgram: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{name=accounts/*/programs/*}:enable", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = programs.EnableProgramRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProgramsServiceRestTransport._BaseEnableProgram._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetProgram: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/programs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = programs.GetProgramRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProgramsServiceRestTransport._BaseGetProgram._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListPrograms: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/programs", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = programs.ListProgramsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProgramsServiceRestTransport._BaseListPrograms._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseProgramsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/README.rst new file mode 100644 index 000000000000..58b1a6574ad7 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`RegionsServiceTransport` is the ABC for all transports. +- public child `RegionsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `RegionsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseRegionsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `RegionsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py index bfde4abba488..630ee6332d7e 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -231,6 +232,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -380,35 +384,44 @@ def list_regions( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_region: gapic_v1.method_async.wrap_method( + self.get_region: self._wrap_method( self.get_region, default_timeout=None, client_info=client_info, ), - self.create_region: gapic_v1.method_async.wrap_method( + self.create_region: self._wrap_method( self.create_region, default_timeout=None, client_info=client_info, ), - self.update_region: gapic_v1.method_async.wrap_method( + self.update_region: self._wrap_method( self.update_region, default_timeout=None, client_info=client_info, ), - self.delete_region: gapic_v1.method_async.wrap_method( + self.delete_region: self._wrap_method( self.delete_region, default_timeout=None, client_info=client_info, ), - self.list_regions: gapic_v1.method_async.wrap_method( + self.list_regions: self._wrap_method( self.list_regions, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("RegionsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py index 4302f83d671a..6dcd70521c82 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import regions + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseRegionsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_accounts_v1beta.types import regions - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import RegionsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -203,8 +199,8 @@ class RegionsServiceRestStub: _interceptor: RegionsServiceRestInterceptor -class RegionsServiceRestTransport(RegionsServiceTransport): - """REST backend transport for RegionsService. +class RegionsServiceRestTransport(_BaseRegionsServiceRestTransport): + """REST backend synchronous transport for RegionsService. Manages regions configuration. @@ -217,7 +213,6 @@ class RegionsServiceRestTransport(RegionsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -271,21 +266,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -296,21 +282,34 @@ def __init__( self._interceptor = interceptor or RegionsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateRegion(RegionsServiceRestStub): + class _CreateRegion( + _BaseRegionsServiceRestTransport._BaseCreateRegion, RegionsServiceRestStub + ): def __hash__(self): - return hash("CreateRegion") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "regionId": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionsServiceRestTransport.CreateRegion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -344,45 +343,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{parent=accounts/*}/regions", - "body": "region", - }, - ] + http_options = ( + _BaseRegionsServiceRestTransport._BaseCreateRegion._get_http_options() + ) request, metadata = self._interceptor.pre_create_region(request, metadata) - pb_request = regions.CreateRegionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseRegionsServiceRestTransport._BaseCreateRegion._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseRegionsServiceRestTransport._BaseCreateRegion._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionsServiceRestTransport._BaseCreateRegion._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RegionsServiceRestTransport._CreateRegion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -398,19 +384,33 @@ def __call__( resp = self._interceptor.post_create_region(resp) return resp - class _DeleteRegion(RegionsServiceRestStub): + class _DeleteRegion( + _BaseRegionsServiceRestTransport._BaseDeleteRegion, RegionsServiceRestStub + ): def __hash__(self): - return hash("DeleteRegion") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionsServiceRestTransport.DeleteRegion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -432,38 +432,27 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/accounts/v1beta/{name=accounts/*/regions/*}", - }, - ] + http_options = ( + _BaseRegionsServiceRestTransport._BaseDeleteRegion._get_http_options() + ) request, metadata = self._interceptor.pre_delete_region(request, metadata) - pb_request = regions.DeleteRegionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseRegionsServiceRestTransport._BaseDeleteRegion._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionsServiceRestTransport._BaseDeleteRegion._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = RegionsServiceRestTransport._DeleteRegion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -471,19 +460,33 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetRegion(RegionsServiceRestStub): + class _GetRegion( + _BaseRegionsServiceRestTransport._BaseGetRegion, RegionsServiceRestStub + ): def __hash__(self): - return hash("GetRegion") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionsServiceRestTransport.GetRegion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -517,38 +520,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/regions/*}", - }, - ] + http_options = ( + _BaseRegionsServiceRestTransport._BaseGetRegion._get_http_options() + ) request, metadata = self._interceptor.pre_get_region(request, metadata) - pb_request = regions.GetRegionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseRegionsServiceRestTransport._BaseGetRegion._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseRegionsServiceRestTransport._BaseGetRegion._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = RegionsServiceRestTransport._GetRegion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -564,19 +560,33 @@ def __call__( resp = self._interceptor.post_get_region(resp) return resp - class _ListRegions(RegionsServiceRestStub): + class _ListRegions( + _BaseRegionsServiceRestTransport._BaseListRegions, RegionsServiceRestStub + ): def __hash__(self): - return hash("ListRegions") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionsServiceRestTransport.ListRegions") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -602,38 +612,27 @@ def __call__( Response message for the ``ListRegions`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/regions", - }, - ] + http_options = ( + _BaseRegionsServiceRestTransport._BaseListRegions._get_http_options() + ) request, metadata = self._interceptor.pre_list_regions(request, metadata) - pb_request = regions.ListRegionsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseRegionsServiceRestTransport._BaseListRegions._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionsServiceRestTransport._BaseListRegions._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = RegionsServiceRestTransport._ListRegions._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -649,19 +648,34 @@ def __call__( resp = self._interceptor.post_list_regions(resp) return resp - class _UpdateRegion(RegionsServiceRestStub): + class _UpdateRegion( + _BaseRegionsServiceRestTransport._BaseUpdateRegion, RegionsServiceRestStub + ): def __hash__(self): - return hash("UpdateRegion") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionsServiceRestTransport.UpdateRegion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -695,45 +709,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{region.name=accounts/*/regions/*}", - "body": "region", - }, - ] + http_options = ( + _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_http_options() + ) request, metadata = self._interceptor.pre_update_region(request, metadata) - pb_request = regions.UpdateRegionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RegionsServiceRestTransport._UpdateRegion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest_base.py new file mode 100644 index 000000000000..6e13a3b1c7a7 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/regions_service/transports/rest_base.py @@ -0,0 +1,349 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import regions + +from .base import DEFAULT_CLIENT_INFO, RegionsServiceTransport + + +class _BaseRegionsServiceRestTransport(RegionsServiceTransport): + """Base REST backend transport for RegionsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateRegion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "regionId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{parent=accounts/*}/regions", + "body": "region", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regions.CreateRegionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionsServiceRestTransport._BaseCreateRegion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteRegion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/accounts/v1beta/{name=accounts/*/regions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regions.DeleteRegionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionsServiceRestTransport._BaseDeleteRegion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetRegion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/regions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regions.GetRegionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionsServiceRestTransport._BaseGetRegion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListRegions: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/regions", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regions.ListRegionsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionsServiceRestTransport._BaseListRegions._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateRegion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{region.name=accounts/*/regions/*}", + "body": "region", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regions.UpdateRegionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionsServiceRestTransport._BaseUpdateRegion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseRegionsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/README.rst new file mode 100644 index 000000000000..a638b7b9035f --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ShippingSettingsServiceTransport` is the ABC for all transports. +- public child `ShippingSettingsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ShippingSettingsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseShippingSettingsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ShippingSettingsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py index 285226d5a973..4afad31922bf 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -302,20 +306,29 @@ def insert_shipping_settings( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_shipping_settings: gapic_v1.method_async.wrap_method( + self.get_shipping_settings: self._wrap_method( self.get_shipping_settings, default_timeout=None, client_info=client_info, ), - self.insert_shipping_settings: gapic_v1.method_async.wrap_method( + self.insert_shipping_settings: self._wrap_method( self.insert_shipping_settings, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("ShippingSettingsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py index 7e2a8e043d3a..cf453743199c 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import shippingsettings + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseShippingSettingsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import shippingsettings - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import ShippingSettingsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -141,8 +138,8 @@ class ShippingSettingsServiceRestStub: _interceptor: ShippingSettingsServiceRestInterceptor -class ShippingSettingsServiceRestTransport(ShippingSettingsServiceTransport): - """REST backend transport for ShippingSettingsService. +class ShippingSettingsServiceRestTransport(_BaseShippingSettingsServiceRestTransport): + """REST backend synchronous transport for ShippingSettingsService. Service to get method call shipping setting information per Merchant API method. @@ -152,7 +149,6 @@ class ShippingSettingsServiceRestTransport(ShippingSettingsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -206,21 +202,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -231,19 +218,34 @@ def __init__( self._interceptor = interceptor or ShippingSettingsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetShippingSettings(ShippingSettingsServiceRestStub): + class _GetShippingSettings( + _BaseShippingSettingsServiceRestTransport._BaseGetShippingSettings, + ShippingSettingsServiceRestStub, + ): def __hash__(self): - return hash("GetShippingSettings") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ShippingSettingsServiceRestTransport.GetShippingSettings") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -271,40 +273,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/shippingSettings}", - }, - ] + http_options = ( + _BaseShippingSettingsServiceRestTransport._BaseGetShippingSettings._get_http_options() + ) request, metadata = self._interceptor.pre_get_shipping_settings( request, metadata ) - pb_request = shippingsettings.GetShippingSettingsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseShippingSettingsServiceRestTransport._BaseGetShippingSettings._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseShippingSettingsServiceRestTransport._BaseGetShippingSettings._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + ShippingSettingsServiceRestTransport._GetShippingSettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -320,19 +313,35 @@ def __call__( resp = self._interceptor.post_get_shipping_settings(resp) return resp - class _InsertShippingSettings(ShippingSettingsServiceRestStub): + class _InsertShippingSettings( + _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings, + ShippingSettingsServiceRestStub, + ): def __hash__(self): - return hash("InsertShippingSettings") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ShippingSettingsServiceRestTransport.InsertShippingSettings") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -361,47 +370,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{parent=accounts/*}/shippingSettings:insert", - "body": "shipping_setting", - }, - ] + http_options = ( + _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings._get_http_options() + ) request, metadata = self._interceptor.pre_insert_shipping_settings( request, metadata ) - pb_request = shippingsettings.InsertShippingSettingsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ShippingSettingsServiceRestTransport._InsertShippingSettings._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest_base.py new file mode 100644 index 000000000000..e72fd347f681 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/shipping_settings_service/transports/rest_base.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import shippingsettings + +from .base import DEFAULT_CLIENT_INFO, ShippingSettingsServiceTransport + + +class _BaseShippingSettingsServiceRestTransport(ShippingSettingsServiceTransport): + """Base REST backend transport for ShippingSettingsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetShippingSettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/shippingSettings}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = shippingsettings.GetShippingSettingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseShippingSettingsServiceRestTransport._BaseGetShippingSettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertShippingSettings: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{parent=accounts/*}/shippingSettings:insert", + "body": "shipping_setting", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = shippingsettings.InsertShippingSettingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseShippingSettingsServiceRestTransport._BaseInsertShippingSettings._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseShippingSettingsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/README.rst new file mode 100644 index 000000000000..344858fa2eb5 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`TermsOfServiceAgreementStateServiceTransport` is the ABC for all transports. +- public child `TermsOfServiceAgreementStateServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseTermsOfServiceAgreementStateServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `TermsOfServiceAgreementStateServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py index 533ef94924a5..7ed678041e1d 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -313,20 +317,29 @@ def retrieve_for_application_terms_of_service_agreement_state( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_terms_of_service_agreement_state: gapic_v1.method_async.wrap_method( + self.get_terms_of_service_agreement_state: self._wrap_method( self.get_terms_of_service_agreement_state, default_timeout=None, client_info=client_info, ), - self.retrieve_for_application_terms_of_service_agreement_state: gapic_v1.method_async.wrap_method( + self.retrieve_for_application_terms_of_service_agreement_state: self._wrap_method( self.retrieve_for_application_terms_of_service_agreement_state, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py index 9249faa9888d..c4d78bf43048 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import termsofserviceagreementstate + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseTermsOfServiceAgreementStateServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_accounts_v1beta.types import termsofserviceagreementstate - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import TermsOfServiceAgreementStateServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -146,9 +143,9 @@ class TermsOfServiceAgreementStateServiceRestStub: class TermsOfServiceAgreementStateServiceRestTransport( - TermsOfServiceAgreementStateServiceTransport + _BaseTermsOfServiceAgreementStateServiceRestTransport ): - """REST backend transport for TermsOfServiceAgreementStateService. + """REST backend synchronous transport for TermsOfServiceAgreementStateService. Service to support ``TermsOfServiceAgreementState`` API. @@ -157,7 +154,6 @@ class TermsOfServiceAgreementStateServiceRestTransport( and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -213,21 +209,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -240,19 +227,36 @@ def __init__( ) self._prep_wrapped_messages(client_info) - class _GetTermsOfServiceAgreementState(TermsOfServiceAgreementStateServiceRestStub): + class _GetTermsOfServiceAgreementState( + _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseGetTermsOfServiceAgreementState, + TermsOfServiceAgreementStateServiceRestStub, + ): def __hash__(self): - return hash("GetTermsOfServiceAgreementState") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "TermsOfServiceAgreementStateServiceRestTransport.GetTermsOfServiceAgreementState" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -308,47 +312,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/termsOfServiceAgreementStates/*}", - }, - ] + http_options = ( + _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseGetTermsOfServiceAgreementState._get_http_options() + ) ( request, metadata, ) = self._interceptor.pre_get_terms_of_service_agreement_state( request, metadata ) - pb_request = ( - termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest.pb( - request - ) + transcoded_request = _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseGetTermsOfServiceAgreementState._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseGetTermsOfServiceAgreementState._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = TermsOfServiceAgreementStateServiceRestTransport._GetTermsOfServiceAgreementState._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -365,20 +354,35 @@ def __call__( return resp class _RetrieveForApplicationTermsOfServiceAgreementState( - TermsOfServiceAgreementStateServiceRestStub + _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseRetrieveForApplicationTermsOfServiceAgreementState, + TermsOfServiceAgreementStateServiceRestStub, ): def __hash__(self): - return hash("RetrieveForApplicationTermsOfServiceAgreementState") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "TermsOfServiceAgreementStateServiceRestTransport.RetrieveForApplicationTermsOfServiceAgreementState" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -435,45 +439,32 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/termsOfServiceAgreementStates:retrieveForApplication", - }, - ] + http_options = ( + _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseRetrieveForApplicationTermsOfServiceAgreementState._get_http_options() + ) ( request, metadata, ) = self._interceptor.pre_retrieve_for_application_terms_of_service_agreement_state( request, metadata ) - pb_request = termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest.pb( - request + transcoded_request = _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseRetrieveForApplicationTermsOfServiceAgreementState._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseRetrieveForApplicationTermsOfServiceAgreementState._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = TermsOfServiceAgreementStateServiceRestTransport._RetrieveForApplicationTermsOfServiceAgreementState._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest_base.py new file mode 100644 index 000000000000..8f46468bf521 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_agreement_state_service/transports/rest_base.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import termsofserviceagreementstate + +from .base import DEFAULT_CLIENT_INFO, TermsOfServiceAgreementStateServiceTransport + + +class _BaseTermsOfServiceAgreementStateServiceRestTransport( + TermsOfServiceAgreementStateServiceTransport +): + """Base REST backend transport for TermsOfServiceAgreementStateService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetTermsOfServiceAgreementState: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/termsOfServiceAgreementStates/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseGetTermsOfServiceAgreementState._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseRetrieveForApplicationTermsOfServiceAgreementState: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/termsOfServiceAgreementStates:retrieveForApplication", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTermsOfServiceAgreementStateServiceRestTransport._BaseRetrieveForApplicationTermsOfServiceAgreementState._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseTermsOfServiceAgreementStateServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/README.rst new file mode 100644 index 000000000000..3a13382bc0d2 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`TermsOfServiceServiceTransport` is the ABC for all transports. +- public child `TermsOfServiceServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `TermsOfServiceServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseTermsOfServiceServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `TermsOfServiceServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py index 34c4780b97b2..ac78365de479 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -334,25 +338,34 @@ def accept_terms_of_service( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_terms_of_service: gapic_v1.method_async.wrap_method( + self.get_terms_of_service: self._wrap_method( self.get_terms_of_service, default_timeout=None, client_info=client_info, ), - self.retrieve_latest_terms_of_service: gapic_v1.method_async.wrap_method( + self.retrieve_latest_terms_of_service: self._wrap_method( self.retrieve_latest_terms_of_service, default_timeout=None, client_info=client_info, ), - self.accept_terms_of_service: gapic_v1.method_async.wrap_method( + self.accept_terms_of_service: self._wrap_method( self.accept_terms_of_service, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("TermsOfServiceServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py index d6840f71ab24..8bff19e0c3b8 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import termsofservice + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseTermsOfServiceServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_accounts_v1beta.types import termsofservice - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import TermsOfServiceServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -159,8 +155,8 @@ class TermsOfServiceServiceRestStub: _interceptor: TermsOfServiceServiceRestInterceptor -class TermsOfServiceServiceRestTransport(TermsOfServiceServiceTransport): - """REST backend transport for TermsOfServiceService. +class TermsOfServiceServiceRestTransport(_BaseTermsOfServiceServiceRestTransport): + """REST backend synchronous transport for TermsOfServiceService. Service to support ``TermsOfService`` API. @@ -169,7 +165,6 @@ class TermsOfServiceServiceRestTransport(TermsOfServiceServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -223,21 +218,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -248,22 +234,34 @@ def __init__( self._interceptor = interceptor or TermsOfServiceServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _AcceptTermsOfService(TermsOfServiceServiceRestStub): + class _AcceptTermsOfService( + _BaseTermsOfServiceServiceRestTransport._BaseAcceptTermsOfService, + TermsOfServiceServiceRestStub, + ): def __hash__(self): - return hash("AcceptTermsOfService") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "account": "", - "regionCode": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("TermsOfServiceServiceRestTransport.AcceptTermsOfService") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -285,40 +283,31 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=termsOfService/*}:accept", - }, - ] + http_options = ( + _BaseTermsOfServiceServiceRestTransport._BaseAcceptTermsOfService._get_http_options() + ) request, metadata = self._interceptor.pre_accept_terms_of_service( request, metadata ) - pb_request = termsofservice.AcceptTermsOfServiceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseTermsOfServiceServiceRestTransport._BaseAcceptTermsOfService._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseTermsOfServiceServiceRestTransport._BaseAcceptTermsOfService._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + TermsOfServiceServiceRestTransport._AcceptTermsOfService._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -326,19 +315,34 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetTermsOfService(TermsOfServiceServiceRestStub): + class _GetTermsOfService( + _BaseTermsOfServiceServiceRestTransport._BaseGetTermsOfService, + TermsOfServiceServiceRestStub, + ): def __hash__(self): - return hash("GetTermsOfService") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("TermsOfServiceServiceRestTransport.GetTermsOfService") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -364,40 +368,31 @@ def __call__( A ``TermsOfService``. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=termsOfService/*}", - }, - ] + http_options = ( + _BaseTermsOfServiceServiceRestTransport._BaseGetTermsOfService._get_http_options() + ) request, metadata = self._interceptor.pre_get_terms_of_service( request, metadata ) - pb_request = termsofservice.GetTermsOfServiceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseTermsOfServiceServiceRestTransport._BaseGetTermsOfService._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseTermsOfServiceServiceRestTransport._BaseGetTermsOfService._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + TermsOfServiceServiceRestTransport._GetTermsOfService._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -413,22 +408,36 @@ def __call__( resp = self._interceptor.post_get_terms_of_service(resp) return resp - class _RetrieveLatestTermsOfService(TermsOfServiceServiceRestStub): + class _RetrieveLatestTermsOfService( + _BaseTermsOfServiceServiceRestTransport._BaseRetrieveLatestTermsOfService, + TermsOfServiceServiceRestStub, + ): def __hash__(self): - return hash("RetrieveLatestTermsOfService") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "regionCode": "", - "kind": {}, - } + return hash( + "TermsOfServiceServiceRestTransport.RetrieveLatestTermsOfService" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -456,40 +465,29 @@ def __call__( A ``TermsOfService``. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/termsOfService:retrieveLatest", - }, - ] + http_options = ( + _BaseTermsOfServiceServiceRestTransport._BaseRetrieveLatestTermsOfService._get_http_options() + ) request, metadata = self._interceptor.pre_retrieve_latest_terms_of_service( request, metadata ) - pb_request = termsofservice.RetrieveLatestTermsOfServiceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseTermsOfServiceServiceRestTransport._BaseRetrieveLatestTermsOfService._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseTermsOfServiceServiceRestTransport._BaseRetrieveLatestTermsOfService._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = TermsOfServiceServiceRestTransport._RetrieveLatestTermsOfService._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest_base.py new file mode 100644 index 000000000000..97a149e30c88 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/terms_of_service_service/transports/rest_base.py @@ -0,0 +1,239 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import termsofservice + +from .base import DEFAULT_CLIENT_INFO, TermsOfServiceServiceTransport + + +class _BaseTermsOfServiceServiceRestTransport(TermsOfServiceServiceTransport): + """Base REST backend transport for TermsOfServiceService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseAcceptTermsOfService: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "account": "", + "regionCode": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=termsOfService/*}:accept", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = termsofservice.AcceptTermsOfServiceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTermsOfServiceServiceRestTransport._BaseAcceptTermsOfService._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetTermsOfService: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=termsOfService/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = termsofservice.GetTermsOfServiceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTermsOfServiceServiceRestTransport._BaseGetTermsOfService._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseRetrieveLatestTermsOfService: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "regionCode": "", + "kind": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/termsOfService:retrieveLatest", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = termsofservice.RetrieveLatestTermsOfServiceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTermsOfServiceServiceRestTransport._BaseRetrieveLatestTermsOfService._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseTermsOfServiceServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/README.rst b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/README.rst new file mode 100644 index 000000000000..815387def1a4 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`UserServiceTransport` is the ABC for all transports. +- public child `UserServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `UserServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseUserServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `UserServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py index bad8c73c8ad5..a8bc96ed310b 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -374,35 +378,44 @@ def list_users( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_user: gapic_v1.method_async.wrap_method( + self.get_user: self._wrap_method( self.get_user, default_timeout=None, client_info=client_info, ), - self.create_user: gapic_v1.method_async.wrap_method( + self.create_user: self._wrap_method( self.create_user, default_timeout=None, client_info=client_info, ), - self.delete_user: gapic_v1.method_async.wrap_method( + self.delete_user: self._wrap_method( self.delete_user, default_timeout=None, client_info=client_info, ), - self.update_user: gapic_v1.method_async.wrap_method( + self.update_user: self._wrap_method( self.update_user, default_timeout=None, client_info=client_info, ), - self.list_users: gapic_v1.method_async.wrap_method( + self.list_users: self._wrap_method( self.list_users, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("UserServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py index 058cc95891ca..c1e3aec5f48a 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest.py @@ -16,34 +16,30 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_accounts_v1beta.types import user +from google.shopping.merchant_accounts_v1beta.types import user as gsma_user + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseUserServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_accounts_v1beta.types import user -from google.shopping.merchant_accounts_v1beta.types import user as gsma_user - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import UserServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -204,8 +200,8 @@ class UserServiceRestStub: _interceptor: UserServiceRestInterceptor -class UserServiceRestTransport(UserServiceTransport): - """REST backend transport for UserService. +class UserServiceRestTransport(_BaseUserServiceRestTransport): + """REST backend synchronous transport for UserService. Service to support user API. @@ -214,7 +210,6 @@ class UserServiceRestTransport(UserServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -268,21 +263,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -293,21 +279,34 @@ def __init__( self._interceptor = interceptor or UserServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateUser(UserServiceRestStub): + class _CreateUser( + _BaseUserServiceRestTransport._BaseCreateUser, UserServiceRestStub + ): def __hash__(self): - return hash("CreateUser") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "userId": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("UserServiceRestTransport.CreateUser") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -335,45 +334,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/accounts/v1beta/{parent=accounts/*}/users", - "body": "user", - }, - ] + http_options = ( + _BaseUserServiceRestTransport._BaseCreateUser._get_http_options() + ) request, metadata = self._interceptor.pre_create_user(request, metadata) - pb_request = gsma_user.CreateUserRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseUserServiceRestTransport._BaseCreateUser._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseUserServiceRestTransport._BaseCreateUser._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseUserServiceRestTransport._BaseCreateUser._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = UserServiceRestTransport._CreateUser._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -389,19 +379,33 @@ def __call__( resp = self._interceptor.post_create_user(resp) return resp - class _DeleteUser(UserServiceRestStub): + class _DeleteUser( + _BaseUserServiceRestTransport._BaseDeleteUser, UserServiceRestStub + ): def __hash__(self): - return hash("DeleteUser") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("UserServiceRestTransport.DeleteUser") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -423,38 +427,31 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/accounts/v1beta/{name=accounts/*/users/*}", - }, - ] + http_options = ( + _BaseUserServiceRestTransport._BaseDeleteUser._get_http_options() + ) request, metadata = self._interceptor.pre_delete_user(request, metadata) - pb_request = user.DeleteUserRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseUserServiceRestTransport._BaseDeleteUser._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseUserServiceRestTransport._BaseDeleteUser._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = UserServiceRestTransport._DeleteUser._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -462,19 +459,31 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetUser(UserServiceRestStub): + class _GetUser(_BaseUserServiceRestTransport._BaseGetUser, UserServiceRestStub): def __hash__(self): - return hash("GetUser") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("UserServiceRestTransport.GetUser") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -502,38 +511,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{name=accounts/*/users/*}", - }, - ] + http_options = ( + _BaseUserServiceRestTransport._BaseGetUser._get_http_options() + ) request, metadata = self._interceptor.pre_get_user(request, metadata) - pb_request = user.GetUserRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseUserServiceRestTransport._BaseGetUser._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseUserServiceRestTransport._BaseGetUser._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = UserServiceRestTransport._GetUser._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -549,19 +551,31 @@ def __call__( resp = self._interceptor.post_get_user(resp) return resp - class _ListUsers(UserServiceRestStub): + class _ListUsers(_BaseUserServiceRestTransport._BaseListUsers, UserServiceRestStub): def __hash__(self): - return hash("ListUsers") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("UserServiceRestTransport.ListUsers") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -587,38 +601,31 @@ def __call__( Response message for the ``ListUsers`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/accounts/v1beta/{parent=accounts/*}/users", - }, - ] + http_options = ( + _BaseUserServiceRestTransport._BaseListUsers._get_http_options() + ) request, metadata = self._interceptor.pre_list_users(request, metadata) - pb_request = user.ListUsersRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseUserServiceRestTransport._BaseListUsers._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseUserServiceRestTransport._BaseListUsers._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = UserServiceRestTransport._ListUsers._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -634,21 +641,34 @@ def __call__( resp = self._interceptor.post_list_users(resp) return resp - class _UpdateUser(UserServiceRestStub): + class _UpdateUser( + _BaseUserServiceRestTransport._BaseUpdateUser, UserServiceRestStub + ): def __hash__(self): - return hash("UpdateUser") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("UserServiceRestTransport.UpdateUser") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -676,45 +696,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/accounts/v1beta/{user.name=accounts/*/users/*}", - "body": "user", - }, - ] + http_options = ( + _BaseUserServiceRestTransport._BaseUpdateUser._get_http_options() + ) request, metadata = self._interceptor.pre_update_user(request, metadata) - pb_request = gsma_user.UpdateUserRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseUserServiceRestTransport._BaseUpdateUser._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseUserServiceRestTransport._BaseUpdateUser._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseUserServiceRestTransport._BaseUpdateUser._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = UserServiceRestTransport._UpdateUser._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest_base.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest_base.py new file mode 100644 index 000000000000..134bdb6071b1 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/user_service/transports/rest_base.py @@ -0,0 +1,352 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_accounts_v1beta.types import user +from google.shopping.merchant_accounts_v1beta.types import user as gsma_user + +from .base import DEFAULT_CLIENT_INFO, UserServiceTransport + + +class _BaseUserServiceRestTransport(UserServiceTransport): + """Base REST backend transport for UserService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateUser: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "userId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/accounts/v1beta/{parent=accounts/*}/users", + "body": "user", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gsma_user.CreateUserRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseUserServiceRestTransport._BaseCreateUser._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteUser: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/accounts/v1beta/{name=accounts/*/users/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = user.DeleteUserRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseUserServiceRestTransport._BaseDeleteUser._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetUser: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{name=accounts/*/users/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = user.GetUserRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseUserServiceRestTransport._BaseGetUser._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListUsers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/accounts/v1beta/{parent=accounts/*}/users", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = user.ListUsersRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseUserServiceRestTransport._BaseListUsers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateUser: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/accounts/v1beta/{user.name=accounts/*/users/*}", + "body": "user", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gsma_user.UpdateUserRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseUserServiceRestTransport._BaseUpdateUser._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseUserServiceRestTransport",) diff --git a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/types/shippingsettings.py b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/types/shippingsettings.py index eacef556bcd1..f3e6a021abc2 100644 --- a/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/types/shippingsettings.py +++ b/packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/types/shippingsettings.py @@ -66,23 +66,23 @@ class ShippingSettings(proto.Message): Required. This field is used for avoid async issue. Make sure shipping setting data didn't change between get call and insert call. - The user should do following steps: + The user should do following steps: - 1. Set etag field as empty string for initial + 1. Set etag field as empty string for initial shipping setting creation. - 2. After initial creation, call get method to + 2. After initial creation, call get method to obtain an etag and current shipping setting data before call insert. - 3. Modify to wanted shipping setting + 3. Modify to wanted shipping setting information. - 4. Call insert method with the wanted shipping + 4. Call insert method with the wanted shipping setting information with the etag obtained from step 2. - 5. If shipping setting data changed between step + 5. If shipping setting data changed between step 2 and step 4. Insert request will fail because the etag changes every time the shipping setting data changes. User should diff --git a/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json b/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json index 7bf436f70f97..91ea23ca0671 100644 --- a/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json +++ b/packages/google-shopping-merchant-accounts/samples/generated_samples/snippet_metadata_google.shopping.merchant.accounts.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-accounts", - "version": "0.2.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-shopping-merchant-accounts/scripts/client-post-processing/doc-formatting.yaml b/packages/google-shopping-merchant-accounts/scripts/client-post-processing/doc-formatting.yaml new file mode 120000 index 000000000000..6e0991666f97 --- /dev/null +++ b/packages/google-shopping-merchant-accounts/scripts/client-post-processing/doc-formatting.yaml @@ -0,0 +1 @@ +../../../../scripts/client-post-processing/doc-formatting.yaml \ No newline at end of file diff --git a/packages/google-shopping-merchant-accounts/setup.py b/packages/google-shopping-merchant-accounts/setup.py index 93d5f848b169..cd289e2d1c81 100644 --- a/packages/google-shopping-merchant-accounts/setup.py +++ b/packages/google-shopping-merchant-accounts/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-accounts" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py index 800b1a6017e0..d2010faad890 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_issue_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_accounts_v1beta.services.account_issue_service import ( AccountIssueServiceAsyncClient, AccountIssueServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import accountissue +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1223,27 +1246,6 @@ def test_list_account_issues(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_account_issues_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountIssueServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_account_issues), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_account_issues() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accountissue.ListAccountIssuesRequest() - - def test_list_account_issues_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1319,31 +1321,6 @@ def test_list_account_issues_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_account_issues_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_account_issues), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accountissue.ListAccountIssuesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_account_issues() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accountissue.ListAccountIssuesRequest() - - @pytest.mark.asyncio async def test_list_account_issues_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1352,7 +1329,7 @@ async def test_list_account_issues_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1391,7 +1368,7 @@ async def test_list_account_issues_async( transport: str = "grpc_asyncio", request_type=accountissue.ListAccountIssuesRequest ): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1461,7 +1438,7 @@ def test_list_account_issues_field_headers(): @pytest.mark.asyncio async def test_list_account_issues_field_headers_async(): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1535,7 +1512,7 @@ def test_list_account_issues_flattened_error(): @pytest.mark.asyncio async def test_list_account_issues_flattened_async(): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1566,7 +1543,7 @@ async def test_list_account_issues_flattened_async(): @pytest.mark.asyncio async def test_list_account_issues_flattened_error_async(): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1680,7 +1657,7 @@ def test_list_account_issues_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_account_issues_async_pager(): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1732,7 +1709,7 @@ async def test_list_account_issues_async_pager(): @pytest.mark.asyncio async def test_list_account_issues_async_pages(): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1780,46 +1757,6 @@ async def test_list_account_issues_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - accountissue.ListAccountIssuesRequest, - dict, - ], -) -def test_list_account_issues_rest(request_type): - client = AccountIssueServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accountissue.ListAccountIssuesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accountissue.ListAccountIssuesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_account_issues(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAccountIssuesPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_account_issues_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1962,87 +1899,6 @@ def test_list_account_issues_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_account_issues_rest_interceptors(null_interceptor): - transport = transports.AccountIssueServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountIssueServiceRestInterceptor(), - ) - client = AccountIssueServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountIssueServiceRestInterceptor, "post_list_account_issues" - ) as post, mock.patch.object( - transports.AccountIssueServiceRestInterceptor, "pre_list_account_issues" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accountissue.ListAccountIssuesRequest.pb( - accountissue.ListAccountIssuesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accountissue.ListAccountIssuesResponse.to_json( - accountissue.ListAccountIssuesResponse() - ) - - request = accountissue.ListAccountIssuesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accountissue.ListAccountIssuesResponse() - - client.list_account_issues( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_account_issues_rest_bad_request( - transport: str = "rest", request_type=accountissue.ListAccountIssuesRequest -): - client = AccountIssueServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_account_issues(request) - - def test_list_account_issues_rest_flattened(): client = AccountIssueServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2254,18 +2110,241 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = AccountIssueServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_account_issues_empty_call_grpc(): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_account_issues), "__call__" + ) as call: + call.return_value = accountissue.ListAccountIssuesResponse() + client.list_account_issues(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accountissue.ListAccountIssuesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AccountIssueServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AccountIssueServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_account_issues_empty_call_grpc_asyncio(): + client = AccountIssueServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_account_issues), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accountissue.ListAccountIssuesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_account_issues(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accountissue.ListAccountIssuesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AccountIssueServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_account_issues_rest_bad_request( + request_type=accountissue.ListAccountIssuesRequest, +): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_account_issues(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + accountissue.ListAccountIssuesRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = AccountIssueServiceClient.get_transport_class(transport_name)( +def test_list_account_issues_rest_call_success(request_type): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accountissue.ListAccountIssuesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accountissue.ListAccountIssuesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_account_issues(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAccountIssuesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_account_issues_rest_interceptors(null_interceptor): + transport = transports.AccountIssueServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountIssueServiceRestInterceptor(), ) - assert transport.kind == transport_name + client = AccountIssueServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountIssueServiceRestInterceptor, "post_list_account_issues" + ) as post, mock.patch.object( + transports.AccountIssueServiceRestInterceptor, "pre_list_account_issues" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accountissue.ListAccountIssuesRequest.pb( + accountissue.ListAccountIssuesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accountissue.ListAccountIssuesResponse.to_json( + accountissue.ListAccountIssuesResponse() + ) + req.return_value.content = return_value + + request = accountissue.ListAccountIssuesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accountissue.ListAccountIssuesResponse() + + client.list_account_issues( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_account_issues_empty_call_rest(): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_account_issues), "__call__" + ) as call: + client.list_account_issues(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accountissue.ListAccountIssuesRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2860,36 +2939,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = AccountIssueServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = AccountIssueServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = AccountIssueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py index 1c24be2ac0a2..daf5b439d0c0 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_account_tax_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,16 +52,8 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.type import interval_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_accounts_v1beta.services.account_tax_service import ( AccountTaxServiceAsyncClient, @@ -59,10 +68,24 @@ from google.shopping.merchant_accounts_v1beta.types import tax_rule +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1200,25 +1223,6 @@ def test_get_account_tax(request_type, transport: str = "grpc"): assert response.account == 749 -def test_get_account_tax_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_account_tax), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_account_tax() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == account_tax.GetAccountTaxRequest() - - def test_get_account_tax_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1282,30 +1286,6 @@ def test_get_account_tax_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_account_tax_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_account_tax), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - account_tax.AccountTax( - name="name_value", - account=749, - ) - ) - response = await client.get_account_tax() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == account_tax.GetAccountTaxRequest() - - @pytest.mark.asyncio async def test_get_account_tax_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1314,7 +1294,7 @@ async def test_get_account_tax_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1353,7 +1333,7 @@ async def test_get_account_tax_async( transport: str = "grpc_asyncio", request_type=account_tax.GetAccountTaxRequest ): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1421,7 +1401,7 @@ def test_get_account_tax_field_headers(): @pytest.mark.asyncio async def test_get_account_tax_field_headers_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1491,7 +1471,7 @@ def test_get_account_tax_flattened_error(): @pytest.mark.asyncio async def test_get_account_tax_flattened_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1520,7 +1500,7 @@ async def test_get_account_tax_flattened_async(): @pytest.mark.asyncio async def test_get_account_tax_flattened_error_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1568,25 +1548,6 @@ def test_list_account_tax(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_account_tax_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_account_tax), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_account_tax() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == account_tax.ListAccountTaxRequest() - - def test_list_account_tax_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1654,29 +1615,6 @@ def test_list_account_tax_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_account_tax_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_account_tax), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - account_tax.ListAccountTaxResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_account_tax() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == account_tax.ListAccountTaxRequest() - - @pytest.mark.asyncio async def test_list_account_tax_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1685,7 +1623,7 @@ async def test_list_account_tax_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1724,7 +1662,7 @@ async def test_list_account_tax_async( transport: str = "grpc_asyncio", request_type=account_tax.ListAccountTaxRequest ): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1790,7 +1728,7 @@ def test_list_account_tax_field_headers(): @pytest.mark.asyncio async def test_list_account_tax_field_headers_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1860,7 +1798,7 @@ def test_list_account_tax_flattened_error(): @pytest.mark.asyncio async def test_list_account_tax_flattened_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1889,7 +1827,7 @@ async def test_list_account_tax_flattened_async(): @pytest.mark.asyncio async def test_list_account_tax_flattened_error_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1999,7 +1937,7 @@ def test_list_account_tax_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_account_tax_async_pager(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2049,7 +1987,7 @@ async def test_list_account_tax_async_pager(): @pytest.mark.asyncio async def test_list_account_tax_async_pages(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2135,27 +2073,6 @@ def test_update_account_tax(request_type, transport: str = "grpc"): assert response.account == 749 -def test_update_account_tax_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_account_tax), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_account_tax() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_account_tax.UpdateAccountTaxRequest() - - def test_update_account_tax_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2221,32 +2138,6 @@ def test_update_account_tax_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_account_tax_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_account_tax), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gsma_account_tax.AccountTax( - name="name_value", - account=749, - ) - ) - response = await client.update_account_tax() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_account_tax.UpdateAccountTaxRequest() - - @pytest.mark.asyncio async def test_update_account_tax_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2255,7 +2146,7 @@ async def test_update_account_tax_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2295,7 +2186,7 @@ async def test_update_account_tax_async( request_type=gsma_account_tax.UpdateAccountTaxRequest, ): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2367,7 +2258,7 @@ def test_update_account_tax_field_headers(): @pytest.mark.asyncio async def test_update_account_tax_field_headers_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2446,7 +2337,7 @@ def test_update_account_tax_flattened_error(): @pytest.mark.asyncio async def test_update_account_tax_flattened_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2481,7 +2372,7 @@ async def test_update_account_tax_flattened_async(): @pytest.mark.asyncio async def test_update_account_tax_flattened_error_async(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2494,48 +2385,6 @@ async def test_update_account_tax_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - account_tax.GetAccountTaxRequest, - dict, - ], -) -def test_get_account_tax_rest(request_type): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/accounttax/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = account_tax.AccountTax( - name="name_value", - account=749, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = account_tax.AccountTax.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_account_tax(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, account_tax.AccountTax) - assert response.name == "name_value" - assert response.account == 749 - - def test_get_account_tax_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2655,117 +2504,36 @@ def test_get_account_tax_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_account_tax_rest_interceptors(null_interceptor): - transport = transports.AccountTaxServiceRestTransport( +def test_get_account_tax_rest_flattened(): + client = AccountTaxServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountTaxServiceRestInterceptor(), + transport="rest", ) - client = AccountTaxServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountTaxServiceRestInterceptor, "post_get_account_tax" - ) as post, mock.patch.object( - transports.AccountTaxServiceRestInterceptor, "pre_get_account_tax" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = account_tax.GetAccountTaxRequest.pb( - account_tax.GetAccountTaxRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = account_tax.AccountTax.to_json( - account_tax.AccountTax() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = account_tax.AccountTax() - request = account_tax.GetAccountTaxRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = account_tax.AccountTax() + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/accounttax/sample2"} - client.get_account_tax( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) + mock_args.update(sample_request) - pre.assert_called_once() - post.assert_called_once() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = account_tax.AccountTax.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value - -def test_get_account_tax_rest_bad_request( - transport: str = "rest", request_type=account_tax.GetAccountTaxRequest -): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/accounttax/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_account_tax(request) - - -def test_get_account_tax_rest_flattened(): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = account_tax.AccountTax() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/accounttax/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = account_tax.AccountTax.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_account_tax(**mock_args) + client.get_account_tax(**mock_args) # Establish that the underlying call was made with the expected # request object values. @@ -2793,52 +2561,6 @@ def test_get_account_tax_rest_flattened_error(transport: str = "rest"): ) -def test_get_account_tax_rest_error(): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - account_tax.ListAccountTaxRequest, - dict, - ], -) -def test_list_account_tax_rest(request_type): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = account_tax.ListAccountTaxResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = account_tax.ListAccountTaxResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_account_tax(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAccountTaxPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_account_tax_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2975,87 +2697,6 @@ def test_list_account_tax_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_account_tax_rest_interceptors(null_interceptor): - transport = transports.AccountTaxServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountTaxServiceRestInterceptor(), - ) - client = AccountTaxServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountTaxServiceRestInterceptor, "post_list_account_tax" - ) as post, mock.patch.object( - transports.AccountTaxServiceRestInterceptor, "pre_list_account_tax" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = account_tax.ListAccountTaxRequest.pb( - account_tax.ListAccountTaxRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = account_tax.ListAccountTaxResponse.to_json( - account_tax.ListAccountTaxResponse() - ) - - request = account_tax.ListAccountTaxRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = account_tax.ListAccountTaxResponse() - - client.list_account_tax( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_account_tax_rest_bad_request( - transport: str = "rest", request_type=account_tax.ListAccountTaxRequest -): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_account_tax(request) - - def test_list_account_tax_rest_flattened(): client = AccountTaxServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3176,167 +2817,40 @@ def test_list_account_tax_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - gsma_account_tax.UpdateAccountTaxRequest, - dict, - ], -) -def test_update_account_tax_rest(request_type): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"account_tax": {"name": "accounts/sample1/accounttax/sample2"}} - request_init["account_tax"] = { - "name": "accounts/sample1/accounttax/sample2", - "account": 749, - "tax_rules": [ - { - "location_id": 1157, - "post_code_range": {"start": "start_value", "end": "end_value"}, - "use_google_rate": True, - "self_specified_rate_micros": 2732, - "region_code": "region_code_value", - "shipping_taxed": True, - "effective_time_period": { - "start_time": {"seconds": 751, "nanos": 543}, - "end_time": {}, - }, - } - ], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 +def test_update_account_tax_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # Determine if the message type is proto-plus or protobuf - test_field = gsma_account_tax.UpdateAccountTaxRequest.meta.fields["account_tax"] + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Ensure method has been cached + assert ( + client._transport.update_account_tax in client._transport._wrapped_methods + ) - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_account_tax + ] = mock_rpc - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields + request = {} + client.update_account_tax(request) - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["account_tax"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["account_tax"][field])): - del request_init["account_tax"][field][i][subfield] - else: - del request_init["account_tax"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gsma_account_tax.AccountTax( - name="name_value", - account=749, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gsma_account_tax.AccountTax.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_account_tax(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, gsma_account_tax.AccountTax) - assert response.name == "name_value" - assert response.account == 749 - - -def test_update_account_tax_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.update_account_tax in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.update_account_tax - ] = mock_rpc - - request = {} - client.update_account_tax(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_account_tax(request) + client.update_account_tax(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 @@ -3405,23 +2919,753 @@ def test_update_account_tax_rest_required_fields( return_value = gsma_account_tax.AccountTax.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_account_tax(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_account_tax_rest_unset_required_fields(): + transport = transports.AccountTaxServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_account_tax._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("accountTax",))) + + +def test_update_account_tax_rest_flattened(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gsma_account_tax.AccountTax() + + # get arguments that satisfy an http rule for this method + sample_request = { + "account_tax": {"name": "accounts/sample1/accounttax/sample2"} + } + + # get truthy value for each flattened field + mock_args = dict( + account_tax=gsma_account_tax.AccountTax(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gsma_account_tax.AccountTax.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_account_tax(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{account_tax.name=accounts/*/accounttax/*}" + % client.transport._host, + args[1], + ) + + +def test_update_account_tax_rest_flattened_error(transport: str = "rest"): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_account_tax( + gsma_account_tax.UpdateAccountTaxRequest(), + account_tax=gsma_account_tax.AccountTax(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AccountTaxServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AccountTaxServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountTaxServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AccountTaxServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountTaxServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountTaxServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AccountTaxServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountTaxServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountTaxServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AccountTaxServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountTaxServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AccountTaxServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AccountTaxServiceGrpcTransport, + transports.AccountTaxServiceGrpcAsyncIOTransport, + transports.AccountTaxServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = AccountTaxServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_account_tax_empty_call_grpc(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account_tax), "__call__") as call: + call.return_value = account_tax.AccountTax() + client.get_account_tax(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = account_tax.GetAccountTaxRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_account_tax_empty_call_grpc(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_account_tax), "__call__") as call: + call.return_value = account_tax.ListAccountTaxResponse() + client.list_account_tax(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = account_tax.ListAccountTaxRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_account_tax_empty_call_grpc(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_account_tax), "__call__" + ) as call: + call.return_value = gsma_account_tax.AccountTax() + client.update_account_tax(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_account_tax.UpdateAccountTaxRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AccountTaxServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AccountTaxServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_account_tax_empty_call_grpc_asyncio(): + client = AccountTaxServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account_tax), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + account_tax.AccountTax( + name="name_value", + account=749, + ) + ) + await client.get_account_tax(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = account_tax.GetAccountTaxRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_account_tax_empty_call_grpc_asyncio(): + client = AccountTaxServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_account_tax), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + account_tax.ListAccountTaxResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_account_tax(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = account_tax.ListAccountTaxRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_account_tax_empty_call_grpc_asyncio(): + client = AccountTaxServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_account_tax), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gsma_account_tax.AccountTax( + name="name_value", + account=749, + ) + ) + await client.update_account_tax(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_account_tax.UpdateAccountTaxRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AccountTaxServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_account_tax_rest_bad_request( + request_type=account_tax.GetAccountTaxRequest, +): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/accounttax/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_account_tax(request) + + +@pytest.mark.parametrize( + "request_type", + [ + account_tax.GetAccountTaxRequest, + dict, + ], +) +def test_get_account_tax_rest_call_success(request_type): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/accounttax/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = account_tax.AccountTax( + name="name_value", + account=749, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = account_tax.AccountTax.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_account_tax(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, account_tax.AccountTax) + assert response.name == "name_value" + assert response.account == 749 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_account_tax_rest_interceptors(null_interceptor): + transport = transports.AccountTaxServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountTaxServiceRestInterceptor(), + ) + client = AccountTaxServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountTaxServiceRestInterceptor, "post_get_account_tax" + ) as post, mock.patch.object( + transports.AccountTaxServiceRestInterceptor, "pre_get_account_tax" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = account_tax.GetAccountTaxRequest.pb( + account_tax.GetAccountTaxRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = account_tax.AccountTax.to_json(account_tax.AccountTax()) + req.return_value.content = return_value + + request = account_tax.GetAccountTaxRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = account_tax.AccountTax() + + client.get_account_tax( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_account_tax_rest_bad_request( + request_type=account_tax.ListAccountTaxRequest, +): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_account_tax(request) + + +@pytest.mark.parametrize( + "request_type", + [ + account_tax.ListAccountTaxRequest, + dict, + ], +) +def test_list_account_tax_rest_call_success(request_type): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = account_tax.ListAccountTaxResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = account_tax.ListAccountTaxResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_account_tax(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAccountTaxPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_account_tax_rest_interceptors(null_interceptor): + transport = transports.AccountTaxServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountTaxServiceRestInterceptor(), + ) + client = AccountTaxServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountTaxServiceRestInterceptor, "post_list_account_tax" + ) as post, mock.patch.object( + transports.AccountTaxServiceRestInterceptor, "pre_list_account_tax" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = account_tax.ListAccountTaxRequest.pb( + account_tax.ListAccountTaxRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = account_tax.ListAccountTaxResponse.to_json( + account_tax.ListAccountTaxResponse() + ) + req.return_value.content = return_value + + request = account_tax.ListAccountTaxRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = account_tax.ListAccountTaxResponse() + + client.list_account_tax( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_account_tax_rest_bad_request( + request_type=gsma_account_tax.UpdateAccountTaxRequest, +): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"account_tax": {"name": "accounts/sample1/accounttax/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_account_tax(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gsma_account_tax.UpdateAccountTaxRequest, + dict, + ], +) +def test_update_account_tax_rest_call_success(request_type): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"account_tax": {"name": "accounts/sample1/accounttax/sample2"}} + request_init["account_tax"] = { + "name": "accounts/sample1/accounttax/sample2", + "account": 749, + "tax_rules": [ + { + "location_id": 1157, + "post_code_range": {"start": "start_value", "end": "end_value"}, + "use_google_rate": True, + "self_specified_rate_micros": 2732, + "region_code": "region_code_value", + "shipping_taxed": True, + "effective_time_period": { + "start_time": {"seconds": 751, "nanos": 543}, + "end_time": {}, + }, + } + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gsma_account_tax.UpdateAccountTaxRequest.meta.fields["account_tax"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["account_tax"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) - response = client.update_account_tax(request) + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["account_tax"][field])): + del request_init["account_tax"][field][i][subfield] + else: + del request_init["account_tax"][field][subfield] + request = request_type(**request_init) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gsma_account_tax.AccountTax( + name="name_value", + account=749, + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_update_account_tax_rest_unset_required_fields(): - transport = transports.AccountTaxServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = gsma_account_tax.AccountTax.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_account_tax(request) - unset_fields = transport.update_account_tax._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("accountTax",))) + # Establish that the response is the type that we expect. + assert isinstance(response, gsma_account_tax.AccountTax) + assert response.name == "name_value" + assert response.account == 749 @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -3433,6 +3677,7 @@ def test_update_account_tax_rest_interceptors(null_interceptor): else transports.AccountTaxServiceRestInterceptor(), ) client = AccountTaxServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -3454,12 +3699,12 @@ def test_update_account_tax_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = gsma_account_tax.AccountTax.to_json( + return_value = gsma_account_tax.AccountTax.to_json( gsma_account_tax.AccountTax() ) + req.return_value.content = return_value request = gsma_account_tax.UpdateAccountTaxRequest() metadata = [ @@ -3481,201 +3726,73 @@ def test_update_account_tax_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_account_tax_rest_bad_request( - transport: str = "rest", request_type=gsma_account_tax.UpdateAccountTaxRequest -): +def test_initialize_client_w_rest(): client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"account_tax": {"name": "accounts/sample1/accounttax/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_account_tax(request) + assert client is not None -def test_update_account_tax_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_account_tax_empty_call_rest(): client = AccountTaxServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gsma_account_tax.AccountTax() - - # get arguments that satisfy an http rule for this method - sample_request = { - "account_tax": {"name": "accounts/sample1/accounttax/sample2"} - } - - # get truthy value for each flattened field - mock_args = dict( - account_tax=gsma_account_tax.AccountTax(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gsma_account_tax.AccountTax.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_account_tax(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{account_tax.name=accounts/*/accounttax/*}" - % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account_tax), "__call__") as call: + client.get_account_tax(request=None) -def test_update_account_tax_rest_flattened_error(transport: str = "rest"): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = account_tax.GetAccountTaxRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_account_tax( - gsma_account_tax.UpdateAccountTaxRequest(), - account_tax=gsma_account_tax.AccountTax(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + assert args[0] == request_msg -def test_update_account_tax_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_account_tax_empty_call_rest(): client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.AccountTaxServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.AccountTaxServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AccountTaxServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.AccountTaxServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountTaxServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountTaxServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.AccountTaxServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountTaxServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_account_tax), "__call__") as call: + client.list_account_tax(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountTaxServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = AccountTaxServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = account_tax.ListAccountTaxRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountTaxServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.AccountTaxServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_account_tax_empty_call_rest(): + client = AccountTaxServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.AccountTaxServiceGrpcTransport, - transports.AccountTaxServiceGrpcAsyncIOTransport, - transports.AccountTaxServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_account_tax), "__call__" + ) as call: + client.update_account_tax(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_account_tax.UpdateAccountTaxRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = AccountTaxServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4260,36 +4377,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = AccountTaxServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = AccountTaxServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = AccountTaxServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py index c688a4d567ce..da6f399a78db 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_accounts_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,15 +52,7 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.type import datetime_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_accounts_v1beta.services.accounts_service import ( AccountsServiceAsyncClient, @@ -59,10 +68,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1194,25 +1217,6 @@ def test_get_account(request_type, transport: str = "grpc"): assert response.language_code == "language_code_value" -def test_get_account_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_account), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.GetAccountRequest() - - def test_get_account_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1276,34 +1280,6 @@ def test_get_account_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_account_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_account), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.Account( - name="name_value", - account_id=1049, - account_name="account_name_value", - adult_content=True, - test_account=True, - language_code="language_code_value", - ) - ) - response = await client.get_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.GetAccountRequest() - - @pytest.mark.asyncio async def test_get_account_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1312,7 +1288,7 @@ async def test_get_account_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1351,7 +1327,7 @@ async def test_get_account_async( transport: str = "grpc_asyncio", request_type=accounts.GetAccountRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1427,7 +1403,7 @@ def test_get_account_field_headers(): @pytest.mark.asyncio async def test_get_account_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1495,7 +1471,7 @@ def test_get_account_flattened_error(): @pytest.mark.asyncio async def test_get_account_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1522,7 +1498,7 @@ async def test_get_account_flattened_async(): @pytest.mark.asyncio async def test_get_account_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1582,27 +1558,6 @@ def test_create_and_configure_account(request_type, transport: str = "grpc"): assert response.language_code == "language_code_value" -def test_create_and_configure_account_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_and_configure_account), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_and_configure_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.CreateAndConfigureAccountRequest() - - def test_create_and_configure_account_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1669,36 +1624,6 @@ def test_create_and_configure_account_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_and_configure_account_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_and_configure_account), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.Account( - name="name_value", - account_id=1049, - account_name="account_name_value", - adult_content=True, - test_account=True, - language_code="language_code_value", - ) - ) - response = await client.create_and_configure_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.CreateAndConfigureAccountRequest() - - @pytest.mark.asyncio async def test_create_and_configure_account_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1707,7 +1632,7 @@ async def test_create_and_configure_account_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1747,7 +1672,7 @@ async def test_create_and_configure_account_async( request_type=accounts.CreateAndConfigureAccountRequest, ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1826,25 +1751,6 @@ def test_delete_account(request_type, transport: str = "grpc"): assert response is None -def test_delete_account_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_account), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.DeleteAccountRequest() - - def test_delete_account_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1908,25 +1814,6 @@ def test_delete_account_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_account_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_account), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.DeleteAccountRequest() - - @pytest.mark.asyncio async def test_delete_account_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1935,7 +1822,7 @@ async def test_delete_account_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1974,7 +1861,7 @@ async def test_delete_account_async( transport: str = "grpc_asyncio", request_type=accounts.DeleteAccountRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2035,7 +1922,7 @@ def test_delete_account_field_headers(): @pytest.mark.asyncio async def test_delete_account_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2103,7 +1990,7 @@ def test_delete_account_flattened_error(): @pytest.mark.asyncio async def test_delete_account_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2130,7 +2017,7 @@ async def test_delete_account_flattened_async(): @pytest.mark.asyncio async def test_delete_account_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2188,25 +2075,6 @@ def test_update_account(request_type, transport: str = "grpc"): assert response.language_code == "language_code_value" -def test_update_account_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_account), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.UpdateAccountRequest() - - def test_update_account_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2266,34 +2134,6 @@ def test_update_account_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_account_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_account), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.Account( - name="name_value", - account_id=1049, - account_name="account_name_value", - adult_content=True, - test_account=True, - language_code="language_code_value", - ) - ) - response = await client.update_account() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.UpdateAccountRequest() - - @pytest.mark.asyncio async def test_update_account_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2302,7 +2142,7 @@ async def test_update_account_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2341,7 +2181,7 @@ async def test_update_account_async( transport: str = "grpc_asyncio", request_type=accounts.UpdateAccountRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2417,7 +2257,7 @@ def test_update_account_field_headers(): @pytest.mark.asyncio async def test_update_account_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2490,7 +2330,7 @@ def test_update_account_flattened_error(): @pytest.mark.asyncio async def test_update_account_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2521,7 +2361,7 @@ async def test_update_account_flattened_async(): @pytest.mark.asyncio async def test_update_account_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2570,25 +2410,6 @@ def test_list_accounts(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_accounts_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_accounts), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_accounts() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.ListAccountsRequest() - - def test_list_accounts_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2654,29 +2475,6 @@ def test_list_accounts_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_accounts_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_accounts), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.ListAccountsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_accounts() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.ListAccountsRequest() - - @pytest.mark.asyncio async def test_list_accounts_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2685,7 +2483,7 @@ async def test_list_accounts_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2724,7 +2522,7 @@ async def test_list_accounts_async( transport: str = "grpc_asyncio", request_type=accounts.ListAccountsRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2853,7 +2651,7 @@ def test_list_accounts_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_accounts_async_pager(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2903,7 +2701,7 @@ async def test_list_accounts_async_pager(): @pytest.mark.asyncio async def test_list_accounts_async_pages(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2987,27 +2785,6 @@ def test_list_sub_accounts(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_sub_accounts_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_sub_accounts), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_sub_accounts() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.ListSubAccountsRequest() - - def test_list_sub_accounts_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3078,41 +2855,16 @@ def test_list_sub_accounts_use_cached_wrapped_rpc(): @pytest.mark.asyncio -async def test_list_sub_accounts_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_sub_accounts), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - accounts.ListSubAccountsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_sub_accounts() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == accounts.ListSubAccountsRequest() - - -@pytest.mark.asyncio -async def test_list_sub_accounts_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) +async def test_list_sub_accounts_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) # Should wrap all calls on client creation assert wrapper_fn.call_count > 0 @@ -3149,7 +2901,7 @@ async def test_list_sub_accounts_async( transport: str = "grpc_asyncio", request_type=accounts.ListSubAccountsRequest ): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3219,7 +2971,7 @@ def test_list_sub_accounts_field_headers(): @pytest.mark.asyncio async def test_list_sub_accounts_field_headers_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3293,7 +3045,7 @@ def test_list_sub_accounts_flattened_error(): @pytest.mark.asyncio async def test_list_sub_accounts_flattened_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3324,7 +3076,7 @@ async def test_list_sub_accounts_flattened_async(): @pytest.mark.asyncio async def test_list_sub_accounts_flattened_error_async(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3438,7 +3190,7 @@ def test_list_sub_accounts_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_sub_accounts_async_pager(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3490,7 +3242,7 @@ async def test_list_sub_accounts_async_pager(): @pytest.mark.asyncio async def test_list_sub_accounts_async_pages(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3538,56 +3290,6 @@ async def test_list_sub_accounts_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - accounts.GetAccountRequest, - dict, - ], -) -def test_get_account_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.Account( - name="name_value", - account_id=1049, - account_name="account_name_value", - adult_content=True, - test_account=True, - language_code="language_code_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.Account.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_account(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts.Account) - assert response.name == "name_value" - assert response.account_id == 1049 - assert response.account_name == "account_name_value" - assert response.adult_content is True - assert response.test_account is True - assert response.language_code == "language_code_value" - - def test_get_account_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3705,83 +3407,6 @@ def test_get_account_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_account_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), - ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_get_account" - ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_get_account" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts.GetAccountRequest.pb(accounts.GetAccountRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.Account.to_json(accounts.Account()) - - request = accounts.GetAccountRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts.Account() - - client.get_account( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_account_rest_bad_request( - transport: str = "rest", request_type=accounts.GetAccountRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_account(request) - - def test_get_account_rest_flattened(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3837,62 +3462,6 @@ def test_get_account_rest_flattened_error(transport: str = "rest"): ) -def test_get_account_rest_error(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - accounts.CreateAndConfigureAccountRequest, - dict, - ], -) -def test_create_and_configure_account_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.Account( - name="name_value", - account_id=1049, - account_name="account_name_value", - adult_content=True, - test_account=True, - language_code="language_code_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.Account.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_and_configure_account(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts.Account) - assert response.name == "name_value" - assert response.account_id == 1049 - assert response.account_name == "account_name_value" - assert response.adult_content is True - assert response.test_account is True - assert response.language_code == "language_code_value" - - def test_create_and_configure_account_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4021,141 +3590,21 @@ def test_create_and_configure_account_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_and_configure_account_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), - ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_create_and_configure_account" - ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_create_and_configure_account" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts.CreateAndConfigureAccountRequest.pb( - accounts.CreateAndConfigureAccountRequest() +def test_delete_account_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.Account.to_json(accounts.Account()) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - request = accounts.CreateAndConfigureAccountRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts.Account() - - client.create_and_configure_account( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_and_configure_account_rest_bad_request( - transport: str = "rest", request_type=accounts.CreateAndConfigureAccountRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_and_configure_account(request) - - -def test_create_and_configure_account_rest_error(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - accounts.DeleteAccountRequest, - dict, - ], -) -def test_delete_account_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_account(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_account_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_account in client._transport._wrapped_methods + # Ensure method has been cached + assert client._transport.delete_account in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -4259,77 +3708,6 @@ def test_delete_account_rest_unset_required_fields(): assert set(unset_fields) == (set(("force",)) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_account_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), - ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_delete_account" - ) as pre: - pre.assert_not_called() - pb_message = accounts.DeleteAccountRequest.pb(accounts.DeleteAccountRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = accounts.DeleteAccountRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_account( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_account_rest_bad_request( - transport: str = "rest", request_type=accounts.DeleteAccountRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_account(request) - - def test_delete_account_rest_flattened(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4383,185 +3761,53 @@ def test_delete_account_rest_flattened_error(transport: str = "rest"): ) -def test_delete_account_rest_error(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_account_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - accounts.UpdateAccountRequest, - dict, - ], -) -def test_update_account_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Ensure method has been cached + assert client._transport.update_account in client._transport._wrapped_methods - # send a request that will satisfy transcoding - request_init = {"account": {"name": "accounts/sample1"}} - request_init["account"] = { - "name": "accounts/sample1", - "account_id": 1049, - "account_name": "account_name_value", - "adult_content": True, - "test_account": True, - "time_zone": {"id": "id_value", "version": "version_value"}, - "language_code": "language_code_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_account] = mock_rpc - # Determine if the message type is proto-plus or protobuf - test_field = accounts.UpdateAccountRequest.meta.fields["account"] + request = {} + client.update_account(request) - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + client.update_account(request) - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - subfields_not_in_runtime = [] +def test_update_account_rest_required_fields( + request_type=accounts.UpdateAccountRequest, +): + transport_class = transports.AccountsServiceRestTransport - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["account"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["account"][field])): - del request_init["account"][field][i][subfield] - else: - del request_init["account"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.Account( - name="name_value", - account_id=1049, - account_name="account_name_value", - adult_content=True, - test_account=True, - language_code="language_code_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.Account.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_account(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, accounts.Account) - assert response.name == "name_value" - assert response.account_id == 1049 - assert response.account_name == "account_name_value" - assert response.adult_content is True - assert response.test_account is True - assert response.language_code == "language_code_value" - - -def test_update_account_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_account in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.update_account] = mock_rpc - - request = {} - client.update_account(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_account(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_account_rest_required_fields( - request_type=accounts.UpdateAccountRequest, -): - transport_class = transports.AccountsServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) # verify fields with default values are dropped @@ -4640,83 +3886,6 @@ def test_update_account_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_account_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), - ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_update_account" - ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_update_account" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts.UpdateAccountRequest.pb(accounts.UpdateAccountRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.Account.to_json(accounts.Account()) - - request = accounts.UpdateAccountRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts.Account() - - client.update_account( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_account_rest_bad_request( - transport: str = "rest", request_type=accounts.UpdateAccountRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"account": {"name": "accounts/sample1"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_account(request) - - def test_update_account_rest_flattened(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4775,52 +3944,6 @@ def test_update_account_rest_flattened_error(transport: str = "rest"): ) -def test_update_account_rest_error(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - accounts.ListAccountsRequest, - dict, - ], -) -def test_list_accounts_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.ListAccountsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.ListAccountsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_accounts(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListAccountsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_accounts_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4857,89 +3980,10 @@ def test_list_accounts_rest_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_accounts_rest_interceptors(null_interceptor): - transport = transports.AccountsServiceRestTransport( +def test_list_accounts_rest_pager(transport: str = "rest"): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AccountsServiceRestInterceptor(), - ) - client = AccountsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AccountsServiceRestInterceptor, "post_list_accounts" - ) as post, mock.patch.object( - transports.AccountsServiceRestInterceptor, "pre_list_accounts" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = accounts.ListAccountsRequest.pb(accounts.ListAccountsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.ListAccountsResponse.to_json( - accounts.ListAccountsResponse() - ) - - request = accounts.ListAccountsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = accounts.ListAccountsResponse() - - client.list_accounts( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_accounts_rest_bad_request( - transport: str = "rest", request_type=accounts.ListAccountsRequest -): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_accounts(request) - - -def test_list_accounts_rest_pager(transport: str = "rest"): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport=transport, ) # Mock the http request call within the method and fake a response. @@ -4997,46 +4041,6 @@ def test_list_accounts_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - accounts.ListSubAccountsRequest, - dict, - ], -) -def test_list_sub_accounts_rest(request_type): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"provider": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.ListSubAccountsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.ListSubAccountsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_sub_accounts(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListSubAccountsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_sub_accounts_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5173,6 +4177,1295 @@ def test_list_sub_accounts_rest_unset_required_fields(): ) +def test_list_sub_accounts_rest_flattened(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.ListSubAccountsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"provider": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + provider="provider_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = accounts.ListSubAccountsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_sub_accounts(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{provider=accounts/*}:listSubaccounts" + % client.transport._host, + args[1], + ) + + +def test_list_sub_accounts_rest_flattened_error(transport: str = "rest"): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_sub_accounts( + accounts.ListSubAccountsRequest(), + provider="provider_value", + ) + + +def test_list_sub_accounts_rest_pager(transport: str = "rest"): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + accounts.ListSubAccountsResponse( + accounts=[ + accounts.Account(), + accounts.Account(), + accounts.Account(), + ], + next_page_token="abc", + ), + accounts.ListSubAccountsResponse( + accounts=[], + next_page_token="def", + ), + accounts.ListSubAccountsResponse( + accounts=[ + accounts.Account(), + ], + next_page_token="ghi", + ), + accounts.ListSubAccountsResponse( + accounts=[ + accounts.Account(), + accounts.Account(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(accounts.ListSubAccountsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"provider": "accounts/sample1"} + + pager = client.list_sub_accounts(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, accounts.Account) for i in results) + + pages = list(client.list_sub_accounts(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AccountsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AccountsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AccountsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AccountsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AccountsServiceGrpcTransport, + transports.AccountsServiceGrpcAsyncIOTransport, + transports.AccountsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = AccountsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_account_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account), "__call__") as call: + call.return_value = accounts.Account() + client.get_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.GetAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_and_configure_account_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_and_configure_account), "__call__" + ) as call: + call.return_value = accounts.Account() + client.create_and_configure_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.CreateAndConfigureAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_account_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_account), "__call__") as call: + call.return_value = None + client.delete_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.DeleteAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_account_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_account), "__call__") as call: + call.return_value = accounts.Account() + client.update_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.UpdateAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_accounts_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_accounts), "__call__") as call: + call.return_value = accounts.ListAccountsResponse() + client.list_accounts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListAccountsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_sub_accounts_empty_call_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_sub_accounts), "__call__" + ) as call: + call.return_value = accounts.ListSubAccountsResponse() + client.list_sub_accounts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListSubAccountsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AccountsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_account_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.Account( + name="name_value", + account_id=1049, + account_name="account_name_value", + adult_content=True, + test_account=True, + language_code="language_code_value", + ) + ) + await client.get_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.GetAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_and_configure_account_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_and_configure_account), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.Account( + name="name_value", + account_id=1049, + account_name="account_name_value", + adult_content=True, + test_account=True, + language_code="language_code_value", + ) + ) + await client.create_and_configure_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.CreateAndConfigureAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_account_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_account), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.DeleteAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_account_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_account), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.Account( + name="name_value", + account_id=1049, + account_name="account_name_value", + adult_content=True, + test_account=True, + language_code="language_code_value", + ) + ) + await client.update_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.UpdateAccountRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_accounts_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_accounts), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.ListAccountsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_accounts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListAccountsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_sub_accounts_empty_call_grpc_asyncio(): + client = AccountsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_sub_accounts), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + accounts.ListSubAccountsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_sub_accounts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListSubAccountsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AccountsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_account_rest_bad_request(request_type=accounts.GetAccountRequest): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_account(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.GetAccountRequest, + dict, + ], +) +def test_get_account_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.Account( + name="name_value", + account_id=1049, + account_name="account_name_value", + adult_content=True, + test_account=True, + language_code="language_code_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.Account.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_account(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, accounts.Account) + assert response.name == "name_value" + assert response.account_id == 1049 + assert response.account_name == "account_name_value" + assert response.adult_content is True + assert response.test_account is True + assert response.language_code == "language_code_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_account_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), + ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "post_get_account" + ) as post, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_get_account" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts.GetAccountRequest.pb(accounts.GetAccountRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts.Account.to_json(accounts.Account()) + req.return_value.content = return_value + + request = accounts.GetAccountRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts.Account() + + client.get_account( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_and_configure_account_rest_bad_request( + request_type=accounts.CreateAndConfigureAccountRequest, +): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_and_configure_account(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.CreateAndConfigureAccountRequest, + dict, + ], +) +def test_create_and_configure_account_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.Account( + name="name_value", + account_id=1049, + account_name="account_name_value", + adult_content=True, + test_account=True, + language_code="language_code_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.Account.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_and_configure_account(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, accounts.Account) + assert response.name == "name_value" + assert response.account_id == 1049 + assert response.account_name == "account_name_value" + assert response.adult_content is True + assert response.test_account is True + assert response.language_code == "language_code_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_and_configure_account_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), + ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "post_create_and_configure_account" + ) as post, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_create_and_configure_account" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts.CreateAndConfigureAccountRequest.pb( + accounts.CreateAndConfigureAccountRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts.Account.to_json(accounts.Account()) + req.return_value.content = return_value + + request = accounts.CreateAndConfigureAccountRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts.Account() + + client.create_and_configure_account( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_account_rest_bad_request(request_type=accounts.DeleteAccountRequest): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_account(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.DeleteAccountRequest, + dict, + ], +) +def test_delete_account_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_account(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_account_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), + ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_delete_account" + ) as pre: + pre.assert_not_called() + pb_message = accounts.DeleteAccountRequest.pb(accounts.DeleteAccountRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = accounts.DeleteAccountRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_account( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_update_account_rest_bad_request(request_type=accounts.UpdateAccountRequest): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"account": {"name": "accounts/sample1"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_account(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.UpdateAccountRequest, + dict, + ], +) +def test_update_account_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"account": {"name": "accounts/sample1"}} + request_init["account"] = { + "name": "accounts/sample1", + "account_id": 1049, + "account_name": "account_name_value", + "adult_content": True, + "test_account": True, + "time_zone": {"id": "id_value", "version": "version_value"}, + "language_code": "language_code_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = accounts.UpdateAccountRequest.meta.fields["account"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["account"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["account"][field])): + del request_init["account"][field][i][subfield] + else: + del request_init["account"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.Account( + name="name_value", + account_id=1049, + account_name="account_name_value", + adult_content=True, + test_account=True, + language_code="language_code_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.Account.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_account(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, accounts.Account) + assert response.name == "name_value" + assert response.account_id == 1049 + assert response.account_name == "account_name_value" + assert response.adult_content is True + assert response.test_account is True + assert response.language_code == "language_code_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_account_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), + ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "post_update_account" + ) as post, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_update_account" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts.UpdateAccountRequest.pb(accounts.UpdateAccountRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts.Account.to_json(accounts.Account()) + req.return_value.content = return_value + + request = accounts.UpdateAccountRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts.Account() + + client.update_account( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_accounts_rest_bad_request(request_type=accounts.ListAccountsRequest): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_accounts(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.ListAccountsRequest, + dict, + ], +) +def test_list_accounts_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.ListAccountsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.ListAccountsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_accounts(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAccountsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_accounts_rest_interceptors(null_interceptor): + transport = transports.AccountsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AccountsServiceRestInterceptor(), + ) + client = AccountsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AccountsServiceRestInterceptor, "post_list_accounts" + ) as post, mock.patch.object( + transports.AccountsServiceRestInterceptor, "pre_list_accounts" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = accounts.ListAccountsRequest.pb(accounts.ListAccountsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = accounts.ListAccountsResponse.to_json( + accounts.ListAccountsResponse() + ) + req.return_value.content = return_value + + request = accounts.ListAccountsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = accounts.ListAccountsResponse() + + client.list_accounts( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_sub_accounts_rest_bad_request( + request_type=accounts.ListSubAccountsRequest, +): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"provider": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_sub_accounts(request) + + +@pytest.mark.parametrize( + "request_type", + [ + accounts.ListSubAccountsRequest, + dict, + ], +) +def test_list_sub_accounts_rest_call_success(request_type): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"provider": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = accounts.ListSubAccountsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = accounts.ListSubAccountsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_sub_accounts(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubAccountsPager) + assert response.next_page_token == "next_page_token_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) def test_list_sub_accounts_rest_interceptors(null_interceptor): transport = transports.AccountsServiceRestTransport( @@ -5182,6 +5475,7 @@ def test_list_sub_accounts_rest_interceptors(null_interceptor): else transports.AccountsServiceRestInterceptor(), ) client = AccountsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -5203,12 +5497,12 @@ def test_list_sub_accounts_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = accounts.ListSubAccountsResponse.to_json( + return_value = accounts.ListSubAccountsResponse.to_json( accounts.ListSubAccountsResponse() ) + req.return_value.content = return_value request = accounts.ListSubAccountsRequest() metadata = [ @@ -5230,252 +5524,135 @@ def test_list_sub_accounts_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_sub_accounts_rest_bad_request( - transport: str = "rest", request_type=accounts.ListSubAccountsRequest -): +def test_initialize_client_w_rest(): client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"provider": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_sub_accounts(request) + assert client is not None -def test_list_sub_accounts_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_account_empty_call_rest(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = accounts.ListSubAccountsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"provider": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - provider="provider_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = accounts.ListSubAccountsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_account), "__call__") as call: + client.get_account(request=None) - client.list_sub_accounts(**mock_args) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.GetAccountRequest() - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{provider=accounts/*}:listSubaccounts" - % client.transport._host, - args[1], - ) + assert args[0] == request_msg -def test_list_sub_accounts_rest_flattened_error(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_and_configure_account_empty_call_rest(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_sub_accounts( - accounts.ListSubAccountsRequest(), - provider="provider_value", - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_and_configure_account), "__call__" + ) as call: + client.create_and_configure_account(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.CreateAndConfigureAccountRequest() + assert args[0] == request_msg -def test_list_sub_accounts_rest_pager(transport: str = "rest"): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_account_empty_call_rest(): client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - accounts.ListSubAccountsResponse( - accounts=[ - accounts.Account(), - accounts.Account(), - accounts.Account(), - ], - next_page_token="abc", - ), - accounts.ListSubAccountsResponse( - accounts=[], - next_page_token="def", - ), - accounts.ListSubAccountsResponse( - accounts=[ - accounts.Account(), - ], - next_page_token="ghi", - ), - accounts.ListSubAccountsResponse( - accounts=[ - accounts.Account(), - accounts.Account(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(accounts.ListSubAccountsResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"provider": "accounts/sample1"} - - pager = client.list_sub_accounts(request=sample_request) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_account), "__call__") as call: + client.delete_account(request=None) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, accounts.Account) for i in results) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.DeleteAccountRequest() - pages = list(client.list_sub_accounts(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + assert args[0] == request_msg -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.AccountsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_account_empty_call_rest(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_account), "__call__") as call: + client.update_account(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.UpdateAccountRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.AccountsServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_accounts_empty_call_rest(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = AccountsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_accounts), "__call__") as call: + client.list_accounts(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = AccountsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListAccountsRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.AccountsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.AccountsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_sub_accounts_empty_call_rest(): + client = AccountsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.AccountsServiceGrpcTransport, - transports.AccountsServiceGrpcAsyncIOTransport, - transports.AccountsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_sub_accounts), "__call__" + ) as call: + client.list_sub_accounts(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = accounts.ListSubAccountsRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = AccountsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -6110,36 +6287,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = AccountsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = AccountsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = AccountsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py index 0c01e92c6a8c..6d063dc27aed 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_autofeed_settings_service.py @@ -22,19 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + from google.shopping.merchant_accounts_v1beta.services.autofeed_settings_service import ( AutofeedSettingsServiceAsyncClient, AutofeedSettingsServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import autofeedsettings +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1231,27 +1254,6 @@ def test_get_autofeed_settings(request_type, transport: str = "grpc"): assert response.eligible is True -def test_get_autofeed_settings_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_autofeed_settings), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_autofeed_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == autofeedsettings.GetAutofeedSettingsRequest() - - def test_get_autofeed_settings_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1322,33 +1324,6 @@ def test_get_autofeed_settings_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_autofeed_settings_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_autofeed_settings), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - autofeedsettings.AutofeedSettings( - name="name_value", - enable_products=True, - eligible=True, - ) - ) - response = await client.get_autofeed_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == autofeedsettings.GetAutofeedSettingsRequest() - - @pytest.mark.asyncio async def test_get_autofeed_settings_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1357,7 +1332,7 @@ async def test_get_autofeed_settings_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1397,7 +1372,7 @@ async def test_get_autofeed_settings_async( request_type=autofeedsettings.GetAutofeedSettingsRequest, ): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1471,7 +1446,7 @@ def test_get_autofeed_settings_field_headers(): @pytest.mark.asyncio async def test_get_autofeed_settings_field_headers_async(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1545,7 +1520,7 @@ def test_get_autofeed_settings_flattened_error(): @pytest.mark.asyncio async def test_get_autofeed_settings_flattened_async(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1576,7 +1551,7 @@ async def test_get_autofeed_settings_flattened_async(): @pytest.mark.asyncio async def test_get_autofeed_settings_flattened_error_async(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1630,27 +1605,6 @@ def test_update_autofeed_settings(request_type, transport: str = "grpc"): assert response.eligible is True -def test_update_autofeed_settings_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_autofeed_settings), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_autofeed_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == autofeedsettings.UpdateAutofeedSettingsRequest() - - def test_update_autofeed_settings_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1717,33 +1671,6 @@ def test_update_autofeed_settings_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_autofeed_settings_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_autofeed_settings), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - autofeedsettings.AutofeedSettings( - name="name_value", - enable_products=True, - eligible=True, - ) - ) - response = await client.update_autofeed_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == autofeedsettings.UpdateAutofeedSettingsRequest() - - @pytest.mark.asyncio async def test_update_autofeed_settings_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1752,7 +1679,7 @@ async def test_update_autofeed_settings_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1792,7 +1719,7 @@ async def test_update_autofeed_settings_async( request_type=autofeedsettings.UpdateAutofeedSettingsRequest, ): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1866,7 +1793,7 @@ def test_update_autofeed_settings_field_headers(): @pytest.mark.asyncio async def test_update_autofeed_settings_field_headers_async(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1945,7 +1872,7 @@ def test_update_autofeed_settings_flattened_error(): @pytest.mark.asyncio async def test_update_autofeed_settings_flattened_async(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1980,7 +1907,7 @@ async def test_update_autofeed_settings_flattened_async(): @pytest.mark.asyncio async def test_update_autofeed_settings_flattened_error_async(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1993,50 +1920,6 @@ async def test_update_autofeed_settings_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - autofeedsettings.GetAutofeedSettingsRequest, - dict, - ], -) -def test_get_autofeed_settings_rest(request_type): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/autofeedSettings"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = autofeedsettings.AutofeedSettings( - name="name_value", - enable_products=True, - eligible=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = autofeedsettings.AutofeedSettings.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_autofeed_settings(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, autofeedsettings.AutofeedSettings) - assert response.name == "name_value" - assert response.enable_products is True - assert response.eligible is True - - def test_get_autofeed_settings_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2161,87 +2044,6 @@ def test_get_autofeed_settings_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_autofeed_settings_rest_interceptors(null_interceptor): - transport = transports.AutofeedSettingsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.AutofeedSettingsServiceRestInterceptor(), - ) - client = AutofeedSettingsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.AutofeedSettingsServiceRestInterceptor, "post_get_autofeed_settings" - ) as post, mock.patch.object( - transports.AutofeedSettingsServiceRestInterceptor, "pre_get_autofeed_settings" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = autofeedsettings.GetAutofeedSettingsRequest.pb( - autofeedsettings.GetAutofeedSettingsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = autofeedsettings.AutofeedSettings.to_json( - autofeedsettings.AutofeedSettings() - ) - - request = autofeedsettings.GetAutofeedSettingsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = autofeedsettings.AutofeedSettings() - - client.get_autofeed_settings( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_autofeed_settings_rest_bad_request( - transport: str = "rest", request_type=autofeedsettings.GetAutofeedSettingsRequest -): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/autofeedSettings"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_autofeed_settings(request) - - def test_get_autofeed_settings_rest_flattened(): client = AutofeedSettingsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2299,142 +2101,18 @@ def test_get_autofeed_settings_rest_flattened_error(transport: str = "rest"): ) -def test_get_autofeed_settings_rest_error(): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_autofeed_settings_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - -@pytest.mark.parametrize( - "request_type", - [ - autofeedsettings.UpdateAutofeedSettingsRequest, - dict, - ], -) -def test_update_autofeed_settings_rest(request_type): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"autofeed_settings": {"name": "accounts/sample1/autofeedSettings"}} - request_init["autofeed_settings"] = { - "name": "accounts/sample1/autofeedSettings", - "enable_products": True, - "eligible": True, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = autofeedsettings.UpdateAutofeedSettingsRequest.meta.fields[ - "autofeed_settings" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["autofeed_settings"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["autofeed_settings"][field])): - del request_init["autofeed_settings"][field][i][subfield] - else: - del request_init["autofeed_settings"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = autofeedsettings.AutofeedSettings( - name="name_value", - enable_products=True, - eligible=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = autofeedsettings.AutofeedSettings.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_autofeed_settings(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, autofeedsettings.AutofeedSettings) - assert response.name == "name_value" - assert response.enable_products is True - assert response.eligible is True - - -def test_update_autofeed_settings_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() # Ensure method has been cached assert ( @@ -2531,26 +2209,588 @@ def test_update_autofeed_settings_rest_required_fields( response = client.update_autofeed_settings(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_autofeed_settings_rest_unset_required_fields(): + transport = transports.AutofeedSettingsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_autofeed_settings._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "autofeedSettings", + "updateMask", + ) + ) + ) + + +def test_update_autofeed_settings_rest_flattened(): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = autofeedsettings.AutofeedSettings() + + # get arguments that satisfy an http rule for this method + sample_request = { + "autofeed_settings": {"name": "accounts/sample1/autofeedSettings"} + } + + # get truthy value for each flattened field + mock_args = dict( + autofeed_settings=autofeedsettings.AutofeedSettings(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = autofeedsettings.AutofeedSettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_autofeed_settings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{autofeed_settings.name=accounts/*/autofeedSettings}" + % client.transport._host, + args[1], + ) + + +def test_update_autofeed_settings_rest_flattened_error(transport: str = "rest"): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_autofeed_settings( + autofeedsettings.UpdateAutofeedSettingsRequest(), + autofeed_settings=autofeedsettings.AutofeedSettings(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AutofeedSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AutofeedSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AutofeedSettingsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AutofeedSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AutofeedSettingsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AutofeedSettingsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AutofeedSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AutofeedSettingsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AutofeedSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AutofeedSettingsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AutofeedSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AutofeedSettingsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AutofeedSettingsServiceGrpcTransport, + transports.AutofeedSettingsServiceGrpcAsyncIOTransport, + transports.AutofeedSettingsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = AutofeedSettingsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_autofeed_settings_empty_call_grpc(): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_autofeed_settings), "__call__" + ) as call: + call.return_value = autofeedsettings.AutofeedSettings() + client.get_autofeed_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = autofeedsettings.GetAutofeedSettingsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_autofeed_settings_empty_call_grpc(): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_autofeed_settings), "__call__" + ) as call: + call.return_value = autofeedsettings.AutofeedSettings() + client.update_autofeed_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = autofeedsettings.UpdateAutofeedSettingsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AutofeedSettingsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AutofeedSettingsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_autofeed_settings_empty_call_grpc_asyncio(): + client = AutofeedSettingsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_autofeed_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + autofeedsettings.AutofeedSettings( + name="name_value", + enable_products=True, + eligible=True, + ) + ) + await client.get_autofeed_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = autofeedsettings.GetAutofeedSettingsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_autofeed_settings_empty_call_grpc_asyncio(): + client = AutofeedSettingsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_autofeed_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + autofeedsettings.AutofeedSettings( + name="name_value", + enable_products=True, + eligible=True, + ) + ) + await client.update_autofeed_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = autofeedsettings.UpdateAutofeedSettingsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AutofeedSettingsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_autofeed_settings_rest_bad_request( + request_type=autofeedsettings.GetAutofeedSettingsRequest, +): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/autofeedSettings"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_autofeed_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + autofeedsettings.GetAutofeedSettingsRequest, + dict, + ], +) +def test_get_autofeed_settings_rest_call_success(request_type): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/autofeedSettings"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = autofeedsettings.AutofeedSettings( + name="name_value", + enable_products=True, + eligible=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = autofeedsettings.AutofeedSettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_autofeed_settings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, autofeedsettings.AutofeedSettings) + assert response.name == "name_value" + assert response.enable_products is True + assert response.eligible is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_autofeed_settings_rest_interceptors(null_interceptor): + transport = transports.AutofeedSettingsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AutofeedSettingsServiceRestInterceptor(), + ) + client = AutofeedSettingsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AutofeedSettingsServiceRestInterceptor, "post_get_autofeed_settings" + ) as post, mock.patch.object( + transports.AutofeedSettingsServiceRestInterceptor, "pre_get_autofeed_settings" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = autofeedsettings.GetAutofeedSettingsRequest.pb( + autofeedsettings.GetAutofeedSettingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = autofeedsettings.AutofeedSettings.to_json( + autofeedsettings.AutofeedSettings() + ) + req.return_value.content = return_value + + request = autofeedsettings.GetAutofeedSettingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = autofeedsettings.AutofeedSettings() + + client.get_autofeed_settings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_autofeed_settings_rest_bad_request( + request_type=autofeedsettings.UpdateAutofeedSettingsRequest, +): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"autofeed_settings": {"name": "accounts/sample1/autofeedSettings"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_autofeed_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + autofeedsettings.UpdateAutofeedSettingsRequest, + dict, + ], +) +def test_update_autofeed_settings_rest_call_success(request_type): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"autofeed_settings": {"name": "accounts/sample1/autofeedSettings"}} + request_init["autofeed_settings"] = { + "name": "accounts/sample1/autofeedSettings", + "enable_products": True, + "eligible": True, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = autofeedsettings.UpdateAutofeedSettingsRequest.meta.fields[ + "autofeed_settings" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["autofeed_settings"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["autofeed_settings"][field])): + del request_init["autofeed_settings"][field][i][subfield] + else: + del request_init["autofeed_settings"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = autofeedsettings.AutofeedSettings( + name="name_value", + enable_products=True, + eligible=True, + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_update_autofeed_settings_rest_unset_required_fields(): - transport = transports.AutofeedSettingsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = autofeedsettings.AutofeedSettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_autofeed_settings(request) - unset_fields = transport.update_autofeed_settings._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("updateMask",)) - & set( - ( - "autofeedSettings", - "updateMask", - ) - ) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, autofeedsettings.AutofeedSettings) + assert response.name == "name_value" + assert response.enable_products is True + assert response.eligible is True @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -2562,6 +2802,7 @@ def test_update_autofeed_settings_rest_interceptors(null_interceptor): else transports.AutofeedSettingsServiceRestInterceptor(), ) client = AutofeedSettingsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2585,12 +2826,12 @@ def test_update_autofeed_settings_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = autofeedsettings.AutofeedSettings.to_json( + return_value = autofeedsettings.AutofeedSettings.to_json( autofeedsettings.AutofeedSettings() ) + req.return_value.content = return_value request = autofeedsettings.UpdateAutofeedSettingsRequest() metadata = [ @@ -2612,201 +2853,55 @@ def test_update_autofeed_settings_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_autofeed_settings_rest_bad_request( - transport: str = "rest", request_type=autofeedsettings.UpdateAutofeedSettingsRequest -): +def test_initialize_client_w_rest(): client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"autofeed_settings": {"name": "accounts/sample1/autofeedSettings"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_autofeed_settings(request) + assert client is not None -def test_update_autofeed_settings_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_autofeed_settings_empty_call_rest(): client = AutofeedSettingsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = autofeedsettings.AutofeedSettings() - - # get arguments that satisfy an http rule for this method - sample_request = { - "autofeed_settings": {"name": "accounts/sample1/autofeedSettings"} - } - - # get truthy value for each flattened field - mock_args = dict( - autofeed_settings=autofeedsettings.AutofeedSettings(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = autofeedsettings.AutofeedSettings.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_autofeed_settings(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{autofeed_settings.name=accounts/*/autofeedSettings}" - % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_autofeed_settings), "__call__" + ) as call: + client.get_autofeed_settings(request=None) -def test_update_autofeed_settings_rest_flattened_error(transport: str = "rest"): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = autofeedsettings.GetAutofeedSettingsRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_autofeed_settings( - autofeedsettings.UpdateAutofeedSettingsRequest(), - autofeed_settings=autofeedsettings.AutofeedSettings(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + assert args[0] == request_msg -def test_update_autofeed_settings_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_autofeed_settings_empty_call_rest(): client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.AutofeedSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.AutofeedSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AutofeedSettingsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.AutofeedSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AutofeedSettingsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = AutofeedSettingsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.AutofeedSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = AutofeedSettingsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.AutofeedSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = AutofeedSettingsServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.AutofeedSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.AutofeedSettingsServiceGrpcAsyncIOTransport( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.AutofeedSettingsServiceGrpcTransport, - transports.AutofeedSettingsServiceGrpcAsyncIOTransport, - transports.AutofeedSettingsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_autofeed_settings), "__call__" + ) as call: + client.update_autofeed_settings(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = autofeedsettings.UpdateAutofeedSettingsRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = AutofeedSettingsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3386,36 +3481,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = AutofeedSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = AutofeedSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = AutofeedSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py index f4566fff4b42..ecd88e7315f2 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_identity_service.py @@ -22,19 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + from google.shopping.merchant_accounts_v1beta.services.business_identity_service import ( BusinessIdentityServiceAsyncClient, BusinessIdentityServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import businessidentity +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1232,27 +1255,6 @@ def test_get_business_identity(request_type, transport: str = "grpc"): ) -def test_get_business_identity_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_business_identity), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_business_identity() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessidentity.GetBusinessIdentityRequest() - - def test_get_business_identity_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1323,32 +1325,6 @@ def test_get_business_identity_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_business_identity_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_business_identity), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - businessidentity.BusinessIdentity( - name="name_value", - promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, - ) - ) - response = await client.get_business_identity() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessidentity.GetBusinessIdentityRequest() - - @pytest.mark.asyncio async def test_get_business_identity_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1357,7 +1333,7 @@ async def test_get_business_identity_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1397,7 +1373,7 @@ async def test_get_business_identity_async( request_type=businessidentity.GetBusinessIdentityRequest, ): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1472,7 +1448,7 @@ def test_get_business_identity_field_headers(): @pytest.mark.asyncio async def test_get_business_identity_field_headers_async(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1546,7 +1522,7 @@ def test_get_business_identity_flattened_error(): @pytest.mark.asyncio async def test_get_business_identity_flattened_async(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1577,7 +1553,7 @@ async def test_get_business_identity_flattened_async(): @pytest.mark.asyncio async def test_get_business_identity_flattened_error_async(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1632,27 +1608,6 @@ def test_update_business_identity(request_type, transport: str = "grpc"): ) -def test_update_business_identity_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_business_identity), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_business_identity() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessidentity.UpdateBusinessIdentityRequest() - - def test_update_business_identity_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1719,32 +1674,6 @@ def test_update_business_identity_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_business_identity_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_business_identity), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - businessidentity.BusinessIdentity( - name="name_value", - promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, - ) - ) - response = await client.update_business_identity() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessidentity.UpdateBusinessIdentityRequest() - - @pytest.mark.asyncio async def test_update_business_identity_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1753,7 +1682,7 @@ async def test_update_business_identity_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1793,7 +1722,7 @@ async def test_update_business_identity_async( request_type=businessidentity.UpdateBusinessIdentityRequest, ): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1868,7 +1797,7 @@ def test_update_business_identity_field_headers(): @pytest.mark.asyncio async def test_update_business_identity_field_headers_async(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1947,7 +1876,7 @@ def test_update_business_identity_flattened_error(): @pytest.mark.asyncio async def test_update_business_identity_flattened_async(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1982,7 +1911,7 @@ async def test_update_business_identity_flattened_async(): @pytest.mark.asyncio async def test_update_business_identity_flattened_error_async(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1995,51 +1924,6 @@ async def test_update_business_identity_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - businessidentity.GetBusinessIdentityRequest, - dict, - ], -) -def test_get_business_identity_rest(request_type): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/businessIdentity"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = businessidentity.BusinessIdentity( - name="name_value", - promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = businessidentity.BusinessIdentity.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_business_identity(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, businessidentity.BusinessIdentity) - assert response.name == "name_value" - assert ( - response.promotions_consent - == businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN - ) - - def test_get_business_identity_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2164,87 +2048,6 @@ def test_get_business_identity_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_business_identity_rest_interceptors(null_interceptor): - transport = transports.BusinessIdentityServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.BusinessIdentityServiceRestInterceptor(), - ) - client = BusinessIdentityServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.BusinessIdentityServiceRestInterceptor, "post_get_business_identity" - ) as post, mock.patch.object( - transports.BusinessIdentityServiceRestInterceptor, "pre_get_business_identity" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = businessidentity.GetBusinessIdentityRequest.pb( - businessidentity.GetBusinessIdentityRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = businessidentity.BusinessIdentity.to_json( - businessidentity.BusinessIdentity() - ) - - request = businessidentity.GetBusinessIdentityRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = businessidentity.BusinessIdentity() - - client.get_business_identity( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_business_identity_rest_bad_request( - transport: str = "rest", request_type=businessidentity.GetBusinessIdentityRequest -): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/businessIdentity"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_business_identity(request) - - def test_get_business_identity_rest_flattened(): client = BusinessIdentityServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2302,147 +2105,18 @@ def test_get_business_identity_rest_flattened_error(transport: str = "rest"): ) -def test_get_business_identity_rest_error(): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_business_identity_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - -@pytest.mark.parametrize( - "request_type", - [ - businessidentity.UpdateBusinessIdentityRequest, - dict, - ], -) -def test_update_business_identity_rest(request_type): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"business_identity": {"name": "accounts/sample1/businessIdentity"}} - request_init["business_identity"] = { - "name": "accounts/sample1/businessIdentity", - "promotions_consent": 1, - "black_owned": {"identity_declaration": 1}, - "women_owned": {}, - "veteran_owned": {}, - "latino_owned": {}, - "small_business": {}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = businessidentity.UpdateBusinessIdentityRequest.meta.fields[ - "business_identity" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["business_identity"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["business_identity"][field])): - del request_init["business_identity"][field][i][subfield] - else: - del request_init["business_identity"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = businessidentity.BusinessIdentity( - name="name_value", - promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = businessidentity.BusinessIdentity.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_business_identity(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, businessidentity.BusinessIdentity) - assert response.name == "name_value" - assert ( - response.promotions_consent - == businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN - ) - - -def test_update_business_identity_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() # Ensure method has been cached assert ( @@ -2539,25 +2213,591 @@ def test_update_business_identity_rest_required_fields( response = client.update_business_identity(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_business_identity_rest_unset_required_fields(): + transport = transports.BusinessIdentityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_business_identity._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "businessIdentity", + "updateMask", + ) + ) + ) + + +def test_update_business_identity_rest_flattened(): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = businessidentity.BusinessIdentity() + + # get arguments that satisfy an http rule for this method + sample_request = { + "business_identity": {"name": "accounts/sample1/businessIdentity"} + } + + # get truthy value for each flattened field + mock_args = dict( + business_identity=businessidentity.BusinessIdentity(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = businessidentity.BusinessIdentity.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_business_identity(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{business_identity.name=accounts/*/businessIdentity}" + % client.transport._host, + args[1], + ) + + +def test_update_business_identity_rest_flattened_error(transport: str = "rest"): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_business_identity( + businessidentity.UpdateBusinessIdentityRequest(), + business_identity=businessidentity.BusinessIdentity(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.BusinessIdentityServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.BusinessIdentityServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BusinessIdentityServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.BusinessIdentityServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BusinessIdentityServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BusinessIdentityServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.BusinessIdentityServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BusinessIdentityServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.BusinessIdentityServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = BusinessIdentityServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.BusinessIdentityServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.BusinessIdentityServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.BusinessIdentityServiceGrpcTransport, + transports.BusinessIdentityServiceGrpcAsyncIOTransport, + transports.BusinessIdentityServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = BusinessIdentityServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_business_identity_empty_call_grpc(): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_business_identity), "__call__" + ) as call: + call.return_value = businessidentity.BusinessIdentity() + client.get_business_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessidentity.GetBusinessIdentityRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_business_identity_empty_call_grpc(): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_business_identity), "__call__" + ) as call: + call.return_value = businessidentity.BusinessIdentity() + client.update_business_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessidentity.UpdateBusinessIdentityRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = BusinessIdentityServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = BusinessIdentityServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_business_identity_empty_call_grpc_asyncio(): + client = BusinessIdentityServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_business_identity), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + businessidentity.BusinessIdentity( + name="name_value", + promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, + ) + ) + await client.get_business_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessidentity.GetBusinessIdentityRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_business_identity_empty_call_grpc_asyncio(): + client = BusinessIdentityServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_business_identity), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + businessidentity.BusinessIdentity( + name="name_value", + promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, + ) + ) + await client.update_business_identity(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessidentity.UpdateBusinessIdentityRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = BusinessIdentityServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_business_identity_rest_bad_request( + request_type=businessidentity.GetBusinessIdentityRequest, +): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/businessIdentity"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_business_identity(request) + + +@pytest.mark.parametrize( + "request_type", + [ + businessidentity.GetBusinessIdentityRequest, + dict, + ], +) +def test_get_business_identity_rest_call_success(request_type): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/businessIdentity"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = businessidentity.BusinessIdentity( + name="name_value", + promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = businessidentity.BusinessIdentity.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_business_identity(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, businessidentity.BusinessIdentity) + assert response.name == "name_value" + assert ( + response.promotions_consent + == businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_business_identity_rest_interceptors(null_interceptor): + transport = transports.BusinessIdentityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.BusinessIdentityServiceRestInterceptor(), + ) + client = BusinessIdentityServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.BusinessIdentityServiceRestInterceptor, "post_get_business_identity" + ) as post, mock.patch.object( + transports.BusinessIdentityServiceRestInterceptor, "pre_get_business_identity" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = businessidentity.GetBusinessIdentityRequest.pb( + businessidentity.GetBusinessIdentityRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = businessidentity.BusinessIdentity.to_json( + businessidentity.BusinessIdentity() + ) + req.return_value.content = return_value + + request = businessidentity.GetBusinessIdentityRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = businessidentity.BusinessIdentity() + + client.get_business_identity( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_business_identity_rest_bad_request( + request_type=businessidentity.UpdateBusinessIdentityRequest, +): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"business_identity": {"name": "accounts/sample1/businessIdentity"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_business_identity(request) + + +@pytest.mark.parametrize( + "request_type", + [ + businessidentity.UpdateBusinessIdentityRequest, + dict, + ], +) +def test_update_business_identity_rest_call_success(request_type): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"business_identity": {"name": "accounts/sample1/businessIdentity"}} + request_init["business_identity"] = { + "name": "accounts/sample1/businessIdentity", + "promotions_consent": 1, + "black_owned": {"identity_declaration": 1}, + "women_owned": {}, + "veteran_owned": {}, + "latino_owned": {}, + "small_business": {}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = businessidentity.UpdateBusinessIdentityRequest.meta.fields[ + "business_identity" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["business_identity"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["business_identity"][field])): + del request_init["business_identity"][field][i][subfield] + else: + del request_init["business_identity"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = businessidentity.BusinessIdentity( + name="name_value", + promotions_consent=businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN, + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_update_business_identity_rest_unset_required_fields(): - transport = transports.BusinessIdentityServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = businessidentity.BusinessIdentity.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_business_identity(request) - unset_fields = transport.update_business_identity._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("updateMask",)) - & set( - ( - "businessIdentity", - "updateMask", - ) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, businessidentity.BusinessIdentity) + assert response.name == "name_value" + assert ( + response.promotions_consent + == businessidentity.BusinessIdentity.PromotionsConsent.PROMOTIONS_CONSENT_GIVEN ) @@ -2570,6 +2810,7 @@ def test_update_business_identity_rest_interceptors(null_interceptor): else transports.BusinessIdentityServiceRestInterceptor(), ) client = BusinessIdentityServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2593,12 +2834,12 @@ def test_update_business_identity_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = businessidentity.BusinessIdentity.to_json( + return_value = businessidentity.BusinessIdentity.to_json( businessidentity.BusinessIdentity() ) + req.return_value.content = return_value request = businessidentity.UpdateBusinessIdentityRequest() metadata = [ @@ -2620,201 +2861,55 @@ def test_update_business_identity_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_business_identity_rest_bad_request( - transport: str = "rest", request_type=businessidentity.UpdateBusinessIdentityRequest -): +def test_initialize_client_w_rest(): client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"business_identity": {"name": "accounts/sample1/businessIdentity"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_business_identity(request) + assert client is not None -def test_update_business_identity_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_business_identity_empty_call_rest(): client = BusinessIdentityServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = businessidentity.BusinessIdentity() - - # get arguments that satisfy an http rule for this method - sample_request = { - "business_identity": {"name": "accounts/sample1/businessIdentity"} - } - - # get truthy value for each flattened field - mock_args = dict( - business_identity=businessidentity.BusinessIdentity(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = businessidentity.BusinessIdentity.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_business_identity(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{business_identity.name=accounts/*/businessIdentity}" - % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_business_identity), "__call__" + ) as call: + client.get_business_identity(request=None) -def test_update_business_identity_rest_flattened_error(transport: str = "rest"): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessidentity.GetBusinessIdentityRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_business_identity( - businessidentity.UpdateBusinessIdentityRequest(), - business_identity=businessidentity.BusinessIdentity(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + assert args[0] == request_msg -def test_update_business_identity_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_business_identity_empty_call_rest(): client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.BusinessIdentityServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.BusinessIdentityServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = BusinessIdentityServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.BusinessIdentityServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = BusinessIdentityServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = BusinessIdentityServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.BusinessIdentityServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = BusinessIdentityServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.BusinessIdentityServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = BusinessIdentityServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.BusinessIdentityServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.BusinessIdentityServiceGrpcAsyncIOTransport( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.BusinessIdentityServiceGrpcTransport, - transports.BusinessIdentityServiceGrpcAsyncIOTransport, - transports.BusinessIdentityServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_business_identity), "__call__" + ) as call: + client.update_business_identity(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessidentity.UpdateBusinessIdentityRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = BusinessIdentityServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3394,36 +3489,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = BusinessIdentityServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = BusinessIdentityServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = BusinessIdentityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py index e2e4eb7c38fb..73c21741b070 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_business_info_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,16 +52,8 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.type import phone_number_pb2 # type: ignore from google.type import postal_address_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_accounts_v1beta.services.business_info_service import ( BusinessInfoServiceAsyncClient, @@ -58,10 +67,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1239,27 +1262,6 @@ def test_get_business_info(request_type, transport: str = "grpc"): ) -def test_get_business_info_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_business_info), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_business_info() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessinfo.GetBusinessInfoRequest() - - def test_get_business_info_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1327,33 +1329,6 @@ def test_get_business_info_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_business_info_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_business_info), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - businessinfo.BusinessInfo( - name="name_value", - phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, - korean_business_registration_number="korean_business_registration_number_value", - ) - ) - response = await client.get_business_info() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessinfo.GetBusinessInfoRequest() - - @pytest.mark.asyncio async def test_get_business_info_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1362,7 +1337,7 @@ async def test_get_business_info_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1401,7 +1376,7 @@ async def test_get_business_info_async( transport: str = "grpc_asyncio", request_type=businessinfo.GetBusinessInfoRequest ): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1481,7 +1456,7 @@ def test_get_business_info_field_headers(): @pytest.mark.asyncio async def test_get_business_info_field_headers_async(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1555,7 +1530,7 @@ def test_get_business_info_flattened_error(): @pytest.mark.asyncio async def test_get_business_info_flattened_async(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1586,7 +1561,7 @@ async def test_get_business_info_flattened_async(): @pytest.mark.asyncio async def test_get_business_info_flattened_error_async(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1646,27 +1621,6 @@ def test_update_business_info(request_type, transport: str = "grpc"): ) -def test_update_business_info_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_business_info), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_business_info() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessinfo.UpdateBusinessInfoRequest() - - def test_update_business_info_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1732,33 +1686,6 @@ def test_update_business_info_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_business_info_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_business_info), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - businessinfo.BusinessInfo( - name="name_value", - phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, - korean_business_registration_number="korean_business_registration_number_value", - ) - ) - response = await client.update_business_info() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == businessinfo.UpdateBusinessInfoRequest() - - @pytest.mark.asyncio async def test_update_business_info_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1767,7 +1694,7 @@ async def test_update_business_info_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1806,7 +1733,7 @@ async def test_update_business_info_async( transport: str = "grpc_asyncio", request_type=businessinfo.UpdateBusinessInfoRequest ): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1886,7 +1813,7 @@ def test_update_business_info_field_headers(): @pytest.mark.asyncio async def test_update_business_info_field_headers_async(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1965,7 +1892,7 @@ def test_update_business_info_flattened_error(): @pytest.mark.asyncio async def test_update_business_info_flattened_async(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2000,7 +1927,7 @@ async def test_update_business_info_flattened_async(): @pytest.mark.asyncio async def test_update_business_info_flattened_error_async(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2013,56 +1940,6 @@ async def test_update_business_info_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - businessinfo.GetBusinessInfoRequest, - dict, - ], -) -def test_get_business_info_rest(request_type): - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/businessInfo"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = businessinfo.BusinessInfo( - name="name_value", - phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, - korean_business_registration_number="korean_business_registration_number_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = businessinfo.BusinessInfo.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_business_info(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, businessinfo.BusinessInfo) - assert response.name == "name_value" - assert ( - response.phone_verification_state - == phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED - ) - assert ( - response.korean_business_registration_number - == "korean_business_registration_number_value" - ) - - def test_get_business_info_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2184,87 +2061,6 @@ def test_get_business_info_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_business_info_rest_interceptors(null_interceptor): - transport = transports.BusinessInfoServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.BusinessInfoServiceRestInterceptor(), - ) - client = BusinessInfoServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.BusinessInfoServiceRestInterceptor, "post_get_business_info" - ) as post, mock.patch.object( - transports.BusinessInfoServiceRestInterceptor, "pre_get_business_info" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = businessinfo.GetBusinessInfoRequest.pb( - businessinfo.GetBusinessInfoRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = businessinfo.BusinessInfo.to_json( - businessinfo.BusinessInfo() - ) - - request = businessinfo.GetBusinessInfoRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = businessinfo.BusinessInfo() - - client.get_business_info( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_business_info_rest_bad_request( - transport: str = "rest", request_type=businessinfo.GetBusinessInfoRequest -): - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/businessInfo"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_business_info(request) - - def test_get_business_info_rest_flattened(): client = BusinessInfoServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2322,23 +2118,592 @@ def test_get_business_info_rest_flattened_error(transport: str = "rest"): ) -def test_get_business_info_rest_error(): - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_business_info_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - businessinfo.UpdateBusinessInfoRequest, + # Ensure method has been cached + assert ( + client._transport.update_business_info in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_business_info + ] = mock_rpc + + request = {} + client.update_business_info(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_business_info(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_business_info_rest_required_fields( + request_type=businessinfo.UpdateBusinessInfoRequest, +): + transport_class = transports.BusinessInfoServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_business_info._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_business_info._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = businessinfo.BusinessInfo() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = businessinfo.BusinessInfo.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_business_info(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_business_info_rest_unset_required_fields(): + transport = transports.BusinessInfoServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_business_info._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "businessInfo", + "updateMask", + ) + ) + ) + + +def test_update_business_info_rest_flattened(): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = businessinfo.BusinessInfo() + + # get arguments that satisfy an http rule for this method + sample_request = {"business_info": {"name": "accounts/sample1/businessInfo"}} + + # get truthy value for each flattened field + mock_args = dict( + business_info=businessinfo.BusinessInfo(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = businessinfo.BusinessInfo.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_business_info(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{business_info.name=accounts/*/businessInfo}" + % client.transport._host, + args[1], + ) + + +def test_update_business_info_rest_flattened_error(transport: str = "rest"): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_business_info( + businessinfo.UpdateBusinessInfoRequest(), + business_info=businessinfo.BusinessInfo(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.BusinessInfoServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.BusinessInfoServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BusinessInfoServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.BusinessInfoServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BusinessInfoServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BusinessInfoServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.BusinessInfoServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BusinessInfoServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.BusinessInfoServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = BusinessInfoServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.BusinessInfoServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.BusinessInfoServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.BusinessInfoServiceGrpcTransport, + transports.BusinessInfoServiceGrpcAsyncIOTransport, + transports.BusinessInfoServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = BusinessInfoServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_business_info_empty_call_grpc(): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_business_info), "__call__" + ) as call: + call.return_value = businessinfo.BusinessInfo() + client.get_business_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessinfo.GetBusinessInfoRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_business_info_empty_call_grpc(): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_business_info), "__call__" + ) as call: + call.return_value = businessinfo.BusinessInfo() + client.update_business_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessinfo.UpdateBusinessInfoRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = BusinessInfoServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = BusinessInfoServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_business_info_empty_call_grpc_asyncio(): + client = BusinessInfoServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_business_info), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + businessinfo.BusinessInfo( + name="name_value", + phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, + korean_business_registration_number="korean_business_registration_number_value", + ) + ) + await client.get_business_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessinfo.GetBusinessInfoRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_business_info_empty_call_grpc_asyncio(): + client = BusinessInfoServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_business_info), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + businessinfo.BusinessInfo( + name="name_value", + phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, + korean_business_registration_number="korean_business_registration_number_value", + ) + ) + await client.update_business_info(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessinfo.UpdateBusinessInfoRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = BusinessInfoServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_business_info_rest_bad_request( + request_type=businessinfo.GetBusinessInfoRequest, +): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/businessInfo"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_business_info(request) + + +@pytest.mark.parametrize( + "request_type", + [ + businessinfo.GetBusinessInfoRequest, + dict, + ], +) +def test_get_business_info_rest_call_success(request_type): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/businessInfo"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = businessinfo.BusinessInfo( + name="name_value", + phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, + korean_business_registration_number="korean_business_registration_number_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = businessinfo.BusinessInfo.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_business_info(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, businessinfo.BusinessInfo) + assert response.name == "name_value" + assert ( + response.phone_verification_state + == phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED + ) + assert ( + response.korean_business_registration_number + == "korean_business_registration_number_value" + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_business_info_rest_interceptors(null_interceptor): + transport = transports.BusinessInfoServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.BusinessInfoServiceRestInterceptor(), + ) + client = BusinessInfoServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.BusinessInfoServiceRestInterceptor, "post_get_business_info" + ) as post, mock.patch.object( + transports.BusinessInfoServiceRestInterceptor, "pre_get_business_info" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = businessinfo.GetBusinessInfoRequest.pb( + businessinfo.GetBusinessInfoRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = businessinfo.BusinessInfo.to_json(businessinfo.BusinessInfo()) + req.return_value.content = return_value + + request = businessinfo.GetBusinessInfoRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = businessinfo.BusinessInfo() + + client.get_business_info( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_business_info_rest_bad_request( + request_type=businessinfo.UpdateBusinessInfoRequest, +): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"business_info": {"name": "accounts/sample1/businessInfo"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_business_info(request) + + +@pytest.mark.parametrize( + "request_type", + [ + businessinfo.UpdateBusinessInfoRequest, dict, ], ) -def test_update_business_info_rest(request_type): +def test_update_business_info_rest_call_success(request_type): client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding @@ -2430,174 +2795,45 @@ def get_message_fields(field): for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER field = subfield_to_delete.get("field") field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["business_info"][field])): - del request_init["business_info"][field][i][subfield] - else: - del request_init["business_info"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = businessinfo.BusinessInfo( - name="name_value", - phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, - korean_business_registration_number="korean_business_registration_number_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = businessinfo.BusinessInfo.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_business_info(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, businessinfo.BusinessInfo) - assert response.name == "name_value" - assert ( - response.phone_verification_state - == phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED - ) - assert ( - response.korean_business_registration_number - == "korean_business_registration_number_value" - ) - - -def test_update_business_info_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.update_business_info in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.update_business_info - ] = mock_rpc - - request = {} - client.update_business_info(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_business_info(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_business_info_rest_required_fields( - request_type=businessinfo.UpdateBusinessInfoRequest, -): - transport_class = transports.BusinessInfoServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_business_info._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_business_info._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = businessinfo.BusinessInfo() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = businessinfo.BusinessInfo.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["business_info"][field])): + del request_init["business_info"][field][i][subfield] + else: + del request_init["business_info"][field][subfield] + request = request_type(**request_init) - response = client.update_business_info(request) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = businessinfo.BusinessInfo( + name="name_value", + phone_verification_state=phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED, + korean_business_registration_number="korean_business_registration_number_value", + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = businessinfo.BusinessInfo.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_business_info(request) -def test_update_business_info_rest_unset_required_fields(): - transport = transports.BusinessInfoServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials + # Establish that the response is the type that we expect. + assert isinstance(response, businessinfo.BusinessInfo) + assert response.name == "name_value" + assert ( + response.phone_verification_state + == phoneverificationstate.PhoneVerificationState.PHONE_VERIFICATION_STATE_VERIFIED ) - - unset_fields = transport.update_business_info._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("updateMask",)) - & set( - ( - "businessInfo", - "updateMask", - ) - ) + assert ( + response.korean_business_registration_number + == "korean_business_registration_number_value" ) @@ -2610,6 +2846,7 @@ def test_update_business_info_rest_interceptors(null_interceptor): else transports.BusinessInfoServiceRestInterceptor(), ) client = BusinessInfoServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2631,12 +2868,10 @@ def test_update_business_info_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = businessinfo.BusinessInfo.to_json( - businessinfo.BusinessInfo() - ) + return_value = businessinfo.BusinessInfo.to_json(businessinfo.BusinessInfo()) + req.return_value.content = return_value request = businessinfo.UpdateBusinessInfoRequest() metadata = [ @@ -2658,199 +2893,55 @@ def test_update_business_info_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_business_info_rest_bad_request( - transport: str = "rest", request_type=businessinfo.UpdateBusinessInfoRequest -): +def test_initialize_client_w_rest(): client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"business_info": {"name": "accounts/sample1/businessInfo"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_business_info(request) + assert client is not None -def test_update_business_info_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_business_info_empty_call_rest(): client = BusinessInfoServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = businessinfo.BusinessInfo() - - # get arguments that satisfy an http rule for this method - sample_request = {"business_info": {"name": "accounts/sample1/businessInfo"}} - - # get truthy value for each flattened field - mock_args = dict( - business_info=businessinfo.BusinessInfo(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = businessinfo.BusinessInfo.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_business_info(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{business_info.name=accounts/*/businessInfo}" - % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_business_info), "__call__" + ) as call: + client.get_business_info(request=None) -def test_update_business_info_rest_flattened_error(transport: str = "rest"): - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessinfo.GetBusinessInfoRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_business_info( - businessinfo.UpdateBusinessInfoRequest(), - business_info=businessinfo.BusinessInfo(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + assert args[0] == request_msg -def test_update_business_info_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_business_info_empty_call_rest(): client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.BusinessInfoServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.BusinessInfoServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = BusinessInfoServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.BusinessInfoServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = BusinessInfoServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = BusinessInfoServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.BusinessInfoServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = BusinessInfoServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.BusinessInfoServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = BusinessInfoServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.BusinessInfoServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.BusinessInfoServiceGrpcAsyncIOTransport( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.BusinessInfoServiceGrpcTransport, - transports.BusinessInfoServiceGrpcAsyncIOTransport, - transports.BusinessInfoServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_business_info), "__call__" + ) as call: + client.update_business_info(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = businessinfo.UpdateBusinessInfoRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = BusinessInfoServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3428,36 +3519,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = BusinessInfoServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = BusinessInfoServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = BusinessInfoServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py index 6ae10d659323..338594ff2f62 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_email_preferences_service.py @@ -22,19 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + from google.shopping.merchant_accounts_v1beta.services.email_preferences_service import ( EmailPreferencesServiceAsyncClient, EmailPreferencesServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import emailpreferences +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1231,27 +1254,6 @@ def test_get_email_preferences(request_type, transport: str = "grpc"): ) -def test_get_email_preferences_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_email_preferences), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_email_preferences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == emailpreferences.GetEmailPreferencesRequest() - - def test_get_email_preferences_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1322,32 +1324,6 @@ def test_get_email_preferences_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_email_preferences_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_email_preferences), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - emailpreferences.EmailPreferences( - name="name_value", - news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, - ) - ) - response = await client.get_email_preferences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == emailpreferences.GetEmailPreferencesRequest() - - @pytest.mark.asyncio async def test_get_email_preferences_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1356,7 +1332,7 @@ async def test_get_email_preferences_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1396,7 +1372,7 @@ async def test_get_email_preferences_async( request_type=emailpreferences.GetEmailPreferencesRequest, ): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1470,7 +1446,7 @@ def test_get_email_preferences_field_headers(): @pytest.mark.asyncio async def test_get_email_preferences_field_headers_async(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1544,7 +1520,7 @@ def test_get_email_preferences_flattened_error(): @pytest.mark.asyncio async def test_get_email_preferences_flattened_async(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1575,7 +1551,7 @@ async def test_get_email_preferences_flattened_async(): @pytest.mark.asyncio async def test_get_email_preferences_flattened_error_async(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1629,27 +1605,6 @@ def test_update_email_preferences(request_type, transport: str = "grpc"): ) -def test_update_email_preferences_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_email_preferences), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_email_preferences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == emailpreferences.UpdateEmailPreferencesRequest() - - def test_update_email_preferences_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1716,32 +1671,6 @@ def test_update_email_preferences_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_email_preferences_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_email_preferences), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - emailpreferences.EmailPreferences( - name="name_value", - news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, - ) - ) - response = await client.update_email_preferences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == emailpreferences.UpdateEmailPreferencesRequest() - - @pytest.mark.asyncio async def test_update_email_preferences_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1750,7 +1679,7 @@ async def test_update_email_preferences_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1790,7 +1719,7 @@ async def test_update_email_preferences_async( request_type=emailpreferences.UpdateEmailPreferencesRequest, ): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1864,7 +1793,7 @@ def test_update_email_preferences_field_headers(): @pytest.mark.asyncio async def test_update_email_preferences_field_headers_async(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1943,7 +1872,7 @@ def test_update_email_preferences_flattened_error(): @pytest.mark.asyncio async def test_update_email_preferences_flattened_async(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1978,7 +1907,7 @@ async def test_update_email_preferences_flattened_async(): @pytest.mark.asyncio async def test_update_email_preferences_flattened_error_async(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1991,50 +1920,6 @@ async def test_update_email_preferences_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - emailpreferences.GetEmailPreferencesRequest, - dict, - ], -) -def test_get_email_preferences_rest(request_type): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/users/sample2/emailPreferences"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = emailpreferences.EmailPreferences( - name="name_value", - news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = emailpreferences.EmailPreferences.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_email_preferences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, emailpreferences.EmailPreferences) - assert response.name == "name_value" - assert ( - response.news_and_tips == emailpreferences.EmailPreferences.OptInState.OPTED_OUT - ) - - def test_get_email_preferences_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2159,87 +2044,6 @@ def test_get_email_preferences_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_email_preferences_rest_interceptors(null_interceptor): - transport = transports.EmailPreferencesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.EmailPreferencesServiceRestInterceptor(), - ) - client = EmailPreferencesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.EmailPreferencesServiceRestInterceptor, "post_get_email_preferences" - ) as post, mock.patch.object( - transports.EmailPreferencesServiceRestInterceptor, "pre_get_email_preferences" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = emailpreferences.GetEmailPreferencesRequest.pb( - emailpreferences.GetEmailPreferencesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = emailpreferences.EmailPreferences.to_json( - emailpreferences.EmailPreferences() - ) - - request = emailpreferences.GetEmailPreferencesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = emailpreferences.EmailPreferences() - - client.get_email_preferences( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_email_preferences_rest_bad_request( - transport: str = "rest", request_type=emailpreferences.GetEmailPreferencesRequest -): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/users/sample2/emailPreferences"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_email_preferences(request) - - def test_get_email_preferences_rest_flattened(): client = EmailPreferencesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2297,143 +2101,18 @@ def test_get_email_preferences_rest_flattened_error(transport: str = "rest"): ) -def test_get_email_preferences_rest_error(): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - +def test_update_email_preferences_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -@pytest.mark.parametrize( - "request_type", - [ - emailpreferences.UpdateEmailPreferencesRequest, - dict, - ], -) -def test_update_email_preferences_rest(request_type): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "email_preferences": {"name": "accounts/sample1/users/sample2/emailPreferences"} - } - request_init["email_preferences"] = { - "name": "accounts/sample1/users/sample2/emailPreferences", - "news_and_tips": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = emailpreferences.UpdateEmailPreferencesRequest.meta.fields[ - "email_preferences" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["email_preferences"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["email_preferences"][field])): - del request_init["email_preferences"][field][i][subfield] - else: - del request_init["email_preferences"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = emailpreferences.EmailPreferences( - name="name_value", - news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = emailpreferences.EmailPreferences.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_email_preferences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, emailpreferences.EmailPreferences) - assert response.name == "name_value" - assert ( - response.news_and_tips == emailpreferences.EmailPreferences.OptInState.OPTED_OUT - ) - - -def test_update_email_preferences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() # Ensure method has been cached assert ( @@ -2530,25 +2209,590 @@ def test_update_email_preferences_rest_required_fields( response = client.update_email_preferences(request) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_email_preferences_rest_unset_required_fields(): + transport = transports.EmailPreferencesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_email_preferences._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "emailPreferences", + "updateMask", + ) + ) + ) + + +def test_update_email_preferences_rest_flattened(): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = emailpreferences.EmailPreferences() + + # get arguments that satisfy an http rule for this method + sample_request = { + "email_preferences": { + "name": "accounts/sample1/users/sample2/emailPreferences" + } + } + + # get truthy value for each flattened field + mock_args = dict( + email_preferences=emailpreferences.EmailPreferences(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = emailpreferences.EmailPreferences.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_email_preferences(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{email_preferences.name=accounts/*/users/*/emailPreferences}" + % client.transport._host, + args[1], + ) + + +def test_update_email_preferences_rest_flattened_error(transport: str = "rest"): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_email_preferences( + emailpreferences.UpdateEmailPreferencesRequest(), + email_preferences=emailpreferences.EmailPreferences(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.EmailPreferencesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.EmailPreferencesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = EmailPreferencesServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.EmailPreferencesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = EmailPreferencesServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = EmailPreferencesServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.EmailPreferencesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = EmailPreferencesServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.EmailPreferencesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = EmailPreferencesServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.EmailPreferencesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.EmailPreferencesServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.EmailPreferencesServiceGrpcTransport, + transports.EmailPreferencesServiceGrpcAsyncIOTransport, + transports.EmailPreferencesServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = EmailPreferencesServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_email_preferences_empty_call_grpc(): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_email_preferences), "__call__" + ) as call: + call.return_value = emailpreferences.EmailPreferences() + client.get_email_preferences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = emailpreferences.GetEmailPreferencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_email_preferences_empty_call_grpc(): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_email_preferences), "__call__" + ) as call: + call.return_value = emailpreferences.EmailPreferences() + client.update_email_preferences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = emailpreferences.UpdateEmailPreferencesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = EmailPreferencesServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = EmailPreferencesServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_email_preferences_empty_call_grpc_asyncio(): + client = EmailPreferencesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_email_preferences), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + emailpreferences.EmailPreferences( + name="name_value", + news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, + ) + ) + await client.get_email_preferences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = emailpreferences.GetEmailPreferencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_email_preferences_empty_call_grpc_asyncio(): + client = EmailPreferencesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_email_preferences), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + emailpreferences.EmailPreferences( + name="name_value", + news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, + ) + ) + await client.update_email_preferences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = emailpreferences.UpdateEmailPreferencesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = EmailPreferencesServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_email_preferences_rest_bad_request( + request_type=emailpreferences.GetEmailPreferencesRequest, +): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/users/sample2/emailPreferences"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_email_preferences(request) + + +@pytest.mark.parametrize( + "request_type", + [ + emailpreferences.GetEmailPreferencesRequest, + dict, + ], +) +def test_get_email_preferences_rest_call_success(request_type): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/users/sample2/emailPreferences"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = emailpreferences.EmailPreferences( + name="name_value", + news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = emailpreferences.EmailPreferences.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_email_preferences(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, emailpreferences.EmailPreferences) + assert response.name == "name_value" + assert ( + response.news_and_tips == emailpreferences.EmailPreferences.OptInState.OPTED_OUT + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_email_preferences_rest_interceptors(null_interceptor): + transport = transports.EmailPreferencesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.EmailPreferencesServiceRestInterceptor(), + ) + client = EmailPreferencesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.EmailPreferencesServiceRestInterceptor, "post_get_email_preferences" + ) as post, mock.patch.object( + transports.EmailPreferencesServiceRestInterceptor, "pre_get_email_preferences" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = emailpreferences.GetEmailPreferencesRequest.pb( + emailpreferences.GetEmailPreferencesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = emailpreferences.EmailPreferences.to_json( + emailpreferences.EmailPreferences() + ) + req.return_value.content = return_value + + request = emailpreferences.GetEmailPreferencesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = emailpreferences.EmailPreferences() + + client.get_email_preferences( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_email_preferences_rest_bad_request( + request_type=emailpreferences.UpdateEmailPreferencesRequest, +): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "email_preferences": {"name": "accounts/sample1/users/sample2/emailPreferences"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_email_preferences(request) + + +@pytest.mark.parametrize( + "request_type", + [ + emailpreferences.UpdateEmailPreferencesRequest, + dict, + ], +) +def test_update_email_preferences_rest_call_success(request_type): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "email_preferences": {"name": "accounts/sample1/users/sample2/emailPreferences"} + } + request_init["email_preferences"] = { + "name": "accounts/sample1/users/sample2/emailPreferences", + "news_and_tips": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = emailpreferences.UpdateEmailPreferencesRequest.meta.fields[ + "email_preferences" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["email_preferences"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["email_preferences"][field])): + del request_init["email_preferences"][field][i][subfield] + else: + del request_init["email_preferences"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = emailpreferences.EmailPreferences( + name="name_value", + news_and_tips=emailpreferences.EmailPreferences.OptInState.OPTED_OUT, + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_update_email_preferences_rest_unset_required_fields(): - transport = transports.EmailPreferencesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = emailpreferences.EmailPreferences.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_email_preferences(request) - unset_fields = transport.update_email_preferences._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("updateMask",)) - & set( - ( - "emailPreferences", - "updateMask", - ) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, emailpreferences.EmailPreferences) + assert response.name == "name_value" + assert ( + response.news_and_tips == emailpreferences.EmailPreferences.OptInState.OPTED_OUT ) @@ -2561,6 +2805,7 @@ def test_update_email_preferences_rest_interceptors(null_interceptor): else transports.EmailPreferencesServiceRestInterceptor(), ) client = EmailPreferencesServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2584,12 +2829,12 @@ def test_update_email_preferences_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = emailpreferences.EmailPreferences.to_json( + return_value = emailpreferences.EmailPreferences.to_json( emailpreferences.EmailPreferences() ) + req.return_value.content = return_value request = emailpreferences.UpdateEmailPreferencesRequest() metadata = [ @@ -2611,205 +2856,55 @@ def test_update_email_preferences_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_email_preferences_rest_bad_request( - transport: str = "rest", request_type=emailpreferences.UpdateEmailPreferencesRequest -): +def test_initialize_client_w_rest(): client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = { - "email_preferences": {"name": "accounts/sample1/users/sample2/emailPreferences"} - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_email_preferences(request) + assert client is not None -def test_update_email_preferences_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_email_preferences_empty_call_rest(): client = EmailPreferencesServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = emailpreferences.EmailPreferences() - - # get arguments that satisfy an http rule for this method - sample_request = { - "email_preferences": { - "name": "accounts/sample1/users/sample2/emailPreferences" - } - } - - # get truthy value for each flattened field - mock_args = dict( - email_preferences=emailpreferences.EmailPreferences(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = emailpreferences.EmailPreferences.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_email_preferences(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{email_preferences.name=accounts/*/users/*/emailPreferences}" - % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_email_preferences), "__call__" + ) as call: + client.get_email_preferences(request=None) -def test_update_email_preferences_rest_flattened_error(transport: str = "rest"): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = emailpreferences.GetEmailPreferencesRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_email_preferences( - emailpreferences.UpdateEmailPreferencesRequest(), - email_preferences=emailpreferences.EmailPreferences(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + assert args[0] == request_msg -def test_update_email_preferences_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_email_preferences_empty_call_rest(): client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.EmailPreferencesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.EmailPreferencesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = EmailPreferencesServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.EmailPreferencesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = EmailPreferencesServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = EmailPreferencesServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.EmailPreferencesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = EmailPreferencesServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.EmailPreferencesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = EmailPreferencesServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.EmailPreferencesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.EmailPreferencesServiceGrpcAsyncIOTransport( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.EmailPreferencesServiceGrpcTransport, - transports.EmailPreferencesServiceGrpcAsyncIOTransport, - transports.EmailPreferencesServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_email_preferences), "__call__" + ) as call: + client.update_email_preferences(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = emailpreferences.UpdateEmailPreferencesRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = EmailPreferencesServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3392,36 +3487,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = EmailPreferencesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = EmailPreferencesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = EmailPreferencesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py index 54fdd2b90714..dd57ad279e30 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_homepage_service.py @@ -22,19 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + from google.shopping.merchant_accounts_v1beta.services.homepage_service import ( HomepageServiceAsyncClient, HomepageServiceClient, @@ -53,10 +62,24 @@ from google.shopping.merchant_accounts_v1beta.types import homepage +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1182,25 +1205,6 @@ def test_get_homepage(request_type, transport: str = "grpc"): assert response.claimed is True -def test_get_homepage_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_homepage), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == homepage.GetHomepageRequest() - - def test_get_homepage_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1264,31 +1268,6 @@ def test_get_homepage_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_homepage_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_homepage), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - ) - response = await client.get_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == homepage.GetHomepageRequest() - - @pytest.mark.asyncio async def test_get_homepage_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1297,7 +1276,7 @@ async def test_get_homepage_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1336,7 +1315,7 @@ async def test_get_homepage_async( transport: str = "grpc_asyncio", request_type=homepage.GetHomepageRequest ): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1406,7 +1385,7 @@ def test_get_homepage_field_headers(): @pytest.mark.asyncio async def test_get_homepage_field_headers_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1474,7 +1453,7 @@ def test_get_homepage_flattened_error(): @pytest.mark.asyncio async def test_get_homepage_flattened_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1501,7 +1480,7 @@ async def test_get_homepage_flattened_async(): @pytest.mark.asyncio async def test_get_homepage_flattened_error_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1553,25 +1532,6 @@ def test_update_homepage(request_type, transport: str = "grpc"): assert response.claimed is True -def test_update_homepage_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_homepage), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_homepage.UpdateHomepageRequest() - - def test_update_homepage_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1631,31 +1591,6 @@ def test_update_homepage_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_homepage_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_homepage), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gsma_homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - ) - response = await client.update_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_homepage.UpdateHomepageRequest() - - @pytest.mark.asyncio async def test_update_homepage_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1664,7 +1599,7 @@ async def test_update_homepage_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1703,7 +1638,7 @@ async def test_update_homepage_async( transport: str = "grpc_asyncio", request_type=gsma_homepage.UpdateHomepageRequest ): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1773,7 +1708,7 @@ def test_update_homepage_field_headers(): @pytest.mark.asyncio async def test_update_homepage_field_headers_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1848,7 +1783,7 @@ def test_update_homepage_flattened_error(): @pytest.mark.asyncio async def test_update_homepage_flattened_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1881,7 +1816,7 @@ async def test_update_homepage_flattened_async(): @pytest.mark.asyncio async def test_update_homepage_flattened_error_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1934,25 +1869,6 @@ def test_claim_homepage(request_type, transport: str = "grpc"): assert response.claimed is True -def test_claim_homepage_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.claim_homepage), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.claim_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == homepage.ClaimHomepageRequest() - - def test_claim_homepage_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2016,31 +1932,6 @@ def test_claim_homepage_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_claim_homepage_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.claim_homepage), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - ) - response = await client.claim_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == homepage.ClaimHomepageRequest() - - @pytest.mark.asyncio async def test_claim_homepage_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2049,7 +1940,7 @@ async def test_claim_homepage_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2088,7 +1979,7 @@ async def test_claim_homepage_async( transport: str = "grpc_asyncio", request_type=homepage.ClaimHomepageRequest ): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2158,7 +2049,7 @@ def test_claim_homepage_field_headers(): @pytest.mark.asyncio async def test_claim_homepage_field_headers_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2225,25 +2116,6 @@ def test_unclaim_homepage(request_type, transport: str = "grpc"): assert response.claimed is True -def test_unclaim_homepage_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.unclaim_homepage), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.unclaim_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == homepage.UnclaimHomepageRequest() - - def test_unclaim_homepage_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2309,31 +2181,6 @@ def test_unclaim_homepage_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_unclaim_homepage_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.unclaim_homepage), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - ) - response = await client.unclaim_homepage() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == homepage.UnclaimHomepageRequest() - - @pytest.mark.asyncio async def test_unclaim_homepage_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2342,7 +2189,7 @@ async def test_unclaim_homepage_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2381,7 +2228,7 @@ async def test_unclaim_homepage_async( transport: str = "grpc_asyncio", request_type=homepage.UnclaimHomepageRequest ): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2451,7 +2298,7 @@ def test_unclaim_homepage_field_headers(): @pytest.mark.asyncio async def test_unclaim_homepage_field_headers_async(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2478,50 +2325,6 @@ async def test_unclaim_homepage_field_headers_async(): ) in kw["metadata"] -@pytest.mark.parametrize( - "request_type", - [ - homepage.GetHomepageRequest, - dict, - ], -) -def test_get_homepage_rest(request_type): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/homepage"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = homepage.Homepage.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_homepage(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, homepage.Homepage) - assert response.name == "name_value" - assert response.uri == "uri_value" - assert response.claimed is True - - def test_get_homepage_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2639,93 +2442,16 @@ def test_get_homepage_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_homepage_rest_interceptors(null_interceptor): - transport = transports.HomepageServiceRestTransport( +def test_get_homepage_rest_flattened(): + client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.HomepageServiceRestInterceptor(), + transport="rest", ) - client = HomepageServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.HomepageServiceRestInterceptor, "post_get_homepage" - ) as post, mock.patch.object( - transports.HomepageServiceRestInterceptor, "pre_get_homepage" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = homepage.GetHomepageRequest.pb(homepage.GetHomepageRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = homepage.Homepage.to_json(homepage.Homepage()) - - request = homepage.GetHomepageRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = homepage.Homepage() - - client.get_homepage( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_homepage_rest_bad_request( - transport: str = "rest", request_type=homepage.GetHomepageRequest -): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/homepage"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_homepage(request) - - -def test_get_homepage_rest_flattened(): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = homepage.Homepage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = homepage.Homepage() # get arguments that satisfy an http rule for this method sample_request = {"name": "accounts/sample1/homepage"} @@ -2772,128 +2498,6 @@ def test_get_homepage_rest_flattened_error(transport: str = "rest"): ) -def test_get_homepage_rest_error(): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - gsma_homepage.UpdateHomepageRequest, - dict, - ], -) -def test_update_homepage_rest(request_type): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"homepage": {"name": "accounts/sample1/homepage"}} - request_init["homepage"] = { - "name": "accounts/sample1/homepage", - "uri": "uri_value", - "claimed": True, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = gsma_homepage.UpdateHomepageRequest.meta.fields["homepage"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["homepage"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["homepage"][field])): - del request_init["homepage"][field][i][subfield] - else: - del request_init["homepage"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gsma_homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gsma_homepage.Homepage.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_homepage(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, gsma_homepage.Homepage) - assert response.name == "name_value" - assert response.uri == "uri_value" - assert response.claimed is True - - def test_update_homepage_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3019,87 +2623,6 @@ def test_update_homepage_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_homepage_rest_interceptors(null_interceptor): - transport = transports.HomepageServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.HomepageServiceRestInterceptor(), - ) - client = HomepageServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.HomepageServiceRestInterceptor, "post_update_homepage" - ) as post, mock.patch.object( - transports.HomepageServiceRestInterceptor, "pre_update_homepage" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = gsma_homepage.UpdateHomepageRequest.pb( - gsma_homepage.UpdateHomepageRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = gsma_homepage.Homepage.to_json( - gsma_homepage.Homepage() - ) - - request = gsma_homepage.UpdateHomepageRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = gsma_homepage.Homepage() - - client.update_homepage( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_homepage_rest_bad_request( - transport: str = "rest", request_type=gsma_homepage.UpdateHomepageRequest -): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"homepage": {"name": "accounts/sample1/homepage"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_homepage(request) - - def test_update_homepage_rest_flattened(): client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3159,56 +2682,6 @@ def test_update_homepage_rest_flattened_error(transport: str = "rest"): ) -def test_update_homepage_rest_error(): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - homepage.ClaimHomepageRequest, - dict, - ], -) -def test_claim_homepage_rest(request_type): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/homepage"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = homepage.Homepage.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.claim_homepage(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, homepage.Homepage) - assert response.name == "name_value" - assert response.uri == "uri_value" - assert response.claimed is True - - def test_claim_homepage_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3329,133 +2802,6 @@ def test_claim_homepage_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_claim_homepage_rest_interceptors(null_interceptor): - transport = transports.HomepageServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.HomepageServiceRestInterceptor(), - ) - client = HomepageServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.HomepageServiceRestInterceptor, "post_claim_homepage" - ) as post, mock.patch.object( - transports.HomepageServiceRestInterceptor, "pre_claim_homepage" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = homepage.ClaimHomepageRequest.pb(homepage.ClaimHomepageRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = homepage.Homepage.to_json(homepage.Homepage()) - - request = homepage.ClaimHomepageRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = homepage.Homepage() - - client.claim_homepage( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_claim_homepage_rest_bad_request( - transport: str = "rest", request_type=homepage.ClaimHomepageRequest -): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/homepage"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.claim_homepage(request) - - -def test_claim_homepage_rest_error(): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - homepage.UnclaimHomepageRequest, - dict, - ], -) -def test_unclaim_homepage_rest(request_type): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/homepage"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = homepage.Homepage( - name="name_value", - uri="uri_value", - claimed=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = homepage.Homepage.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.unclaim_homepage(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, homepage.Homepage) - assert response.name == "name_value" - assert response.uri == "uri_value" - assert response.claimed is True - - def test_unclaim_homepage_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3569,17 +2915,723 @@ def test_unclaim_homepage_rest_required_fields( assert expected_params == actual_params -def test_unclaim_homepage_rest_unset_required_fields(): - transport = transports.HomepageServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) +def test_unclaim_homepage_rest_unset_required_fields(): + transport = transports.HomepageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.unclaim_homepage._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.HomepageServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.HomepageServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = HomepageServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.HomepageServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = HomepageServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = HomepageServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.HomepageServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = HomepageServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.HomepageServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = HomepageServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.HomepageServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.HomepageServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.HomepageServiceGrpcTransport, + transports.HomepageServiceGrpcAsyncIOTransport, + transports.HomepageServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = HomepageServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_homepage_empty_call_grpc(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_homepage), "__call__") as call: + call.return_value = homepage.Homepage() + client.get_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.GetHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_homepage_empty_call_grpc(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_homepage), "__call__") as call: + call.return_value = gsma_homepage.Homepage() + client.update_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_homepage.UpdateHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_claim_homepage_empty_call_grpc(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.claim_homepage), "__call__") as call: + call.return_value = homepage.Homepage() + client.claim_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.ClaimHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_unclaim_homepage_empty_call_grpc(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.unclaim_homepage), "__call__") as call: + call.return_value = homepage.Homepage() + client.unclaim_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.UnclaimHomepageRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = HomepageServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = HomepageServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_homepage_empty_call_grpc_asyncio(): + client = HomepageServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_homepage), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + ) + await client.get_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.GetHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_homepage_empty_call_grpc_asyncio(): + client = HomepageServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_homepage), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gsma_homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + ) + await client.update_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_homepage.UpdateHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_claim_homepage_empty_call_grpc_asyncio(): + client = HomepageServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.claim_homepage), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + ) + await client.claim_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.ClaimHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_unclaim_homepage_empty_call_grpc_asyncio(): + client = HomepageServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.unclaim_homepage), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + ) + await client.unclaim_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.UnclaimHomepageRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = HomepageServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_homepage_rest_bad_request(request_type=homepage.GetHomepageRequest): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/homepage"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_homepage(request) + + +@pytest.mark.parametrize( + "request_type", + [ + homepage.GetHomepageRequest, + dict, + ], +) +def test_get_homepage_rest_call_success(request_type): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/homepage"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = homepage.Homepage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_homepage(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, homepage.Homepage) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.claimed is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_homepage_rest_interceptors(null_interceptor): + transport = transports.HomepageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HomepageServiceRestInterceptor(), + ) + client = HomepageServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.HomepageServiceRestInterceptor, "post_get_homepage" + ) as post, mock.patch.object( + transports.HomepageServiceRestInterceptor, "pre_get_homepage" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = homepage.GetHomepageRequest.pb(homepage.GetHomepageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = homepage.Homepage.to_json(homepage.Homepage()) + req.return_value.content = return_value + + request = homepage.GetHomepageRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = homepage.Homepage() + + client.get_homepage( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_homepage_rest_bad_request( + request_type=gsma_homepage.UpdateHomepageRequest, +): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"homepage": {"name": "accounts/sample1/homepage"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_homepage(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gsma_homepage.UpdateHomepageRequest, + dict, + ], +) +def test_update_homepage_rest_call_success(request_type): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"homepage": {"name": "accounts/sample1/homepage"}} + request_init["homepage"] = { + "name": "accounts/sample1/homepage", + "uri": "uri_value", + "claimed": True, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gsma_homepage.UpdateHomepageRequest.meta.fields["homepage"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["homepage"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["homepage"][field])): + del request_init["homepage"][field][i][subfield] + else: + del request_init["homepage"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gsma_homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gsma_homepage.Homepage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_homepage(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gsma_homepage.Homepage) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.claimed is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_homepage_rest_interceptors(null_interceptor): + transport = transports.HomepageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HomepageServiceRestInterceptor(), + ) + client = HomepageServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.HomepageServiceRestInterceptor, "post_update_homepage" + ) as post, mock.patch.object( + transports.HomepageServiceRestInterceptor, "pre_update_homepage" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = gsma_homepage.UpdateHomepageRequest.pb( + gsma_homepage.UpdateHomepageRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = gsma_homepage.Homepage.to_json(gsma_homepage.Homepage()) + req.return_value.content = return_value + + request = gsma_homepage.UpdateHomepageRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gsma_homepage.Homepage() + + client.update_homepage( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_claim_homepage_rest_bad_request(request_type=homepage.ClaimHomepageRequest): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/homepage"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.claim_homepage(request) + + +@pytest.mark.parametrize( + "request_type", + [ + homepage.ClaimHomepageRequest, + dict, + ], +) +def test_claim_homepage_rest_call_success(request_type): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/homepage"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = homepage.Homepage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.claim_homepage(request) - unset_fields = transport.unclaim_homepage._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, homepage.Homepage) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.claimed is True @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_unclaim_homepage_rest_interceptors(null_interceptor): +def test_claim_homepage_rest_interceptors(null_interceptor): transport = transports.HomepageServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -3587,20 +3639,19 @@ def test_unclaim_homepage_rest_interceptors(null_interceptor): else transports.HomepageServiceRestInterceptor(), ) client = HomepageServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.HomepageServiceRestInterceptor, "post_unclaim_homepage" + transports.HomepageServiceRestInterceptor, "post_claim_homepage" ) as post, mock.patch.object( - transports.HomepageServiceRestInterceptor, "pre_unclaim_homepage" + transports.HomepageServiceRestInterceptor, "pre_claim_homepage" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = homepage.UnclaimHomepageRequest.pb( - homepage.UnclaimHomepageRequest() - ) + pb_message = homepage.ClaimHomepageRequest.pb(homepage.ClaimHomepageRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -3608,12 +3659,12 @@ def test_unclaim_homepage_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = homepage.Homepage.to_json(homepage.Homepage()) + return_value = homepage.Homepage.to_json(homepage.Homepage()) + req.return_value.content = return_value - request = homepage.UnclaimHomepageRequest() + request = homepage.ClaimHomepageRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -3621,7 +3672,7 @@ def test_unclaim_homepage_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = homepage.Homepage() - client.unclaim_homepage( + client.claim_homepage( request, metadata=[ ("key", "val"), @@ -3634,13 +3685,11 @@ def test_unclaim_homepage_rest_interceptors(null_interceptor): def test_unclaim_homepage_rest_bad_request( - transport: str = "rest", request_type=homepage.UnclaimHomepageRequest + request_type=homepage.UnclaimHomepageRequest, ): client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1/homepage"} request = request_type(**request_init) @@ -3650,123 +3699,199 @@ def test_unclaim_homepage_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.unclaim_homepage(request) -def test_unclaim_homepage_rest_error(): +@pytest.mark.parametrize( + "request_type", + [ + homepage.UnclaimHomepageRequest, + dict, + ], +) +def test_unclaim_homepage_rest_call_success(request_type): client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/homepage"} + request = request_type(**request_init) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.HomepageServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = homepage.Homepage( + name="name_value", + uri="uri_value", + claimed=True, ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.HomepageServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = HomepageServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 - # It is an error to provide an api_key and a transport instance. - transport = transports.HomepageServiceGrpcTransport( + # Convert return value to protobuf type + return_value = homepage.Homepage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.unclaim_homepage(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, homepage.Homepage) + assert response.name == "name_value" + assert response.uri == "uri_value" + assert response.claimed is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_unclaim_homepage_rest_interceptors(null_interceptor): + transport = transports.HomepageServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.HomepageServiceRestInterceptor(), ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = HomepageServiceClient( - client_options=options, - transport=transport, + client = HomepageServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.HomepageServiceRestInterceptor, "post_unclaim_homepage" + ) as post, mock.patch.object( + transports.HomepageServiceRestInterceptor, "pre_unclaim_homepage" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = homepage.UnclaimHomepageRequest.pb( + homepage.UnclaimHomepageRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = HomepageServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = homepage.Homepage.to_json(homepage.Homepage()) + req.return_value.content = return_value + + request = homepage.UnclaimHomepageRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = homepage.Homepage() + + client.unclaim_homepage( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - # It is an error to provide scopes and a transport instance. - transport = transports.HomepageServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - with pytest.raises(ValueError): - client = HomepageServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + assert client is not None -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.HomepageServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_homepage_empty_call_rest(): + client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = HomepageServiceClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_homepage), "__call__") as call: + client.get_homepage(request=None) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.HomepageServiceGrpcTransport( + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.GetHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_homepage_empty_call_rest(): + client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - transport = transports.HomepageServiceGrpcAsyncIOTransport( + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_homepage), "__call__") as call: + client.update_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_homepage.UpdateHomepageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_claim_homepage_empty_call_rest(): + client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.claim_homepage), "__call__") as call: + client.claim_homepage(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.HomepageServiceGrpcTransport, - transports.HomepageServiceGrpcAsyncIOTransport, - transports.HomepageServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.ClaimHomepageRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = HomepageServiceClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_unclaim_homepage_empty_call_rest(): + client = HomepageServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.unclaim_homepage), "__call__") as call: + client.unclaim_homepage(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = homepage.UnclaimHomepageRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4350,36 +4475,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = HomepageServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = HomepageServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = HomepageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py index fc5a00a8058e..24356a61ea9b 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_online_return_policy_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_accounts_v1beta.services.online_return_policy_service import ( OnlineReturnPolicyServiceAsyncClient, OnlineReturnPolicyServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import online_return_policy +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1263,27 +1286,6 @@ def test_get_online_return_policy(request_type, transport: str = "grpc"): assert response.accept_exchange is True -def test_get_online_return_policy_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_online_return_policy), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_online_return_policy() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == online_return_policy.GetOnlineReturnPolicyRequest() - - def test_get_online_return_policy_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1354,44 +1356,6 @@ def test_get_online_return_policy_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_online_return_policy_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_online_return_policy), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - online_return_policy.OnlineReturnPolicy( - name="name_value", - return_policy_id="return_policy_id_value", - label="label_value", - countries=["countries_value"], - return_methods=[ - online_return_policy.OnlineReturnPolicy.ReturnMethod.BY_MAIL - ], - item_conditions=[ - online_return_policy.OnlineReturnPolicy.ItemCondition.NEW - ], - return_policy_uri="return_policy_uri_value", - accept_defective_only=True, - process_refund_days=2034, - accept_exchange=True, - ) - ) - response = await client.get_online_return_policy() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == online_return_policy.GetOnlineReturnPolicyRequest() - - @pytest.mark.asyncio async def test_get_online_return_policy_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1400,7 +1364,7 @@ async def test_get_online_return_policy_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1440,7 +1404,7 @@ async def test_get_online_return_policy_async( request_type=online_return_policy.GetOnlineReturnPolicyRequest, ): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1536,7 +1500,7 @@ def test_get_online_return_policy_field_headers(): @pytest.mark.asyncio async def test_get_online_return_policy_field_headers_async(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1610,7 +1574,7 @@ def test_get_online_return_policy_flattened_error(): @pytest.mark.asyncio async def test_get_online_return_policy_flattened_async(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1641,7 +1605,7 @@ async def test_get_online_return_policy_flattened_async(): @pytest.mark.asyncio async def test_get_online_return_policy_flattened_error_async(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1691,27 +1655,6 @@ def test_list_online_return_policies(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_online_return_policies_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_online_return_policies), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_online_return_policies() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == online_return_policy.ListOnlineReturnPoliciesRequest() - - def test_list_online_return_policies_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1784,31 +1727,6 @@ def test_list_online_return_policies_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_online_return_policies_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_online_return_policies), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - online_return_policy.ListOnlineReturnPoliciesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_online_return_policies() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == online_return_policy.ListOnlineReturnPoliciesRequest() - - @pytest.mark.asyncio async def test_list_online_return_policies_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1817,7 +1735,7 @@ async def test_list_online_return_policies_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1857,7 +1775,7 @@ async def test_list_online_return_policies_async( request_type=online_return_policy.ListOnlineReturnPoliciesRequest, ): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1927,7 +1845,7 @@ def test_list_online_return_policies_field_headers(): @pytest.mark.asyncio async def test_list_online_return_policies_field_headers_async(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2001,7 +1919,7 @@ def test_list_online_return_policies_flattened_error(): @pytest.mark.asyncio async def test_list_online_return_policies_flattened_async(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2032,7 +1950,7 @@ async def test_list_online_return_policies_flattened_async(): @pytest.mark.asyncio async def test_list_online_return_policies_flattened_error_async(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2150,7 +2068,7 @@ def test_list_online_return_policies_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_online_return_policies_async_pager(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2204,7 +2122,7 @@ async def test_list_online_return_policies_async_pager(): @pytest.mark.asyncio async def test_list_online_return_policies_async_pages(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2252,70 +2170,6 @@ async def test_list_online_return_policies_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - online_return_policy.GetOnlineReturnPolicyRequest, - dict, - ], -) -def test_get_online_return_policy_rest(request_type): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/onlineReturnPolicies/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = online_return_policy.OnlineReturnPolicy( - name="name_value", - return_policy_id="return_policy_id_value", - label="label_value", - countries=["countries_value"], - return_methods=[ - online_return_policy.OnlineReturnPolicy.ReturnMethod.BY_MAIL - ], - item_conditions=[online_return_policy.OnlineReturnPolicy.ItemCondition.NEW], - return_policy_uri="return_policy_uri_value", - accept_defective_only=True, - process_refund_days=2034, - accept_exchange=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = online_return_policy.OnlineReturnPolicy.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_online_return_policy(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, online_return_policy.OnlineReturnPolicy) - assert response.name == "name_value" - assert response.return_policy_id == "return_policy_id_value" - assert response.label == "label_value" - assert response.countries == ["countries_value"] - assert response.return_methods == [ - online_return_policy.OnlineReturnPolicy.ReturnMethod.BY_MAIL - ] - assert response.item_conditions == [ - online_return_policy.OnlineReturnPolicy.ItemCondition.NEW - ] - assert response.return_policy_uri == "return_policy_uri_value" - assert response.accept_defective_only is True - assert response.process_refund_days == 2034 - assert response.accept_exchange is True - - def test_get_online_return_policy_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2440,120 +2294,36 @@ def test_get_online_return_policy_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_online_return_policy_rest_interceptors(null_interceptor): - transport = transports.OnlineReturnPolicyServiceRestTransport( +def test_get_online_return_policy_rest_flattened(): + client = OnlineReturnPolicyServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.OnlineReturnPolicyServiceRestInterceptor(), + transport="rest", ) - client = OnlineReturnPolicyServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.OnlineReturnPolicyServiceRestInterceptor, - "post_get_online_return_policy", - ) as post, mock.patch.object( - transports.OnlineReturnPolicyServiceRestInterceptor, - "pre_get_online_return_policy", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = online_return_policy.GetOnlineReturnPolicyRequest.pb( - online_return_policy.GetOnlineReturnPolicyRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = online_return_policy.OnlineReturnPolicy.to_json( - online_return_policy.OnlineReturnPolicy() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = online_return_policy.OnlineReturnPolicy() - request = online_return_policy.GetOnlineReturnPolicyRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = online_return_policy.OnlineReturnPolicy() + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/onlineReturnPolicies/sample2"} - client.get_online_return_policy( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) + mock_args.update(sample_request) - pre.assert_called_once() - post.assert_called_once() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = online_return_policy.OnlineReturnPolicy.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value - -def test_get_online_return_policy_rest_bad_request( - transport: str = "rest", - request_type=online_return_policy.GetOnlineReturnPolicyRequest, -): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/onlineReturnPolicies/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_online_return_policy(request) - - -def test_get_online_return_policy_rest_flattened(): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = online_return_policy.OnlineReturnPolicy() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/onlineReturnPolicies/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = online_return_policy.OnlineReturnPolicy.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_online_return_policy(**mock_args) + client.get_online_return_policy(**mock_args) # Establish that the underlying call was made with the expected # request object values. @@ -2581,54 +2351,6 @@ def test_get_online_return_policy_rest_flattened_error(transport: str = "rest"): ) -def test_get_online_return_policy_rest_error(): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - online_return_policy.ListOnlineReturnPoliciesRequest, - dict, - ], -) -def test_list_online_return_policies_rest(request_type): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = online_return_policy.ListOnlineReturnPoliciesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = online_return_policy.ListOnlineReturnPoliciesResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_online_return_policies(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOnlineReturnPoliciesPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_online_return_policies_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2770,92 +2492,6 @@ def test_list_online_return_policies_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_online_return_policies_rest_interceptors(null_interceptor): - transport = transports.OnlineReturnPolicyServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.OnlineReturnPolicyServiceRestInterceptor(), - ) - client = OnlineReturnPolicyServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.OnlineReturnPolicyServiceRestInterceptor, - "post_list_online_return_policies", - ) as post, mock.patch.object( - transports.OnlineReturnPolicyServiceRestInterceptor, - "pre_list_online_return_policies", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = online_return_policy.ListOnlineReturnPoliciesRequest.pb( - online_return_policy.ListOnlineReturnPoliciesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - online_return_policy.ListOnlineReturnPoliciesResponse.to_json( - online_return_policy.ListOnlineReturnPoliciesResponse() - ) - ) - - request = online_return_policy.ListOnlineReturnPoliciesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = online_return_policy.ListOnlineReturnPoliciesResponse() - - client.list_online_return_policies( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_online_return_policies_rest_bad_request( - transport: str = "rest", - request_type=online_return_policy.ListOnlineReturnPoliciesRequest, -): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_online_return_policies(request) - - def test_list_online_return_policies_rest_flattened(): client = OnlineReturnPolicyServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2915,176 +2551,637 @@ def test_list_online_return_policies_rest_flattened_error(transport: str = "rest ) -def test_list_online_return_policies_rest_pager(transport: str = "rest"): +def test_list_online_return_policies_rest_pager(transport: str = "rest"): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + online_return_policy.ListOnlineReturnPoliciesResponse( + online_return_policies=[ + online_return_policy.OnlineReturnPolicy(), + online_return_policy.OnlineReturnPolicy(), + online_return_policy.OnlineReturnPolicy(), + ], + next_page_token="abc", + ), + online_return_policy.ListOnlineReturnPoliciesResponse( + online_return_policies=[], + next_page_token="def", + ), + online_return_policy.ListOnlineReturnPoliciesResponse( + online_return_policies=[ + online_return_policy.OnlineReturnPolicy(), + ], + next_page_token="ghi", + ), + online_return_policy.ListOnlineReturnPoliciesResponse( + online_return_policies=[ + online_return_policy.OnlineReturnPolicy(), + online_return_policy.OnlineReturnPolicy(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + online_return_policy.ListOnlineReturnPoliciesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_online_return_policies(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, online_return_policy.OnlineReturnPolicy) for i in results + ) + + pages = list(client.list_online_return_policies(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.OnlineReturnPolicyServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.OnlineReturnPolicyServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = OnlineReturnPolicyServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.OnlineReturnPolicyServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = OnlineReturnPolicyServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = OnlineReturnPolicyServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.OnlineReturnPolicyServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = OnlineReturnPolicyServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.OnlineReturnPolicyServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = OnlineReturnPolicyServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.OnlineReturnPolicyServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.OnlineReturnPolicyServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.OnlineReturnPolicyServiceGrpcTransport, + transports.OnlineReturnPolicyServiceGrpcAsyncIOTransport, + transports.OnlineReturnPolicyServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = OnlineReturnPolicyServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_online_return_policy_empty_call_grpc(): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_online_return_policy), "__call__" + ) as call: + call.return_value = online_return_policy.OnlineReturnPolicy() + client.get_online_return_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = online_return_policy.GetOnlineReturnPolicyRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_online_return_policies_empty_call_grpc(): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_online_return_policies), "__call__" + ) as call: + call.return_value = online_return_policy.ListOnlineReturnPoliciesResponse() + client.list_online_return_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = online_return_policy.ListOnlineReturnPoliciesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = OnlineReturnPolicyServiceAsyncClient.get_transport_class( + "grpc_asyncio" + )(credentials=async_anonymous_credentials()) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = OnlineReturnPolicyServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_online_return_policy_empty_call_grpc_asyncio(): + client = OnlineReturnPolicyServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_online_return_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + online_return_policy.OnlineReturnPolicy( + name="name_value", + return_policy_id="return_policy_id_value", + label="label_value", + countries=["countries_value"], + return_methods=[ + online_return_policy.OnlineReturnPolicy.ReturnMethod.BY_MAIL + ], + item_conditions=[ + online_return_policy.OnlineReturnPolicy.ItemCondition.NEW + ], + return_policy_uri="return_policy_uri_value", + accept_defective_only=True, + process_refund_days=2034, + accept_exchange=True, + ) + ) + await client.get_online_return_policy(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = online_return_policy.GetOnlineReturnPolicyRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_online_return_policies_empty_call_grpc_asyncio(): + client = OnlineReturnPolicyServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_online_return_policies), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + online_return_policy.ListOnlineReturnPoliciesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_online_return_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = online_return_policy.ListOnlineReturnPoliciesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = OnlineReturnPolicyServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_online_return_policy_rest_bad_request( + request_type=online_return_policy.GetOnlineReturnPolicyRequest, +): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/onlineReturnPolicies/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_online_return_policy(request) + + +@pytest.mark.parametrize( + "request_type", + [ + online_return_policy.GetOnlineReturnPolicyRequest, + dict, + ], +) +def test_get_online_return_policy_rest_call_success(request_type): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/onlineReturnPolicies/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = online_return_policy.OnlineReturnPolicy( + name="name_value", + return_policy_id="return_policy_id_value", + label="label_value", + countries=["countries_value"], + return_methods=[ + online_return_policy.OnlineReturnPolicy.ReturnMethod.BY_MAIL + ], + item_conditions=[online_return_policy.OnlineReturnPolicy.ItemCondition.NEW], + return_policy_uri="return_policy_uri_value", + accept_defective_only=True, + process_refund_days=2034, + accept_exchange=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = online_return_policy.OnlineReturnPolicy.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_online_return_policy(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, online_return_policy.OnlineReturnPolicy) + assert response.name == "name_value" + assert response.return_policy_id == "return_policy_id_value" + assert response.label == "label_value" + assert response.countries == ["countries_value"] + assert response.return_methods == [ + online_return_policy.OnlineReturnPolicy.ReturnMethod.BY_MAIL + ] + assert response.item_conditions == [ + online_return_policy.OnlineReturnPolicy.ItemCondition.NEW + ] + assert response.return_policy_uri == "return_policy_uri_value" + assert response.accept_defective_only is True + assert response.process_refund_days == 2034 + assert response.accept_exchange is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_online_return_policy_rest_interceptors(null_interceptor): + transport = transports.OnlineReturnPolicyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OnlineReturnPolicyServiceRestInterceptor(), + ) + client = OnlineReturnPolicyServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.OnlineReturnPolicyServiceRestInterceptor, + "post_get_online_return_policy", + ) as post, mock.patch.object( + transports.OnlineReturnPolicyServiceRestInterceptor, + "pre_get_online_return_policy", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = online_return_policy.GetOnlineReturnPolicyRequest.pb( + online_return_policy.GetOnlineReturnPolicyRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = online_return_policy.OnlineReturnPolicy.to_json( + online_return_policy.OnlineReturnPolicy() + ) + req.return_value.content = return_value + + request = online_return_policy.GetOnlineReturnPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = online_return_policy.OnlineReturnPolicy() + + client.get_online_return_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_online_return_policies_rest_bad_request( + request_type=online_return_policy.ListOnlineReturnPoliciesRequest, +): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_online_return_policies(request) + + +@pytest.mark.parametrize( + "request_type", + [ + online_return_policy.ListOnlineReturnPoliciesRequest, + dict, + ], +) +def test_list_online_return_policies_rest_call_success(request_type): client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - online_return_policy.ListOnlineReturnPoliciesResponse( - online_return_policies=[ - online_return_policy.OnlineReturnPolicy(), - online_return_policy.OnlineReturnPolicy(), - online_return_policy.OnlineReturnPolicy(), - ], - next_page_token="abc", - ), - online_return_policy.ListOnlineReturnPoliciesResponse( - online_return_policies=[], - next_page_token="def", - ), - online_return_policy.ListOnlineReturnPoliciesResponse( - online_return_policies=[ - online_return_policy.OnlineReturnPolicy(), - ], - next_page_token="ghi", - ), - online_return_policy.ListOnlineReturnPoliciesResponse( - online_return_policies=[ - online_return_policy.OnlineReturnPolicy(), - online_return_policy.OnlineReturnPolicy(), - ], - ), - ) - # Two responses for two calls - response = response + response + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) - # Wrap the values into proper Response objs - response = tuple( - online_return_policy.ListOnlineReturnPoliciesResponse.to_json(x) - for x in response + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = online_return_policy.ListOnlineReturnPoliciesResponse( + next_page_token="next_page_token_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_online_return_policies(request=sample_request) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, online_return_policy.OnlineReturnPolicy) for i in results + # Convert return value to protobuf type + return_value = online_return_policy.ListOnlineReturnPoliciesResponse.pb( + return_value ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_online_return_policies(request) - pages = list(client.list_online_return_policies(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListOnlineReturnPoliciesPager) + assert response.next_page_token == "next_page_token_value" -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.OnlineReturnPolicyServiceGrpcTransport( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_online_return_policies_rest_interceptors(null_interceptor): + transport = transports.OnlineReturnPolicyServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.OnlineReturnPolicyServiceRestInterceptor(), ) - with pytest.raises(ValueError): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + client = OnlineReturnPolicyServiceClient(transport=transport) - # It is an error to provide a credentials file and a transport instance. - transport = transports.OnlineReturnPolicyServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = OnlineReturnPolicyServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.OnlineReturnPolicyServiceRestInterceptor, + "post_list_online_return_policies", + ) as post, mock.patch.object( + transports.OnlineReturnPolicyServiceRestInterceptor, + "pre_list_online_return_policies", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = online_return_policy.ListOnlineReturnPoliciesRequest.pb( + online_return_policy.ListOnlineReturnPoliciesRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # It is an error to provide an api_key and a transport instance. - transport = transports.OnlineReturnPolicyServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = OnlineReturnPolicyServiceClient( - client_options=options, - transport=transport, + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = online_return_policy.ListOnlineReturnPoliciesResponse.to_json( + online_return_policy.ListOnlineReturnPoliciesResponse() ) + req.return_value.content = return_value - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = OnlineReturnPolicyServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + request = online_return_policy.ListOnlineReturnPoliciesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = online_return_policy.ListOnlineReturnPoliciesResponse() - # It is an error to provide scopes and a transport instance. - transport = transports.OnlineReturnPolicyServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = OnlineReturnPolicyServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, + client.list_online_return_policies( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.OnlineReturnPolicyServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + +def test_initialize_client_w_rest(): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - client = OnlineReturnPolicyServiceClient(transport=transport) - assert client.transport is transport + assert client is not None -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.OnlineReturnPolicyServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_online_return_policy_empty_call_rest(): + client = OnlineReturnPolicyServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - transport = transports.OnlineReturnPolicyServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_online_return_policy), "__call__" + ) as call: + client.get_online_return_policy(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = online_return_policy.GetOnlineReturnPolicyRequest() -@pytest.mark.parametrize( - "transport_class", - [ - transports.OnlineReturnPolicyServiceGrpcTransport, - transports.OnlineReturnPolicyServiceGrpcAsyncIOTransport, - transports.OnlineReturnPolicyServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = OnlineReturnPolicyServiceClient.get_transport_class(transport_name)( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_online_return_policies_empty_call_rest(): + client = OnlineReturnPolicyServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_online_return_policies), "__call__" + ) as call: + client.list_online_return_policies(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = online_return_policy.ListOnlineReturnPoliciesRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3673,36 +3770,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = OnlineReturnPolicyServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = OnlineReturnPolicyServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = OnlineReturnPolicyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py index f3d21efba569..7c0ffab5da7a 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_programs_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_accounts_v1beta.services.programs_service import ( ProgramsServiceAsyncClient, ProgramsServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import programs +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1183,25 +1206,6 @@ def test_get_program(request_type, transport: str = "grpc"): assert response.active_region_codes == ["active_region_codes_value"] -def test_get_program_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_program), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_program() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.GetProgramRequest() - - def test_get_program_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1265,32 +1269,6 @@ def test_get_program_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_program_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_program), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - programs.Program( - name="name_value", - documentation_uri="documentation_uri_value", - state=programs.Program.State.NOT_ELIGIBLE, - active_region_codes=["active_region_codes_value"], - ) - ) - response = await client.get_program() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.GetProgramRequest() - - @pytest.mark.asyncio async def test_get_program_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1299,7 +1277,7 @@ async def test_get_program_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1338,7 +1316,7 @@ async def test_get_program_async( transport: str = "grpc_asyncio", request_type=programs.GetProgramRequest ): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1410,7 +1388,7 @@ def test_get_program_field_headers(): @pytest.mark.asyncio async def test_get_program_field_headers_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1478,7 +1456,7 @@ def test_get_program_flattened_error(): @pytest.mark.asyncio async def test_get_program_flattened_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1505,7 +1483,7 @@ async def test_get_program_flattened_async(): @pytest.mark.asyncio async def test_get_program_flattened_error_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1553,25 +1531,6 @@ def test_list_programs(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_programs_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_programs), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_programs() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.ListProgramsRequest() - - def test_list_programs_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1637,29 +1596,6 @@ def test_list_programs_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_programs_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_programs), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - programs.ListProgramsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_programs() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.ListProgramsRequest() - - @pytest.mark.asyncio async def test_list_programs_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1668,7 +1604,7 @@ async def test_list_programs_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1707,7 +1643,7 @@ async def test_list_programs_async( transport: str = "grpc_asyncio", request_type=programs.ListProgramsRequest ): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1773,7 +1709,7 @@ def test_list_programs_field_headers(): @pytest.mark.asyncio async def test_list_programs_field_headers_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1843,7 +1779,7 @@ def test_list_programs_flattened_error(): @pytest.mark.asyncio async def test_list_programs_flattened_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1872,7 +1808,7 @@ async def test_list_programs_flattened_async(): @pytest.mark.asyncio async def test_list_programs_flattened_error_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1982,7 +1918,7 @@ def test_list_programs_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_programs_async_pager(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2032,7 +1968,7 @@ async def test_list_programs_async_pager(): @pytest.mark.asyncio async def test_list_programs_async_pages(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2120,25 +2056,6 @@ def test_enable_program(request_type, transport: str = "grpc"): assert response.active_region_codes == ["active_region_codes_value"] -def test_enable_program_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.enable_program), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.enable_program() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.EnableProgramRequest() - - def test_enable_program_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2202,32 +2119,6 @@ def test_enable_program_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_enable_program_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.enable_program), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - programs.Program( - name="name_value", - documentation_uri="documentation_uri_value", - state=programs.Program.State.NOT_ELIGIBLE, - active_region_codes=["active_region_codes_value"], - ) - ) - response = await client.enable_program() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.EnableProgramRequest() - - @pytest.mark.asyncio async def test_enable_program_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2236,7 +2127,7 @@ async def test_enable_program_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2275,7 +2166,7 @@ async def test_enable_program_async( transport: str = "grpc_asyncio", request_type=programs.EnableProgramRequest ): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2347,7 +2238,7 @@ def test_enable_program_field_headers(): @pytest.mark.asyncio async def test_enable_program_field_headers_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2415,7 +2306,7 @@ def test_enable_program_flattened_error(): @pytest.mark.asyncio async def test_enable_program_flattened_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2442,7 +2333,7 @@ async def test_enable_program_flattened_async(): @pytest.mark.asyncio async def test_enable_program_flattened_error_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2496,25 +2387,6 @@ def test_disable_program(request_type, transport: str = "grpc"): assert response.active_region_codes == ["active_region_codes_value"] -def test_disable_program_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.disable_program), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.disable_program() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.DisableProgramRequest() - - def test_disable_program_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2578,32 +2450,6 @@ def test_disable_program_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_disable_program_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.disable_program), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - programs.Program( - name="name_value", - documentation_uri="documentation_uri_value", - state=programs.Program.State.NOT_ELIGIBLE, - active_region_codes=["active_region_codes_value"], - ) - ) - response = await client.disable_program() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == programs.DisableProgramRequest() - - @pytest.mark.asyncio async def test_disable_program_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2612,7 +2458,7 @@ async def test_disable_program_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2651,7 +2497,7 @@ async def test_disable_program_async( transport: str = "grpc_asyncio", request_type=programs.DisableProgramRequest ): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2723,7 +2569,7 @@ def test_disable_program_field_headers(): @pytest.mark.asyncio async def test_disable_program_field_headers_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2791,7 +2637,7 @@ def test_disable_program_flattened_error(): @pytest.mark.asyncio async def test_disable_program_flattened_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2818,7 +2664,7 @@ async def test_disable_program_flattened_async(): @pytest.mark.asyncio async def test_disable_program_flattened_error_async(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2830,52 +2676,6 @@ async def test_disable_program_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - programs.GetProgramRequest, - dict, - ], -) -def test_get_program_rest(request_type): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/programs/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = programs.Program( - name="name_value", - documentation_uri="documentation_uri_value", - state=programs.Program.State.NOT_ELIGIBLE, - active_region_codes=["active_region_codes_value"], - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = programs.Program.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_program(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, programs.Program) - assert response.name == "name_value" - assert response.documentation_uri == "documentation_uri_value" - assert response.state == programs.Program.State.NOT_ELIGIBLE - assert response.active_region_codes == ["active_region_codes_value"] - - def test_get_program_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2993,87 +2793,10 @@ def test_get_program_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_program_rest_interceptors(null_interceptor): - transport = transports.ProgramsServiceRestTransport( +def test_get_program_rest_flattened(): + client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ProgramsServiceRestInterceptor(), - ) - client = ProgramsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "post_get_program" - ) as post, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "pre_get_program" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = programs.GetProgramRequest.pb(programs.GetProgramRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = programs.Program.to_json(programs.Program()) - - request = programs.GetProgramRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = programs.Program() - - client.get_program( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_program_rest_bad_request( - transport: str = "rest", request_type=programs.GetProgramRequest -): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/programs/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_program(request) - - -def test_get_program_rest_flattened(): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="rest", ) # Mock the http request call within the method and fake a response. @@ -3126,52 +2849,6 @@ def test_get_program_rest_flattened_error(transport: str = "rest"): ) -def test_get_program_rest_error(): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - programs.ListProgramsRequest, - dict, - ], -) -def test_list_programs_rest(request_type): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = programs.ListProgramsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = programs.ListProgramsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_programs(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListProgramsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_programs_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3304,85 +2981,6 @@ def test_list_programs_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_programs_rest_interceptors(null_interceptor): - transport = transports.ProgramsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ProgramsServiceRestInterceptor(), - ) - client = ProgramsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "post_list_programs" - ) as post, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "pre_list_programs" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = programs.ListProgramsRequest.pb(programs.ListProgramsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = programs.ListProgramsResponse.to_json( - programs.ListProgramsResponse() - ) - - request = programs.ListProgramsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = programs.ListProgramsResponse() - - client.list_programs( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_programs_rest_bad_request( - transport: str = "rest", request_type=programs.ListProgramsRequest -): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_programs(request) - - def test_list_programs_rest_flattened(): client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3500,52 +3098,6 @@ def test_list_programs_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - programs.EnableProgramRequest, - dict, - ], -) -def test_enable_program_rest(request_type): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/programs/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = programs.Program( - name="name_value", - documentation_uri="documentation_uri_value", - state=programs.Program.State.NOT_ELIGIBLE, - active_region_codes=["active_region_codes_value"], - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = programs.Program.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.enable_program(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, programs.Program) - assert response.name == "name_value" - assert response.documentation_uri == "documentation_uri_value" - assert response.state == programs.Program.State.NOT_ELIGIBLE - assert response.active_region_codes == ["active_region_codes_value"] - - def test_enable_program_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3666,96 +3218,19 @@ def test_enable_program_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_enable_program_rest_interceptors(null_interceptor): - transport = transports.ProgramsServiceRestTransport( +def test_enable_program_rest_flattened(): + client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ProgramsServiceRestInterceptor(), + transport="rest", ) - client = ProgramsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "post_enable_program" - ) as post, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "pre_enable_program" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = programs.EnableProgramRequest.pb(programs.EnableProgramRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = programs.Program.to_json(programs.Program()) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = programs.Program() - request = programs.EnableProgramRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = programs.Program() - - client.enable_program( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_enable_program_rest_bad_request( - transport: str = "rest", request_type=programs.EnableProgramRequest -): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/programs/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.enable_program(request) - - -def test_enable_program_rest_flattened(): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = programs.Program() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/programs/sample2"} + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/programs/sample2"} # get truthy value for each flattened field mock_args = dict( @@ -3800,58 +3275,6 @@ def test_enable_program_rest_flattened_error(transport: str = "rest"): ) -def test_enable_program_rest_error(): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - programs.DisableProgramRequest, - dict, - ], -) -def test_disable_program_rest(request_type): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/programs/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = programs.Program( - name="name_value", - documentation_uri="documentation_uri_value", - state=programs.Program.State.NOT_ELIGIBLE, - active_region_codes=["active_region_codes_value"], - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = programs.Program.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.disable_program(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, programs.Program) - assert response.name == "name_value" - assert response.documentation_uri == "documentation_uri_value" - assert response.state == programs.Program.State.NOT_ELIGIBLE - assert response.active_region_codes == ["active_region_codes_value"] - - def test_disable_program_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3968,12 +3391,702 @@ def test_disable_program_rest_unset_required_fields(): credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.disable_program._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.disable_program._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_disable_program_rest_flattened(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = programs.Program() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/programs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = programs.Program.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.disable_program(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{name=accounts/*/programs/*}:disable" + % client.transport._host, + args[1], + ) + + +def test_disable_program_rest_flattened_error(transport: str = "rest"): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.disable_program( + programs.DisableProgramRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProgramsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProgramsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProgramsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProgramsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProgramsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProgramsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProgramsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProgramsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProgramsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProgramsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProgramsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProgramsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProgramsServiceGrpcTransport, + transports.ProgramsServiceGrpcAsyncIOTransport, + transports.ProgramsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = ProgramsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_program_empty_call_grpc(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_program), "__call__") as call: + call.return_value = programs.Program() + client.get_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.GetProgramRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_programs_empty_call_grpc(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_programs), "__call__") as call: + call.return_value = programs.ListProgramsResponse() + client.list_programs(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.ListProgramsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_enable_program_empty_call_grpc(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.enable_program), "__call__") as call: + call.return_value = programs.Program() + client.enable_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.EnableProgramRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_disable_program_empty_call_grpc(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.disable_program), "__call__") as call: + call.return_value = programs.Program() + client.disable_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.DisableProgramRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ProgramsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ProgramsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_program_empty_call_grpc_asyncio(): + client = ProgramsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_program), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + programs.Program( + name="name_value", + documentation_uri="documentation_uri_value", + state=programs.Program.State.NOT_ELIGIBLE, + active_region_codes=["active_region_codes_value"], + ) + ) + await client.get_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.GetProgramRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_programs_empty_call_grpc_asyncio(): + client = ProgramsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_programs), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + programs.ListProgramsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_programs(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.ListProgramsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_enable_program_empty_call_grpc_asyncio(): + client = ProgramsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.enable_program), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + programs.Program( + name="name_value", + documentation_uri="documentation_uri_value", + state=programs.Program.State.NOT_ELIGIBLE, + active_region_codes=["active_region_codes_value"], + ) + ) + await client.enable_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.EnableProgramRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_disable_program_empty_call_grpc_asyncio(): + client = ProgramsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.disable_program), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + programs.Program( + name="name_value", + documentation_uri="documentation_uri_value", + state=programs.Program.State.NOT_ELIGIBLE, + active_region_codes=["active_region_codes_value"], + ) + ) + await client.disable_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.DisableProgramRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ProgramsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_program_rest_bad_request(request_type=programs.GetProgramRequest): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/programs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_program(request) + + +@pytest.mark.parametrize( + "request_type", + [ + programs.GetProgramRequest, + dict, + ], +) +def test_get_program_rest_call_success(request_type): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/programs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = programs.Program( + name="name_value", + documentation_uri="documentation_uri_value", + state=programs.Program.State.NOT_ELIGIBLE, + active_region_codes=["active_region_codes_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = programs.Program.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_program(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, programs.Program) + assert response.name == "name_value" + assert response.documentation_uri == "documentation_uri_value" + assert response.state == programs.Program.State.NOT_ELIGIBLE + assert response.active_region_codes == ["active_region_codes_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_program_rest_interceptors(null_interceptor): + transport = transports.ProgramsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ProgramsServiceRestInterceptor(), + ) + client = ProgramsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ProgramsServiceRestInterceptor, "post_get_program" + ) as post, mock.patch.object( + transports.ProgramsServiceRestInterceptor, "pre_get_program" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = programs.GetProgramRequest.pb(programs.GetProgramRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = programs.Program.to_json(programs.Program()) + req.return_value.content = return_value + + request = programs.GetProgramRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = programs.Program() + + client.get_program( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_programs_rest_bad_request(request_type=programs.ListProgramsRequest): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_programs(request) + + +@pytest.mark.parametrize( + "request_type", + [ + programs.ListProgramsRequest, + dict, + ], +) +def test_list_programs_rest_call_success(request_type): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = programs.ListProgramsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = programs.ListProgramsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_programs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProgramsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_programs_rest_interceptors(null_interceptor): + transport = transports.ProgramsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ProgramsServiceRestInterceptor(), + ) + client = ProgramsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ProgramsServiceRestInterceptor, "post_list_programs" + ) as post, mock.patch.object( + transports.ProgramsServiceRestInterceptor, "pre_list_programs" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = programs.ListProgramsRequest.pb(programs.ListProgramsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = programs.ListProgramsResponse.to_json( + programs.ListProgramsResponse() + ) + req.return_value.content = return_value + + request = programs.ListProgramsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = programs.ListProgramsResponse() + + client.list_programs( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_enable_program_rest_bad_request(request_type=programs.EnableProgramRequest): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/programs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.enable_program(request) + + +@pytest.mark.parametrize( + "request_type", + [ + programs.EnableProgramRequest, + dict, + ], +) +def test_enable_program_rest_call_success(request_type): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/programs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = programs.Program( + name="name_value", + documentation_uri="documentation_uri_value", + state=programs.Program.State.NOT_ELIGIBLE, + active_region_codes=["active_region_codes_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = programs.Program.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.enable_program(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, programs.Program) + assert response.name == "name_value" + assert response.documentation_uri == "documentation_uri_value" + assert response.state == programs.Program.State.NOT_ELIGIBLE + assert response.active_region_codes == ["active_region_codes_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_disable_program_rest_interceptors(null_interceptor): +def test_enable_program_rest_interceptors(null_interceptor): transport = transports.ProgramsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -3981,18 +4094,19 @@ def test_disable_program_rest_interceptors(null_interceptor): else transports.ProgramsServiceRestInterceptor(), ) client = ProgramsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "post_disable_program" + transports.ProgramsServiceRestInterceptor, "post_enable_program" ) as post, mock.patch.object( - transports.ProgramsServiceRestInterceptor, "pre_disable_program" + transports.ProgramsServiceRestInterceptor, "pre_enable_program" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = programs.DisableProgramRequest.pb(programs.DisableProgramRequest()) + pb_message = programs.EnableProgramRequest.pb(programs.EnableProgramRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -4000,12 +4114,12 @@ def test_disable_program_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = programs.Program.to_json(programs.Program()) + return_value = programs.Program.to_json(programs.Program()) + req.return_value.content = return_value - request = programs.DisableProgramRequest() + request = programs.EnableProgramRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -4013,7 +4127,7 @@ def test_disable_program_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = programs.Program() - client.disable_program( + client.enable_program( request, metadata=[ ("key", "val"), @@ -4025,14 +4139,10 @@ def test_disable_program_rest_interceptors(null_interceptor): post.assert_called_once() -def test_disable_program_rest_bad_request( - transport: str = "rest", request_type=programs.DisableProgramRequest -): +def test_disable_program_rest_bad_request(request_type=programs.DisableProgramRequest): client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1/programs/sample2"} request = request_type(**request_init) @@ -4042,180 +4152,199 @@ def test_disable_program_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.disable_program(request) -def test_disable_program_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + programs.DisableProgramRequest, + dict, + ], +) +def test_disable_program_rest_call_success(request_type): client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/programs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = programs.Program() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/programs/sample2"} - - # get truthy value for each flattened field - mock_args = dict( + return_value = programs.Program( name="name_value", + documentation_uri="documentation_uri_value", + state=programs.Program.State.NOT_ELIGIBLE, + active_region_codes=["active_region_codes_value"], ) - mock_args.update(sample_request) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = programs.Program.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.disable_program(request) - client.disable_program(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{name=accounts/*/programs/*}:disable" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, programs.Program) + assert response.name == "name_value" + assert response.documentation_uri == "documentation_uri_value" + assert response.state == programs.Program.State.NOT_ELIGIBLE + assert response.active_region_codes == ["active_region_codes_value"] -def test_disable_program_rest_flattened_error(transport: str = "rest"): - client = ProgramsServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_disable_program_rest_interceptors(null_interceptor): + transport = transports.ProgramsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.ProgramsServiceRestInterceptor(), ) + client = ProgramsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ProgramsServiceRestInterceptor, "post_disable_program" + ) as post, mock.patch.object( + transports.ProgramsServiceRestInterceptor, "pre_disable_program" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = programs.DisableProgramRequest.pb(programs.DisableProgramRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = programs.Program.to_json(programs.Program()) + req.return_value.content = return_value + + request = programs.DisableProgramRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = programs.Program() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.disable_program( - programs.DisableProgramRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() -def test_disable_program_rest_error(): + +def test_initialize_client_w_rest(): client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ProgramsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_program_empty_call_rest(): + client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.ProgramsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ProgramsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_program), "__call__") as call: + client.get_program(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.ProgramsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ProgramsServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.GetProgramRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ProgramsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.ProgramsServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_programs_empty_call_rest(): + client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ProgramsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_programs), "__call__") as call: + client.list_programs(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ProgramsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ProgramsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.ListProgramsRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ProgramsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.ProgramsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_enable_program_empty_call_rest(): + client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.enable_program), "__call__") as call: + client.enable_program(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.ProgramsServiceGrpcTransport, - transports.ProgramsServiceGrpcAsyncIOTransport, - transports.ProgramsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.EnableProgramRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = ProgramsServiceClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_disable_program_empty_call_rest(): + client = ProgramsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.disable_program), "__call__") as call: + client.disable_program(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = programs.DisableProgramRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4802,36 +4931,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = ProgramsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ProgramsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = ProgramsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py index 4a4aa5aeb46a..91fb6ef46d3d 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_regions_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,15 +52,7 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import wrappers_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_accounts_v1beta.services.regions_service import ( RegionsServiceAsyncClient, @@ -54,10 +63,24 @@ from google.shopping.merchant_accounts_v1beta.types import regions +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1157,25 +1180,6 @@ def test_get_region(request_type, transport: str = "grpc"): assert response.display_name == "display_name_value" -def test_get_region_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_region), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.GetRegionRequest() - - def test_get_region_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1239,37 +1243,13 @@ def test_get_region_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_region_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_region), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - regions.Region( - name="name_value", - display_name="display_name_value", - ) - ) - response = await client.get_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.GetRegionRequest() - - @pytest.mark.asyncio async def test_get_region_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1308,7 +1288,7 @@ async def test_get_region_async( transport: str = "grpc_asyncio", request_type=regions.GetRegionRequest ): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1376,7 +1356,7 @@ def test_get_region_field_headers(): @pytest.mark.asyncio async def test_get_region_field_headers_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1444,7 +1424,7 @@ def test_get_region_flattened_error(): @pytest.mark.asyncio async def test_get_region_flattened_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1471,7 +1451,7 @@ async def test_get_region_flattened_async(): @pytest.mark.asyncio async def test_get_region_flattened_error_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1521,25 +1501,6 @@ def test_create_region(request_type, transport: str = "grpc"): assert response.display_name == "display_name_value" -def test_create_region_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_region), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.CreateRegionRequest() - - def test_create_region_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1605,30 +1566,6 @@ def test_create_region_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_region_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_region), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - regions.Region( - name="name_value", - display_name="display_name_value", - ) - ) - response = await client.create_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.CreateRegionRequest() - - @pytest.mark.asyncio async def test_create_region_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1637,7 +1574,7 @@ async def test_create_region_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1676,7 +1613,7 @@ async def test_create_region_async( transport: str = "grpc_asyncio", request_type=regions.CreateRegionRequest ): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1744,7 +1681,7 @@ def test_create_region_field_headers(): @pytest.mark.asyncio async def test_create_region_field_headers_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1822,7 +1759,7 @@ def test_create_region_flattened_error(): @pytest.mark.asyncio async def test_create_region_flattened_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1857,7 +1794,7 @@ async def test_create_region_flattened_async(): @pytest.mark.asyncio async def test_create_region_flattened_error_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1909,25 +1846,6 @@ def test_update_region(request_type, transport: str = "grpc"): assert response.display_name == "display_name_value" -def test_update_region_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_region), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.UpdateRegionRequest() - - def test_update_region_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1987,30 +1905,6 @@ def test_update_region_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_region_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_region), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - regions.Region( - name="name_value", - display_name="display_name_value", - ) - ) - response = await client.update_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.UpdateRegionRequest() - - @pytest.mark.asyncio async def test_update_region_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2019,7 +1913,7 @@ async def test_update_region_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2058,7 +1952,7 @@ async def test_update_region_async( transport: str = "grpc_asyncio", request_type=regions.UpdateRegionRequest ): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2126,7 +2020,7 @@ def test_update_region_field_headers(): @pytest.mark.asyncio async def test_update_region_field_headers_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2199,7 +2093,7 @@ def test_update_region_flattened_error(): @pytest.mark.asyncio async def test_update_region_flattened_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2230,7 +2124,7 @@ async def test_update_region_flattened_async(): @pytest.mark.asyncio async def test_update_region_flattened_error_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2276,25 +2170,6 @@ def test_delete_region(request_type, transport: str = "grpc"): assert response is None -def test_delete_region_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_region), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.DeleteRegionRequest() - - def test_delete_region_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2358,25 +2233,6 @@ def test_delete_region_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_region_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_region), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_region() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.DeleteRegionRequest() - - @pytest.mark.asyncio async def test_delete_region_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2385,7 +2241,7 @@ async def test_delete_region_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2424,7 +2280,7 @@ async def test_delete_region_async( transport: str = "grpc_asyncio", request_type=regions.DeleteRegionRequest ): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2485,7 +2341,7 @@ def test_delete_region_field_headers(): @pytest.mark.asyncio async def test_delete_region_field_headers_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2553,7 +2409,7 @@ def test_delete_region_flattened_error(): @pytest.mark.asyncio async def test_delete_region_flattened_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2580,7 +2436,7 @@ async def test_delete_region_flattened_async(): @pytest.mark.asyncio async def test_delete_region_flattened_error_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2628,25 +2484,6 @@ def test_list_regions(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_regions_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_regions), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_regions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.ListRegionsRequest() - - def test_list_regions_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2712,29 +2549,6 @@ def test_list_regions_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_regions_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_regions), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - regions.ListRegionsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_regions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regions.ListRegionsRequest() - - @pytest.mark.asyncio async def test_list_regions_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2743,7 +2557,7 @@ async def test_list_regions_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2782,7 +2596,7 @@ async def test_list_regions_async( transport: str = "grpc_asyncio", request_type=regions.ListRegionsRequest ): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2848,7 +2662,7 @@ def test_list_regions_field_headers(): @pytest.mark.asyncio async def test_list_regions_field_headers_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2918,7 +2732,7 @@ def test_list_regions_flattened_error(): @pytest.mark.asyncio async def test_list_regions_flattened_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2947,7 +2761,7 @@ async def test_list_regions_flattened_async(): @pytest.mark.asyncio async def test_list_regions_flattened_error_async(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3057,7 +2871,7 @@ def test_list_regions_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_regions_async_pager(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3107,7 +2921,7 @@ async def test_list_regions_async_pager(): @pytest.mark.asyncio async def test_list_regions_async_pages(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3153,48 +2967,6 @@ async def test_list_regions_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - regions.GetRegionRequest, - dict, - ], -) -def test_get_region_rest(request_type): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/regions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regions.Region( - name="name_value", - display_name="display_name_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regions.Region.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_region(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, regions.Region) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - - def test_get_region_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3312,83 +3084,6 @@ def test_get_region_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_region_rest_interceptors(null_interceptor): - transport = transports.RegionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RegionsServiceRestInterceptor(), - ) - client = RegionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RegionsServiceRestInterceptor, "post_get_region" - ) as post, mock.patch.object( - transports.RegionsServiceRestInterceptor, "pre_get_region" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = regions.GetRegionRequest.pb(regions.GetRegionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = regions.Region.to_json(regions.Region()) - - request = regions.GetRegionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = regions.Region() - - client.get_region( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_region_rest_bad_request( - transport: str = "rest", request_type=regions.GetRegionRequest -): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/regions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_region(request) - - def test_get_region_rest_flattened(): client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3445,132 +3140,6 @@ def test_get_region_rest_flattened_error(transport: str = "rest"): ) -def test_get_region_rest_error(): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - regions.CreateRegionRequest, - dict, - ], -) -def test_create_region_rest(request_type): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["region"] = { - "name": "name_value", - "display_name": "display_name_value", - "postal_code_area": { - "region_code": "region_code_value", - "postal_codes": [{"begin": "begin_value", "end": "end_value"}], - }, - "geotarget_area": {"geotarget_criteria_ids": [2324, 2325]}, - "regional_inventory_eligible": {"value": True}, - "shipping_eligible": {}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = regions.CreateRegionRequest.meta.fields["region"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["region"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["region"][field])): - del request_init["region"][field][i][subfield] - else: - del request_init["region"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regions.Region( - name="name_value", - display_name="display_name_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regions.Region.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_region(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, regions.Region) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - - def test_create_region_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3713,104 +3282,27 @@ def test_create_region_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_region_rest_interceptors(null_interceptor): - transport = transports.RegionsServiceRestTransport( +def test_create_region_rest_flattened(): + client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RegionsServiceRestInterceptor(), + transport="rest", ) - client = RegionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RegionsServiceRestInterceptor, "post_create_region" - ) as post, mock.patch.object( - transports.RegionsServiceRestInterceptor, "pre_create_region" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = regions.CreateRegionRequest.pb(regions.CreateRegionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = regions.Region.to_json(regions.Region()) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regions.Region() - request = regions.CreateRegionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = regions.Region() + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} - client.create_region( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + region=regions.Region(name="name_value"), + region_id="region_id_value", ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_region_rest_bad_request( - transport: str = "rest", request_type=regions.CreateRegionRequest -): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_region(request) - - -def test_create_region_rest_flattened(): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regions.Region() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - region=regions.Region(name="name_value"), - region_id="region_id_value", - ) - mock_args.update(sample_request) + mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() @@ -3850,132 +3342,6 @@ def test_create_region_rest_flattened_error(transport: str = "rest"): ) -def test_create_region_rest_error(): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - regions.UpdateRegionRequest, - dict, - ], -) -def test_update_region_rest(request_type): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"region": {"name": "accounts/sample1/regions/sample2"}} - request_init["region"] = { - "name": "accounts/sample1/regions/sample2", - "display_name": "display_name_value", - "postal_code_area": { - "region_code": "region_code_value", - "postal_codes": [{"begin": "begin_value", "end": "end_value"}], - }, - "geotarget_area": {"geotarget_criteria_ids": [2324, 2325]}, - "regional_inventory_eligible": {"value": True}, - "shipping_eligible": {}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = regions.UpdateRegionRequest.meta.fields["region"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["region"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["region"][field])): - del request_init["region"][field][i][subfield] - else: - del request_init["region"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regions.Region( - name="name_value", - display_name="display_name_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regions.Region.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_region(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, regions.Region) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - - def test_update_region_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4091,83 +3457,6 @@ def test_update_region_rest_unset_required_fields(): assert set(unset_fields) == (set(("updateMask",)) & set(("region",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_region_rest_interceptors(null_interceptor): - transport = transports.RegionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RegionsServiceRestInterceptor(), - ) - client = RegionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RegionsServiceRestInterceptor, "post_update_region" - ) as post, mock.patch.object( - transports.RegionsServiceRestInterceptor, "pre_update_region" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = regions.UpdateRegionRequest.pb(regions.UpdateRegionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = regions.Region.to_json(regions.Region()) - - request = regions.UpdateRegionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = regions.Region() - - client.update_region( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_region_rest_bad_request( - transport: str = "rest", request_type=regions.UpdateRegionRequest -): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"region": {"name": "accounts/sample1/regions/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_region(request) - - def test_update_region_rest_flattened(): client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4227,59 +3516,18 @@ def test_update_region_rest_flattened_error(transport: str = "rest"): ) -def test_update_region_rest_error(): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_delete_region_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - -@pytest.mark.parametrize( - "request_type", - [ - regions.DeleteRegionRequest, - dict, - ], -) -def test_delete_region_rest(request_type): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/regions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_region(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_region_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() # Ensure method has been cached assert client._transport.delete_region in client._transport._wrapped_methods @@ -4382,77 +3630,6 @@ def test_delete_region_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_region_rest_interceptors(null_interceptor): - transport = transports.RegionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RegionsServiceRestInterceptor(), - ) - client = RegionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RegionsServiceRestInterceptor, "pre_delete_region" - ) as pre: - pre.assert_not_called() - pb_message = regions.DeleteRegionRequest.pb(regions.DeleteRegionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = regions.DeleteRegionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_region( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_region_rest_bad_request( - transport: str = "rest", request_type=regions.DeleteRegionRequest -): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/regions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_region(request) - - def test_delete_region_rest_flattened(): client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4507,52 +3684,6 @@ def test_delete_region_rest_flattened_error(transport: str = "rest"): ) -def test_delete_region_rest_error(): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - regions.ListRegionsRequest, - dict, - ], -) -def test_list_regions_rest(request_type): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regions.ListRegionsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regions.ListRegionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_regions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListRegionsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_regions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4685,6 +3816,1159 @@ def test_list_regions_rest_unset_required_fields(): ) +def test_list_regions_rest_flattened(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regions.ListRegionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = regions.ListRegionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_regions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{parent=accounts/*}/regions" % client.transport._host, + args[1], + ) + + +def test_list_regions_rest_flattened_error(transport: str = "rest"): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_regions( + regions.ListRegionsRequest(), + parent="parent_value", + ) + + +def test_list_regions_rest_pager(transport: str = "rest"): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + regions.ListRegionsResponse( + regions=[ + regions.Region(), + regions.Region(), + regions.Region(), + ], + next_page_token="abc", + ), + regions.ListRegionsResponse( + regions=[], + next_page_token="def", + ), + regions.ListRegionsResponse( + regions=[ + regions.Region(), + ], + next_page_token="ghi", + ), + regions.ListRegionsResponse( + regions=[ + regions.Region(), + regions.Region(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(regions.ListRegionsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_regions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, regions.Region) for i in results) + + pages = list(client.list_regions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.RegionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.RegionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RegionsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.RegionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RegionsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RegionsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.RegionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RegionsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.RegionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = RegionsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.RegionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.RegionsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RegionsServiceGrpcTransport, + transports.RegionsServiceGrpcAsyncIOTransport, + transports.RegionsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = RegionsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_region_empty_call_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_region), "__call__") as call: + call.return_value = regions.Region() + client.get_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.GetRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_region_empty_call_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_region), "__call__") as call: + call.return_value = regions.Region() + client.create_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.CreateRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_region_empty_call_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_region), "__call__") as call: + call.return_value = regions.Region() + client.update_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.UpdateRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_region_empty_call_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_region), "__call__") as call: + call.return_value = None + client.delete_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.DeleteRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_regions_empty_call_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_regions), "__call__") as call: + call.return_value = regions.ListRegionsResponse() + client.list_regions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.ListRegionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = RegionsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = RegionsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_region_empty_call_grpc_asyncio(): + client = RegionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_region), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + regions.Region( + name="name_value", + display_name="display_name_value", + ) + ) + await client.get_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.GetRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_region_empty_call_grpc_asyncio(): + client = RegionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_region), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + regions.Region( + name="name_value", + display_name="display_name_value", + ) + ) + await client.create_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.CreateRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_region_empty_call_grpc_asyncio(): + client = RegionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_region), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + regions.Region( + name="name_value", + display_name="display_name_value", + ) + ) + await client.update_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.UpdateRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_region_empty_call_grpc_asyncio(): + client = RegionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_region), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_region(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.DeleteRegionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_regions_empty_call_grpc_asyncio(): + client = RegionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_regions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + regions.ListRegionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_regions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.ListRegionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = RegionsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_region_rest_bad_request(request_type=regions.GetRegionRequest): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/regions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_region(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regions.GetRegionRequest, + dict, + ], +) +def test_get_region_rest_call_success(request_type): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/regions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regions.Region( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = regions.Region.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_region(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, regions.Region) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_region_rest_interceptors(null_interceptor): + transport = transports.RegionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RegionsServiceRestInterceptor(), + ) + client = RegionsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RegionsServiceRestInterceptor, "post_get_region" + ) as post, mock.patch.object( + transports.RegionsServiceRestInterceptor, "pre_get_region" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = regions.GetRegionRequest.pb(regions.GetRegionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = regions.Region.to_json(regions.Region()) + req.return_value.content = return_value + + request = regions.GetRegionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = regions.Region() + + client.get_region( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_region_rest_bad_request(request_type=regions.CreateRegionRequest): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_region(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regions.CreateRegionRequest, + dict, + ], +) +def test_create_region_rest_call_success(request_type): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["region"] = { + "name": "name_value", + "display_name": "display_name_value", + "postal_code_area": { + "region_code": "region_code_value", + "postal_codes": [{"begin": "begin_value", "end": "end_value"}], + }, + "geotarget_area": {"geotarget_criteria_ids": [2324, 2325]}, + "regional_inventory_eligible": {"value": True}, + "shipping_eligible": {}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = regions.CreateRegionRequest.meta.fields["region"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["region"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["region"][field])): + del request_init["region"][field][i][subfield] + else: + del request_init["region"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regions.Region( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = regions.Region.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_region(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, regions.Region) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_region_rest_interceptors(null_interceptor): + transport = transports.RegionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RegionsServiceRestInterceptor(), + ) + client = RegionsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RegionsServiceRestInterceptor, "post_create_region" + ) as post, mock.patch.object( + transports.RegionsServiceRestInterceptor, "pre_create_region" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = regions.CreateRegionRequest.pb(regions.CreateRegionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = regions.Region.to_json(regions.Region()) + req.return_value.content = return_value + + request = regions.CreateRegionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = regions.Region() + + client.create_region( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_region_rest_bad_request(request_type=regions.UpdateRegionRequest): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"region": {"name": "accounts/sample1/regions/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_region(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regions.UpdateRegionRequest, + dict, + ], +) +def test_update_region_rest_call_success(request_type): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"region": {"name": "accounts/sample1/regions/sample2"}} + request_init["region"] = { + "name": "accounts/sample1/regions/sample2", + "display_name": "display_name_value", + "postal_code_area": { + "region_code": "region_code_value", + "postal_codes": [{"begin": "begin_value", "end": "end_value"}], + }, + "geotarget_area": {"geotarget_criteria_ids": [2324, 2325]}, + "regional_inventory_eligible": {"value": True}, + "shipping_eligible": {}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = regions.UpdateRegionRequest.meta.fields["region"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["region"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["region"][field])): + del request_init["region"][field][i][subfield] + else: + del request_init["region"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regions.Region( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = regions.Region.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_region(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, regions.Region) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_region_rest_interceptors(null_interceptor): + transport = transports.RegionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RegionsServiceRestInterceptor(), + ) + client = RegionsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RegionsServiceRestInterceptor, "post_update_region" + ) as post, mock.patch.object( + transports.RegionsServiceRestInterceptor, "pre_update_region" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = regions.UpdateRegionRequest.pb(regions.UpdateRegionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = regions.Region.to_json(regions.Region()) + req.return_value.content = return_value + + request = regions.UpdateRegionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = regions.Region() + + client.update_region( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_region_rest_bad_request(request_type=regions.DeleteRegionRequest): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/regions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_region(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regions.DeleteRegionRequest, + dict, + ], +) +def test_delete_region_rest_call_success(request_type): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/regions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_region(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_region_rest_interceptors(null_interceptor): + transport = transports.RegionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RegionsServiceRestInterceptor(), + ) + client = RegionsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RegionsServiceRestInterceptor, "pre_delete_region" + ) as pre: + pre.assert_not_called() + pb_message = regions.DeleteRegionRequest.pb(regions.DeleteRegionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = regions.DeleteRegionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_region( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_list_regions_rest_bad_request(request_type=regions.ListRegionsRequest): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_regions(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regions.ListRegionsRequest, + dict, + ], +) +def test_list_regions_rest_call_success(request_type): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regions.ListRegionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = regions.ListRegionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_regions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRegionsPager) + assert response.next_page_token == "next_page_token_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) def test_list_regions_rest_interceptors(null_interceptor): transport = transports.RegionsServiceRestTransport( @@ -4694,6 +4978,7 @@ def test_list_regions_rest_interceptors(null_interceptor): else transports.RegionsServiceRestInterceptor(), ) client = RegionsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -4713,12 +4998,12 @@ def test_list_regions_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = regions.ListRegionsResponse.to_json( + return_value = regions.ListRegionsResponse.to_json( regions.ListRegionsResponse() ) + req.return_value.content = return_value request = regions.ListRegionsRequest() metadata = [ @@ -4740,251 +5025,111 @@ def test_list_regions_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_regions_rest_bad_request( - transport: str = "rest", request_type=regions.ListRegionsRequest -): +def test_initialize_client_w_rest(): client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_regions(request) + assert client is not None -def test_list_regions_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_region_empty_call_rest(): client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regions.ListRegionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regions.ListRegionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_regions(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{parent=accounts/*}/regions" % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_region), "__call__") as call: + client.get_region(request=None) -def test_list_regions_rest_flattened_error(transport: str = "rest"): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.GetRegionRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_regions( - regions.ListRegionsRequest(), - parent="parent_value", - ) + assert args[0] == request_msg -def test_list_regions_rest_pager(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_region_empty_call_rest(): client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - regions.ListRegionsResponse( - regions=[ - regions.Region(), - regions.Region(), - regions.Region(), - ], - next_page_token="abc", - ), - regions.ListRegionsResponse( - regions=[], - next_page_token="def", - ), - regions.ListRegionsResponse( - regions=[ - regions.Region(), - ], - next_page_token="ghi", - ), - regions.ListRegionsResponse( - regions=[ - regions.Region(), - regions.Region(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(regions.ListRegionsResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_regions(request=sample_request) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_region), "__call__") as call: + client.create_region(request=None) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, regions.Region) for i in results) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.CreateRegionRequest() - pages = list(client.list_regions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + assert args[0] == request_msg -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.RegionsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_region_empty_call_rest(): + client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.RegionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = RegionsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_region), "__call__") as call: + client.update_region(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.RegionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = RegionsServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.UpdateRegionRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = RegionsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.RegionsServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_region_empty_call_rest(): + client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = RegionsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_region), "__call__") as call: + client.delete_region(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.RegionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = RegionsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.DeleteRegionRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.RegionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.RegionsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_regions_empty_call_rest(): + client = RegionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.RegionsServiceGrpcTransport, - transports.RegionsServiceGrpcAsyncIOTransport, - transports.RegionsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_regions), "__call__") as call: + client.list_regions(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regions.ListRegionsRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = RegionsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -5595,36 +5740,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = RegionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = RegionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = RegionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py index e5c3a1557a94..f0d632d6c795 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_shipping_settings_service.py @@ -22,20 +22,12 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format -from google.shopping.type.types import types import grpc from grpc.experimental import aio from proto.marshal.rules import wrappers @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.shopping.type.types import types + from google.shopping.merchant_accounts_v1beta.services.shipping_settings_service import ( ShippingSettingsServiceAsyncClient, ShippingSettingsServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_accounts_v1beta.types import shippingsettings +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1229,27 +1252,6 @@ def test_get_shipping_settings(request_type, transport: str = "grpc"): assert response.etag == "etag_value" -def test_get_shipping_settings_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_shipping_settings), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_shipping_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == shippingsettings.GetShippingSettingsRequest() - - def test_get_shipping_settings_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1320,32 +1322,6 @@ def test_get_shipping_settings_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_shipping_settings_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_shipping_settings), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - shippingsettings.ShippingSettings( - name="name_value", - etag="etag_value", - ) - ) - response = await client.get_shipping_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == shippingsettings.GetShippingSettingsRequest() - - @pytest.mark.asyncio async def test_get_shipping_settings_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1354,7 +1330,7 @@ async def test_get_shipping_settings_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1394,7 +1370,7 @@ async def test_get_shipping_settings_async( request_type=shippingsettings.GetShippingSettingsRequest, ): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1466,7 +1442,7 @@ def test_get_shipping_settings_field_headers(): @pytest.mark.asyncio async def test_get_shipping_settings_field_headers_async(): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1540,7 +1516,7 @@ def test_get_shipping_settings_flattened_error(): @pytest.mark.asyncio async def test_get_shipping_settings_flattened_async(): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1571,7 +1547,7 @@ async def test_get_shipping_settings_flattened_async(): @pytest.mark.asyncio async def test_get_shipping_settings_flattened_error_async(): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1623,27 +1599,6 @@ def test_insert_shipping_settings(request_type, transport: str = "grpc"): assert response.etag == "etag_value" -def test_insert_shipping_settings_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_shipping_settings), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_shipping_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == shippingsettings.InsertShippingSettingsRequest() - - def test_insert_shipping_settings_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1714,32 +1669,6 @@ def test_insert_shipping_settings_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_shipping_settings_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_shipping_settings), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - shippingsettings.ShippingSettings( - name="name_value", - etag="etag_value", - ) - ) - response = await client.insert_shipping_settings() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == shippingsettings.InsertShippingSettingsRequest() - - @pytest.mark.asyncio async def test_insert_shipping_settings_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1748,7 +1677,7 @@ async def test_insert_shipping_settings_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1788,7 +1717,7 @@ async def test_insert_shipping_settings_async( request_type=shippingsettings.InsertShippingSettingsRequest, ): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1860,7 +1789,7 @@ def test_insert_shipping_settings_field_headers(): @pytest.mark.asyncio async def test_insert_shipping_settings_field_headers_async(): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1891,48 +1820,6 @@ async def test_insert_shipping_settings_field_headers_async(): ) in kw["metadata"] -@pytest.mark.parametrize( - "request_type", - [ - shippingsettings.GetShippingSettingsRequest, - dict, - ], -) -def test_get_shipping_settings_rest(request_type): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/shippingSettings"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = shippingsettings.ShippingSettings( - name="name_value", - etag="etag_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = shippingsettings.ShippingSettings.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_shipping_settings(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, shippingsettings.ShippingSettings) - assert response.name == "name_value" - assert response.etag == "etag_value" - - def test_get_shipping_settings_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2057,87 +1944,6 @@ def test_get_shipping_settings_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_shipping_settings_rest_interceptors(null_interceptor): - transport = transports.ShippingSettingsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ShippingSettingsServiceRestInterceptor(), - ) - client = ShippingSettingsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ShippingSettingsServiceRestInterceptor, "post_get_shipping_settings" - ) as post, mock.patch.object( - transports.ShippingSettingsServiceRestInterceptor, "pre_get_shipping_settings" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = shippingsettings.GetShippingSettingsRequest.pb( - shippingsettings.GetShippingSettingsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = shippingsettings.ShippingSettings.to_json( - shippingsettings.ShippingSettings() - ) - - request = shippingsettings.GetShippingSettingsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = shippingsettings.ShippingSettings() - - client.get_shipping_settings( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_shipping_settings_rest_bad_request( - transport: str = "rest", request_type=shippingsettings.GetShippingSettingsRequest -): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/shippingSettings"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_shipping_settings(request) - - def test_get_shipping_settings_rest_flattened(): client = ShippingSettingsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2195,27 +2001,533 @@ def test_get_shipping_settings_rest_flattened_error(transport: str = "rest"): ) -def test_get_shipping_settings_rest_error(): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_insert_shipping_settings_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - shippingsettings.InsertShippingSettingsRequest, - dict, - ], -) -def test_insert_shipping_settings_rest(request_type): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Ensure method has been cached + assert ( + client._transport.insert_shipping_settings + in client._transport._wrapped_methods + ) - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.insert_shipping_settings + ] = mock_rpc + + request = {} + client.insert_shipping_settings(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.insert_shipping_settings(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_insert_shipping_settings_rest_required_fields( + request_type=shippingsettings.InsertShippingSettingsRequest, +): + transport_class = transports.ShippingSettingsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).insert_shipping_settings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).insert_shipping_settings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = shippingsettings.ShippingSettings() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = shippingsettings.ShippingSettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.insert_shipping_settings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_insert_shipping_settings_rest_unset_required_fields(): + transport = transports.ShippingSettingsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.insert_shipping_settings._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "shippingSetting", + ) + ) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ShippingSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ShippingSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ShippingSettingsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ShippingSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ShippingSettingsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ShippingSettingsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ShippingSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ShippingSettingsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ShippingSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ShippingSettingsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ShippingSettingsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ShippingSettingsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ShippingSettingsServiceGrpcTransport, + transports.ShippingSettingsServiceGrpcAsyncIOTransport, + transports.ShippingSettingsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = ShippingSettingsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_shipping_settings_empty_call_grpc(): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_shipping_settings), "__call__" + ) as call: + call.return_value = shippingsettings.ShippingSettings() + client.get_shipping_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = shippingsettings.GetShippingSettingsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_shipping_settings_empty_call_grpc(): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_shipping_settings), "__call__" + ) as call: + call.return_value = shippingsettings.ShippingSettings() + client.insert_shipping_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = shippingsettings.InsertShippingSettingsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ShippingSettingsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ShippingSettingsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_shipping_settings_empty_call_grpc_asyncio(): + client = ShippingSettingsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_shipping_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + shippingsettings.ShippingSettings( + name="name_value", + etag="etag_value", + ) + ) + await client.get_shipping_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = shippingsettings.GetShippingSettingsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_shipping_settings_empty_call_grpc_asyncio(): + client = ShippingSettingsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_shipping_settings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + shippingsettings.ShippingSettings( + name="name_value", + etag="etag_value", + ) + ) + await client.insert_shipping_settings(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = shippingsettings.InsertShippingSettingsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ShippingSettingsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_shipping_settings_rest_bad_request( + request_type=shippingsettings.GetShippingSettingsRequest, +): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/shippingSettings"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_shipping_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + shippingsettings.GetShippingSettingsRequest, + dict, + ], +) +def test_get_shipping_settings_rest_call_success(request_type): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/shippingSettings"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = shippingsettings.ShippingSettings( + name="name_value", + etag="etag_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = shippingsettings.ShippingSettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_shipping_settings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, shippingsettings.ShippingSettings) + assert response.name == "name_value" + assert response.etag == "etag_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_shipping_settings_rest_interceptors(null_interceptor): + transport = transports.ShippingSettingsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ShippingSettingsServiceRestInterceptor(), + ) + client = ShippingSettingsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ShippingSettingsServiceRestInterceptor, "post_get_shipping_settings" + ) as post, mock.patch.object( + transports.ShippingSettingsServiceRestInterceptor, "pre_get_shipping_settings" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = shippingsettings.GetShippingSettingsRequest.pb( + shippingsettings.GetShippingSettingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = shippingsettings.ShippingSettings.to_json( + shippingsettings.ShippingSettings() + ) + req.return_value.content = return_value + + request = shippingsettings.GetShippingSettingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = shippingsettings.ShippingSettings() + + client.get_shipping_settings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_insert_shipping_settings_rest_bad_request( + request_type=shippingsettings.InsertShippingSettingsRequest, +): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_shipping_settings(request) + + +@pytest.mark.parametrize( + "request_type", + [ + shippingsettings.InsertShippingSettingsRequest, + dict, + ], +) +def test_insert_shipping_settings_rest_call_success(request_type): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} request_init["shipping_setting"] = { "name": "name_value", "services": [ @@ -2365,232 +2677,99 @@ def test_insert_shipping_settings_rest(request_type): "etag": "etag_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = shippingsettings.InsertShippingSettingsRequest.meta.fields[ - "shipping_setting" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["shipping_setting"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["shipping_setting"][field])): - del request_init["shipping_setting"][field][i][subfield] - else: - del request_init["shipping_setting"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = shippingsettings.ShippingSettings( - name="name_value", - etag="etag_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = shippingsettings.ShippingSettings.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_shipping_settings(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, shippingsettings.ShippingSettings) - assert response.name == "name_value" - assert response.etag == "etag_value" - - -def test_insert_shipping_settings_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.insert_shipping_settings - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.insert_shipping_settings - ] = mock_rpc - - request = {} - client.insert_shipping_settings(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.insert_shipping_settings(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_insert_shipping_settings_rest_required_fields( - request_type=shippingsettings.InsertShippingSettingsRequest, -): - transport_class = transports.ShippingSettingsServiceRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).insert_shipping_settings._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).insert_shipping_settings._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = shippingsettings.ShippingSettings() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 - response_value = Response() - response_value.status_code = 200 + # Determine if the message type is proto-plus or protobuf + test_field = shippingsettings.InsertShippingSettingsRequest.meta.fields[ + "shipping_setting" + ] - # Convert return value to protobuf type - return_value = shippingsettings.ShippingSettings.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - response = client.insert_shipping_settings(request) + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + subfields_not_in_runtime = [] -def test_insert_shipping_settings_rest_unset_required_fields(): - transport = transports.ShippingSettingsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["shipping_setting"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value - unset_fields = transport.insert_shipping_settings._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "parent", - "shippingSetting", - ) + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["shipping_setting"][field])): + del request_init["shipping_setting"][field][i][subfield] + else: + del request_init["shipping_setting"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = shippingsettings.ShippingSettings( + name="name_value", + etag="etag_value", ) - ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = shippingsettings.ShippingSettings.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_shipping_settings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, shippingsettings.ShippingSettings) + assert response.name == "name_value" + assert response.etag == "etag_value" @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -2602,6 +2781,7 @@ def test_insert_shipping_settings_rest_interceptors(null_interceptor): else transports.ShippingSettingsServiceRestInterceptor(), ) client = ShippingSettingsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2625,12 +2805,12 @@ def test_insert_shipping_settings_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = shippingsettings.ShippingSettings.to_json( + return_value = shippingsettings.ShippingSettings.to_json( shippingsettings.ShippingSettings() ) + req.return_value.content = return_value request = shippingsettings.InsertShippingSettingsRequest() metadata = [ @@ -2652,140 +2832,55 @@ def test_insert_shipping_settings_rest_interceptors(null_interceptor): post.assert_called_once() -def test_insert_shipping_settings_rest_bad_request( - transport: str = "rest", request_type=shippingsettings.InsertShippingSettingsRequest -): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_shipping_settings(request) - - -def test_insert_shipping_settings_rest_error(): +def test_initialize_client_w_rest(): client = ShippingSettingsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ShippingSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.ShippingSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ShippingSettingsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.ShippingSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ShippingSettingsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ShippingSettingsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ShippingSettingsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_shipping_settings_empty_call_rest(): + client = ShippingSettingsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ShippingSettingsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_shipping_settings), "__call__" + ) as call: + client.get_shipping_settings(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ShippingSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ShippingSettingsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = shippingsettings.GetShippingSettingsRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ShippingSettingsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.ShippingSettingsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_shipping_settings_empty_call_rest(): + client = ShippingSettingsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ShippingSettingsServiceGrpcTransport, - transports.ShippingSettingsServiceGrpcAsyncIOTransport, - transports.ShippingSettingsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_shipping_settings), "__call__" + ) as call: + client.insert_shipping_settings(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = shippingsettings.InsertShippingSettingsRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = ShippingSettingsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3365,36 +3460,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = ShippingSettingsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ShippingSettingsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = ShippingSettingsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py index eeed3bd18c59..42e58e531a89 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_agreement_state_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_accounts_v1beta.services.terms_of_service_agreement_state_service import ( TermsOfServiceAgreementStateServiceAsyncClient, TermsOfServiceAgreementStateServiceClient, @@ -54,10 +63,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1277,30 +1300,6 @@ def test_get_terms_of_service_agreement_state(request_type, transport: str = "gr ) -def test_get_terms_of_service_agreement_state_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_terms_of_service_agreement_state), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_terms_of_service_agreement_state() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert ( - args[0] - == termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() - ) - - def test_get_terms_of_service_agreement_state_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1373,36 +1372,6 @@ def test_get_terms_of_service_agreement_state_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_terms_of_service_agreement_state_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_terms_of_service_agreement_state), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - termsofserviceagreementstate.TermsOfServiceAgreementState( - name="name_value", - region_code="region_code_value", - terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - ) - ) - response = await client.get_terms_of_service_agreement_state() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert ( - args[0] - == termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() - ) - - @pytest.mark.asyncio async def test_get_terms_of_service_agreement_state_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1411,7 +1380,7 @@ async def test_get_terms_of_service_agreement_state_async_use_cached_wrapped_rpc # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1451,7 +1420,7 @@ async def test_get_terms_of_service_agreement_state_async( request_type=termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, ): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1530,7 +1499,7 @@ def test_get_terms_of_service_agreement_state_field_headers(): @pytest.mark.asyncio async def test_get_terms_of_service_agreement_state_field_headers_async(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1604,7 +1573,7 @@ def test_get_terms_of_service_agreement_state_flattened_error(): @pytest.mark.asyncio async def test_get_terms_of_service_agreement_state_flattened_async(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1635,7 +1604,7 @@ async def test_get_terms_of_service_agreement_state_flattened_async(): @pytest.mark.asyncio async def test_get_terms_of_service_agreement_state_flattened_error_async(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1703,33 +1672,6 @@ def test_retrieve_for_application_terms_of_service_agreement_state( ) -def test_retrieve_for_application_terms_of_service_agreement_state_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type( - client.transport.retrieve_for_application_terms_of_service_agreement_state - ), - "__call__", - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.retrieve_for_application_terms_of_service_agreement_state() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert ( - args[0] - == termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest() - ) - - def test_retrieve_for_application_terms_of_service_agreement_state_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1807,41 +1749,6 @@ def test_retrieve_for_application_terms_of_service_agreement_state_use_cached_wr assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_retrieve_for_application_terms_of_service_agreement_state_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type( - client.transport.retrieve_for_application_terms_of_service_agreement_state - ), - "__call__", - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - termsofserviceagreementstate.TermsOfServiceAgreementState( - name="name_value", - region_code="region_code_value", - terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - ) - ) - response = ( - await client.retrieve_for_application_terms_of_service_agreement_state() - ) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert ( - args[0] - == termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest() - ) - - @pytest.mark.asyncio async def test_retrieve_for_application_terms_of_service_agreement_state_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1850,7 +1757,7 @@ async def test_retrieve_for_application_terms_of_service_agreement_state_async_u # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1890,7 +1797,7 @@ async def test_retrieve_for_application_terms_of_service_agreement_state_async( request_type=termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, ): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1985,7 +1892,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_field_headers @pytest.mark.asyncio async def test_retrieve_for_application_terms_of_service_agreement_state_field_headers_async(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2067,7 +1974,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_flattened_err @pytest.mark.asyncio async def test_retrieve_for_application_terms_of_service_agreement_state_flattened_async(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2103,7 +2010,7 @@ async def test_retrieve_for_application_terms_of_service_agreement_state_flatten @pytest.mark.asyncio async def test_retrieve_for_application_terms_of_service_agreement_state_flattened_error_async(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2115,57 +2022,6 @@ async def test_retrieve_for_application_terms_of_service_agreement_state_flatten ) -@pytest.mark.parametrize( - "request_type", - [ - termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, - dict, - ], -) -def test_get_terms_of_service_agreement_state_rest(request_type): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/termsOfServiceAgreementStates/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState( - name="name_value", - region_code="region_code_value", - terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_terms_of_service_agreement_state(request) - - # Establish that the response is the type that we expect. - assert isinstance( - response, termsofserviceagreementstate.TermsOfServiceAgreementState - ) - assert response.name == "name_value" - assert response.region_code == "region_code_value" - assert ( - response.terms_of_service_kind - == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER - ) - - def test_get_terms_of_service_agreement_state_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2294,128 +2150,40 @@ def test_get_terms_of_service_agreement_state_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_terms_of_service_agreement_state_rest_interceptors(null_interceptor): - transport = transports.TermsOfServiceAgreementStateServiceRestTransport( +def test_get_terms_of_service_agreement_state_rest_flattened(): + client = TermsOfServiceAgreementStateServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.TermsOfServiceAgreementStateServiceRestInterceptor(), + transport="rest", ) - client = TermsOfServiceAgreementStateServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.TermsOfServiceAgreementStateServiceRestInterceptor, - "post_get_terms_of_service_agreement_state", - ) as post, mock.patch.object( - transports.TermsOfServiceAgreementStateServiceRestInterceptor, - "pre_get_terms_of_service_agreement_state", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = ( - termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest.pb( - termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() - ) - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - termsofserviceagreementstate.TermsOfServiceAgreementState.to_json( - termsofserviceagreementstate.TermsOfServiceAgreementState() - ) - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() - request = termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "accounts/sample1/termsOfServiceAgreementStates/sample2" + } - client.get_terms_of_service_agreement_state( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) + mock_args.update(sample_request) - pre.assert_called_once() - post.assert_called_once() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value - -def test_get_terms_of_service_agreement_state_rest_bad_request( - transport: str = "rest", - request_type=termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, -): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/termsOfServiceAgreementStates/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_terms_of_service_agreement_state(request) - - -def test_get_terms_of_service_agreement_state_rest_flattened(): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "accounts/sample1/termsOfServiceAgreementStates/sample2" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_terms_of_service_agreement_state(**mock_args) + client.get_terms_of_service_agreement_state(**mock_args) # Establish that the underlying call was made with the expected # request object values. @@ -2445,65 +2213,6 @@ def test_get_terms_of_service_agreement_state_rest_flattened_error( ) -def test_get_terms_of_service_agreement_state_rest_error(): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, - dict, - ], -) -def test_retrieve_for_application_terms_of_service_agreement_state_rest(request_type): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState( - name="name_value", - region_code="region_code_value", - terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.retrieve_for_application_terms_of_service_agreement_state( - request - ) - - # Establish that the response is the type that we expect. - assert isinstance( - response, termsofserviceagreementstate.TermsOfServiceAgreementState - ) - assert response.name == "name_value" - assert response.region_code == "region_code_value" - assert ( - response.terms_of_service_kind - == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER - ) - - def test_retrieve_for_application_terms_of_service_agreement_state_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2615,27 +2324,555 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_required ) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.retrieve_for_application_terms_of_service_agreement_state( + request + ) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_retrieve_for_application_terms_of_service_agreement_state_rest_unset_required_fields(): + transport = transports.TermsOfServiceAgreementStateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.retrieve_for_application_terms_of_service_agreement_state._get_unset_required_fields( + {} + ) + assert set(unset_fields) == (set(()) & set(("parent",))) + + +def test_retrieve_for_application_terms_of_service_agreement_state_rest_flattened(): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.retrieve_for_application_terms_of_service_agreement_state(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{parent=accounts/*}/termsOfServiceAgreementStates:retrieveForApplication" + % client.transport._host, + args[1], + ) + + +def test_retrieve_for_application_terms_of_service_agreement_state_rest_flattened_error( + transport: str = "rest", +): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.retrieve_for_application_terms_of_service_agreement_state( + termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest(), + parent="parent_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TermsOfServiceAgreementStateServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = TermsOfServiceAgreementStateServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = TermsOfServiceAgreementStateServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TermsOfServiceAgreementStateServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = TermsOfServiceAgreementStateServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.TermsOfServiceAgreementStateServiceGrpcTransport, + transports.TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport, + transports.TermsOfServiceAgreementStateServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = TermsOfServiceAgreementStateServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_terms_of_service_agreement_state_empty_call_grpc(): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_terms_of_service_agreement_state), "__call__" + ) as call: + call.return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() + client.get_terms_of_service_agreement_state(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() + ) + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_retrieve_for_application_terms_of_service_agreement_state_empty_call_grpc(): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type( + client.transport.retrieve_for_application_terms_of_service_agreement_state + ), + "__call__", + ) as call: + call.return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() + client.retrieve_for_application_terms_of_service_agreement_state(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest() + ) + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = TermsOfServiceAgreementStateServiceAsyncClient.get_transport_class( + "grpc_asyncio" + )(credentials=async_anonymous_credentials()) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = TermsOfServiceAgreementStateServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_terms_of_service_agreement_state_empty_call_grpc_asyncio(): + client = TermsOfServiceAgreementStateServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_terms_of_service_agreement_state), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + termsofserviceagreementstate.TermsOfServiceAgreementState( + name="name_value", + region_code="region_code_value", + terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + ) + ) + await client.get_terms_of_service_agreement_state(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() + ) + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_retrieve_for_application_terms_of_service_agreement_state_empty_call_grpc_asyncio(): + client = TermsOfServiceAgreementStateServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type( + client.transport.retrieve_for_application_terms_of_service_agreement_state + ), + "__call__", + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + termsofserviceagreementstate.TermsOfServiceAgreementState( + name="name_value", + region_code="region_code_value", + terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + ) + ) + await client.retrieve_for_application_terms_of_service_agreement_state( + request=None + ) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest() + ) + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = TermsOfServiceAgreementStateServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_terms_of_service_agreement_state_rest_bad_request( + request_type=termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, +): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/termsOfServiceAgreementStates/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_terms_of_service_agreement_state(request) + + +@pytest.mark.parametrize( + "request_type", + [ + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest, + dict, + ], +) +def test_get_terms_of_service_agreement_state_rest_call_success(request_type): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/termsOfServiceAgreementStates/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState( + name="name_value", + region_code="region_code_value", + terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_terms_of_service_agreement_state(request) + + # Establish that the response is the type that we expect. + assert isinstance( + response, termsofserviceagreementstate.TermsOfServiceAgreementState + ) + assert response.name == "name_value" + assert response.region_code == "region_code_value" + assert ( + response.terms_of_service_kind + == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_terms_of_service_agreement_state_rest_interceptors(null_interceptor): + transport = transports.TermsOfServiceAgreementStateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TermsOfServiceAgreementStateServiceRestInterceptor(), + ) + client = TermsOfServiceAgreementStateServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TermsOfServiceAgreementStateServiceRestInterceptor, + "post_get_terms_of_service_agreement_state", + ) as post, mock.patch.object( + transports.TermsOfServiceAgreementStateServiceRestInterceptor, + "pre_get_terms_of_service_agreement_state", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = ( + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest.pb( + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() + ) + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = ( + termsofserviceagreementstate.TermsOfServiceAgreementState.to_json( + termsofserviceagreementstate.TermsOfServiceAgreementState() + ) + ) + req.return_value.content = return_value + + request = termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() + + client.get_terms_of_service_agreement_state( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_retrieve_for_application_terms_of_service_agreement_state_rest_bad_request( + request_type=termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, +): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.retrieve_for_application_terms_of_service_agreement_state(request) + + +@pytest.mark.parametrize( + "request_type", + [ + termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, + dict, + ], +) +def test_retrieve_for_application_terms_of_service_agreement_state_rest_call_success( + request_type, +): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) - response = client.retrieve_for_application_terms_of_service_agreement_state( - request - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState( + name="name_value", + region_code="region_code_value", + terms_of_service_kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.retrieve_for_application_terms_of_service_agreement_state( + request + ) -def test_retrieve_for_application_terms_of_service_agreement_state_rest_unset_required_fields(): - transport = transports.TermsOfServiceAgreementStateServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials + # Establish that the response is the type that we expect. + assert isinstance( + response, termsofserviceagreementstate.TermsOfServiceAgreementState ) - - unset_fields = transport.retrieve_for_application_terms_of_service_agreement_state._get_unset_required_fields( - {} + assert response.name == "name_value" + assert response.region_code == "region_code_value" + assert ( + response.terms_of_service_kind + == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER ) - assert set(unset_fields) == (set(()) & set(("parent",))) @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -2649,6 +2886,7 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_intercep else transports.TermsOfServiceAgreementStateServiceRestInterceptor(), ) client = TermsOfServiceAgreementStateServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -2672,14 +2910,14 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_intercep "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( + return_value = ( termsofserviceagreementstate.TermsOfServiceAgreementState.to_json( termsofserviceagreementstate.TermsOfServiceAgreementState() ) ) + req.return_value.content = return_value request = ( termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest() @@ -2703,204 +2941,62 @@ def test_retrieve_for_application_terms_of_service_agreement_state_rest_intercep post.assert_called_once() -def test_retrieve_for_application_terms_of_service_agreement_state_rest_bad_request( - transport: str = "rest", - request_type=termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest, -): +def test_initialize_client_w_rest(): client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.retrieve_for_application_terms_of_service_agreement_state(request) + assert client is not None -def test_retrieve_for_application_terms_of_service_agreement_state_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_terms_of_service_agreement_state_empty_call_rest(): client = TermsOfServiceAgreementStateServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = termsofserviceagreementstate.TermsOfServiceAgreementState.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.retrieve_for_application_terms_of_service_agreement_state(**mock_args) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_terms_of_service_agreement_state), "__call__" + ) as call: + client.get_terms_of_service_agreement_state(request=None) - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{parent=accounts/*}/termsOfServiceAgreementStates:retrieveForApplication" - % client.transport._host, - args[1], + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + termsofserviceagreementstate.GetTermsOfServiceAgreementStateRequest() ) - -def test_retrieve_for_application_terms_of_service_agreement_state_rest_flattened_error( - transport: str = "rest", -): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.retrieve_for_application_terms_of_service_agreement_state( - termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest(), - parent="parent_value", - ) + assert args[0] == request_msg -def test_retrieve_for_application_terms_of_service_agreement_state_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_retrieve_for_application_terms_of_service_agreement_state_empty_call_rest(): client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = TermsOfServiceAgreementStateServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = TermsOfServiceAgreementStateServiceClient( - client_options=options, - transport=transport, - ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = TermsOfServiceAgreementStateServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type( + client.transport.retrieve_for_application_terms_of_service_agreement_state + ), + "__call__", + ) as call: + client.retrieve_for_application_terms_of_service_agreement_state(request=None) - # It is an error to provide scopes and a transport instance. - transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = TermsOfServiceAgreementStateServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ( + termsofserviceagreementstate.RetrieveForApplicationTermsOfServiceAgreementStateRequest() ) - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = TermsOfServiceAgreementStateServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.TermsOfServiceAgreementStateServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.TermsOfServiceAgreementStateServiceGrpcTransport, - transports.TermsOfServiceAgreementStateServiceGrpcAsyncIOTransport, - transports.TermsOfServiceAgreementStateServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = TermsOfServiceAgreementStateServiceClient.get_transport_class( - transport_name - )( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3566,36 +3662,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = TermsOfServiceAgreementStateServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = TermsOfServiceAgreementStateServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = TermsOfServiceAgreementStateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py index 4ea60222ebc9..aee2172ae17b 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_terms_of_service_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_accounts_v1beta.services.terms_of_service_service import ( TermsOfServiceServiceAsyncClient, TermsOfServiceServiceClient, @@ -54,10 +63,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1237,27 +1260,6 @@ def test_get_terms_of_service(request_type, transport: str = "grpc"): assert response.external is True -def test_get_terms_of_service_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_terms_of_service), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_terms_of_service() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == termsofservice.GetTermsOfServiceRequest() - - def test_get_terms_of_service_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1327,35 +1329,6 @@ def test_get_terms_of_service_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_terms_of_service_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_terms_of_service), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - termsofservice.TermsOfService( - name="name_value", - region_code="region_code_value", - kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - file_uri="file_uri_value", - external=True, - ) - ) - response = await client.get_terms_of_service() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == termsofservice.GetTermsOfServiceRequest() - - @pytest.mark.asyncio async def test_get_terms_of_service_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1364,7 +1337,7 @@ async def test_get_terms_of_service_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1404,7 +1377,7 @@ async def test_get_terms_of_service_async( request_type=termsofservice.GetTermsOfServiceRequest, ): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1482,7 +1455,7 @@ def test_get_terms_of_service_field_headers(): @pytest.mark.asyncio async def test_get_terms_of_service_field_headers_async(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1556,7 +1529,7 @@ def test_get_terms_of_service_flattened_error(): @pytest.mark.asyncio async def test_get_terms_of_service_flattened_async(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1587,7 +1560,7 @@ async def test_get_terms_of_service_flattened_async(): @pytest.mark.asyncio async def test_get_terms_of_service_flattened_error_async(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1645,27 +1618,6 @@ def test_retrieve_latest_terms_of_service(request_type, transport: str = "grpc") assert response.external is True -def test_retrieve_latest_terms_of_service_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.retrieve_latest_terms_of_service), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.retrieve_latest_terms_of_service() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == termsofservice.RetrieveLatestTermsOfServiceRequest() - - def test_retrieve_latest_terms_of_service_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1736,35 +1688,6 @@ def test_retrieve_latest_terms_of_service_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_retrieve_latest_terms_of_service_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.retrieve_latest_terms_of_service), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - termsofservice.TermsOfService( - name="name_value", - region_code="region_code_value", - kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - file_uri="file_uri_value", - external=True, - ) - ) - response = await client.retrieve_latest_terms_of_service() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == termsofservice.RetrieveLatestTermsOfServiceRequest() - - @pytest.mark.asyncio async def test_retrieve_latest_terms_of_service_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1773,7 +1696,7 @@ async def test_retrieve_latest_terms_of_service_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1813,7 +1736,7 @@ async def test_retrieve_latest_terms_of_service_async( request_type=termsofservice.RetrieveLatestTermsOfServiceRequest, ): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1892,27 +1815,6 @@ def test_accept_terms_of_service(request_type, transport: str = "grpc"): assert response is None -def test_accept_terms_of_service_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.accept_terms_of_service), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.accept_terms_of_service() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == termsofservice.AcceptTermsOfServiceRequest() - - def test_accept_terms_of_service_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1987,27 +1889,6 @@ def test_accept_terms_of_service_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_accept_terms_of_service_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.accept_terms_of_service), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.accept_terms_of_service() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == termsofservice.AcceptTermsOfServiceRequest() - - @pytest.mark.asyncio async def test_accept_terms_of_service_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2016,7 +1897,7 @@ async def test_accept_terms_of_service_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2056,7 +1937,7 @@ async def test_accept_terms_of_service_async( request_type=termsofservice.AcceptTermsOfServiceRequest, ): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2121,7 +2002,7 @@ def test_accept_terms_of_service_field_headers(): @pytest.mark.asyncio async def test_accept_terms_of_service_field_headers_async(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2193,7 +2074,7 @@ def test_accept_terms_of_service_flattened_error(): @pytest.mark.asyncio async def test_accept_terms_of_service_flattened_async(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2222,7 +2103,7 @@ async def test_accept_terms_of_service_flattened_async(): @pytest.mark.asyncio async def test_accept_terms_of_service_flattened_error_async(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2234,54 +2115,6 @@ async def test_accept_terms_of_service_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - termsofservice.GetTermsOfServiceRequest, - dict, - ], -) -def test_get_terms_of_service_rest(request_type): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "termsOfService/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofservice.TermsOfService( - name="name_value", - region_code="region_code_value", - kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - file_uri="file_uri_value", - external=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = termsofservice.TermsOfService.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_terms_of_service(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, termsofservice.TermsOfService) - assert response.name == "name_value" - assert response.region_code == "region_code_value" - assert response.kind == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER - assert response.file_uri == "file_uri_value" - assert response.external is True - - def test_get_terms_of_service_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2405,106 +2238,25 @@ def test_get_terms_of_service_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_terms_of_service_rest_interceptors(null_interceptor): - transport = transports.TermsOfServiceServiceRestTransport( +def test_get_terms_of_service_rest_flattened(): + client = TermsOfServiceServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.TermsOfServiceServiceRestInterceptor(), + transport="rest", ) - client = TermsOfServiceServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.TermsOfServiceServiceRestInterceptor, "post_get_terms_of_service" - ) as post, mock.patch.object( - transports.TermsOfServiceServiceRestInterceptor, "pre_get_terms_of_service" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = termsofservice.GetTermsOfServiceRequest.pb( - termsofservice.GetTermsOfServiceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = termsofservice.TermsOfService.to_json( - termsofservice.TermsOfService() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofservice.TermsOfService() - request = termsofservice.GetTermsOfServiceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = termsofservice.TermsOfService() + # get arguments that satisfy an http rule for this method + sample_request = {"name": "termsOfService/sample1"} - client.get_terms_of_service( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_terms_of_service_rest_bad_request( - transport: str = "rest", request_type=termsofservice.GetTermsOfServiceRequest -): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "termsOfService/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_terms_of_service(request) - - -def test_get_terms_of_service_rest_flattened(): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofservice.TermsOfService() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "termsOfService/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() @@ -2542,60 +2294,6 @@ def test_get_terms_of_service_rest_flattened_error(transport: str = "rest"): ) -def test_get_terms_of_service_rest_error(): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - termsofservice.RetrieveLatestTermsOfServiceRequest, - dict, - ], -) -def test_retrieve_latest_terms_of_service_rest(request_type): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = termsofservice.TermsOfService( - name="name_value", - region_code="region_code_value", - kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, - file_uri="file_uri_value", - external=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = termsofservice.TermsOfService.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.retrieve_latest_terms_of_service(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, termsofservice.TermsOfService) - assert response.name == "name_value" - assert response.region_code == "region_code_value" - assert response.kind == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER - assert response.file_uri == "file_uri_value" - assert response.external is True - - def test_retrieve_latest_terms_of_service_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2751,131 +2449,6 @@ def test_retrieve_latest_terms_of_service_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_retrieve_latest_terms_of_service_rest_interceptors(null_interceptor): - transport = transports.TermsOfServiceServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.TermsOfServiceServiceRestInterceptor(), - ) - client = TermsOfServiceServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.TermsOfServiceServiceRestInterceptor, - "post_retrieve_latest_terms_of_service", - ) as post, mock.patch.object( - transports.TermsOfServiceServiceRestInterceptor, - "pre_retrieve_latest_terms_of_service", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = termsofservice.RetrieveLatestTermsOfServiceRequest.pb( - termsofservice.RetrieveLatestTermsOfServiceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = termsofservice.TermsOfService.to_json( - termsofservice.TermsOfService() - ) - - request = termsofservice.RetrieveLatestTermsOfServiceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = termsofservice.TermsOfService() - - client.retrieve_latest_terms_of_service( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_retrieve_latest_terms_of_service_rest_bad_request( - transport: str = "rest", - request_type=termsofservice.RetrieveLatestTermsOfServiceRequest, -): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.retrieve_latest_terms_of_service(request) - - -def test_retrieve_latest_terms_of_service_rest_error(): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - termsofservice.AcceptTermsOfServiceRequest, - dict, - ], -) -def test_accept_terms_of_service_rest(request_type): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "termsOfService/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.accept_terms_of_service(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_accept_terms_of_service_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3042,8 +2615,550 @@ def test_accept_terms_of_service_rest_unset_required_fields(): ) +def test_accept_terms_of_service_rest_flattened(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "termsOfService/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.accept_terms_of_service(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{name=termsOfService/*}:accept" + % client.transport._host, + args[1], + ) + + +def test_accept_terms_of_service_rest_flattened_error(transport: str = "rest"): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.accept_terms_of_service( + termsofservice.AcceptTermsOfServiceRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.TermsOfServiceServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.TermsOfServiceServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TermsOfServiceServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.TermsOfServiceServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = TermsOfServiceServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = TermsOfServiceServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.TermsOfServiceServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TermsOfServiceServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.TermsOfServiceServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = TermsOfServiceServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.TermsOfServiceServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.TermsOfServiceServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.TermsOfServiceServiceGrpcTransport, + transports.TermsOfServiceServiceGrpcAsyncIOTransport, + transports.TermsOfServiceServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = TermsOfServiceServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_terms_of_service_empty_call_grpc(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_terms_of_service), "__call__" + ) as call: + call.return_value = termsofservice.TermsOfService() + client.get_terms_of_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.GetTermsOfServiceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_retrieve_latest_terms_of_service_empty_call_grpc(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_latest_terms_of_service), "__call__" + ) as call: + call.return_value = termsofservice.TermsOfService() + client.retrieve_latest_terms_of_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.RetrieveLatestTermsOfServiceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_accept_terms_of_service_empty_call_grpc(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.accept_terms_of_service), "__call__" + ) as call: + call.return_value = None + client.accept_terms_of_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.AcceptTermsOfServiceRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = TermsOfServiceServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = TermsOfServiceServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_terms_of_service_empty_call_grpc_asyncio(): + client = TermsOfServiceServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_terms_of_service), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + termsofservice.TermsOfService( + name="name_value", + region_code="region_code_value", + kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + file_uri="file_uri_value", + external=True, + ) + ) + await client.get_terms_of_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.GetTermsOfServiceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_retrieve_latest_terms_of_service_empty_call_grpc_asyncio(): + client = TermsOfServiceServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_latest_terms_of_service), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + termsofservice.TermsOfService( + name="name_value", + region_code="region_code_value", + kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + file_uri="file_uri_value", + external=True, + ) + ) + await client.retrieve_latest_terms_of_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.RetrieveLatestTermsOfServiceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_accept_terms_of_service_empty_call_grpc_asyncio(): + client = TermsOfServiceServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.accept_terms_of_service), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.accept_terms_of_service(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.AcceptTermsOfServiceRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = TermsOfServiceServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_terms_of_service_rest_bad_request( + request_type=termsofservice.GetTermsOfServiceRequest, +): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "termsOfService/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_terms_of_service(request) + + +@pytest.mark.parametrize( + "request_type", + [ + termsofservice.GetTermsOfServiceRequest, + dict, + ], +) +def test_get_terms_of_service_rest_call_success(request_type): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "termsOfService/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofservice.TermsOfService( + name="name_value", + region_code="region_code_value", + kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + file_uri="file_uri_value", + external=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = termsofservice.TermsOfService.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_terms_of_service(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, termsofservice.TermsOfService) + assert response.name == "name_value" + assert response.region_code == "region_code_value" + assert response.kind == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER + assert response.file_uri == "file_uri_value" + assert response.external is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_terms_of_service_rest_interceptors(null_interceptor): + transport = transports.TermsOfServiceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TermsOfServiceServiceRestInterceptor(), + ) + client = TermsOfServiceServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TermsOfServiceServiceRestInterceptor, "post_get_terms_of_service" + ) as post, mock.patch.object( + transports.TermsOfServiceServiceRestInterceptor, "pre_get_terms_of_service" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = termsofservice.GetTermsOfServiceRequest.pb( + termsofservice.GetTermsOfServiceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = termsofservice.TermsOfService.to_json( + termsofservice.TermsOfService() + ) + req.return_value.content = return_value + + request = termsofservice.GetTermsOfServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = termsofservice.TermsOfService() + + client.get_terms_of_service( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_retrieve_latest_terms_of_service_rest_bad_request( + request_type=termsofservice.RetrieveLatestTermsOfServiceRequest, +): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.retrieve_latest_terms_of_service(request) + + +@pytest.mark.parametrize( + "request_type", + [ + termsofservice.RetrieveLatestTermsOfServiceRequest, + dict, + ], +) +def test_retrieve_latest_terms_of_service_rest_call_success(request_type): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = termsofservice.TermsOfService( + name="name_value", + region_code="region_code_value", + kind=termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER, + file_uri="file_uri_value", + external=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = termsofservice.TermsOfService.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.retrieve_latest_terms_of_service(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, termsofservice.TermsOfService) + assert response.name == "name_value" + assert response.region_code == "region_code_value" + assert response.kind == termsofservicekind.TermsOfServiceKind.MERCHANT_CENTER + assert response.file_uri == "file_uri_value" + assert response.external is True + + @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_accept_terms_of_service_rest_interceptors(null_interceptor): +def test_retrieve_latest_terms_of_service_rest_interceptors(null_interceptor): transport = transports.TermsOfServiceServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -3051,16 +3166,22 @@ def test_accept_terms_of_service_rest_interceptors(null_interceptor): else transports.TermsOfServiceServiceRestInterceptor(), ) client = TermsOfServiceServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.TermsOfServiceServiceRestInterceptor, "pre_accept_terms_of_service" + transports.TermsOfServiceServiceRestInterceptor, + "post_retrieve_latest_terms_of_service", + ) as post, mock.patch.object( + transports.TermsOfServiceServiceRestInterceptor, + "pre_retrieve_latest_terms_of_service", ) as pre: pre.assert_not_called() - pb_message = termsofservice.AcceptTermsOfServiceRequest.pb( - termsofservice.AcceptTermsOfServiceRequest() + post.assert_not_called() + pb_message = termsofservice.RetrieveLatestTermsOfServiceRequest.pb( + termsofservice.RetrieveLatestTermsOfServiceRequest() ) transcode.return_value = { "method": "post", @@ -3069,18 +3190,22 @@ def test_accept_terms_of_service_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = termsofservice.TermsOfService.to_json( + termsofservice.TermsOfService() + ) + req.return_value.content = return_value - request = termsofservice.AcceptTermsOfServiceRequest() + request = termsofservice.RetrieveLatestTermsOfServiceRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = termsofservice.TermsOfService() - client.accept_terms_of_service( + client.retrieve_latest_terms_of_service( request, metadata=[ ("key", "val"), @@ -3089,16 +3214,15 @@ def test_accept_terms_of_service_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_accept_terms_of_service_rest_bad_request( - transport: str = "rest", request_type=termsofservice.AcceptTermsOfServiceRequest + request_type=termsofservice.AcceptTermsOfServiceRequest, ): client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "termsOfService/sample1"} request = request_type(**request_init) @@ -3108,178 +3232,168 @@ def test_accept_terms_of_service_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.accept_terms_of_service(request) -def test_accept_terms_of_service_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + termsofservice.AcceptTermsOfServiceRequest, + dict, + ], +) +def test_accept_terms_of_service_rest_call_success(request_type): client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "termsOfService/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = {"name": "termsOfService/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.accept_terms_of_service(request) - client.accept_terms_of_service(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{name=termsOfService/*}:accept" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert response is None -def test_accept_terms_of_service_rest_flattened_error(transport: str = "rest"): - client = TermsOfServiceServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_accept_terms_of_service_rest_interceptors(null_interceptor): + transport = transports.TermsOfServiceServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.TermsOfServiceServiceRestInterceptor(), ) + client = TermsOfServiceServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TermsOfServiceServiceRestInterceptor, "pre_accept_terms_of_service" + ) as pre: + pre.assert_not_called() + pb_message = termsofservice.AcceptTermsOfServiceRequest.pb( + termsofservice.AcceptTermsOfServiceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = termsofservice.AcceptTermsOfServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.accept_terms_of_service( - termsofservice.AcceptTermsOfServiceRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + -def test_accept_terms_of_service_rest_error(): +def test_initialize_client_w_rest(): client = TermsOfServiceServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.TermsOfServiceServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_terms_of_service_empty_call_rest(): + client = TermsOfServiceServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.TermsOfServiceServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = TermsOfServiceServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_terms_of_service), "__call__" + ) as call: + client.get_terms_of_service(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.TermsOfServiceServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = TermsOfServiceServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.GetTermsOfServiceRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = TermsOfServiceServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.TermsOfServiceServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_retrieve_latest_terms_of_service_empty_call_rest(): + client = TermsOfServiceServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = TermsOfServiceServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.retrieve_latest_terms_of_service), "__call__" + ) as call: + client.retrieve_latest_terms_of_service(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.TermsOfServiceServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = TermsOfServiceServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.RetrieveLatestTermsOfServiceRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.TermsOfServiceServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.TermsOfServiceServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_accept_terms_of_service_empty_call_rest(): + client = TermsOfServiceServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.TermsOfServiceServiceGrpcTransport, - transports.TermsOfServiceServiceGrpcAsyncIOTransport, - transports.TermsOfServiceServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.accept_terms_of_service), "__call__" + ) as call: + client.accept_terms_of_service(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = termsofservice.AcceptTermsOfServiceRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = TermsOfServiceServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3883,36 +3997,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = TermsOfServiceServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = TermsOfServiceServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = TermsOfServiceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py index cf9e307285c0..d2c31455ddde 100644 --- a/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py +++ b/packages/google-shopping-merchant-accounts/tests/unit/gapic/merchant_accounts_v1beta/test_user_service.py @@ -22,19 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + from google.shopping.merchant_accounts_v1beta.services.user_service import ( UserServiceAsyncClient, UserServiceClient, @@ -55,10 +64,24 @@ from google.shopping.merchant_accounts_v1beta.types import user as gsma_user +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1123,25 +1146,6 @@ def test_get_user(request_type, transport: str = "grpc"): assert response.access_rights == [accessright.AccessRight.STANDARD] -def test_get_user_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_user), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user.GetUserRequest() - - def test_get_user_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1205,38 +1209,13 @@ def test_get_user_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_user_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_user), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - user.User( - name="name_value", - state=user.User.State.PENDING, - access_rights=[accessright.AccessRight.STANDARD], - ) - ) - response = await client.get_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user.GetUserRequest() - - @pytest.mark.asyncio async def test_get_user_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1275,7 +1254,7 @@ async def test_get_user_async( transport: str = "grpc_asyncio", request_type=user.GetUserRequest ): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1345,7 +1324,7 @@ def test_get_user_field_headers(): @pytest.mark.asyncio async def test_get_user_field_headers_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1413,7 +1392,7 @@ def test_get_user_flattened_error(): @pytest.mark.asyncio async def test_get_user_flattened_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1440,7 +1419,7 @@ async def test_get_user_flattened_async(): @pytest.mark.asyncio async def test_get_user_flattened_error_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1492,25 +1471,6 @@ def test_create_user(request_type, transport: str = "grpc"): assert response.access_rights == [accessright.AccessRight.STANDARD] -def test_create_user_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_user), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_user.CreateUserRequest() - - def test_create_user_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1576,31 +1536,6 @@ def test_create_user_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_user_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_user), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gsma_user.User( - name="name_value", - state=gsma_user.User.State.PENDING, - access_rights=[accessright.AccessRight.STANDARD], - ) - ) - response = await client.create_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_user.CreateUserRequest() - - @pytest.mark.asyncio async def test_create_user_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1609,7 +1544,7 @@ async def test_create_user_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1648,7 +1583,7 @@ async def test_create_user_async( transport: str = "grpc_asyncio", request_type=gsma_user.CreateUserRequest ): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1718,7 +1653,7 @@ def test_create_user_field_headers(): @pytest.mark.asyncio async def test_create_user_field_headers_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1791,7 +1726,7 @@ def test_create_user_flattened_error(): @pytest.mark.asyncio async def test_create_user_flattened_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1822,7 +1757,7 @@ async def test_create_user_flattened_async(): @pytest.mark.asyncio async def test_create_user_flattened_error_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1868,25 +1803,6 @@ def test_delete_user(request_type, transport: str = "grpc"): assert response is None -def test_delete_user_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_user), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user.DeleteUserRequest() - - def test_delete_user_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1950,25 +1866,6 @@ def test_delete_user_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_user_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_user), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user.DeleteUserRequest() - - @pytest.mark.asyncio async def test_delete_user_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1977,7 +1874,7 @@ async def test_delete_user_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2016,7 +1913,7 @@ async def test_delete_user_async( transport: str = "grpc_asyncio", request_type=user.DeleteUserRequest ): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2077,7 +1974,7 @@ def test_delete_user_field_headers(): @pytest.mark.asyncio async def test_delete_user_field_headers_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2145,7 +2042,7 @@ def test_delete_user_flattened_error(): @pytest.mark.asyncio async def test_delete_user_flattened_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2172,7 +2069,7 @@ async def test_delete_user_flattened_async(): @pytest.mark.asyncio async def test_delete_user_flattened_error_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2224,25 +2121,6 @@ def test_update_user(request_type, transport: str = "grpc"): assert response.access_rights == [accessright.AccessRight.STANDARD] -def test_update_user_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_user), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_user.UpdateUserRequest() - - def test_update_user_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2302,31 +2180,6 @@ def test_update_user_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_user_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_user), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - gsma_user.User( - name="name_value", - state=gsma_user.User.State.PENDING, - access_rights=[accessright.AccessRight.STANDARD], - ) - ) - response = await client.update_user() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == gsma_user.UpdateUserRequest() - - @pytest.mark.asyncio async def test_update_user_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2335,7 +2188,7 @@ async def test_update_user_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2374,7 +2227,7 @@ async def test_update_user_async( transport: str = "grpc_asyncio", request_type=gsma_user.UpdateUserRequest ): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2444,7 +2297,7 @@ def test_update_user_field_headers(): @pytest.mark.asyncio async def test_update_user_field_headers_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2517,7 +2370,7 @@ def test_update_user_flattened_error(): @pytest.mark.asyncio async def test_update_user_flattened_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2548,7 +2401,7 @@ async def test_update_user_flattened_async(): @pytest.mark.asyncio async def test_update_user_flattened_error_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2597,25 +2450,6 @@ def test_list_users(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_users_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_users), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_users() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user.ListUsersRequest() - - def test_list_users_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2681,36 +2515,13 @@ def test_list_users_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_users_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_users), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - user.ListUsersResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_users() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == user.ListUsersRequest() - - @pytest.mark.asyncio async def test_list_users_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2749,7 +2560,7 @@ async def test_list_users_async( transport: str = "grpc_asyncio", request_type=user.ListUsersRequest ): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2815,7 +2626,7 @@ def test_list_users_field_headers(): @pytest.mark.asyncio async def test_list_users_field_headers_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2885,7 +2696,7 @@ def test_list_users_flattened_error(): @pytest.mark.asyncio async def test_list_users_flattened_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2914,7 +2725,7 @@ async def test_list_users_flattened_async(): @pytest.mark.asyncio async def test_list_users_flattened_error_async(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3024,7 +2835,7 @@ def test_list_users_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_users_async_pager(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3074,7 +2885,7 @@ async def test_list_users_async_pager(): @pytest.mark.asyncio async def test_list_users_async_pages(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3120,72 +2931,28 @@ async def test_list_users_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - user.GetUserRequest, - dict, - ], -) -def test_get_user_rest(request_type): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +def test_get_user_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/users/sample2"} - request = request_type(**request_init) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = user.User( - name="name_value", - state=user.User.State.PENDING, - access_rights=[accessright.AccessRight.STANDARD], + # Ensure method has been cached + assert client._transport.get_user in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = user.User.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_user(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, user.User) - assert response.name == "name_value" - assert response.state == user.User.State.PENDING - assert response.access_rights == [accessright.AccessRight.STANDARD] - - -def test_get_user_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_user in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.get_user] = mock_rpc + client._transport._wrapped_methods[client._transport.get_user] = mock_rpc request = {} client.get_user(request) @@ -3281,83 +3048,6 @@ def test_get_user_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_user_rest_interceptors(null_interceptor): - transport = transports.UserServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.UserServiceRestInterceptor(), - ) - client = UserServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.UserServiceRestInterceptor, "post_get_user" - ) as post, mock.patch.object( - transports.UserServiceRestInterceptor, "pre_get_user" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = user.GetUserRequest.pb(user.GetUserRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = user.User.to_json(user.User()) - - request = user.GetUserRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = user.User() - - client.get_user( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_user_rest_bad_request( - transport: str = "rest", request_type=user.GetUserRequest -): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/users/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_user(request) - - def test_get_user_rest_flattened(): client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3414,124 +3104,6 @@ def test_get_user_rest_flattened_error(transport: str = "rest"): ) -def test_get_user_rest_error(): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - gsma_user.CreateUserRequest, - dict, - ], -) -def test_create_user_rest(request_type): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["user"] = {"name": "name_value", "state": 1, "access_rights": [1]} - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = gsma_user.CreateUserRequest.meta.fields["user"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["user"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["user"][field])): - del request_init["user"][field][i][subfield] - else: - del request_init["user"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gsma_user.User( - name="name_value", - state=gsma_user.User.State.PENDING, - access_rights=[accessright.AccessRight.STANDARD], - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gsma_user.User.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_user(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, gsma_user.User) - assert response.name == "name_value" - assert response.state == gsma_user.User.State.PENDING - assert response.access_rights == [accessright.AccessRight.STANDARD] - - def test_create_user_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3674,87 +3246,10 @@ def test_create_user_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_user_rest_interceptors(null_interceptor): - transport = transports.UserServiceRestTransport( +def test_create_user_rest_flattened(): + client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.UserServiceRestInterceptor(), - ) - client = UserServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.UserServiceRestInterceptor, "post_create_user" - ) as post, mock.patch.object( - transports.UserServiceRestInterceptor, "pre_create_user" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = gsma_user.CreateUserRequest.pb(gsma_user.CreateUserRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = gsma_user.User.to_json(gsma_user.User()) - - request = gsma_user.CreateUserRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = gsma_user.User() - - client.create_user( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_user_rest_bad_request( - transport: str = "rest", request_type=gsma_user.CreateUserRequest -): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_user(request) - - -def test_create_user_rest_flattened(): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="rest", ) # Mock the http request call within the method and fake a response. @@ -3809,47 +3304,6 @@ def test_create_user_rest_flattened_error(transport: str = "rest"): ) -def test_create_user_rest_error(): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - user.DeleteUserRequest, - dict, - ], -) -def test_delete_user_rest(request_type): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/users/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_user(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_user_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3964,77 +3418,6 @@ def test_delete_user_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_user_rest_interceptors(null_interceptor): - transport = transports.UserServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.UserServiceRestInterceptor(), - ) - client = UserServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.UserServiceRestInterceptor, "pre_delete_user" - ) as pre: - pre.assert_not_called() - pb_message = user.DeleteUserRequest.pb(user.DeleteUserRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = user.DeleteUserRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_user( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_user_rest_bad_request( - transport: str = "rest", request_type=user.DeleteUserRequest -): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/users/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_user(request) - - def test_delete_user_rest_flattened(): client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4089,173 +3472,51 @@ def test_delete_user_rest_flattened_error(transport: str = "rest"): ) -def test_delete_user_rest_error(): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_user_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - gsma_user.UpdateUserRequest, - dict, - ], -) -def test_update_user_rest(request_type): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Ensure method has been cached + assert client._transport.update_user in client._transport._wrapped_methods - # send a request that will satisfy transcoding - request_init = {"user": {"name": "accounts/sample1/users/sample2"}} - request_init["user"] = { - "name": "accounts/sample1/users/sample2", - "state": 1, - "access_rights": [1], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_user] = mock_rpc - # Determine if the message type is proto-plus or protobuf - test_field = gsma_user.UpdateUserRequest.meta.fields["user"] + request = {} + client.update_user(request) - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + client.update_user(request) - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - subfields_not_in_runtime = [] +def test_update_user_rest_required_fields(request_type=gsma_user.UpdateUserRequest): + transport_class = transports.UserServiceRestTransport - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["user"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["user"][field])): - del request_init["user"][field][i][subfield] - else: - del request_init["user"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = gsma_user.User( - name="name_value", - state=gsma_user.User.State.PENDING, - access_rights=[accessright.AccessRight.STANDARD], - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = gsma_user.User.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_user(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, gsma_user.User) - assert response.name == "name_value" - assert response.state == gsma_user.User.State.PENDING - assert response.access_rights == [accessright.AccessRight.STANDARD] - - -def test_update_user_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_user in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.update_user] = mock_rpc - - request = {} - client.update_user(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_user(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_user_rest_required_fields(request_type=gsma_user.UpdateUserRequest): - transport_class = transports.UserServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) # verify fields with default values are dropped @@ -4334,83 +3595,6 @@ def test_update_user_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_user_rest_interceptors(null_interceptor): - transport = transports.UserServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.UserServiceRestInterceptor(), - ) - client = UserServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.UserServiceRestInterceptor, "post_update_user" - ) as post, mock.patch.object( - transports.UserServiceRestInterceptor, "pre_update_user" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = gsma_user.UpdateUserRequest.pb(gsma_user.UpdateUserRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = gsma_user.User.to_json(gsma_user.User()) - - request = gsma_user.UpdateUserRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = gsma_user.User() - - client.update_user( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_user_rest_bad_request( - transport: str = "rest", request_type=gsma_user.UpdateUserRequest -): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"user": {"name": "accounts/sample1/users/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_user(request) - - def test_update_user_rest_flattened(): client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4470,52 +3654,6 @@ def test_update_user_rest_flattened_error(transport: str = "rest"): ) -def test_update_user_rest_error(): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - user.ListUsersRequest, - dict, - ], -) -def test_list_users_rest(request_type): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = user.ListUsersResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = user.ListUsersResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_users(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListUsersPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_users_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4648,6 +3786,1152 @@ def test_list_users_rest_unset_required_fields(): ) +def test_list_users_rest_flattened(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = user.ListUsersResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = user.ListUsersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_users(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/accounts/v1beta/{parent=accounts/*}/users" % client.transport._host, + args[1], + ) + + +def test_list_users_rest_flattened_error(transport: str = "rest"): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_users( + user.ListUsersRequest(), + parent="parent_value", + ) + + +def test_list_users_rest_pager(transport: str = "rest"): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + user.ListUsersResponse( + users=[ + user.User(), + user.User(), + user.User(), + ], + next_page_token="abc", + ), + user.ListUsersResponse( + users=[], + next_page_token="def", + ), + user.ListUsersResponse( + users=[ + user.User(), + ], + next_page_token="ghi", + ), + user.ListUsersResponse( + users=[ + user.User(), + user.User(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(user.ListUsersResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_users(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, user.User) for i in results) + + pages = list(client.list_users(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.UserServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.UserServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.UserServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.UserServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = UserServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.UserServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserServiceGrpcTransport, + transports.UserServiceGrpcAsyncIOTransport, + transports.UserServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = UserServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_user_empty_call_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_user), "__call__") as call: + call.return_value = user.User() + client.get_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.GetUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_user_empty_call_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_user), "__call__") as call: + call.return_value = gsma_user.User() + client.create_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_user.CreateUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_user_empty_call_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_user), "__call__") as call: + call.return_value = None + client.delete_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.DeleteUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_user_empty_call_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_user), "__call__") as call: + call.return_value = gsma_user.User() + client.update_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_user.UpdateUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_users_empty_call_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_users), "__call__") as call: + call.return_value = user.ListUsersResponse() + client.list_users(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.ListUsersRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = UserServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = UserServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_user_empty_call_grpc_asyncio(): + client = UserServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_user), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + user.User( + name="name_value", + state=user.User.State.PENDING, + access_rights=[accessright.AccessRight.STANDARD], + ) + ) + await client.get_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.GetUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_user_empty_call_grpc_asyncio(): + client = UserServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_user), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gsma_user.User( + name="name_value", + state=gsma_user.User.State.PENDING, + access_rights=[accessright.AccessRight.STANDARD], + ) + ) + await client.create_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_user.CreateUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_user_empty_call_grpc_asyncio(): + client = UserServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_user), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.DeleteUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_user_empty_call_grpc_asyncio(): + client = UserServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_user), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gsma_user.User( + name="name_value", + state=gsma_user.User.State.PENDING, + access_rights=[accessright.AccessRight.STANDARD], + ) + ) + await client.update_user(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_user.UpdateUserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_users_empty_call_grpc_asyncio(): + client = UserServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_users), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + user.ListUsersResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_users(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.ListUsersRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = UserServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_user_rest_bad_request(request_type=user.GetUserRequest): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/users/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_user(request) + + +@pytest.mark.parametrize( + "request_type", + [ + user.GetUserRequest, + dict, + ], +) +def test_get_user_rest_call_success(request_type): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/users/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = user.User( + name="name_value", + state=user.User.State.PENDING, + access_rights=[accessright.AccessRight.STANDARD], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = user.User.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_user(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, user.User) + assert response.name == "name_value" + assert response.state == user.User.State.PENDING + assert response.access_rights == [accessright.AccessRight.STANDARD] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_user_rest_interceptors(null_interceptor): + transport = transports.UserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.UserServiceRestInterceptor(), + ) + client = UserServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.UserServiceRestInterceptor, "post_get_user" + ) as post, mock.patch.object( + transports.UserServiceRestInterceptor, "pre_get_user" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user.GetUserRequest.pb(user.GetUserRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = user.User.to_json(user.User()) + req.return_value.content = return_value + + request = user.GetUserRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = user.User() + + client.get_user( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_user_rest_bad_request(request_type=gsma_user.CreateUserRequest): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_user(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gsma_user.CreateUserRequest, + dict, + ], +) +def test_create_user_rest_call_success(request_type): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["user"] = {"name": "name_value", "state": 1, "access_rights": [1]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gsma_user.CreateUserRequest.meta.fields["user"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["user"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["user"][field])): + del request_init["user"][field][i][subfield] + else: + del request_init["user"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gsma_user.User( + name="name_value", + state=gsma_user.User.State.PENDING, + access_rights=[accessright.AccessRight.STANDARD], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gsma_user.User.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_user(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gsma_user.User) + assert response.name == "name_value" + assert response.state == gsma_user.User.State.PENDING + assert response.access_rights == [accessright.AccessRight.STANDARD] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_user_rest_interceptors(null_interceptor): + transport = transports.UserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.UserServiceRestInterceptor(), + ) + client = UserServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.UserServiceRestInterceptor, "post_create_user" + ) as post, mock.patch.object( + transports.UserServiceRestInterceptor, "pre_create_user" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = gsma_user.CreateUserRequest.pb(gsma_user.CreateUserRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = gsma_user.User.to_json(gsma_user.User()) + req.return_value.content = return_value + + request = gsma_user.CreateUserRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gsma_user.User() + + client.create_user( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_user_rest_bad_request(request_type=user.DeleteUserRequest): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/users/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_user(request) + + +@pytest.mark.parametrize( + "request_type", + [ + user.DeleteUserRequest, + dict, + ], +) +def test_delete_user_rest_call_success(request_type): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/users/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_user(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_user_rest_interceptors(null_interceptor): + transport = transports.UserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.UserServiceRestInterceptor(), + ) + client = UserServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.UserServiceRestInterceptor, "pre_delete_user" + ) as pre: + pre.assert_not_called() + pb_message = user.DeleteUserRequest.pb(user.DeleteUserRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = user.DeleteUserRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_user( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_update_user_rest_bad_request(request_type=gsma_user.UpdateUserRequest): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"user": {"name": "accounts/sample1/users/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_user(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gsma_user.UpdateUserRequest, + dict, + ], +) +def test_update_user_rest_call_success(request_type): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"user": {"name": "accounts/sample1/users/sample2"}} + request_init["user"] = { + "name": "accounts/sample1/users/sample2", + "state": 1, + "access_rights": [1], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gsma_user.UpdateUserRequest.meta.fields["user"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["user"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["user"][field])): + del request_init["user"][field][i][subfield] + else: + del request_init["user"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gsma_user.User( + name="name_value", + state=gsma_user.User.State.PENDING, + access_rights=[accessright.AccessRight.STANDARD], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gsma_user.User.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_user(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gsma_user.User) + assert response.name == "name_value" + assert response.state == gsma_user.User.State.PENDING + assert response.access_rights == [accessright.AccessRight.STANDARD] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_user_rest_interceptors(null_interceptor): + transport = transports.UserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.UserServiceRestInterceptor(), + ) + client = UserServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.UserServiceRestInterceptor, "post_update_user" + ) as post, mock.patch.object( + transports.UserServiceRestInterceptor, "pre_update_user" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = gsma_user.UpdateUserRequest.pb(gsma_user.UpdateUserRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = gsma_user.User.to_json(gsma_user.User()) + req.return_value.content = return_value + + request = gsma_user.UpdateUserRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gsma_user.User() + + client.update_user( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_users_rest_bad_request(request_type=user.ListUsersRequest): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_users(request) + + +@pytest.mark.parametrize( + "request_type", + [ + user.ListUsersRequest, + dict, + ], +) +def test_list_users_rest_call_success(request_type): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = user.ListUsersResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = user.ListUsersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_users(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListUsersPager) + assert response.next_page_token == "next_page_token_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) def test_list_users_rest_interceptors(null_interceptor): transport = transports.UserServiceRestTransport( @@ -4657,6 +4941,7 @@ def test_list_users_rest_interceptors(null_interceptor): else transports.UserServiceRestInterceptor(), ) client = UserServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -4676,12 +4961,10 @@ def test_list_users_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = user.ListUsersResponse.to_json( - user.ListUsersResponse() - ) + return_value = user.ListUsersResponse.to_json(user.ListUsersResponse()) + req.return_value.content = return_value request = user.ListUsersRequest() metadata = [ @@ -4703,251 +4986,111 @@ def test_list_users_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_users_rest_bad_request( - transport: str = "rest", request_type=user.ListUsersRequest -): +def test_initialize_client_w_rest(): client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_users(request) + assert client is not None -def test_list_users_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_user_empty_call_rest(): client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = user.ListUsersResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = user.ListUsersResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_users(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/accounts/v1beta/{parent=accounts/*}/users" % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_user), "__call__") as call: + client.get_user(request=None) -def test_list_users_rest_flattened_error(transport: str = "rest"): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.GetUserRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_users( - user.ListUsersRequest(), - parent="parent_value", - ) + assert args[0] == request_msg -def test_list_users_rest_pager(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_user_empty_call_rest(): client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - user.ListUsersResponse( - users=[ - user.User(), - user.User(), - user.User(), - ], - next_page_token="abc", - ), - user.ListUsersResponse( - users=[], - next_page_token="def", - ), - user.ListUsersResponse( - users=[ - user.User(), - ], - next_page_token="ghi", - ), - user.ListUsersResponse( - users=[ - user.User(), - user.User(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(user.ListUsersResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_users(request=sample_request) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_user), "__call__") as call: + client.create_user(request=None) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, user.User) for i in results) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_user.CreateUserRequest() - pages = list(client.list_users(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + assert args[0] == request_msg -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.UserServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_user_empty_call_rest(): + client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.UserServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = UserServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_user), "__call__") as call: + client.delete_user(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.UserServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = UserServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.DeleteUserRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = UserServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.UserServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_user_empty_call_rest(): + client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = UserServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_user), "__call__") as call: + client.update_user(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.UserServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = UserServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gsma_user.UpdateUserRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.UserServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.UserServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_users_empty_call_rest(): + client = UserServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.UserServiceGrpcTransport, - transports.UserServiceGrpcAsyncIOTransport, - transports.UserServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_users), "__call__") as call: + client.list_users(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = user.ListUsersRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = UserServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -5547,36 +5690,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = UserServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = UserServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = UserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/README.rst b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/README.rst new file mode 100644 index 000000000000..3ffc61f2806b --- /dev/null +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ConversionSourcesServiceTransport` is the ABC for all transports. +- public child `ConversionSourcesServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ConversionSourcesServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseConversionSourcesServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ConversionSourcesServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py index 17070f95241d..4da59395d836 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -425,40 +429,49 @@ def list_conversion_sources( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.create_conversion_source: gapic_v1.method_async.wrap_method( + self.create_conversion_source: self._wrap_method( self.create_conversion_source, default_timeout=None, client_info=client_info, ), - self.update_conversion_source: gapic_v1.method_async.wrap_method( + self.update_conversion_source: self._wrap_method( self.update_conversion_source, default_timeout=None, client_info=client_info, ), - self.delete_conversion_source: gapic_v1.method_async.wrap_method( + self.delete_conversion_source: self._wrap_method( self.delete_conversion_source, default_timeout=None, client_info=client_info, ), - self.undelete_conversion_source: gapic_v1.method_async.wrap_method( + self.undelete_conversion_source: self._wrap_method( self.undelete_conversion_source, default_timeout=None, client_info=client_info, ), - self.get_conversion_source: gapic_v1.method_async.wrap_method( + self.get_conversion_source: self._wrap_method( self.get_conversion_source, default_timeout=None, client_info=client_info, ), - self.list_conversion_sources: gapic_v1.method_async.wrap_method( + self.list_conversion_sources: self._wrap_method( self.list_conversion_sources, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("ConversionSourcesServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py index 4effc73b0ec1..196fc300bdf6 100644 --- a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_conversions_v1beta.types import conversionsources + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseConversionSourcesServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_conversions_v1beta.types import conversionsources - -from .base import ConversionSourcesServiceTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -260,8 +256,8 @@ class ConversionSourcesServiceRestStub: _interceptor: ConversionSourcesServiceRestInterceptor -class ConversionSourcesServiceRestTransport(ConversionSourcesServiceTransport): - """REST backend transport for ConversionSourcesService. +class ConversionSourcesServiceRestTransport(_BaseConversionSourcesServiceRestTransport): + """REST backend synchronous transport for ConversionSourcesService. Service for managing conversion sources for a merchant account. @@ -271,7 +267,6 @@ class ConversionSourcesServiceRestTransport(ConversionSourcesServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -325,21 +320,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -350,19 +336,35 @@ def __init__( self._interceptor = interceptor or ConversionSourcesServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateConversionSource(ConversionSourcesServiceRestStub): + class _CreateConversionSource( + _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource, + ConversionSourcesServiceRestStub, + ): def __hash__(self): - return hash("CreateConversionSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ConversionSourcesServiceRestTransport.CreateConversionSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -393,47 +395,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/conversions/v1beta/{parent=accounts/*}/conversionSources", - "body": "conversion_source", - }, - ] + http_options = ( + _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource._get_http_options() + ) request, metadata = self._interceptor.pre_create_conversion_source( request, metadata ) - pb_request = conversionsources.CreateConversionSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ConversionSourcesServiceRestTransport._CreateConversionSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -449,19 +438,34 @@ def __call__( resp = self._interceptor.post_create_conversion_source(resp) return resp - class _DeleteConversionSource(ConversionSourcesServiceRestStub): + class _DeleteConversionSource( + _BaseConversionSourcesServiceRestTransport._BaseDeleteConversionSource, + ConversionSourcesServiceRestStub, + ): def __hash__(self): - return hash("DeleteConversionSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ConversionSourcesServiceRestTransport.DeleteConversionSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -484,40 +488,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/conversions/v1beta/{name=accounts/*/conversionSources/*}", - }, - ] + http_options = ( + _BaseConversionSourcesServiceRestTransport._BaseDeleteConversionSource._get_http_options() + ) request, metadata = self._interceptor.pre_delete_conversion_source( request, metadata ) - pb_request = conversionsources.DeleteConversionSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseConversionSourcesServiceRestTransport._BaseDeleteConversionSource._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseConversionSourcesServiceRestTransport._BaseDeleteConversionSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ConversionSourcesServiceRestTransport._DeleteConversionSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -525,19 +518,34 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetConversionSource(ConversionSourcesServiceRestStub): + class _GetConversionSource( + _BaseConversionSourcesServiceRestTransport._BaseGetConversionSource, + ConversionSourcesServiceRestStub, + ): def __hash__(self): - return hash("GetConversionSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ConversionSourcesServiceRestTransport.GetConversionSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -568,40 +576,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/conversions/v1beta/{name=accounts/*/conversionSources/*}", - }, - ] + http_options = ( + _BaseConversionSourcesServiceRestTransport._BaseGetConversionSource._get_http_options() + ) request, metadata = self._interceptor.pre_get_conversion_source( request, metadata ) - pb_request = conversionsources.GetConversionSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseConversionSourcesServiceRestTransport._BaseGetConversionSource._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseConversionSourcesServiceRestTransport._BaseGetConversionSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ConversionSourcesServiceRestTransport._GetConversionSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -617,19 +614,34 @@ def __call__( resp = self._interceptor.post_get_conversion_source(resp) return resp - class _ListConversionSources(ConversionSourcesServiceRestStub): + class _ListConversionSources( + _BaseConversionSourcesServiceRestTransport._BaseListConversionSources, + ConversionSourcesServiceRestStub, + ): def __hash__(self): - return hash("ListConversionSources") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ConversionSourcesServiceRestTransport.ListConversionSources") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -658,40 +670,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/conversions/v1beta/{parent=accounts/*}/conversionSources", - }, - ] + http_options = ( + _BaseConversionSourcesServiceRestTransport._BaseListConversionSources._get_http_options() + ) request, metadata = self._interceptor.pre_list_conversion_sources( request, metadata ) - pb_request = conversionsources.ListConversionSourcesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseConversionSourcesServiceRestTransport._BaseListConversionSources._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseConversionSourcesServiceRestTransport._BaseListConversionSources._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ConversionSourcesServiceRestTransport._ListConversionSources._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -707,19 +708,37 @@ def __call__( resp = self._interceptor.post_list_conversion_sources(resp) return resp - class _UndeleteConversionSource(ConversionSourcesServiceRestStub): + class _UndeleteConversionSource( + _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource, + ConversionSourcesServiceRestStub, + ): def __hash__(self): - return hash("UndeleteConversionSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "ConversionSourcesServiceRestTransport.UndeleteConversionSource" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -751,47 +770,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/conversions/v1beta/{name=accounts/*/conversionSources/*}:undelete", - "body": "*", - }, - ] + http_options = ( + _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource._get_http_options() + ) request, metadata = self._interceptor.pre_undelete_conversion_source( request, metadata ) - pb_request = conversionsources.UndeleteConversionSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ConversionSourcesServiceRestTransport._UndeleteConversionSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -807,21 +813,35 @@ def __call__( resp = self._interceptor.post_undelete_conversion_source(resp) return resp - class _UpdateConversionSource(ConversionSourcesServiceRestStub): + class _UpdateConversionSource( + _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource, + ConversionSourcesServiceRestStub, + ): def __hash__(self): - return hash("UpdateConversionSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ConversionSourcesServiceRestTransport.UpdateConversionSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -852,47 +872,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/conversions/v1beta/{conversion_source.name=accounts/*/conversionSources/*}", - "body": "conversion_source", - }, - ] + http_options = ( + _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource._get_http_options() + ) request, metadata = self._interceptor.pre_update_conversion_source( request, metadata ) - pb_request = conversionsources.UpdateConversionSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ConversionSourcesServiceRestTransport._UpdateConversionSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest_base.py b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest_base.py new file mode 100644 index 000000000000..ab5ca5aec59f --- /dev/null +++ b/packages/google-shopping-merchant-conversions/google/shopping/merchant_conversions_v1beta/services/conversion_sources_service/transports/rest_base.py @@ -0,0 +1,406 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_conversions_v1beta.types import conversionsources + +from .base import DEFAULT_CLIENT_INFO, ConversionSourcesServiceTransport + + +class _BaseConversionSourcesServiceRestTransport(ConversionSourcesServiceTransport): + """Base REST backend transport for ConversionSourcesService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateConversionSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/conversions/v1beta/{parent=accounts/*}/conversionSources", + "body": "conversion_source", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = conversionsources.CreateConversionSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseConversionSourcesServiceRestTransport._BaseCreateConversionSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteConversionSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/conversions/v1beta/{name=accounts/*/conversionSources/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = conversionsources.DeleteConversionSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseConversionSourcesServiceRestTransport._BaseDeleteConversionSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetConversionSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/conversions/v1beta/{name=accounts/*/conversionSources/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = conversionsources.GetConversionSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseConversionSourcesServiceRestTransport._BaseGetConversionSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListConversionSources: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/conversions/v1beta/{parent=accounts/*}/conversionSources", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = conversionsources.ListConversionSourcesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseConversionSourcesServiceRestTransport._BaseListConversionSources._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUndeleteConversionSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/conversions/v1beta/{name=accounts/*/conversionSources/*}:undelete", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = conversionsources.UndeleteConversionSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseConversionSourcesServiceRestTransport._BaseUndeleteConversionSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateConversionSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/conversions/v1beta/{conversion_source.name=accounts/*/conversionSources/*}", + "body": "conversion_source", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = conversionsources.UpdateConversionSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseConversionSourcesServiceRestTransport._BaseUpdateConversionSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseConversionSourcesServiceRestTransport",) diff --git a/packages/google-shopping-merchant-conversions/setup.py b/packages/google-shopping-merchant-conversions/setup.py index cfc3c7beef57..77e80b0f6063 100644 --- a/packages/google-shopping-merchant-conversions/setup.py +++ b/packages/google-shopping-merchant-conversions/setup.py @@ -48,6 +48,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-conversions" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -90,6 +91,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py b/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py index 8165aed2dcc2..9fe9e2e509cd 100644 --- a/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py +++ b/packages/google-shopping-merchant-conversions/tests/unit/gapic/merchant_conversions_v1beta/test_conversion_sources_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,15 +52,7 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_conversions_v1beta.services.conversion_sources_service import ( ConversionSourcesServiceAsyncClient, @@ -54,10 +63,24 @@ from google.shopping.merchant_conversions_v1beta.types import conversionsources +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1239,27 +1262,6 @@ def test_create_conversion_source(request_type, transport: str = "grpc"): assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT -def test_create_conversion_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_conversion_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.CreateConversionSourceRequest() - - def test_create_conversion_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1330,33 +1332,6 @@ def test_create_conversion_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_conversion_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_conversion_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - ) - response = await client.create_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.CreateConversionSourceRequest() - - @pytest.mark.asyncio async def test_create_conversion_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1365,7 +1340,7 @@ async def test_create_conversion_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1405,7 +1380,7 @@ async def test_create_conversion_source_async( request_type=conversionsources.CreateConversionSourceRequest, ): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1479,7 +1454,7 @@ def test_create_conversion_source_field_headers(): @pytest.mark.asyncio async def test_create_conversion_source_field_headers_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1570,7 +1545,7 @@ def test_create_conversion_source_flattened_error(): @pytest.mark.asyncio async def test_create_conversion_source_flattened_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1613,7 +1588,7 @@ async def test_create_conversion_source_flattened_async(): @pytest.mark.asyncio async def test_create_conversion_source_flattened_error_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1672,27 +1647,6 @@ def test_update_conversion_source(request_type, transport: str = "grpc"): assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT -def test_update_conversion_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_conversion_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.UpdateConversionSourceRequest() - - def test_update_conversion_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1759,33 +1713,6 @@ def test_update_conversion_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_conversion_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_conversion_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - ) - response = await client.update_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.UpdateConversionSourceRequest() - - @pytest.mark.asyncio async def test_update_conversion_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1794,7 +1721,7 @@ async def test_update_conversion_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1834,7 +1761,7 @@ async def test_update_conversion_source_async( request_type=conversionsources.UpdateConversionSourceRequest, ): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1908,7 +1835,7 @@ def test_update_conversion_source_field_headers(): @pytest.mark.asyncio async def test_update_conversion_source_field_headers_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1999,7 +1926,7 @@ def test_update_conversion_source_flattened_error(): @pytest.mark.asyncio async def test_update_conversion_source_flattened_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2042,7 +1969,7 @@ async def test_update_conversion_source_flattened_async(): @pytest.mark.asyncio async def test_update_conversion_source_flattened_error_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2094,27 +2021,6 @@ def test_delete_conversion_source(request_type, transport: str = "grpc"): assert response is None -def test_delete_conversion_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_conversion_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.DeleteConversionSourceRequest() - - def test_delete_conversion_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2185,27 +2091,6 @@ def test_delete_conversion_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_conversion_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_conversion_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.DeleteConversionSourceRequest() - - @pytest.mark.asyncio async def test_delete_conversion_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2214,7 +2099,7 @@ async def test_delete_conversion_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2254,7 +2139,7 @@ async def test_delete_conversion_source_async( request_type=conversionsources.DeleteConversionSourceRequest, ): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2319,7 +2204,7 @@ def test_delete_conversion_source_field_headers(): @pytest.mark.asyncio async def test_delete_conversion_source_field_headers_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2391,7 +2276,7 @@ def test_delete_conversion_source_flattened_error(): @pytest.mark.asyncio async def test_delete_conversion_source_flattened_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2420,7 +2305,7 @@ async def test_delete_conversion_source_flattened_async(): @pytest.mark.asyncio async def test_delete_conversion_source_flattened_error_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2474,27 +2359,6 @@ def test_undelete_conversion_source(request_type, transport: str = "grpc"): assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT -def test_undelete_conversion_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.undelete_conversion_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.undelete_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.UndeleteConversionSourceRequest() - - def test_undelete_conversion_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2565,33 +2429,6 @@ def test_undelete_conversion_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_undelete_conversion_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.undelete_conversion_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - ) - response = await client.undelete_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.UndeleteConversionSourceRequest() - - @pytest.mark.asyncio async def test_undelete_conversion_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2600,7 +2437,7 @@ async def test_undelete_conversion_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2640,7 +2477,7 @@ async def test_undelete_conversion_source_async( request_type=conversionsources.UndeleteConversionSourceRequest, ): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2714,7 +2551,7 @@ def test_undelete_conversion_source_field_headers(): @pytest.mark.asyncio async def test_undelete_conversion_source_field_headers_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2787,27 +2624,6 @@ def test_get_conversion_source(request_type, transport: str = "grpc"): assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT -def test_get_conversion_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_conversion_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.GetConversionSourceRequest() - - def test_get_conversion_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2878,33 +2694,6 @@ def test_get_conversion_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_conversion_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_conversion_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - ) - response = await client.get_conversion_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.GetConversionSourceRequest() - - @pytest.mark.asyncio async def test_get_conversion_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2913,7 +2702,7 @@ async def test_get_conversion_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2953,7 +2742,7 @@ async def test_get_conversion_source_async( request_type=conversionsources.GetConversionSourceRequest, ): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3027,7 +2816,7 @@ def test_get_conversion_source_field_headers(): @pytest.mark.asyncio async def test_get_conversion_source_field_headers_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3101,7 +2890,7 @@ def test_get_conversion_source_flattened_error(): @pytest.mark.asyncio async def test_get_conversion_source_flattened_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3132,7 +2921,7 @@ async def test_get_conversion_source_flattened_async(): @pytest.mark.asyncio async def test_get_conversion_source_flattened_error_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3182,27 +2971,6 @@ def test_list_conversion_sources(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_conversion_sources_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_conversion_sources), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_conversion_sources() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.ListConversionSourcesRequest() - - def test_list_conversion_sources_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3275,31 +3043,6 @@ def test_list_conversion_sources_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_conversion_sources_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_conversion_sources), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - conversionsources.ListConversionSourcesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_conversion_sources() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == conversionsources.ListConversionSourcesRequest() - - @pytest.mark.asyncio async def test_list_conversion_sources_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -3308,7 +3051,7 @@ async def test_list_conversion_sources_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3348,7 +3091,7 @@ async def test_list_conversion_sources_async( request_type=conversionsources.ListConversionSourcesRequest, ): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3418,7 +3161,7 @@ def test_list_conversion_sources_field_headers(): @pytest.mark.asyncio async def test_list_conversion_sources_field_headers_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3492,7 +3235,7 @@ def test_list_conversion_sources_flattened_error(): @pytest.mark.asyncio async def test_list_conversion_sources_flattened_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3523,7 +3266,7 @@ async def test_list_conversion_sources_flattened_async(): @pytest.mark.asyncio async def test_list_conversion_sources_flattened_error_async(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3637,7 +3380,7 @@ def test_list_conversion_sources_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_conversion_sources_async_pager(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3689,7 +3432,7 @@ async def test_list_conversion_sources_async_pager(): @pytest.mark.asyncio async def test_list_conversion_sources_async_pages(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3737,140 +3480,6 @@ async def test_list_conversion_sources_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - conversionsources.CreateConversionSourceRequest, - dict, - ], -) -def test_create_conversion_source_rest(request_type): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["conversion_source"] = { - "google_analytics_link": { - "property_id": 1201, - "attribution_settings": { - "attribution_lookback_window_days": 3425, - "attribution_model": 1, - "conversion_type": [{"name": "name_value", "report": True}], - }, - "property": "property_value", - }, - "merchant_center_destination": { - "destination": "destination_value", - "attribution_settings": {}, - "display_name": "display_name_value", - "currency_code": "currency_code_value", - }, - "name": "name_value", - "state": 1, - "expire_time": {"seconds": 751, "nanos": 543}, - "controller": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = conversionsources.CreateConversionSourceRequest.meta.fields[ - "conversion_source" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["conversion_source"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["conversion_source"][field])): - del request_init["conversion_source"][field][i][subfield] - else: - del request_init["conversion_source"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = conversionsources.ConversionSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_conversion_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, conversionsources.ConversionSource) - assert response.name == "name_value" - assert response.state == conversionsources.ConversionSource.State.ACTIVE - assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT - - def test_create_conversion_source_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4004,90 +3613,6 @@ def test_create_conversion_source_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_conversion_source_rest_interceptors(null_interceptor): - transport = transports.ConversionSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ConversionSourcesServiceRestInterceptor(), - ) - client = ConversionSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "post_create_conversion_source", - ) as post, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "pre_create_conversion_source", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = conversionsources.CreateConversionSourceRequest.pb( - conversionsources.CreateConversionSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = conversionsources.ConversionSource.to_json( - conversionsources.ConversionSource() - ) - - request = conversionsources.CreateConversionSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = conversionsources.ConversionSource() - - client.create_conversion_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_conversion_source_rest_bad_request( - transport: str = "rest", - request_type=conversionsources.CreateConversionSourceRequest, -): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_conversion_source(request) - - def test_create_conversion_source_rest_flattened(): client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4155,160 +3680,18 @@ def test_create_conversion_source_rest_flattened_error(transport: str = "rest"): ) -def test_create_conversion_source_rest_error(): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_update_conversion_source_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - -@pytest.mark.parametrize( - "request_type", - [ - conversionsources.UpdateConversionSourceRequest, - dict, - ], -) -def test_update_conversion_source_rest(request_type): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "conversion_source": {"name": "accounts/sample1/conversionSources/sample2"} - } - request_init["conversion_source"] = { - "google_analytics_link": { - "property_id": 1201, - "attribution_settings": { - "attribution_lookback_window_days": 3425, - "attribution_model": 1, - "conversion_type": [{"name": "name_value", "report": True}], - }, - "property": "property_value", - }, - "merchant_center_destination": { - "destination": "destination_value", - "attribution_settings": {}, - "display_name": "display_name_value", - "currency_code": "currency_code_value", - }, - "name": "accounts/sample1/conversionSources/sample2", - "state": 1, - "expire_time": {"seconds": 751, "nanos": 543}, - "controller": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = conversionsources.UpdateConversionSourceRequest.meta.fields[ - "conversion_source" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["conversion_source"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["conversion_source"][field])): - del request_init["conversion_source"][field][i][subfield] - else: - del request_init["conversion_source"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = conversionsources.ConversionSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_conversion_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, conversionsources.ConversionSource) - assert response.name == "name_value" - assert response.state == conversionsources.ConversionSource.State.ACTIVE - assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT - - -def test_update_conversion_source_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() # Ensure method has been cached assert ( @@ -4427,92 +3810,6 @@ def test_update_conversion_source_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_conversion_source_rest_interceptors(null_interceptor): - transport = transports.ConversionSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ConversionSourcesServiceRestInterceptor(), - ) - client = ConversionSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "post_update_conversion_source", - ) as post, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "pre_update_conversion_source", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = conversionsources.UpdateConversionSourceRequest.pb( - conversionsources.UpdateConversionSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = conversionsources.ConversionSource.to_json( - conversionsources.ConversionSource() - ) - - request = conversionsources.UpdateConversionSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = conversionsources.ConversionSource() - - client.update_conversion_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_conversion_source_rest_bad_request( - transport: str = "rest", - request_type=conversionsources.UpdateConversionSourceRequest, -): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = { - "conversion_source": {"name": "accounts/sample1/conversionSources/sample2"} - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_conversion_source(request) - - def test_update_conversion_source_rest_flattened(): client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4582,65 +3879,24 @@ def test_update_conversion_source_rest_flattened_error(transport: str = "rest"): ) -def test_update_conversion_source_rest_error(): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - +def test_delete_conversion_source_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -@pytest.mark.parametrize( - "request_type", - [ - conversionsources.DeleteConversionSourceRequest, - dict, - ], -) -def test_delete_conversion_source_rest(request_type): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/conversionSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_conversion_source(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_conversion_source_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.delete_conversion_source - in client._transport._wrapped_methods - ) + # Ensure method has been cached + assert ( + client._transport.delete_conversion_source + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -4744,81 +4000,6 @@ def test_delete_conversion_source_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_conversion_source_rest_interceptors(null_interceptor): - transport = transports.ConversionSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ConversionSourcesServiceRestInterceptor(), - ) - client = ConversionSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "pre_delete_conversion_source", - ) as pre: - pre.assert_not_called() - pb_message = conversionsources.DeleteConversionSourceRequest.pb( - conversionsources.DeleteConversionSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = conversionsources.DeleteConversionSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_conversion_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_conversion_source_rest_bad_request( - transport: str = "rest", - request_type=conversionsources.DeleteConversionSourceRequest, -): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/conversionSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_conversion_source(request) - - def test_delete_conversion_source_rest_flattened(): client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4874,56 +4055,6 @@ def test_delete_conversion_source_rest_flattened_error(transport: str = "rest"): ) -def test_delete_conversion_source_rest_error(): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - conversionsources.UndeleteConversionSourceRequest, - dict, - ], -) -def test_undelete_conversion_source_rest(request_type): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/conversionSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = conversionsources.ConversionSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.undelete_conversion_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, conversionsources.ConversionSource) - assert response.name == "name_value" - assert response.state == conversionsources.ConversionSource.State.ACTIVE - assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT - - def test_undelete_conversion_source_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5049,185 +4180,51 @@ def test_undelete_conversion_source_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_undelete_conversion_source_rest_interceptors(null_interceptor): - transport = transports.ConversionSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ConversionSourcesServiceRestInterceptor(), - ) - client = ConversionSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "post_undelete_conversion_source", - ) as post, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "pre_undelete_conversion_source", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = conversionsources.UndeleteConversionSourceRequest.pb( - conversionsources.UndeleteConversionSourceRequest() +def test_get_conversion_source_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = conversionsources.ConversionSource.to_json( - conversionsources.ConversionSource() - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - request = conversionsources.UndeleteConversionSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = conversionsources.ConversionSource() + # Ensure method has been cached + assert ( + client._transport.get_conversion_source + in client._transport._wrapped_methods + ) - client.undelete_conversion_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) + client._transport._wrapped_methods[ + client._transport.get_conversion_source + ] = mock_rpc - pre.assert_called_once() - post.assert_called_once() + request = {} + client.get_conversion_source(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -def test_undelete_conversion_source_rest_bad_request( - transport: str = "rest", - request_type=conversionsources.UndeleteConversionSourceRequest, -): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + client.get_conversion_source(request) - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/conversionSources/sample2"} - request = request_type(**request_init) + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.undelete_conversion_source(request) - -def test_undelete_conversion_source_rest_error(): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - conversionsources.GetConversionSourceRequest, - dict, - ], -) -def test_get_conversion_source_rest(request_type): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/conversionSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = conversionsources.ConversionSource( - name="name_value", - state=conversionsources.ConversionSource.State.ACTIVE, - controller=conversionsources.ConversionSource.Controller.MERCHANT, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = conversionsources.ConversionSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_conversion_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, conversionsources.ConversionSource) - assert response.name == "name_value" - assert response.state == conversionsources.ConversionSource.State.ACTIVE - assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT - - -def test_get_conversion_source_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.get_conversion_source - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.get_conversion_source - ] = mock_rpc - - request = {} - client.get_conversion_source(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_conversion_source(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_conversion_source_rest_required_fields( - request_type=conversionsources.GetConversionSourceRequest, -): - transport_class = transports.ConversionSourcesServiceRestTransport +def test_get_conversion_source_rest_required_fields( + request_type=conversionsources.GetConversionSourceRequest, +): + transport_class = transports.ConversionSourcesServiceRestTransport request_init = {} request_init["name"] = "" @@ -5307,87 +4304,6 @@ def test_get_conversion_source_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_conversion_source_rest_interceptors(null_interceptor): - transport = transports.ConversionSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ConversionSourcesServiceRestInterceptor(), - ) - client = ConversionSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, "post_get_conversion_source" - ) as post, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, "pre_get_conversion_source" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = conversionsources.GetConversionSourceRequest.pb( - conversionsources.GetConversionSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = conversionsources.ConversionSource.to_json( - conversionsources.ConversionSource() - ) - - request = conversionsources.GetConversionSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = conversionsources.ConversionSource() - - client.get_conversion_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_conversion_source_rest_bad_request( - transport: str = "rest", request_type=conversionsources.GetConversionSourceRequest -): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/conversionSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_conversion_source(request) - - def test_get_conversion_source_rest_flattened(): client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5445,52 +4361,6 @@ def test_get_conversion_source_rest_flattened_error(transport: str = "rest"): ) -def test_get_conversion_source_rest_error(): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - conversionsources.ListConversionSourcesRequest, - dict, - ], -) -def test_list_conversion_sources_rest(request_type): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = conversionsources.ListConversionSourcesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = conversionsources.ListConversionSourcesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_conversion_sources(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListConversionSourcesPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_conversion_sources_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5634,56 +4504,1230 @@ def test_list_conversion_sources_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_conversion_sources_rest_interceptors(null_interceptor): - transport = transports.ConversionSourcesServiceRestTransport( +def test_list_conversion_sources_rest_flattened(): + client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ConversionSourcesServiceRestInterceptor(), + transport="rest", ) - client = ConversionSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "post_list_conversion_sources", - ) as post, mock.patch.object( - transports.ConversionSourcesServiceRestInterceptor, - "pre_list_conversion_sources", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = conversionsources.ListConversionSourcesRequest.pb( - conversionsources.ListConversionSourcesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - conversionsources.ListConversionSourcesResponse.to_json( - conversionsources.ListConversionSourcesResponse() - ) - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = conversionsources.ListConversionSourcesResponse() - request = conversionsources.ListConversionSourcesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = conversionsources.ListConversionSourcesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_conversion_sources(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/conversions/v1beta/{parent=accounts/*}/conversionSources" + % client.transport._host, + args[1], + ) + + +def test_list_conversion_sources_rest_flattened_error(transport: str = "rest"): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_conversion_sources( + conversionsources.ListConversionSourcesRequest(), + parent="parent_value", + ) + + +def test_list_conversion_sources_rest_pager(transport: str = "rest"): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + conversionsources.ListConversionSourcesResponse( + conversion_sources=[ + conversionsources.ConversionSource(), + conversionsources.ConversionSource(), + conversionsources.ConversionSource(), + ], + next_page_token="abc", + ), + conversionsources.ListConversionSourcesResponse( + conversion_sources=[], + next_page_token="def", + ), + conversionsources.ListConversionSourcesResponse( + conversion_sources=[ + conversionsources.ConversionSource(), + ], + next_page_token="ghi", + ), + conversionsources.ListConversionSourcesResponse( + conversion_sources=[ + conversionsources.ConversionSource(), + conversionsources.ConversionSource(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + conversionsources.ListConversionSourcesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_conversion_sources(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, conversionsources.ConversionSource) for i in results) + + pages = list(client.list_conversion_sources(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ConversionSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ConversionSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ConversionSourcesServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ConversionSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ConversionSourcesServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ConversionSourcesServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ConversionSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ConversionSourcesServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ConversionSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ConversionSourcesServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ConversionSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ConversionSourcesServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ConversionSourcesServiceGrpcTransport, + transports.ConversionSourcesServiceGrpcAsyncIOTransport, + transports.ConversionSourcesServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = ConversionSourcesServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_conversion_source_empty_call_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_conversion_source), "__call__" + ) as call: + call.return_value = conversionsources.ConversionSource() + client.create_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.CreateConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_conversion_source_empty_call_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_conversion_source), "__call__" + ) as call: + call.return_value = conversionsources.ConversionSource() + client.update_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.UpdateConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_conversion_source_empty_call_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_conversion_source), "__call__" + ) as call: + call.return_value = None + client.delete_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.DeleteConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_undelete_conversion_source_empty_call_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.undelete_conversion_source), "__call__" + ) as call: + call.return_value = conversionsources.ConversionSource() + client.undelete_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.UndeleteConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_conversion_source_empty_call_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_conversion_source), "__call__" + ) as call: + call.return_value = conversionsources.ConversionSource() + client.get_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.GetConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_conversion_sources_empty_call_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_conversion_sources), "__call__" + ) as call: + call.return_value = conversionsources.ListConversionSourcesResponse() + client.list_conversion_sources(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.ListConversionSourcesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ConversionSourcesServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_conversion_source_empty_call_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_conversion_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + ) + await client.create_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.CreateConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_conversion_source_empty_call_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_conversion_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + ) + await client.update_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.UpdateConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_conversion_source_empty_call_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_conversion_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.DeleteConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_undelete_conversion_source_empty_call_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.undelete_conversion_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + ) + await client.undelete_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.UndeleteConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_conversion_source_empty_call_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_conversion_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + ) + await client.get_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.GetConversionSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_conversion_sources_empty_call_grpc_asyncio(): + client = ConversionSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_conversion_sources), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + conversionsources.ListConversionSourcesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_conversion_sources(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.ListConversionSourcesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ConversionSourcesServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_create_conversion_source_rest_bad_request( + request_type=conversionsources.CreateConversionSourceRequest, +): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_conversion_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + conversionsources.CreateConversionSourceRequest, + dict, + ], +) +def test_create_conversion_source_rest_call_success(request_type): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["conversion_source"] = { + "google_analytics_link": { + "property_id": 1201, + "attribution_settings": { + "attribution_lookback_window_days": 3425, + "attribution_model": 1, + "conversion_type": [{"name": "name_value", "report": True}], + }, + "property": "property_value", + }, + "merchant_center_destination": { + "destination": "destination_value", + "attribution_settings": {}, + "display_name": "display_name_value", + "currency_code": "currency_code_value", + }, + "name": "name_value", + "state": 1, + "expire_time": {"seconds": 751, "nanos": 543}, + "controller": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = conversionsources.CreateConversionSourceRequest.meta.fields[ + "conversion_source" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["conversion_source"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["conversion_source"][field])): + del request_init["conversion_source"][field][i][subfield] + else: + del request_init["conversion_source"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = conversionsources.ConversionSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_conversion_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, conversionsources.ConversionSource) + assert response.name == "name_value" + assert response.state == conversionsources.ConversionSource.State.ACTIVE + assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_conversion_source_rest_interceptors(null_interceptor): + transport = transports.ConversionSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ConversionSourcesServiceRestInterceptor(), + ) + client = ConversionSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "post_create_conversion_source", + ) as post, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "pre_create_conversion_source", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = conversionsources.CreateConversionSourceRequest.pb( + conversionsources.CreateConversionSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = conversionsources.ConversionSource.to_json( + conversionsources.ConversionSource() + ) + req.return_value.content = return_value + + request = conversionsources.CreateConversionSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = conversionsources.ConversionSource() + + client.create_conversion_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_conversion_source_rest_bad_request( + request_type=conversionsources.UpdateConversionSourceRequest, +): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "conversion_source": {"name": "accounts/sample1/conversionSources/sample2"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_conversion_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + conversionsources.UpdateConversionSourceRequest, + dict, + ], +) +def test_update_conversion_source_rest_call_success(request_type): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "conversion_source": {"name": "accounts/sample1/conversionSources/sample2"} + } + request_init["conversion_source"] = { + "google_analytics_link": { + "property_id": 1201, + "attribution_settings": { + "attribution_lookback_window_days": 3425, + "attribution_model": 1, + "conversion_type": [{"name": "name_value", "report": True}], + }, + "property": "property_value", + }, + "merchant_center_destination": { + "destination": "destination_value", + "attribution_settings": {}, + "display_name": "display_name_value", + "currency_code": "currency_code_value", + }, + "name": "accounts/sample1/conversionSources/sample2", + "state": 1, + "expire_time": {"seconds": 751, "nanos": 543}, + "controller": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = conversionsources.UpdateConversionSourceRequest.meta.fields[ + "conversion_source" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["conversion_source"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["conversion_source"][field])): + del request_init["conversion_source"][field][i][subfield] + else: + del request_init["conversion_source"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = conversionsources.ConversionSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_conversion_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, conversionsources.ConversionSource) + assert response.name == "name_value" + assert response.state == conversionsources.ConversionSource.State.ACTIVE + assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_conversion_source_rest_interceptors(null_interceptor): + transport = transports.ConversionSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ConversionSourcesServiceRestInterceptor(), + ) + client = ConversionSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "post_update_conversion_source", + ) as post, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "pre_update_conversion_source", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = conversionsources.UpdateConversionSourceRequest.pb( + conversionsources.UpdateConversionSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = conversionsources.ConversionSource.to_json( + conversionsources.ConversionSource() + ) + req.return_value.content = return_value + + request = conversionsources.UpdateConversionSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = conversionsources.ConversionSource() + + client.update_conversion_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_conversion_source_rest_bad_request( + request_type=conversionsources.DeleteConversionSourceRequest, +): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/conversionSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_conversion_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + conversionsources.DeleteConversionSourceRequest, + dict, + ], +) +def test_delete_conversion_source_rest_call_success(request_type): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/conversionSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_conversion_source(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_conversion_source_rest_interceptors(null_interceptor): + transport = transports.ConversionSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ConversionSourcesServiceRestInterceptor(), + ) + client = ConversionSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "pre_delete_conversion_source", + ) as pre: + pre.assert_not_called() + pb_message = conversionsources.DeleteConversionSourceRequest.pb( + conversionsources.DeleteConversionSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = conversionsources.DeleteConversionSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_conversion_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_undelete_conversion_source_rest_bad_request( + request_type=conversionsources.UndeleteConversionSourceRequest, +): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/conversionSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.undelete_conversion_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + conversionsources.UndeleteConversionSourceRequest, + dict, + ], +) +def test_undelete_conversion_source_rest_call_success(request_type): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/conversionSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = conversionsources.ConversionSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.undelete_conversion_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, conversionsources.ConversionSource) + assert response.name == "name_value" + assert response.state == conversionsources.ConversionSource.State.ACTIVE + assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_undelete_conversion_source_rest_interceptors(null_interceptor): + transport = transports.ConversionSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ConversionSourcesServiceRestInterceptor(), + ) + client = ConversionSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "post_undelete_conversion_source", + ) as post, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "pre_undelete_conversion_source", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = conversionsources.UndeleteConversionSourceRequest.pb( + conversionsources.UndeleteConversionSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = conversionsources.ConversionSource.to_json( + conversionsources.ConversionSource() + ) + req.return_value.content = return_value + + request = conversionsources.UndeleteConversionSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = conversionsources.ListConversionSourcesResponse() + post.return_value = conversionsources.ConversionSource() - client.list_conversion_sources( + client.undelete_conversion_source( request, metadata=[ ("key", "val"), @@ -5695,14 +5739,137 @@ def test_list_conversion_sources_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_conversion_sources_rest_bad_request( - transport: str = "rest", request_type=conversionsources.ListConversionSourcesRequest +def test_get_conversion_source_rest_bad_request( + request_type=conversionsources.GetConversionSourceRequest, ): client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/conversionSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_conversion_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + conversionsources.GetConversionSourceRequest, + dict, + ], +) +def test_get_conversion_source_rest_call_success(request_type): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/conversionSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = conversionsources.ConversionSource( + name="name_value", + state=conversionsources.ConversionSource.State.ACTIVE, + controller=conversionsources.ConversionSource.Controller.MERCHANT, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = conversionsources.ConversionSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_conversion_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, conversionsources.ConversionSource) + assert response.name == "name_value" + assert response.state == conversionsources.ConversionSource.State.ACTIVE + assert response.controller == conversionsources.ConversionSource.Controller.MERCHANT + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_conversion_source_rest_interceptors(null_interceptor): + transport = transports.ConversionSourcesServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.ConversionSourcesServiceRestInterceptor(), ) + client = ConversionSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, "post_get_conversion_source" + ) as post, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, "pre_get_conversion_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = conversionsources.GetConversionSourceRequest.pb( + conversionsources.GetConversionSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = conversionsources.ConversionSource.to_json( + conversionsources.ConversionSource() + ) + req.return_value.content = return_value + + request = conversionsources.GetConversionSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = conversionsources.ConversionSource() + + client.get_conversion_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + +def test_list_conversion_sources_rest_bad_request( + request_type=conversionsources.ListConversionSourcesRequest, +): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) # send a request that will satisfy transcoding request_init = {"parent": "accounts/sample1"} request = request_type(**request_init) @@ -5712,237 +5879,251 @@ def test_list_conversion_sources_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.list_conversion_sources(request) -def test_list_conversion_sources_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + conversionsources.ListConversionSourcesRequest, + dict, + ], +) +def test_list_conversion_sources_rest_call_success(request_type): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = conversionsources.ListConversionSourcesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = conversionsources.ListConversionSourcesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_conversion_sources(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListConversionSourcesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_conversion_sources_rest_interceptors(null_interceptor): + transport = transports.ConversionSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ConversionSourcesServiceRestInterceptor(), + ) + client = ConversionSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "post_list_conversion_sources", + ) as post, mock.patch.object( + transports.ConversionSourcesServiceRestInterceptor, + "pre_list_conversion_sources", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = conversionsources.ListConversionSourcesRequest.pb( + conversionsources.ListConversionSourcesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = conversionsources.ListConversionSourcesResponse.to_json( + conversionsources.ListConversionSourcesResponse() + ) + req.return_value.content = return_value + + request = conversionsources.ListConversionSourcesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = conversionsources.ListConversionSourcesResponse() + + client.list_conversion_sources( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = conversionsources.ListConversionSourcesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_conversion_source_empty_call_rest(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = conversionsources.ListConversionSourcesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_conversion_source), "__call__" + ) as call: + client.create_conversion_source(request=None) - client.list_conversion_sources(**mock_args) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.CreateConversionSourceRequest() - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/conversions/v1beta/{parent=accounts/*}/conversionSources" - % client.transport._host, - args[1], - ) + assert args[0] == request_msg -def test_list_conversion_sources_rest_flattened_error(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_conversion_source_empty_call_rest(): client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_conversion_sources( - conversionsources.ListConversionSourcesRequest(), - parent="parent_value", - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_conversion_source), "__call__" + ) as call: + client.update_conversion_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.UpdateConversionSourceRequest() + assert args[0] == request_msg -def test_list_conversion_sources_rest_pager(transport: str = "rest"): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_conversion_source_empty_call_rest(): client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - conversionsources.ListConversionSourcesResponse( - conversion_sources=[ - conversionsources.ConversionSource(), - conversionsources.ConversionSource(), - conversionsources.ConversionSource(), - ], - next_page_token="abc", - ), - conversionsources.ListConversionSourcesResponse( - conversion_sources=[], - next_page_token="def", - ), - conversionsources.ListConversionSourcesResponse( - conversion_sources=[ - conversionsources.ConversionSource(), - ], - next_page_token="ghi", - ), - conversionsources.ListConversionSourcesResponse( - conversion_sources=[ - conversionsources.ConversionSource(), - conversionsources.ConversionSource(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - conversionsources.ListConversionSourcesResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_conversion_sources(request=sample_request) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_conversion_source), "__call__" + ) as call: + client.delete_conversion_source(request=None) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, conversionsources.ConversionSource) for i in results) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.DeleteConversionSourceRequest() - pages = list(client.list_conversion_sources(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + assert args[0] == request_msg -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ConversionSourcesServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_undelete_conversion_source_empty_call_rest(): + client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.ConversionSourcesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ConversionSourcesServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.undelete_conversion_source), "__call__" + ) as call: + client.undelete_conversion_source(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.ConversionSourcesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ConversionSourcesServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.UndeleteConversionSourceRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ConversionSourcesServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.ConversionSourcesServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_conversion_source_empty_call_rest(): + client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ConversionSourcesServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_conversion_source), "__call__" + ) as call: + client.get_conversion_source(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ConversionSourcesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ConversionSourcesServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.GetConversionSourceRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ConversionSourcesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.ConversionSourcesServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_conversion_sources_empty_call_rest(): + client = ConversionSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ConversionSourcesServiceGrpcTransport, - transports.ConversionSourcesServiceGrpcAsyncIOTransport, - transports.ConversionSourcesServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_conversion_sources), "__call__" + ) as call: + client.list_conversion_sources(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = conversionsources.ListConversionSourcesRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = ConversionSourcesServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -6543,36 +6724,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = ConversionSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ConversionSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = ConversionSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py index 114e40645800..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.3" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py index 114e40645800..558c8aab67c5 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.3" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/README.rst b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/README.rst new file mode 100644 index 000000000000..bed349bac943 --- /dev/null +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`DataSourcesServiceTransport` is the ABC for all transports. +- public child `DataSourcesServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `DataSourcesServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseDataSourcesServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `DataSourcesServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py index 3dcdd03209ab..77dcf8525878 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -230,6 +231,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -422,40 +426,49 @@ def fetch_data_source( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_data_source: gapic_v1.method_async.wrap_method( + self.get_data_source: self._wrap_method( self.get_data_source, default_timeout=None, client_info=client_info, ), - self.list_data_sources: gapic_v1.method_async.wrap_method( + self.list_data_sources: self._wrap_method( self.list_data_sources, default_timeout=None, client_info=client_info, ), - self.create_data_source: gapic_v1.method_async.wrap_method( + self.create_data_source: self._wrap_method( self.create_data_source, default_timeout=None, client_info=client_info, ), - self.update_data_source: gapic_v1.method_async.wrap_method( + self.update_data_source: self._wrap_method( self.update_data_source, default_timeout=None, client_info=client_info, ), - self.delete_data_source: gapic_v1.method_async.wrap_method( + self.delete_data_source: self._wrap_method( self.delete_data_source, default_timeout=None, client_info=client_info, ), - self.fetch_data_source: gapic_v1.method_async.wrap_method( + self.fetch_data_source: self._wrap_method( self.fetch_data_source, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("DataSourcesServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py index c20f208bb222..e4de94262023 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_datasources_v1beta.types import datasources + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseDataSourcesServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_datasources_v1beta.types import datasources - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import DataSourcesServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -235,8 +231,8 @@ class DataSourcesServiceRestStub: _interceptor: DataSourcesServiceRestInterceptor -class DataSourcesServiceRestTransport(DataSourcesServiceTransport): - """REST backend transport for DataSourcesService. +class DataSourcesServiceRestTransport(_BaseDataSourcesServiceRestTransport): + """REST backend synchronous transport for DataSourcesService. Service to manage primary, supplemental, inventory and other data sources. See more in the `Merchant @@ -248,7 +244,6 @@ class DataSourcesServiceRestTransport(DataSourcesServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -302,21 +297,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -327,19 +313,35 @@ def __init__( self._interceptor = interceptor or DataSourcesServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateDataSource(DataSourcesServiceRestStub): + class _CreateDataSource( + _BaseDataSourcesServiceRestTransport._BaseCreateDataSource, + DataSourcesServiceRestStub, + ): def __hash__(self): - return hash("CreateDataSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DataSourcesServiceRestTransport.CreateDataSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -369,47 +371,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/datasources/v1beta/{parent=accounts/*}/dataSources", - "body": "data_source", - }, - ] + http_options = ( + _BaseDataSourcesServiceRestTransport._BaseCreateDataSource._get_http_options() + ) request, metadata = self._interceptor.pre_create_data_source( request, metadata ) - pb_request = datasources.CreateDataSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDataSourcesServiceRestTransport._BaseCreateDataSource._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDataSourcesServiceRestTransport._BaseCreateDataSource._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDataSourcesServiceRestTransport._BaseCreateDataSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = DataSourcesServiceRestTransport._CreateDataSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -425,19 +414,34 @@ def __call__( resp = self._interceptor.post_create_data_source(resp) return resp - class _DeleteDataSource(DataSourcesServiceRestStub): + class _DeleteDataSource( + _BaseDataSourcesServiceRestTransport._BaseDeleteDataSource, + DataSourcesServiceRestStub, + ): def __hash__(self): - return hash("DeleteDataSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DataSourcesServiceRestTransport.DeleteDataSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -460,40 +464,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*}", - }, - ] + http_options = ( + _BaseDataSourcesServiceRestTransport._BaseDeleteDataSource._get_http_options() + ) request, metadata = self._interceptor.pre_delete_data_source( request, metadata ) - pb_request = datasources.DeleteDataSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDataSourcesServiceRestTransport._BaseDeleteDataSource._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDataSourcesServiceRestTransport._BaseDeleteDataSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DataSourcesServiceRestTransport._DeleteDataSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -501,19 +494,35 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _FetchDataSource(DataSourcesServiceRestStub): + class _FetchDataSource( + _BaseDataSourcesServiceRestTransport._BaseFetchDataSource, + DataSourcesServiceRestStub, + ): def __hash__(self): - return hash("FetchDataSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DataSourcesServiceRestTransport.FetchDataSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -536,47 +545,34 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*}:fetch", - "body": "*", - }, - ] + http_options = ( + _BaseDataSourcesServiceRestTransport._BaseFetchDataSource._get_http_options() + ) request, metadata = self._interceptor.pre_fetch_data_source( request, metadata ) - pb_request = datasources.FetchDataSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDataSourcesServiceRestTransport._BaseFetchDataSource._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDataSourcesServiceRestTransport._BaseFetchDataSource._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDataSourcesServiceRestTransport._BaseFetchDataSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = DataSourcesServiceRestTransport._FetchDataSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -584,19 +580,34 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetDataSource(DataSourcesServiceRestStub): + class _GetDataSource( + _BaseDataSourcesServiceRestTransport._BaseGetDataSource, + DataSourcesServiceRestStub, + ): def __hash__(self): - return hash("GetDataSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DataSourcesServiceRestTransport.GetDataSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -626,38 +637,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*}", - }, - ] + http_options = ( + _BaseDataSourcesServiceRestTransport._BaseGetDataSource._get_http_options() + ) request, metadata = self._interceptor.pre_get_data_source(request, metadata) - pb_request = datasources.GetDataSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDataSourcesServiceRestTransport._BaseGetDataSource._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDataSourcesServiceRestTransport._BaseGetDataSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DataSourcesServiceRestTransport._GetDataSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -673,19 +673,34 @@ def __call__( resp = self._interceptor.post_get_data_source(resp) return resp - class _ListDataSources(DataSourcesServiceRestStub): + class _ListDataSources( + _BaseDataSourcesServiceRestTransport._BaseListDataSources, + DataSourcesServiceRestStub, + ): def __hash__(self): - return hash("ListDataSources") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DataSourcesServiceRestTransport.ListDataSources") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -714,40 +729,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/datasources/v1beta/{parent=accounts/*}/dataSources", - }, - ] + http_options = ( + _BaseDataSourcesServiceRestTransport._BaseListDataSources._get_http_options() + ) request, metadata = self._interceptor.pre_list_data_sources( request, metadata ) - pb_request = datasources.ListDataSourcesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseDataSourcesServiceRestTransport._BaseListDataSources._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDataSourcesServiceRestTransport._BaseListDataSources._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = DataSourcesServiceRestTransport._ListDataSources._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -763,21 +767,35 @@ def __call__( resp = self._interceptor.post_list_data_sources(resp) return resp - class _UpdateDataSource(DataSourcesServiceRestStub): + class _UpdateDataSource( + _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource, + DataSourcesServiceRestStub, + ): def __hash__(self): - return hash("UpdateDataSource") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "updateMask": {}, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("DataSourcesServiceRestTransport.UpdateDataSource") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -807,47 +825,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/datasources/v1beta/{data_source.name=accounts/*/dataSources/*}", - "body": "data_source", - }, - ] + http_options = ( + _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource._get_http_options() + ) request, metadata = self._interceptor.pre_update_data_source( request, metadata ) - pb_request = datasources.UpdateDataSourceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = DataSourcesServiceRestTransport._UpdateDataSource._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest_base.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest_base.py new file mode 100644 index 000000000000..0f5b1d1b9272 --- /dev/null +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/data_sources_service/transports/rest_base.py @@ -0,0 +1,406 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_datasources_v1beta.types import datasources + +from .base import DEFAULT_CLIENT_INFO, DataSourcesServiceTransport + + +class _BaseDataSourcesServiceRestTransport(DataSourcesServiceTransport): + """Base REST backend transport for DataSourcesService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateDataSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/datasources/v1beta/{parent=accounts/*}/dataSources", + "body": "data_source", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = datasources.CreateDataSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSourcesServiceRestTransport._BaseCreateDataSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteDataSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = datasources.DeleteDataSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSourcesServiceRestTransport._BaseDeleteDataSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseFetchDataSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*}:fetch", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = datasources.FetchDataSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSourcesServiceRestTransport._BaseFetchDataSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetDataSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = datasources.GetDataSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSourcesServiceRestTransport._BaseGetDataSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDataSources: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/datasources/v1beta/{parent=accounts/*}/dataSources", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = datasources.ListDataSourcesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSourcesServiceRestTransport._BaseListDataSources._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateDataSource: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/datasources/v1beta/{data_source.name=accounts/*/dataSources/*}", + "body": "data_source", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = datasources.UpdateDataSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDataSourcesServiceRestTransport._BaseUpdateDataSource._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseDataSourcesServiceRestTransport",) diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/README.rst b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/README.rst new file mode 100644 index 000000000000..950ff4a21abd --- /dev/null +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`FileUploadsServiceTransport` is the ABC for all transports. +- public child `FileUploadsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `FileUploadsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseFileUploadsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `FileUploadsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py index fc8a254fac63..5ef15b13b560 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -270,15 +274,24 @@ def get_file_upload( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_file_upload: gapic_v1.method_async.wrap_method( + self.get_file_upload: self._wrap_method( self.get_file_upload, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("FileUploadsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py index 1647f7ff13a9..4ad41fab303c 100644 --- a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_datasources_v1beta.types import fileuploads + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseFileUploadsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_datasources_v1beta.types import fileuploads - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import FileUploadsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -108,8 +105,8 @@ class FileUploadsServiceRestStub: _interceptor: FileUploadsServiceRestInterceptor -class FileUploadsServiceRestTransport(FileUploadsServiceTransport): - """REST backend transport for FileUploadsService. +class FileUploadsServiceRestTransport(_BaseFileUploadsServiceRestTransport): + """REST backend synchronous transport for FileUploadsService. Service to manage data source file uploads. @@ -118,7 +115,6 @@ class FileUploadsServiceRestTransport(FileUploadsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -172,21 +168,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -197,19 +184,34 @@ def __init__( self._interceptor = interceptor or FileUploadsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetFileUpload(FileUploadsServiceRestStub): + class _GetFileUpload( + _BaseFileUploadsServiceRestTransport._BaseGetFileUpload, + FileUploadsServiceRestStub, + ): def __hash__(self): - return hash("GetFileUpload") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("FileUploadsServiceRestTransport.GetFileUpload") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -243,38 +245,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*/fileUploads/*}", - }, - ] + http_options = ( + _BaseFileUploadsServiceRestTransport._BaseGetFileUpload._get_http_options() + ) request, metadata = self._interceptor.pre_get_file_upload(request, metadata) - pb_request = fileuploads.GetFileUploadRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseFileUploadsServiceRestTransport._BaseGetFileUpload._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseFileUploadsServiceRestTransport._BaseGetFileUpload._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = FileUploadsServiceRestTransport._GetFileUpload._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest_base.py b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest_base.py new file mode 100644 index 000000000000..7e430be06582 --- /dev/null +++ b/packages/google-shopping-merchant-datasources/google/shopping/merchant_datasources_v1beta/services/file_uploads_service/transports/rest_base.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_datasources_v1beta.types import fileuploads + +from .base import DEFAULT_CLIENT_INFO, FileUploadsServiceTransport + + +class _BaseFileUploadsServiceRestTransport(FileUploadsServiceTransport): + """Base REST backend transport for FileUploadsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetFileUpload: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/datasources/v1beta/{name=accounts/*/dataSources/*/fileUploads/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = fileuploads.GetFileUploadRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseFileUploadsServiceRestTransport._BaseGetFileUpload._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseFileUploadsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json b/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json index 930545c42afc..8af0e5a52d60 100644 --- a/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json +++ b/packages/google-shopping-merchant-datasources/samples/generated_samples/snippet_metadata_google.shopping.merchant.datasources.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-shopping-merchant-datasources", - "version": "0.1.3" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-shopping-merchant-datasources/setup.py b/packages/google-shopping-merchant-datasources/setup.py index bc5a85a93d89..7ac5bf511e28 100644 --- a/packages/google-shopping-merchant-datasources/setup.py +++ b/packages/google-shopping-merchant-datasources/setup.py @@ -48,6 +48,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-datasources" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -90,6 +91,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py index 5ef814bac36e..73fbd8248ec8 100644 --- a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py +++ b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_data_sources_service.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -35,16 +52,8 @@ from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.type import dayofweek_pb2 # type: ignore from google.type import timeofday_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_datasources_v1beta.services.data_sources_service import ( DataSourcesServiceAsyncClient, @@ -59,10 +68,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1208,25 +1231,6 @@ def test_get_data_source(request_type, transport: str = "grpc"): assert response.input == datasources.DataSource.Input.API -def test_get_data_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_data_source), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.GetDataSourceRequest() - - def test_get_data_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1290,32 +1294,6 @@ def test_get_data_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_data_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_data_source), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - datasources.DataSource( - name="name_value", - data_source_id=1462, - display_name="display_name_value", - input=datasources.DataSource.Input.API, - ) - ) - response = await client.get_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.GetDataSourceRequest() - - @pytest.mark.asyncio async def test_get_data_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1324,7 +1302,7 @@ async def test_get_data_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1363,7 +1341,7 @@ async def test_get_data_source_async( transport: str = "grpc_asyncio", request_type=datasources.GetDataSourceRequest ): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1435,7 +1413,7 @@ def test_get_data_source_field_headers(): @pytest.mark.asyncio async def test_get_data_source_field_headers_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1505,7 +1483,7 @@ def test_get_data_source_flattened_error(): @pytest.mark.asyncio async def test_get_data_source_flattened_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1534,7 +1512,7 @@ async def test_get_data_source_flattened_async(): @pytest.mark.asyncio async def test_get_data_source_flattened_error_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1584,27 +1562,6 @@ def test_list_data_sources(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_data_sources_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_data_sources), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_data_sources() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.ListDataSourcesRequest() - - def test_list_data_sources_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1674,31 +1631,6 @@ def test_list_data_sources_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_data_sources_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_data_sources), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - datasources.ListDataSourcesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_data_sources() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.ListDataSourcesRequest() - - @pytest.mark.asyncio async def test_list_data_sources_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1707,7 +1639,7 @@ async def test_list_data_sources_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1746,7 +1678,7 @@ async def test_list_data_sources_async( transport: str = "grpc_asyncio", request_type=datasources.ListDataSourcesRequest ): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1816,7 +1748,7 @@ def test_list_data_sources_field_headers(): @pytest.mark.asyncio async def test_list_data_sources_field_headers_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1890,7 +1822,7 @@ def test_list_data_sources_flattened_error(): @pytest.mark.asyncio async def test_list_data_sources_flattened_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1921,7 +1853,7 @@ async def test_list_data_sources_flattened_async(): @pytest.mark.asyncio async def test_list_data_sources_flattened_error_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2035,7 +1967,7 @@ def test_list_data_sources_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_data_sources_async_pager(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2087,7 +2019,7 @@ async def test_list_data_sources_async_pager(): @pytest.mark.asyncio async def test_list_data_sources_async_pages(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2179,27 +2111,6 @@ def test_create_data_source(request_type, transport: str = "grpc"): assert response.input == datasources.DataSource.Input.API -def test_create_data_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_data_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.CreateDataSourceRequest() - - def test_create_data_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2269,34 +2180,6 @@ def test_create_data_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_data_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_data_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - datasources.DataSource( - name="name_value", - data_source_id=1462, - display_name="display_name_value", - input=datasources.DataSource.Input.API, - ) - ) - response = await client.create_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.CreateDataSourceRequest() - - @pytest.mark.asyncio async def test_create_data_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2305,7 +2188,7 @@ async def test_create_data_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2344,7 +2227,7 @@ async def test_create_data_source_async( transport: str = "grpc_asyncio", request_type=datasources.CreateDataSourceRequest ): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2420,7 +2303,7 @@ def test_create_data_source_field_headers(): @pytest.mark.asyncio async def test_create_data_source_field_headers_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2511,7 +2394,7 @@ def test_create_data_source_flattened_error(): @pytest.mark.asyncio async def test_create_data_source_flattened_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2554,7 +2437,7 @@ async def test_create_data_source_flattened_async(): @pytest.mark.asyncio async def test_create_data_source_flattened_error_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2615,27 +2498,6 @@ def test_update_data_source(request_type, transport: str = "grpc"): assert response.input == datasources.DataSource.Input.API -def test_update_data_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_data_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.UpdateDataSourceRequest() - - def test_update_data_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2701,34 +2563,6 @@ def test_update_data_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_data_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_data_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - datasources.DataSource( - name="name_value", - data_source_id=1462, - display_name="display_name_value", - input=datasources.DataSource.Input.API, - ) - ) - response = await client.update_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.UpdateDataSourceRequest() - - @pytest.mark.asyncio async def test_update_data_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2737,7 +2571,7 @@ async def test_update_data_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2776,7 +2610,7 @@ async def test_update_data_source_async( transport: str = "grpc_asyncio", request_type=datasources.UpdateDataSourceRequest ): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2852,7 +2686,7 @@ def test_update_data_source_field_headers(): @pytest.mark.asyncio async def test_update_data_source_field_headers_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2943,7 +2777,7 @@ def test_update_data_source_flattened_error(): @pytest.mark.asyncio async def test_update_data_source_flattened_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2986,7 +2820,7 @@ async def test_update_data_source_flattened_async(): @pytest.mark.asyncio async def test_update_data_source_flattened_error_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3038,27 +2872,6 @@ def test_delete_data_source(request_type, transport: str = "grpc"): assert response is None -def test_delete_data_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_data_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.DeleteDataSourceRequest() - - def test_delete_data_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3128,27 +2941,6 @@ def test_delete_data_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_data_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_data_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.DeleteDataSourceRequest() - - @pytest.mark.asyncio async def test_delete_data_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -3157,7 +2949,7 @@ async def test_delete_data_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3196,7 +2988,7 @@ async def test_delete_data_source_async( transport: str = "grpc_asyncio", request_type=datasources.DeleteDataSourceRequest ): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3261,7 +3053,7 @@ def test_delete_data_source_field_headers(): @pytest.mark.asyncio async def test_delete_data_source_field_headers_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3333,7 +3125,7 @@ def test_delete_data_source_flattened_error(): @pytest.mark.asyncio async def test_delete_data_source_flattened_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3362,7 +3154,7 @@ async def test_delete_data_source_flattened_async(): @pytest.mark.asyncio async def test_delete_data_source_flattened_error_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3409,27 +3201,6 @@ def test_fetch_data_source(request_type, transport: str = "grpc"): assert response is None -def test_fetch_data_source_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.fetch_data_source), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.fetch_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.FetchDataSourceRequest() - - def test_fetch_data_source_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3497,27 +3268,6 @@ def test_fetch_data_source_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_fetch_data_source_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.fetch_data_source), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.fetch_data_source() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == datasources.FetchDataSourceRequest() - - @pytest.mark.asyncio async def test_fetch_data_source_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -3526,7 +3276,7 @@ async def test_fetch_data_source_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3565,7 +3315,7 @@ async def test_fetch_data_source_async( transport: str = "grpc_asyncio", request_type=datasources.FetchDataSourceRequest ): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3630,7 +3380,7 @@ def test_fetch_data_source_field_headers(): @pytest.mark.asyncio async def test_fetch_data_source_field_headers_async(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3659,52 +3409,6 @@ async def test_fetch_data_source_field_headers_async(): ) in kw["metadata"] -@pytest.mark.parametrize( - "request_type", - [ - datasources.GetDataSourceRequest, - dict, - ], -) -def test_get_data_source_rest(request_type): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = datasources.DataSource( - name="name_value", - data_source_id=1462, - display_name="display_name_value", - input=datasources.DataSource.Input.API, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = datasources.DataSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_data_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, datasources.DataSource) - assert response.name == "name_value" - assert response.data_source_id == 1462 - assert response.display_name == "display_name_value" - assert response.input == datasources.DataSource.Input.API - - def test_get_data_source_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3824,87 +3528,6 @@ def test_get_data_source_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_data_source_rest_interceptors(null_interceptor): - transport = transports.DataSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DataSourcesServiceRestInterceptor(), - ) - client = DataSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "post_get_data_source" - ) as post, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "pre_get_data_source" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = datasources.GetDataSourceRequest.pb( - datasources.GetDataSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = datasources.DataSource.to_json( - datasources.DataSource() - ) - - request = datasources.GetDataSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = datasources.DataSource() - - client.get_data_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_data_source_rest_bad_request( - transport: str = "rest", request_type=datasources.GetDataSourceRequest -): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_data_source(request) - - def test_get_data_source_rest_flattened(): client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3962,52 +3585,6 @@ def test_get_data_source_rest_flattened_error(transport: str = "rest"): ) -def test_get_data_source_rest_error(): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - datasources.ListDataSourcesRequest, - dict, - ], -) -def test_list_data_sources_rest(request_type): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = datasources.ListDataSourcesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = datasources.ListDataSourcesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_data_sources(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListDataSourcesPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_data_sources_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4144,87 +3721,6 @@ def test_list_data_sources_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_data_sources_rest_interceptors(null_interceptor): - transport = transports.DataSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DataSourcesServiceRestInterceptor(), - ) - client = DataSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "post_list_data_sources" - ) as post, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "pre_list_data_sources" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = datasources.ListDataSourcesRequest.pb( - datasources.ListDataSourcesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = datasources.ListDataSourcesResponse.to_json( - datasources.ListDataSourcesResponse() - ) - - request = datasources.ListDataSourcesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = datasources.ListDataSourcesResponse() - - client.list_data_sources( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_data_sources_rest_bad_request( - transport: str = "rest", request_type=datasources.ListDataSourcesRequest -): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_data_sources(request) - - def test_list_data_sources_rest_flattened(): client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4345,177 +3841,6 @@ def test_list_data_sources_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - datasources.CreateDataSourceRequest, - dict, - ], -) -def test_create_data_source_rest(request_type): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["data_source"] = { - "primary_product_data_source": { - "channel": 1, - "feed_label": "feed_label_value", - "content_language": "content_language_value", - "countries": ["countries_value1", "countries_value2"], - "default_rule": { - "take_from_data_sources": [ - { - "self_": True, - "primary_data_source_name": "primary_data_source_name_value", - "supplemental_data_source_name": "supplemental_data_source_name_value", - } - ] - }, - }, - "supplemental_product_data_source": { - "feed_label": "feed_label_value", - "content_language": "content_language_value", - "referencing_primary_data_sources": {}, - }, - "local_inventory_data_source": { - "feed_label": "feed_label_value", - "content_language": "content_language_value", - }, - "regional_inventory_data_source": { - "feed_label": "feed_label_value", - "content_language": "content_language_value", - }, - "promotion_data_source": { - "target_country": "target_country_value", - "content_language": "content_language_value", - }, - "name": "name_value", - "data_source_id": 1462, - "display_name": "display_name_value", - "input": 1, - "file_input": { - "fetch_settings": { - "enabled": True, - "day_of_month": 1271, - "time_of_day": { - "hours": 561, - "minutes": 773, - "seconds": 751, - "nanos": 543, - }, - "day_of_week": 1, - "time_zone": "time_zone_value", - "frequency": 1, - "fetch_uri": "fetch_uri_value", - "username": "username_value", - "password": "password_value", - }, - "file_name": "file_name_value", - "file_input_type": 1, - }, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = datasources.CreateDataSourceRequest.meta.fields["data_source"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["data_source"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["data_source"][field])): - del request_init["data_source"][field][i][subfield] - else: - del request_init["data_source"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = datasources.DataSource( - name="name_value", - data_source_id=1462, - display_name="display_name_value", - input=datasources.DataSource.Input.API, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = datasources.DataSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_data_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, datasources.DataSource) - assert response.name == "name_value" - assert response.data_source_id == 1462 - assert response.display_name == "display_name_value" - assert response.input == datasources.DataSource.Input.API - - def test_create_data_source_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4648,87 +3973,6 @@ def test_create_data_source_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_data_source_rest_interceptors(null_interceptor): - transport = transports.DataSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DataSourcesServiceRestInterceptor(), - ) - client = DataSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "post_create_data_source" - ) as post, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "pre_create_data_source" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = datasources.CreateDataSourceRequest.pb( - datasources.CreateDataSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = datasources.DataSource.to_json( - datasources.DataSource() - ) - - request = datasources.CreateDataSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = datasources.DataSource() - - client.create_data_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_data_source_rest_bad_request( - transport: str = "rest", request_type=datasources.CreateDataSourceRequest -): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_data_source(request) - - def test_create_data_source_rest_flattened(): client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4796,191 +4040,14 @@ def test_create_data_source_rest_flattened_error(transport: str = "rest"): ) -def test_create_data_source_rest_error(): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - datasources.UpdateDataSourceRequest, - dict, - ], -) -def test_update_data_source_rest(request_type): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"data_source": {"name": "accounts/sample1/dataSources/sample2"}} - request_init["data_source"] = { - "primary_product_data_source": { - "channel": 1, - "feed_label": "feed_label_value", - "content_language": "content_language_value", - "countries": ["countries_value1", "countries_value2"], - "default_rule": { - "take_from_data_sources": [ - { - "self_": True, - "primary_data_source_name": "primary_data_source_name_value", - "supplemental_data_source_name": "supplemental_data_source_name_value", - } - ] - }, - }, - "supplemental_product_data_source": { - "feed_label": "feed_label_value", - "content_language": "content_language_value", - "referencing_primary_data_sources": {}, - }, - "local_inventory_data_source": { - "feed_label": "feed_label_value", - "content_language": "content_language_value", - }, - "regional_inventory_data_source": { - "feed_label": "feed_label_value", - "content_language": "content_language_value", - }, - "promotion_data_source": { - "target_country": "target_country_value", - "content_language": "content_language_value", - }, - "name": "accounts/sample1/dataSources/sample2", - "data_source_id": 1462, - "display_name": "display_name_value", - "input": 1, - "file_input": { - "fetch_settings": { - "enabled": True, - "day_of_month": 1271, - "time_of_day": { - "hours": 561, - "minutes": 773, - "seconds": 751, - "nanos": 543, - }, - "day_of_week": 1, - "time_zone": "time_zone_value", - "frequency": 1, - "fetch_uri": "fetch_uri_value", - "username": "username_value", - "password": "password_value", - }, - "file_name": "file_name_value", - "file_input_type": 1, - }, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = datasources.UpdateDataSourceRequest.meta.fields["data_source"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["data_source"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["data_source"][field])): - del request_init["data_source"][field][i][subfield] - else: - del request_init["data_source"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = datasources.DataSource( - name="name_value", - data_source_id=1462, - display_name="display_name_value", - input=datasources.DataSource.Input.API, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = datasources.DataSource.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_data_source(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, datasources.DataSource) - assert response.name == "name_value" - assert response.data_source_id == 1462 - assert response.display_name == "display_name_value" - assert response.input == datasources.DataSource.Input.API - - -def test_update_data_source_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +def test_update_data_source_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) # Should wrap all calls on client creation assert wrapper_fn.call_count > 0 @@ -5102,87 +4169,6 @@ def test_update_data_source_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_data_source_rest_interceptors(null_interceptor): - transport = transports.DataSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DataSourcesServiceRestInterceptor(), - ) - client = DataSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "post_update_data_source" - ) as post, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "pre_update_data_source" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = datasources.UpdateDataSourceRequest.pb( - datasources.UpdateDataSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = datasources.DataSource.to_json( - datasources.DataSource() - ) - - request = datasources.UpdateDataSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = datasources.DataSource() - - client.update_data_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_data_source_rest_bad_request( - transport: str = "rest", request_type=datasources.UpdateDataSourceRequest -): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"data_source": {"name": "accounts/sample1/dataSources/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_data_source(request) - - def test_update_data_source_rest_flattened(): client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5252,47 +4238,6 @@ def test_update_data_source_rest_flattened_error(transport: str = "rest"): ) -def test_update_data_source_rest_error(): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - datasources.DeleteDataSourceRequest, - dict, - ], -) -def test_delete_data_source_rest(request_type): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_data_source(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_data_source_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5413,79 +4358,6 @@ def test_delete_data_source_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_data_source_rest_interceptors(null_interceptor): - transport = transports.DataSourcesServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.DataSourcesServiceRestInterceptor(), - ) - client = DataSourcesServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "pre_delete_data_source" - ) as pre: - pre.assert_not_called() - pb_message = datasources.DeleteDataSourceRequest.pb( - datasources.DeleteDataSourceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = datasources.DeleteDataSourceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_data_source( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_data_source_rest_bad_request( - transport: str = "rest", request_type=datasources.DeleteDataSourceRequest -): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_data_source(request) - - def test_delete_data_source_rest_flattened(): client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5541,47 +4413,6 @@ def test_delete_data_source_rest_flattened_error(transport: str = "rest"): ) -def test_delete_data_source_rest_error(): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - datasources.FetchDataSourceRequest, - dict, - ], -) -def test_fetch_data_source_rest(request_type): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.fetch_data_source(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_fetch_data_source_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5697,12 +4528,1251 @@ def test_fetch_data_source_rest_unset_required_fields(): credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.fetch_data_source._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.fetch_data_source._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DataSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DataSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataSourcesServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DataSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DataSourcesServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DataSourcesServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DataSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DataSourcesServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DataSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DataSourcesServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.DataSourcesServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.DataSourcesServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DataSourcesServiceGrpcTransport, + transports.DataSourcesServiceGrpcAsyncIOTransport, + transports.DataSourcesServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = DataSourcesServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_data_source_empty_call_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_source), "__call__") as call: + call.return_value = datasources.DataSource() + client.get_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.GetDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_data_sources_empty_call_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_data_sources), "__call__" + ) as call: + call.return_value = datasources.ListDataSourcesResponse() + client.list_data_sources(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.ListDataSourcesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_data_source_empty_call_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_data_source), "__call__" + ) as call: + call.return_value = datasources.DataSource() + client.create_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.CreateDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_data_source_empty_call_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_data_source), "__call__" + ) as call: + call.return_value = datasources.DataSource() + client.update_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.UpdateDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_data_source_empty_call_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_data_source), "__call__" + ) as call: + call.return_value = None + client.delete_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.DeleteDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_fetch_data_source_empty_call_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.fetch_data_source), "__call__" + ) as call: + call.return_value = None + client.fetch_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.FetchDataSourceRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = DataSourcesServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_data_source_empty_call_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + datasources.DataSource( + name="name_value", + data_source_id=1462, + display_name="display_name_value", + input=datasources.DataSource.Input.API, + ) + ) + await client.get_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.GetDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_data_sources_empty_call_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_data_sources), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + datasources.ListDataSourcesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_data_sources(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.ListDataSourcesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_data_source_empty_call_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_data_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + datasources.DataSource( + name="name_value", + data_source_id=1462, + display_name="display_name_value", + input=datasources.DataSource.Input.API, + ) + ) + await client.create_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.CreateDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_data_source_empty_call_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_data_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + datasources.DataSource( + name="name_value", + data_source_id=1462, + display_name="display_name_value", + input=datasources.DataSource.Input.API, + ) + ) + await client.update_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.UpdateDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_data_source_empty_call_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_data_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.DeleteDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_fetch_data_source_empty_call_grpc_asyncio(): + client = DataSourcesServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.fetch_data_source), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.fetch_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.FetchDataSourceRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = DataSourcesServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_data_source_rest_bad_request( + request_type=datasources.GetDataSourceRequest, +): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_data_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + datasources.GetDataSourceRequest, + dict, + ], +) +def test_get_data_source_rest_call_success(request_type): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = datasources.DataSource( + name="name_value", + data_source_id=1462, + display_name="display_name_value", + input=datasources.DataSource.Input.API, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = datasources.DataSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_data_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, datasources.DataSource) + assert response.name == "name_value" + assert response.data_source_id == 1462 + assert response.display_name == "display_name_value" + assert response.input == datasources.DataSource.Input.API + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_data_source_rest_interceptors(null_interceptor): + transport = transports.DataSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSourcesServiceRestInterceptor(), + ) + client = DataSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "post_get_data_source" + ) as post, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "pre_get_data_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = datasources.GetDataSourceRequest.pb( + datasources.GetDataSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = datasources.DataSource.to_json(datasources.DataSource()) + req.return_value.content = return_value + + request = datasources.GetDataSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = datasources.DataSource() + + client.get_data_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_data_sources_rest_bad_request( + request_type=datasources.ListDataSourcesRequest, +): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_data_sources(request) + + +@pytest.mark.parametrize( + "request_type", + [ + datasources.ListDataSourcesRequest, + dict, + ], +) +def test_list_data_sources_rest_call_success(request_type): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = datasources.ListDataSourcesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = datasources.ListDataSourcesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_data_sources(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDataSourcesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_data_sources_rest_interceptors(null_interceptor): + transport = transports.DataSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSourcesServiceRestInterceptor(), + ) + client = DataSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "post_list_data_sources" + ) as post, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "pre_list_data_sources" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = datasources.ListDataSourcesRequest.pb( + datasources.ListDataSourcesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = datasources.ListDataSourcesResponse.to_json( + datasources.ListDataSourcesResponse() + ) + req.return_value.content = return_value + + request = datasources.ListDataSourcesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = datasources.ListDataSourcesResponse() + + client.list_data_sources( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_data_source_rest_bad_request( + request_type=datasources.CreateDataSourceRequest, +): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_data_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + datasources.CreateDataSourceRequest, + dict, + ], +) +def test_create_data_source_rest_call_success(request_type): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["data_source"] = { + "primary_product_data_source": { + "channel": 1, + "feed_label": "feed_label_value", + "content_language": "content_language_value", + "countries": ["countries_value1", "countries_value2"], + "default_rule": { + "take_from_data_sources": [ + { + "self_": True, + "primary_data_source_name": "primary_data_source_name_value", + "supplemental_data_source_name": "supplemental_data_source_name_value", + } + ] + }, + }, + "supplemental_product_data_source": { + "feed_label": "feed_label_value", + "content_language": "content_language_value", + "referencing_primary_data_sources": {}, + }, + "local_inventory_data_source": { + "feed_label": "feed_label_value", + "content_language": "content_language_value", + }, + "regional_inventory_data_source": { + "feed_label": "feed_label_value", + "content_language": "content_language_value", + }, + "promotion_data_source": { + "target_country": "target_country_value", + "content_language": "content_language_value", + }, + "name": "name_value", + "data_source_id": 1462, + "display_name": "display_name_value", + "input": 1, + "file_input": { + "fetch_settings": { + "enabled": True, + "day_of_month": 1271, + "time_of_day": { + "hours": 561, + "minutes": 773, + "seconds": 751, + "nanos": 543, + }, + "day_of_week": 1, + "time_zone": "time_zone_value", + "frequency": 1, + "fetch_uri": "fetch_uri_value", + "username": "username_value", + "password": "password_value", + }, + "file_name": "file_name_value", + "file_input_type": 1, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = datasources.CreateDataSourceRequest.meta.fields["data_source"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["data_source"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["data_source"][field])): + del request_init["data_source"][field][i][subfield] + else: + del request_init["data_source"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = datasources.DataSource( + name="name_value", + data_source_id=1462, + display_name="display_name_value", + input=datasources.DataSource.Input.API, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = datasources.DataSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_data_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, datasources.DataSource) + assert response.name == "name_value" + assert response.data_source_id == 1462 + assert response.display_name == "display_name_value" + assert response.input == datasources.DataSource.Input.API + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_data_source_rest_interceptors(null_interceptor): + transport = transports.DataSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSourcesServiceRestInterceptor(), + ) + client = DataSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "post_create_data_source" + ) as post, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "pre_create_data_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = datasources.CreateDataSourceRequest.pb( + datasources.CreateDataSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = datasources.DataSource.to_json(datasources.DataSource()) + req.return_value.content = return_value + + request = datasources.CreateDataSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = datasources.DataSource() + + client.create_data_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_data_source_rest_bad_request( + request_type=datasources.UpdateDataSourceRequest, +): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"data_source": {"name": "accounts/sample1/dataSources/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_data_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + datasources.UpdateDataSourceRequest, + dict, + ], +) +def test_update_data_source_rest_call_success(request_type): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"data_source": {"name": "accounts/sample1/dataSources/sample2"}} + request_init["data_source"] = { + "primary_product_data_source": { + "channel": 1, + "feed_label": "feed_label_value", + "content_language": "content_language_value", + "countries": ["countries_value1", "countries_value2"], + "default_rule": { + "take_from_data_sources": [ + { + "self_": True, + "primary_data_source_name": "primary_data_source_name_value", + "supplemental_data_source_name": "supplemental_data_source_name_value", + } + ] + }, + }, + "supplemental_product_data_source": { + "feed_label": "feed_label_value", + "content_language": "content_language_value", + "referencing_primary_data_sources": {}, + }, + "local_inventory_data_source": { + "feed_label": "feed_label_value", + "content_language": "content_language_value", + }, + "regional_inventory_data_source": { + "feed_label": "feed_label_value", + "content_language": "content_language_value", + }, + "promotion_data_source": { + "target_country": "target_country_value", + "content_language": "content_language_value", + }, + "name": "accounts/sample1/dataSources/sample2", + "data_source_id": 1462, + "display_name": "display_name_value", + "input": 1, + "file_input": { + "fetch_settings": { + "enabled": True, + "day_of_month": 1271, + "time_of_day": { + "hours": 561, + "minutes": 773, + "seconds": 751, + "nanos": 543, + }, + "day_of_week": 1, + "time_zone": "time_zone_value", + "frequency": 1, + "fetch_uri": "fetch_uri_value", + "username": "username_value", + "password": "password_value", + }, + "file_name": "file_name_value", + "file_input_type": 1, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = datasources.UpdateDataSourceRequest.meta.fields["data_source"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["data_source"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["data_source"][field])): + del request_init["data_source"][field][i][subfield] + else: + del request_init["data_source"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = datasources.DataSource( + name="name_value", + data_source_id=1462, + display_name="display_name_value", + input=datasources.DataSource.Input.API, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = datasources.DataSource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_data_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, datasources.DataSource) + assert response.name == "name_value" + assert response.data_source_id == 1462 + assert response.display_name == "display_name_value" + assert response.input == datasources.DataSource.Input.API + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_data_source_rest_interceptors(null_interceptor): + transport = transports.DataSourcesServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSourcesServiceRestInterceptor(), + ) + client = DataSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "post_update_data_source" + ) as post, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "pre_update_data_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = datasources.UpdateDataSourceRequest.pb( + datasources.UpdateDataSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = datasources.DataSource.to_json(datasources.DataSource()) + req.return_value.content = return_value + + request = datasources.UpdateDataSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = datasources.DataSource() + + client.update_data_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_data_source_rest_bad_request( + request_type=datasources.DeleteDataSourceRequest, +): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_data_source(request) + + +@pytest.mark.parametrize( + "request_type", + [ + datasources.DeleteDataSourceRequest, + dict, + ], +) +def test_delete_data_source_rest_call_success(request_type): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_data_source(request) + + # Establish that the response is the type that we expect. + assert response is None @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_fetch_data_source_rest_interceptors(null_interceptor): +def test_delete_data_source_rest_interceptors(null_interceptor): transport = transports.DataSourcesServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -5710,16 +5780,17 @@ def test_fetch_data_source_rest_interceptors(null_interceptor): else transports.DataSourcesServiceRestInterceptor(), ) client = DataSourcesServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.DataSourcesServiceRestInterceptor, "pre_fetch_data_source" + transports.DataSourcesServiceRestInterceptor, "pre_delete_data_source" ) as pre: pre.assert_not_called() - pb_message = datasources.FetchDataSourceRequest.pb( - datasources.FetchDataSourceRequest() + pb_message = datasources.DeleteDataSourceRequest.pb( + datasources.DeleteDataSourceRequest() ) transcode.return_value = { "method": "post", @@ -5728,18 +5799,17 @@ def test_fetch_data_source_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - request = datasources.FetchDataSourceRequest() + request = datasources.DeleteDataSourceRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - client.fetch_data_source( + client.delete_data_source( request, metadata=[ ("key", "val"), @@ -5751,13 +5821,11 @@ def test_fetch_data_source_rest_interceptors(null_interceptor): def test_fetch_data_source_rest_bad_request( - transport: str = "rest", request_type=datasources.FetchDataSourceRequest + request_type=datasources.FetchDataSourceRequest, ): client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1/dataSources/sample2"} request = request_type(**request_init) @@ -5767,123 +5835,232 @@ def test_fetch_data_source_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.fetch_data_source(request) -def test_fetch_data_source_rest_error(): +@pytest.mark.parametrize( + "request_type", + [ + datasources.FetchDataSourceRequest, + dict, + ], +) +def test_fetch_data_source_rest_call_success(request_type): client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2"} + request = request_type(**request_init) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.DataSourcesServiceGrpcTransport( + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.fetch_data_source(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_fetch_data_source_rest_interceptors(null_interceptor): + transport = transports.DataSourcesServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DataSourcesServiceRestInterceptor(), ) - with pytest.raises(ValueError): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + client = DataSourcesServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DataSourcesServiceRestInterceptor, "pre_fetch_data_source" + ) as pre: + pre.assert_not_called() + pb_message = datasources.FetchDataSourceRequest.pb( + datasources.FetchDataSourceRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # It is an error to provide a credentials file and a transport instance. - transport = transports.DataSourcesServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = DataSourcesServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = datasources.FetchDataSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.fetch_data_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - # It is an error to provide an api_key and a transport instance. - transport = transports.DataSourcesServiceGrpcTransport( + pre.assert_called_once() + + +def test_initialize_client_w_rest(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_data_source_empty_call_rest(): + client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = DataSourcesServiceClient( - client_options=options, - transport=transport, - ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = DataSourcesServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_data_source), "__call__") as call: + client.get_data_source(request=None) - # It is an error to provide scopes and a transport instance. - transport = transports.DataSourcesServiceGrpcTransport( + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.GetDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_data_sources_empty_call_rest(): + client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = DataSourcesServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_data_sources), "__call__" + ) as call: + client.list_data_sources(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.ListDataSourcesRequest() -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.DataSourcesServiceGrpcTransport( + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_data_source_empty_call_rest(): + client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = DataSourcesServiceClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_data_source), "__call__" + ) as call: + client.create_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.CreateDataSourceRequest() + + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.DataSourcesServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_data_source_empty_call_rest(): + client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - transport = transports.DataSourcesServiceGrpcAsyncIOTransport( + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_data_source), "__call__" + ) as call: + client.update_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.UpdateDataSourceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_data_source_empty_call_rest(): + client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_data_source), "__call__" + ) as call: + client.delete_data_source(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.DataSourcesServiceGrpcTransport, - transports.DataSourcesServiceGrpcAsyncIOTransport, - transports.DataSourcesServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.DeleteDataSourceRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = DataSourcesServiceClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_fetch_data_source_empty_call_rest(): + client = DataSourcesServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.fetch_data_source), "__call__" + ) as call: + client.fetch_data_source(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = datasources.FetchDataSourceRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -6480,36 +6657,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = DataSourcesServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = DataSourcesServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = DataSourcesServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py index 7c1b989a8758..b925a4d5adde 100644 --- a/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py +++ b/packages/google-shopping-merchant-datasources/tests/unit/gapic/merchant_datasources_v1beta/test_file_uploads_service.py @@ -22,20 +22,12 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format -from google.protobuf import timestamp_pb2 # type: ignore import grpc from grpc.experimental import aio from proto.marshal.rules import wrappers @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import timestamp_pb2 # type: ignore + from google.shopping.merchant_datasources_v1beta.services.file_uploads_service import ( FileUploadsServiceAsyncClient, FileUploadsServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_datasources_v1beta.types import fileuploads +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1205,25 +1228,6 @@ def test_get_file_upload(request_type, transport: str = "grpc"): assert response.items_updated == 1384 -def test_get_file_upload_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = FileUploadsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_file_upload), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_file_upload() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == fileuploads.GetFileUploadRequest() - - def test_get_file_upload_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1287,34 +1291,6 @@ def test_get_file_upload_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_file_upload_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_file_upload), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - fileuploads.FileUpload( - name="name_value", - data_source_id=1462, - processing_state=fileuploads.FileUpload.ProcessingState.FAILED, - items_total=1189, - items_created=1369, - items_updated=1384, - ) - ) - response = await client.get_file_upload() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == fileuploads.GetFileUploadRequest() - - @pytest.mark.asyncio async def test_get_file_upload_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1323,7 +1299,7 @@ async def test_get_file_upload_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1362,7 +1338,7 @@ async def test_get_file_upload_async( transport: str = "grpc_asyncio", request_type=fileuploads.GetFileUploadRequest ): client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1438,7 +1414,7 @@ def test_get_file_upload_field_headers(): @pytest.mark.asyncio async def test_get_file_upload_field_headers_async(): client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1508,7 +1484,7 @@ def test_get_file_upload_flattened_error(): @pytest.mark.asyncio async def test_get_file_upload_flattened_async(): client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1537,7 +1513,7 @@ async def test_get_file_upload_flattened_async(): @pytest.mark.asyncio async def test_get_file_upload_flattened_error_async(): client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1549,56 +1525,6 @@ async def test_get_file_upload_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - fileuploads.GetFileUploadRequest, - dict, - ], -) -def test_get_file_upload_rest(request_type): - client = FileUploadsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2/fileUploads/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = fileuploads.FileUpload( - name="name_value", - data_source_id=1462, - processing_state=fileuploads.FileUpload.ProcessingState.FAILED, - items_total=1189, - items_created=1369, - items_updated=1384, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = fileuploads.FileUpload.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_file_upload(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, fileuploads.FileUpload) - assert response.name == "name_value" - assert response.data_source_id == 1462 - assert response.processing_state == fileuploads.FileUpload.ProcessingState.FAILED - assert response.items_total == 1189 - assert response.items_created == 1369 - assert response.items_updated == 1384 - - def test_get_file_upload_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1718,87 +1644,6 @@ def test_get_file_upload_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_file_upload_rest_interceptors(null_interceptor): - transport = transports.FileUploadsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.FileUploadsServiceRestInterceptor(), - ) - client = FileUploadsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.FileUploadsServiceRestInterceptor, "post_get_file_upload" - ) as post, mock.patch.object( - transports.FileUploadsServiceRestInterceptor, "pre_get_file_upload" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = fileuploads.GetFileUploadRequest.pb( - fileuploads.GetFileUploadRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = fileuploads.FileUpload.to_json( - fileuploads.FileUpload() - ) - - request = fileuploads.GetFileUploadRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = fileuploads.FileUpload() - - client.get_file_upload( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_file_upload_rest_bad_request( - transport: str = "rest", request_type=fileuploads.GetFileUploadRequest -): - client = FileUploadsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/dataSources/sample2/fileUploads/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_file_upload(request) - - def test_get_file_upload_rest_flattened(): client = FileUploadsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -1858,12 +1703,6 @@ def test_get_file_upload_rest_flattened_error(transport: str = "rest"): ) -def test_get_file_upload_rest_error(): - client = FileUploadsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.FileUploadsServiceGrpcTransport( @@ -1956,18 +1795,248 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = FileUploadsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_file_upload_empty_call_grpc(): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_file_upload), "__call__") as call: + call.return_value = fileuploads.FileUpload() + client.get_file_upload(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = fileuploads.GetFileUploadRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = FileUploadsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = FileUploadsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_file_upload_empty_call_grpc_asyncio(): + client = FileUploadsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_file_upload), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + fileuploads.FileUpload( + name="name_value", + data_source_id=1462, + processing_state=fileuploads.FileUpload.ProcessingState.FAILED, + items_total=1189, + items_created=1369, + items_updated=1384, + ) + ) + await client.get_file_upload(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = fileuploads.GetFileUploadRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = FileUploadsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_file_upload_rest_bad_request( + request_type=fileuploads.GetFileUploadRequest, +): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2/fileUploads/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_file_upload(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + fileuploads.GetFileUploadRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = FileUploadsServiceClient.get_transport_class(transport_name)( +def test_get_file_upload_rest_call_success(request_type): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/dataSources/sample2/fileUploads/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = fileuploads.FileUpload( + name="name_value", + data_source_id=1462, + processing_state=fileuploads.FileUpload.ProcessingState.FAILED, + items_total=1189, + items_created=1369, + items_updated=1384, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = fileuploads.FileUpload.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_file_upload(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, fileuploads.FileUpload) + assert response.name == "name_value" + assert response.data_source_id == 1462 + assert response.processing_state == fileuploads.FileUpload.ProcessingState.FAILED + assert response.items_total == 1189 + assert response.items_created == 1369 + assert response.items_updated == 1384 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_file_upload_rest_interceptors(null_interceptor): + transport = transports.FileUploadsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FileUploadsServiceRestInterceptor(), ) - assert transport.kind == transport_name + client = FileUploadsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.FileUploadsServiceRestInterceptor, "post_get_file_upload" + ) as post, mock.patch.object( + transports.FileUploadsServiceRestInterceptor, "pre_get_file_upload" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = fileuploads.GetFileUploadRequest.pb( + fileuploads.GetFileUploadRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = fileuploads.FileUpload.to_json(fileuploads.FileUpload()) + req.return_value.content = return_value + + request = fileuploads.GetFileUploadRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = fileuploads.FileUpload() + + client.get_file_upload( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_file_upload_empty_call_rest(): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_file_upload), "__call__") as call: + client.get_file_upload(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = fileuploads.GetFileUploadRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2547,36 +2616,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = FileUploadsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = FileUploadsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = FileUploadsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/README.rst b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/README.rst new file mode 100644 index 000000000000..816e98eb5847 --- /dev/null +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`LocalInventoryServiceTransport` is the ABC for all transports. +- public child `LocalInventoryServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `LocalInventoryServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseLocalInventoryServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `LocalInventoryServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py index 0558547bfd51..8a71b2ecadb1 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -347,25 +351,34 @@ def delete_local_inventory( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.list_local_inventories: gapic_v1.method_async.wrap_method( + self.list_local_inventories: self._wrap_method( self.list_local_inventories, default_timeout=None, client_info=client_info, ), - self.insert_local_inventory: gapic_v1.method_async.wrap_method( + self.insert_local_inventory: self._wrap_method( self.insert_local_inventory, default_timeout=None, client_info=client_info, ), - self.delete_local_inventory: gapic_v1.method_async.wrap_method( + self.delete_local_inventory: self._wrap_method( self.delete_local_inventory, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("LocalInventoryServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py index 78f8207ceef3..7a17a0203e3c 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_inventories_v1beta.types import localinventory + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseLocalInventoryServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_inventories_v1beta.types import localinventory - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import LocalInventoryServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -157,8 +153,8 @@ class LocalInventoryServiceRestStub: _interceptor: LocalInventoryServiceRestInterceptor -class LocalInventoryServiceRestTransport(LocalInventoryServiceTransport): - """REST backend transport for LocalInventoryService. +class LocalInventoryServiceRestTransport(_BaseLocalInventoryServiceRestTransport): + """REST backend synchronous transport for LocalInventoryService. Service to manage local inventory for products @@ -167,7 +163,6 @@ class LocalInventoryServiceRestTransport(LocalInventoryServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -221,21 +216,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -246,19 +232,34 @@ def __init__( self._interceptor = interceptor or LocalInventoryServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _DeleteLocalInventory(LocalInventoryServiceRestStub): + class _DeleteLocalInventory( + _BaseLocalInventoryServiceRestTransport._BaseDeleteLocalInventory, + LocalInventoryServiceRestStub, + ): def __hash__(self): - return hash("DeleteLocalInventory") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LocalInventoryServiceRestTransport.DeleteLocalInventory") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -280,40 +281,31 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/inventories/v1beta/{name=accounts/*/products/*/localInventories/*}", - }, - ] + http_options = ( + _BaseLocalInventoryServiceRestTransport._BaseDeleteLocalInventory._get_http_options() + ) request, metadata = self._interceptor.pre_delete_local_inventory( request, metadata ) - pb_request = localinventory.DeleteLocalInventoryRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseLocalInventoryServiceRestTransport._BaseDeleteLocalInventory._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLocalInventoryServiceRestTransport._BaseDeleteLocalInventory._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + LocalInventoryServiceRestTransport._DeleteLocalInventory._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -321,19 +313,35 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _InsertLocalInventory(LocalInventoryServiceRestStub): + class _InsertLocalInventory( + _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory, + LocalInventoryServiceRestStub, + ): def __hash__(self): - return hash("InsertLocalInventory") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LocalInventoryServiceRestTransport.InsertLocalInventory") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -366,47 +374,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/localInventories:insert", - "body": "local_inventory", - }, - ] + http_options = ( + _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory._get_http_options() + ) request, metadata = self._interceptor.pre_insert_local_inventory( request, metadata ) - pb_request = localinventory.InsertLocalInventoryRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + LocalInventoryServiceRestTransport._InsertLocalInventory._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -422,19 +419,34 @@ def __call__( resp = self._interceptor.post_insert_local_inventory(resp) return resp - class _ListLocalInventories(LocalInventoryServiceRestStub): + class _ListLocalInventories( + _BaseLocalInventoryServiceRestTransport._BaseListLocalInventories, + LocalInventoryServiceRestStub, + ): def __hash__(self): - return hash("ListLocalInventories") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LocalInventoryServiceRestTransport.ListLocalInventories") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -462,40 +474,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/localInventories", - }, - ] + http_options = ( + _BaseLocalInventoryServiceRestTransport._BaseListLocalInventories._get_http_options() + ) request, metadata = self._interceptor.pre_list_local_inventories( request, metadata ) - pb_request = localinventory.ListLocalInventoriesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseLocalInventoryServiceRestTransport._BaseListLocalInventories._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLocalInventoryServiceRestTransport._BaseListLocalInventories._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + LocalInventoryServiceRestTransport._ListLocalInventories._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest_base.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest_base.py new file mode 100644 index 000000000000..d7b2f8b9b775 --- /dev/null +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/local_inventory_service/transports/rest_base.py @@ -0,0 +1,243 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_inventories_v1beta.types import localinventory + +from .base import DEFAULT_CLIENT_INFO, LocalInventoryServiceTransport + + +class _BaseLocalInventoryServiceRestTransport(LocalInventoryServiceTransport): + """Base REST backend transport for LocalInventoryService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseDeleteLocalInventory: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/inventories/v1beta/{name=accounts/*/products/*/localInventories/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = localinventory.DeleteLocalInventoryRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLocalInventoryServiceRestTransport._BaseDeleteLocalInventory._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertLocalInventory: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/localInventories:insert", + "body": "local_inventory", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = localinventory.InsertLocalInventoryRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLocalInventoryServiceRestTransport._BaseInsertLocalInventory._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListLocalInventories: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/localInventories", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = localinventory.ListLocalInventoriesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLocalInventoryServiceRestTransport._BaseListLocalInventories._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseLocalInventoryServiceRestTransport",) diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/README.rst b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/README.rst new file mode 100644 index 000000000000..0b66f48dbd0c --- /dev/null +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`RegionalInventoryServiceTransport` is the ABC for all transports. +- public child `RegionalInventoryServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `RegionalInventoryServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseRegionalInventoryServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `RegionalInventoryServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py index fa44b3b8d366..ee343ccd46f6 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -348,25 +352,34 @@ def delete_regional_inventory( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.list_regional_inventories: gapic_v1.method_async.wrap_method( + self.list_regional_inventories: self._wrap_method( self.list_regional_inventories, default_timeout=None, client_info=client_info, ), - self.insert_regional_inventory: gapic_v1.method_async.wrap_method( + self.insert_regional_inventory: self._wrap_method( self.insert_regional_inventory, default_timeout=None, client_info=client_info, ), - self.delete_regional_inventory: gapic_v1.method_async.wrap_method( + self.delete_regional_inventory: self._wrap_method( self.delete_regional_inventory, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("RegionalInventoryServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py index 3ecbd6993bae..e1cbde0e8436 100644 --- a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_inventories_v1beta.types import regionalinventory + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseRegionalInventoryServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_inventories_v1beta.types import regionalinventory - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import RegionalInventoryServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -163,8 +159,8 @@ class RegionalInventoryServiceRestStub: _interceptor: RegionalInventoryServiceRestInterceptor -class RegionalInventoryServiceRestTransport(RegionalInventoryServiceTransport): - """REST backend transport for RegionalInventoryService. +class RegionalInventoryServiceRestTransport(_BaseRegionalInventoryServiceRestTransport): + """REST backend synchronous transport for RegionalInventoryService. Service to manage regional inventory for products. There is also separate ``regions`` resource and API to manage regions definitions. @@ -174,7 +170,6 @@ class RegionalInventoryServiceRestTransport(RegionalInventoryServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -228,21 +223,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -253,19 +239,34 @@ def __init__( self._interceptor = interceptor or RegionalInventoryServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _DeleteRegionalInventory(RegionalInventoryServiceRestStub): + class _DeleteRegionalInventory( + _BaseRegionalInventoryServiceRestTransport._BaseDeleteRegionalInventory, + RegionalInventoryServiceRestStub, + ): def __hash__(self): - return hash("DeleteRegionalInventory") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionalInventoryServiceRestTransport.DeleteRegionalInventory") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -288,40 +289,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/inventories/v1beta/{name=accounts/*/products/*/regionalInventories/*}", - }, - ] + http_options = ( + _BaseRegionalInventoryServiceRestTransport._BaseDeleteRegionalInventory._get_http_options() + ) request, metadata = self._interceptor.pre_delete_regional_inventory( request, metadata ) - pb_request = regionalinventory.DeleteRegionalInventoryRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseRegionalInventoryServiceRestTransport._BaseDeleteRegionalInventory._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionalInventoryServiceRestTransport._BaseDeleteRegionalInventory._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = RegionalInventoryServiceRestTransport._DeleteRegionalInventory._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -329,19 +319,35 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _InsertRegionalInventory(RegionalInventoryServiceRestStub): + class _InsertRegionalInventory( + _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory, + RegionalInventoryServiceRestStub, + ): def __hash__(self): - return hash("InsertRegionalInventory") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionalInventoryServiceRestTransport.InsertRegionalInventory") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -375,47 +381,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/regionalInventories:insert", - "body": "regional_inventory", - }, - ] + http_options = ( + _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory._get_http_options() + ) request, metadata = self._interceptor.pre_insert_regional_inventory( request, metadata ) - pb_request = regionalinventory.InsertRegionalInventoryRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = RegionalInventoryServiceRestTransport._InsertRegionalInventory._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -431,19 +424,34 @@ def __call__( resp = self._interceptor.post_insert_regional_inventory(resp) return resp - class _ListRegionalInventories(RegionalInventoryServiceRestStub): + class _ListRegionalInventories( + _BaseRegionalInventoryServiceRestTransport._BaseListRegionalInventories, + RegionalInventoryServiceRestStub, + ): def __hash__(self): - return hash("ListRegionalInventories") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("RegionalInventoryServiceRestTransport.ListRegionalInventories") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -472,40 +480,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/regionalInventories", - }, - ] + http_options = ( + _BaseRegionalInventoryServiceRestTransport._BaseListRegionalInventories._get_http_options() + ) request, metadata = self._interceptor.pre_list_regional_inventories( request, metadata ) - pb_request = regionalinventory.ListRegionalInventoriesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseRegionalInventoryServiceRestTransport._BaseListRegionalInventories._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseRegionalInventoryServiceRestTransport._BaseListRegionalInventories._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = RegionalInventoryServiceRestTransport._ListRegionalInventories._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest_base.py b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest_base.py new file mode 100644 index 000000000000..210144241e19 --- /dev/null +++ b/packages/google-shopping-merchant-inventories/google/shopping/merchant_inventories_v1beta/services/regional_inventory_service/transports/rest_base.py @@ -0,0 +1,243 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_inventories_v1beta.types import regionalinventory + +from .base import DEFAULT_CLIENT_INFO, RegionalInventoryServiceTransport + + +class _BaseRegionalInventoryServiceRestTransport(RegionalInventoryServiceTransport): + """Base REST backend transport for RegionalInventoryService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseDeleteRegionalInventory: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/inventories/v1beta/{name=accounts/*/products/*/regionalInventories/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regionalinventory.DeleteRegionalInventoryRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionalInventoryServiceRestTransport._BaseDeleteRegionalInventory._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertRegionalInventory: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/regionalInventories:insert", + "body": "regional_inventory", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regionalinventory.InsertRegionalInventoryRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionalInventoryServiceRestTransport._BaseInsertRegionalInventory._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListRegionalInventories: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/inventories/v1beta/{parent=accounts/*/products/*}/regionalInventories", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = regionalinventory.ListRegionalInventoriesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseRegionalInventoryServiceRestTransport._BaseListRegionalInventories._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseRegionalInventoryServiceRestTransport",) diff --git a/packages/google-shopping-merchant-inventories/setup.py b/packages/google-shopping-merchant-inventories/setup.py index c01e43dcf9c4..417f532a2718 100644 --- a/packages/google-shopping-merchant-inventories/setup.py +++ b/packages/google-shopping-merchant-inventories/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-inventories" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py index d16aebb40700..8c8a79c438a8 100644 --- a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py +++ b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_local_inventory_service.py @@ -22,29 +22,38 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types from google.type import interval_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_inventories_v1beta.services.local_inventory_service import ( LocalInventoryServiceAsyncClient, @@ -55,10 +64,24 @@ from google.shopping.merchant_inventories_v1beta.types import localinventory +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1228,27 +1251,6 @@ def test_list_local_inventories(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_local_inventories_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_local_inventories), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_local_inventories() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == localinventory.ListLocalInventoriesRequest() - - def test_list_local_inventories_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1321,31 +1323,6 @@ def test_list_local_inventories_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_local_inventories_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_local_inventories), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - localinventory.ListLocalInventoriesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_local_inventories() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == localinventory.ListLocalInventoriesRequest() - - @pytest.mark.asyncio async def test_list_local_inventories_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1354,7 +1331,7 @@ async def test_list_local_inventories_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1394,7 +1371,7 @@ async def test_list_local_inventories_async( request_type=localinventory.ListLocalInventoriesRequest, ): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1464,7 +1441,7 @@ def test_list_local_inventories_field_headers(): @pytest.mark.asyncio async def test_list_local_inventories_field_headers_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1538,7 +1515,7 @@ def test_list_local_inventories_flattened_error(): @pytest.mark.asyncio async def test_list_local_inventories_flattened_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1569,7 +1546,7 @@ async def test_list_local_inventories_flattened_async(): @pytest.mark.asyncio async def test_list_local_inventories_flattened_error_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1683,7 +1660,7 @@ def test_list_local_inventories_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_local_inventories_async_pager(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1735,7 +1712,7 @@ async def test_list_local_inventories_async_pager(): @pytest.mark.asyncio async def test_list_local_inventories_async_pages(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1835,27 +1812,6 @@ def test_insert_local_inventory(request_type, transport: str = "grpc"): assert response.instore_product_location == "instore_product_location_value" -def test_insert_local_inventory_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_local_inventory), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_local_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == localinventory.InsertLocalInventoryRequest() - - def test_insert_local_inventory_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1926,38 +1882,6 @@ def test_insert_local_inventory_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_local_inventory_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_local_inventory), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - localinventory.LocalInventory( - name="name_value", - account=749, - store_code="store_code_value", - availability="availability_value", - quantity=895, - pickup_method="pickup_method_value", - pickup_sla="pickup_sla_value", - instore_product_location="instore_product_location_value", - ) - ) - response = await client.insert_local_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == localinventory.InsertLocalInventoryRequest() - - @pytest.mark.asyncio async def test_insert_local_inventory_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1966,7 +1890,7 @@ async def test_insert_local_inventory_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2006,7 +1930,7 @@ async def test_insert_local_inventory_async( request_type=localinventory.InsertLocalInventoryRequest, ): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2090,7 +2014,7 @@ def test_insert_local_inventory_field_headers(): @pytest.mark.asyncio async def test_insert_local_inventory_field_headers_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2156,27 +2080,6 @@ def test_delete_local_inventory(request_type, transport: str = "grpc"): assert response is None -def test_delete_local_inventory_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_local_inventory), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_local_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == localinventory.DeleteLocalInventoryRequest() - - def test_delete_local_inventory_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2247,27 +2150,6 @@ def test_delete_local_inventory_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_local_inventory_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_local_inventory), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_local_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == localinventory.DeleteLocalInventoryRequest() - - @pytest.mark.asyncio async def test_delete_local_inventory_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2276,7 +2158,7 @@ async def test_delete_local_inventory_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2316,7 +2198,7 @@ async def test_delete_local_inventory_async( request_type=localinventory.DeleteLocalInventoryRequest, ): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2381,7 +2263,7 @@ def test_delete_local_inventory_field_headers(): @pytest.mark.asyncio async def test_delete_local_inventory_field_headers_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2453,7 +2335,7 @@ def test_delete_local_inventory_flattened_error(): @pytest.mark.asyncio async def test_delete_local_inventory_flattened_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2482,7 +2364,7 @@ async def test_delete_local_inventory_flattened_async(): @pytest.mark.asyncio async def test_delete_local_inventory_flattened_error_async(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2494,46 +2376,6 @@ async def test_delete_local_inventory_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - localinventory.ListLocalInventoriesRequest, - dict, - ], -) -def test_list_local_inventories_rest(request_type): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = localinventory.ListLocalInventoriesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = localinventory.ListLocalInventoriesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_local_inventories(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListLocalInventoriesPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_local_inventories_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2673,115 +2515,34 @@ def test_list_local_inventories_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_local_inventories_rest_interceptors(null_interceptor): - transport = transports.LocalInventoryServiceRestTransport( +def test_list_local_inventories_rest_flattened(): + client = LocalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LocalInventoryServiceRestInterceptor(), + transport="rest", ) - client = LocalInventoryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LocalInventoryServiceRestInterceptor, "post_list_local_inventories" - ) as post, mock.patch.object( - transports.LocalInventoryServiceRestInterceptor, "pre_list_local_inventories" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = localinventory.ListLocalInventoriesRequest.pb( - localinventory.ListLocalInventoriesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = localinventory.ListLocalInventoriesResponse.to_json( - localinventory.ListLocalInventoriesResponse() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = localinventory.ListLocalInventoriesResponse() - request = localinventory.ListLocalInventoriesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = localinventory.ListLocalInventoriesResponse() + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1/products/sample2"} - client.list_local_inventories( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", ) + mock_args.update(sample_request) - pre.assert_called_once() - post.assert_called_once() - - -def test_list_local_inventories_rest_bad_request( - transport: str = "rest", request_type=localinventory.ListLocalInventoriesRequest -): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_local_inventories(request) - - -def test_list_local_inventories_rest_flattened(): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = localinventory.ListLocalInventoriesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1/products/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = localinventory.ListLocalInventoriesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = localinventory.ListLocalInventoriesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value client.list_local_inventories(**mock_args) @@ -2874,148 +2635,6 @@ def test_list_local_inventories_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - localinventory.InsertLocalInventoryRequest, - dict, - ], -) -def test_insert_local_inventory_rest(request_type): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request_init["local_inventory"] = { - "name": "name_value", - "account": 749, - "store_code": "store_code_value", - "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, - "sale_price": {}, - "sale_price_effective_date": { - "start_time": {"seconds": 751, "nanos": 543}, - "end_time": {}, - }, - "availability": "availability_value", - "quantity": 895, - "pickup_method": "pickup_method_value", - "pickup_sla": "pickup_sla_value", - "instore_product_location": "instore_product_location_value", - "custom_attributes": [ - {"name": "name_value", "value": "value_value", "group_values": {}} - ], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = localinventory.InsertLocalInventoryRequest.meta.fields[ - "local_inventory" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["local_inventory"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["local_inventory"][field])): - del request_init["local_inventory"][field][i][subfield] - else: - del request_init["local_inventory"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = localinventory.LocalInventory( - name="name_value", - account=749, - store_code="store_code_value", - availability="availability_value", - quantity=895, - pickup_method="pickup_method_value", - pickup_sla="pickup_sla_value", - instore_product_location="instore_product_location_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = localinventory.LocalInventory.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_local_inventory(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, localinventory.LocalInventory) - assert response.name == "name_value" - assert response.account == 749 - assert response.store_code == "store_code_value" - assert response.availability == "availability_value" - assert response.quantity == 895 - assert response.pickup_method == "pickup_method_value" - assert response.pickup_sla == "pickup_sla_value" - assert response.instore_product_location == "instore_product_location_value" - - def test_insert_local_inventory_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3149,147 +2768,23 @@ def test_insert_local_inventory_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_local_inventory_rest_interceptors(null_interceptor): - transport = transports.LocalInventoryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LocalInventoryServiceRestInterceptor(), - ) - client = LocalInventoryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LocalInventoryServiceRestInterceptor, "post_insert_local_inventory" - ) as post, mock.patch.object( - transports.LocalInventoryServiceRestInterceptor, "pre_insert_local_inventory" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = localinventory.InsertLocalInventoryRequest.pb( - localinventory.InsertLocalInventoryRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = localinventory.LocalInventory.to_json( - localinventory.LocalInventory() +def test_delete_local_inventory_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - request = localinventory.InsertLocalInventoryRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = localinventory.LocalInventory() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - client.insert_local_inventory( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_insert_local_inventory_rest_bad_request( - transport: str = "rest", request_type=localinventory.InsertLocalInventoryRequest -): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_local_inventory(request) - - -def test_insert_local_inventory_rest_error(): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - localinventory.DeleteLocalInventoryRequest, - dict, - ], -) -def test_delete_local_inventory_rest(request_type): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "accounts/sample1/products/sample2/localInventories/sample3" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_local_inventory(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_local_inventory_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.delete_local_inventory - in client._transport._wrapped_methods + # Ensure method has been cached + assert ( + client._transport.delete_local_inventory + in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -3394,8 +2889,637 @@ def test_delete_local_inventory_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) +def test_delete_local_inventory_rest_flattened(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "accounts/sample1/products/sample2/localInventories/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_local_inventory(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/inventories/v1beta/{name=accounts/*/products/*/localInventories/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_local_inventory_rest_flattened_error(transport: str = "rest"): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_local_inventory( + localinventory.DeleteLocalInventoryRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.LocalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.LocalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LocalInventoryServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.LocalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = LocalInventoryServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = LocalInventoryServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.LocalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LocalInventoryServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.LocalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = LocalInventoryServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.LocalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.LocalInventoryServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.LocalInventoryServiceGrpcTransport, + transports.LocalInventoryServiceGrpcAsyncIOTransport, + transports.LocalInventoryServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = LocalInventoryServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_local_inventories_empty_call_grpc(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_local_inventories), "__call__" + ) as call: + call.return_value = localinventory.ListLocalInventoriesResponse() + client.list_local_inventories(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.ListLocalInventoriesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_local_inventory_empty_call_grpc(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_local_inventory), "__call__" + ) as call: + call.return_value = localinventory.LocalInventory() + client.insert_local_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.InsertLocalInventoryRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_local_inventory_empty_call_grpc(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_local_inventory), "__call__" + ) as call: + call.return_value = None + client.delete_local_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.DeleteLocalInventoryRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = LocalInventoryServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = LocalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_local_inventories_empty_call_grpc_asyncio(): + client = LocalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_local_inventories), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + localinventory.ListLocalInventoriesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_local_inventories(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.ListLocalInventoriesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_local_inventory_empty_call_grpc_asyncio(): + client = LocalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_local_inventory), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + localinventory.LocalInventory( + name="name_value", + account=749, + store_code="store_code_value", + availability="availability_value", + quantity=895, + pickup_method="pickup_method_value", + pickup_sla="pickup_sla_value", + instore_product_location="instore_product_location_value", + ) + ) + await client.insert_local_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.InsertLocalInventoryRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_local_inventory_empty_call_grpc_asyncio(): + client = LocalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_local_inventory), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_local_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.DeleteLocalInventoryRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = LocalInventoryServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_local_inventories_rest_bad_request( + request_type=localinventory.ListLocalInventoriesRequest, +): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_local_inventories(request) + + +@pytest.mark.parametrize( + "request_type", + [ + localinventory.ListLocalInventoriesRequest, + dict, + ], +) +def test_list_local_inventories_rest_call_success(request_type): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = localinventory.ListLocalInventoriesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = localinventory.ListLocalInventoriesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_local_inventories(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListLocalInventoriesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_local_inventories_rest_interceptors(null_interceptor): + transport = transports.LocalInventoryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.LocalInventoryServiceRestInterceptor(), + ) + client = LocalInventoryServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LocalInventoryServiceRestInterceptor, "post_list_local_inventories" + ) as post, mock.patch.object( + transports.LocalInventoryServiceRestInterceptor, "pre_list_local_inventories" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = localinventory.ListLocalInventoriesRequest.pb( + localinventory.ListLocalInventoriesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = localinventory.ListLocalInventoriesResponse.to_json( + localinventory.ListLocalInventoriesResponse() + ) + req.return_value.content = return_value + + request = localinventory.ListLocalInventoriesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = localinventory.ListLocalInventoriesResponse() + + client.list_local_inventories( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_insert_local_inventory_rest_bad_request( + request_type=localinventory.InsertLocalInventoryRequest, +): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_local_inventory(request) + + +@pytest.mark.parametrize( + "request_type", + [ + localinventory.InsertLocalInventoryRequest, + dict, + ], +) +def test_insert_local_inventory_rest_call_success(request_type): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request_init["local_inventory"] = { + "name": "name_value", + "account": 749, + "store_code": "store_code_value", + "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, + "sale_price": {}, + "sale_price_effective_date": { + "start_time": {"seconds": 751, "nanos": 543}, + "end_time": {}, + }, + "availability": "availability_value", + "quantity": 895, + "pickup_method": "pickup_method_value", + "pickup_sla": "pickup_sla_value", + "instore_product_location": "instore_product_location_value", + "custom_attributes": [ + {"name": "name_value", "value": "value_value", "group_values": {}} + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = localinventory.InsertLocalInventoryRequest.meta.fields[ + "local_inventory" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["local_inventory"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["local_inventory"][field])): + del request_init["local_inventory"][field][i][subfield] + else: + del request_init["local_inventory"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = localinventory.LocalInventory( + name="name_value", + account=749, + store_code="store_code_value", + availability="availability_value", + quantity=895, + pickup_method="pickup_method_value", + pickup_sla="pickup_sla_value", + instore_product_location="instore_product_location_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = localinventory.LocalInventory.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_local_inventory(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, localinventory.LocalInventory) + assert response.name == "name_value" + assert response.account == 749 + assert response.store_code == "store_code_value" + assert response.availability == "availability_value" + assert response.quantity == 895 + assert response.pickup_method == "pickup_method_value" + assert response.pickup_sla == "pickup_sla_value" + assert response.instore_product_location == "instore_product_location_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_local_inventory_rest_interceptors(null_interceptor): +def test_insert_local_inventory_rest_interceptors(null_interceptor): transport = transports.LocalInventoryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -3403,16 +3527,20 @@ def test_delete_local_inventory_rest_interceptors(null_interceptor): else transports.LocalInventoryServiceRestInterceptor(), ) client = LocalInventoryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.LocalInventoryServiceRestInterceptor, "pre_delete_local_inventory" + transports.LocalInventoryServiceRestInterceptor, "post_insert_local_inventory" + ) as post, mock.patch.object( + transports.LocalInventoryServiceRestInterceptor, "pre_insert_local_inventory" ) as pre: pre.assert_not_called() - pb_message = localinventory.DeleteLocalInventoryRequest.pb( - localinventory.DeleteLocalInventoryRequest() + post.assert_not_called() + pb_message = localinventory.InsertLocalInventoryRequest.pb( + localinventory.InsertLocalInventoryRequest() ) transcode.return_value = { "method": "post", @@ -3421,18 +3549,22 @@ def test_delete_local_inventory_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = localinventory.LocalInventory.to_json( + localinventory.LocalInventory() + ) + req.return_value.content = return_value - request = localinventory.DeleteLocalInventoryRequest() + request = localinventory.InsertLocalInventoryRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = localinventory.LocalInventory() - client.delete_local_inventory( + client.insert_local_inventory( request, metadata=[ ("key", "val"), @@ -3441,16 +3573,15 @@ def test_delete_local_inventory_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_delete_local_inventory_rest_bad_request( - transport: str = "rest", request_type=localinventory.DeleteLocalInventoryRequest + request_type=localinventory.DeleteLocalInventoryRequest, ): client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = { "name": "accounts/sample1/products/sample2/localInventories/sample3" @@ -3462,180 +3593,170 @@ def test_delete_local_inventory_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.delete_local_inventory(request) -def test_delete_local_inventory_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + localinventory.DeleteLocalInventoryRequest, + dict, + ], +) +def test_delete_local_inventory_rest_call_success(request_type): client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = { + "name": "accounts/sample1/products/sample2/localInventories/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "accounts/sample1/products/sample2/localInventories/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_local_inventory(request) - client.delete_local_inventory(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/inventories/v1beta/{name=accounts/*/products/*/localInventories/*}" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert response is None -def test_delete_local_inventory_rest_flattened_error(transport: str = "rest"): - client = LocalInventoryServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_local_inventory_rest_interceptors(null_interceptor): + transport = transports.LocalInventoryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.LocalInventoryServiceRestInterceptor(), ) + client = LocalInventoryServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LocalInventoryServiceRestInterceptor, "pre_delete_local_inventory" + ) as pre: + pre.assert_not_called() + pb_message = localinventory.DeleteLocalInventoryRequest.pb( + localinventory.DeleteLocalInventoryRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = localinventory.DeleteLocalInventoryRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.delete_local_inventory( - localinventory.DeleteLocalInventoryRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + -def test_delete_local_inventory_rest_error(): +def test_initialize_client_w_rest(): client = LocalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.LocalInventoryServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_local_inventories_empty_call_rest(): + client = LocalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.LocalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = LocalInventoryServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_local_inventories), "__call__" + ) as call: + client.list_local_inventories(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.LocalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = LocalInventoryServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.ListLocalInventoriesRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = LocalInventoryServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.LocalInventoryServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_local_inventory_empty_call_rest(): + client = LocalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = LocalInventoryServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_local_inventory), "__call__" + ) as call: + client.insert_local_inventory(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.LocalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = LocalInventoryServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.InsertLocalInventoryRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.LocalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.LocalInventoryServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_local_inventory_empty_call_rest(): + client = LocalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.LocalInventoryServiceGrpcTransport, - transports.LocalInventoryServiceGrpcAsyncIOTransport, - transports.LocalInventoryServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_local_inventory), "__call__" + ) as call: + client.delete_local_inventory(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = localinventory.DeleteLocalInventoryRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = LocalInventoryServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4229,36 +4350,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = LocalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = LocalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = LocalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py index 054d04148e18..5b6327cad66a 100644 --- a/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py +++ b/packages/google-shopping-merchant-inventories/tests/unit/gapic/merchant_inventories_v1beta/test_regional_inventory_service.py @@ -22,29 +22,38 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types from google.type import interval_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_inventories_v1beta.services.regional_inventory_service import ( RegionalInventoryServiceAsyncClient, @@ -55,10 +64,24 @@ from google.shopping.merchant_inventories_v1beta.types import regionalinventory +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1236,27 +1259,6 @@ def test_list_regional_inventories(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_regional_inventories_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_regional_inventories), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_regional_inventories() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regionalinventory.ListRegionalInventoriesRequest() - - def test_list_regional_inventories_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1329,31 +1331,6 @@ def test_list_regional_inventories_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_regional_inventories_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_regional_inventories), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - regionalinventory.ListRegionalInventoriesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_regional_inventories() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regionalinventory.ListRegionalInventoriesRequest() - - @pytest.mark.asyncio async def test_list_regional_inventories_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1362,7 +1339,7 @@ async def test_list_regional_inventories_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1402,7 +1379,7 @@ async def test_list_regional_inventories_async( request_type=regionalinventory.ListRegionalInventoriesRequest, ): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1472,7 +1449,7 @@ def test_list_regional_inventories_field_headers(): @pytest.mark.asyncio async def test_list_regional_inventories_field_headers_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1546,7 +1523,7 @@ def test_list_regional_inventories_flattened_error(): @pytest.mark.asyncio async def test_list_regional_inventories_flattened_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1577,7 +1554,7 @@ async def test_list_regional_inventories_flattened_async(): @pytest.mark.asyncio async def test_list_regional_inventories_flattened_error_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1693,7 +1670,7 @@ def test_list_regional_inventories_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_regional_inventories_async_pager(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1747,7 +1724,7 @@ async def test_list_regional_inventories_async_pager(): @pytest.mark.asyncio async def test_list_regional_inventories_async_pages(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1839,27 +1816,6 @@ def test_insert_regional_inventory(request_type, transport: str = "grpc"): assert response.availability == "availability_value" -def test_insert_regional_inventory_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_regional_inventory), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_regional_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regionalinventory.InsertRegionalInventoryRequest() - - def test_insert_regional_inventory_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1930,34 +1886,6 @@ def test_insert_regional_inventory_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_regional_inventory_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_regional_inventory), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - regionalinventory.RegionalInventory( - name="name_value", - account=749, - region="region_value", - availability="availability_value", - ) - ) - response = await client.insert_regional_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regionalinventory.InsertRegionalInventoryRequest() - - @pytest.mark.asyncio async def test_insert_regional_inventory_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1966,7 +1894,7 @@ async def test_insert_regional_inventory_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2006,7 +1934,7 @@ async def test_insert_regional_inventory_async( request_type=regionalinventory.InsertRegionalInventoryRequest, ): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2082,7 +2010,7 @@ def test_insert_regional_inventory_field_headers(): @pytest.mark.asyncio async def test_insert_regional_inventory_field_headers_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2148,27 +2076,6 @@ def test_delete_regional_inventory(request_type, transport: str = "grpc"): assert response is None -def test_delete_regional_inventory_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_regional_inventory), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_regional_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regionalinventory.DeleteRegionalInventoryRequest() - - def test_delete_regional_inventory_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2239,27 +2146,6 @@ def test_delete_regional_inventory_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_regional_inventory_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_regional_inventory), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_regional_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == regionalinventory.DeleteRegionalInventoryRequest() - - @pytest.mark.asyncio async def test_delete_regional_inventory_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2268,7 +2154,7 @@ async def test_delete_regional_inventory_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2308,7 +2194,7 @@ async def test_delete_regional_inventory_async( request_type=regionalinventory.DeleteRegionalInventoryRequest, ): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2373,7 +2259,7 @@ def test_delete_regional_inventory_field_headers(): @pytest.mark.asyncio async def test_delete_regional_inventory_field_headers_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2445,7 +2331,7 @@ def test_delete_regional_inventory_flattened_error(): @pytest.mark.asyncio async def test_delete_regional_inventory_flattened_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2474,7 +2360,7 @@ async def test_delete_regional_inventory_flattened_async(): @pytest.mark.asyncio async def test_delete_regional_inventory_flattened_error_async(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2486,48 +2372,6 @@ async def test_delete_regional_inventory_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - regionalinventory.ListRegionalInventoriesRequest, - dict, - ], -) -def test_list_regional_inventories_rest(request_type): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regionalinventory.ListRegionalInventoriesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regionalinventory.ListRegionalInventoriesResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_regional_inventories(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListRegionalInventoriesPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_regional_inventories_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2669,111 +2513,25 @@ def test_list_regional_inventories_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_regional_inventories_rest_interceptors(null_interceptor): - transport = transports.RegionalInventoryServiceRestTransport( +def test_list_regional_inventories_rest_flattened(): + client = RegionalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RegionalInventoryServiceRestInterceptor(), + transport="rest", ) - client = RegionalInventoryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RegionalInventoryServiceRestInterceptor, - "post_list_regional_inventories", - ) as post, mock.patch.object( - transports.RegionalInventoryServiceRestInterceptor, - "pre_list_regional_inventories", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = regionalinventory.ListRegionalInventoriesRequest.pb( - regionalinventory.ListRegionalInventoriesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - regionalinventory.ListRegionalInventoriesResponse.to_json( - regionalinventory.ListRegionalInventoriesResponse() - ) - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regionalinventory.ListRegionalInventoriesResponse() - request = regionalinventory.ListRegionalInventoriesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = regionalinventory.ListRegionalInventoriesResponse() + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1/products/sample2"} - client.list_regional_inventories( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_regional_inventories_rest_bad_request( - transport: str = "rest", - request_type=regionalinventory.ListRegionalInventoriesRequest, -): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_regional_inventories(request) - - -def test_list_regional_inventories_rest_flattened(): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regionalinventory.ListRegionalInventoriesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1/products/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) + mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() @@ -2878,136 +2636,6 @@ def test_list_regional_inventories_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - regionalinventory.InsertRegionalInventoryRequest, - dict, - ], -) -def test_insert_regional_inventory_rest(request_type): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request_init["regional_inventory"] = { - "name": "name_value", - "account": 749, - "region": "region_value", - "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, - "sale_price": {}, - "sale_price_effective_date": { - "start_time": {"seconds": 751, "nanos": 543}, - "end_time": {}, - }, - "availability": "availability_value", - "custom_attributes": [ - {"name": "name_value", "value": "value_value", "group_values": {}} - ], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = regionalinventory.InsertRegionalInventoryRequest.meta.fields[ - "regional_inventory" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["regional_inventory"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["regional_inventory"][field])): - del request_init["regional_inventory"][field][i][subfield] - else: - del request_init["regional_inventory"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = regionalinventory.RegionalInventory( - name="name_value", - account=749, - region="region_value", - availability="availability_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = regionalinventory.RegionalInventory.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_regional_inventory(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, regionalinventory.RegionalInventory) - assert response.name == "name_value" - assert response.account == 749 - assert response.region == "region_value" - assert response.availability == "availability_value" - - def test_insert_regional_inventory_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3141,172 +2769,45 @@ def test_insert_regional_inventory_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_regional_inventory_rest_interceptors(null_interceptor): - transport = transports.RegionalInventoryServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.RegionalInventoryServiceRestInterceptor(), - ) - client = RegionalInventoryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RegionalInventoryServiceRestInterceptor, - "post_insert_regional_inventory", - ) as post, mock.patch.object( - transports.RegionalInventoryServiceRestInterceptor, - "pre_insert_regional_inventory", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = regionalinventory.InsertRegionalInventoryRequest.pb( - regionalinventory.InsertRegionalInventoryRequest() +def test_delete_regional_inventory_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = regionalinventory.RegionalInventory.to_json( - regionalinventory.RegionalInventory() - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - request = regionalinventory.InsertRegionalInventoryRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = regionalinventory.RegionalInventory() + # Ensure method has been cached + assert ( + client._transport.delete_regional_inventory + in client._transport._wrapped_methods + ) - client.insert_regional_inventory( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) + client._transport._wrapped_methods[ + client._transport.delete_regional_inventory + ] = mock_rpc - pre.assert_called_once() - post.assert_called_once() + request = {} + client.delete_regional_inventory(request) + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 -def test_insert_regional_inventory_rest_bad_request( - transport: str = "rest", - request_type=regionalinventory.InsertRegionalInventoryRequest, -): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + client.delete_regional_inventory(request) - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_regional_inventory(request) - - -def test_insert_regional_inventory_rest_error(): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - regionalinventory.DeleteRegionalInventoryRequest, - dict, - ], -) -def test_delete_regional_inventory_rest(request_type): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "accounts/sample1/products/sample2/regionalInventories/sample3" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_regional_inventory(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_regional_inventory_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.delete_regional_inventory - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.delete_regional_inventory - ] = mock_rpc - - request = {} - client.delete_regional_inventory(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_regional_inventory(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 def test_delete_regional_inventory_rest_required_fields( @@ -3389,8 +2890,625 @@ def test_delete_regional_inventory_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) +def test_delete_regional_inventory_rest_flattened(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "accounts/sample1/products/sample2/regionalInventories/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_regional_inventory(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/inventories/v1beta/{name=accounts/*/products/*/regionalInventories/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_regional_inventory_rest_flattened_error(transport: str = "rest"): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_regional_inventory( + regionalinventory.DeleteRegionalInventoryRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.RegionalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.RegionalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RegionalInventoryServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.RegionalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RegionalInventoryServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = RegionalInventoryServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.RegionalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = RegionalInventoryServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.RegionalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = RegionalInventoryServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.RegionalInventoryServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.RegionalInventoryServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.RegionalInventoryServiceGrpcTransport, + transports.RegionalInventoryServiceGrpcAsyncIOTransport, + transports.RegionalInventoryServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = RegionalInventoryServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_regional_inventories_empty_call_grpc(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_regional_inventories), "__call__" + ) as call: + call.return_value = regionalinventory.ListRegionalInventoriesResponse() + client.list_regional_inventories(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.ListRegionalInventoriesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_regional_inventory_empty_call_grpc(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_regional_inventory), "__call__" + ) as call: + call.return_value = regionalinventory.RegionalInventory() + client.insert_regional_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.InsertRegionalInventoryRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_regional_inventory_empty_call_grpc(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_regional_inventory), "__call__" + ) as call: + call.return_value = None + client.delete_regional_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.DeleteRegionalInventoryRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = RegionalInventoryServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = RegionalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_regional_inventories_empty_call_grpc_asyncio(): + client = RegionalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_regional_inventories), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + regionalinventory.ListRegionalInventoriesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_regional_inventories(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.ListRegionalInventoriesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_regional_inventory_empty_call_grpc_asyncio(): + client = RegionalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_regional_inventory), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + regionalinventory.RegionalInventory( + name="name_value", + account=749, + region="region_value", + availability="availability_value", + ) + ) + await client.insert_regional_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.InsertRegionalInventoryRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_regional_inventory_empty_call_grpc_asyncio(): + client = RegionalInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_regional_inventory), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_regional_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.DeleteRegionalInventoryRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = RegionalInventoryServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_regional_inventories_rest_bad_request( + request_type=regionalinventory.ListRegionalInventoriesRequest, +): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_regional_inventories(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regionalinventory.ListRegionalInventoriesRequest, + dict, + ], +) +def test_list_regional_inventories_rest_call_success(request_type): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regionalinventory.ListRegionalInventoriesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = regionalinventory.ListRegionalInventoriesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_regional_inventories(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRegionalInventoriesPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_regional_inventories_rest_interceptors(null_interceptor): + transport = transports.RegionalInventoryServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.RegionalInventoryServiceRestInterceptor(), + ) + client = RegionalInventoryServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RegionalInventoryServiceRestInterceptor, + "post_list_regional_inventories", + ) as post, mock.patch.object( + transports.RegionalInventoryServiceRestInterceptor, + "pre_list_regional_inventories", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = regionalinventory.ListRegionalInventoriesRequest.pb( + regionalinventory.ListRegionalInventoriesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = regionalinventory.ListRegionalInventoriesResponse.to_json( + regionalinventory.ListRegionalInventoriesResponse() + ) + req.return_value.content = return_value + + request = regionalinventory.ListRegionalInventoriesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = regionalinventory.ListRegionalInventoriesResponse() + + client.list_regional_inventories( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_insert_regional_inventory_rest_bad_request( + request_type=regionalinventory.InsertRegionalInventoryRequest, +): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_regional_inventory(request) + + +@pytest.mark.parametrize( + "request_type", + [ + regionalinventory.InsertRegionalInventoryRequest, + dict, + ], +) +def test_insert_regional_inventory_rest_call_success(request_type): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1/products/sample2"} + request_init["regional_inventory"] = { + "name": "name_value", + "account": 749, + "region": "region_value", + "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, + "sale_price": {}, + "sale_price_effective_date": { + "start_time": {"seconds": 751, "nanos": 543}, + "end_time": {}, + }, + "availability": "availability_value", + "custom_attributes": [ + {"name": "name_value", "value": "value_value", "group_values": {}} + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = regionalinventory.InsertRegionalInventoryRequest.meta.fields[ + "regional_inventory" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["regional_inventory"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["regional_inventory"][field])): + del request_init["regional_inventory"][field][i][subfield] + else: + del request_init["regional_inventory"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = regionalinventory.RegionalInventory( + name="name_value", + account=749, + region="region_value", + availability="availability_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = regionalinventory.RegionalInventory.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_regional_inventory(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, regionalinventory.RegionalInventory) + assert response.name == "name_value" + assert response.account == 749 + assert response.region == "region_value" + assert response.availability == "availability_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_regional_inventory_rest_interceptors(null_interceptor): +def test_insert_regional_inventory_rest_interceptors(null_interceptor): transport = transports.RegionalInventoryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -3398,17 +3516,22 @@ def test_delete_regional_inventory_rest_interceptors(null_interceptor): else transports.RegionalInventoryServiceRestInterceptor(), ) client = RegionalInventoryServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( transports.RegionalInventoryServiceRestInterceptor, - "pre_delete_regional_inventory", + "post_insert_regional_inventory", + ) as post, mock.patch.object( + transports.RegionalInventoryServiceRestInterceptor, + "pre_insert_regional_inventory", ) as pre: pre.assert_not_called() - pb_message = regionalinventory.DeleteRegionalInventoryRequest.pb( - regionalinventory.DeleteRegionalInventoryRequest() + post.assert_not_called() + pb_message = regionalinventory.InsertRegionalInventoryRequest.pb( + regionalinventory.InsertRegionalInventoryRequest() ) transcode.return_value = { "method": "post", @@ -3417,18 +3540,22 @@ def test_delete_regional_inventory_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = regionalinventory.RegionalInventory.to_json( + regionalinventory.RegionalInventory() + ) + req.return_value.content = return_value - request = regionalinventory.DeleteRegionalInventoryRequest() + request = regionalinventory.InsertRegionalInventoryRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = regionalinventory.RegionalInventory() - client.delete_regional_inventory( + client.insert_regional_inventory( request, metadata=[ ("key", "val"), @@ -3437,17 +3564,15 @@ def test_delete_regional_inventory_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_delete_regional_inventory_rest_bad_request( - transport: str = "rest", request_type=regionalinventory.DeleteRegionalInventoryRequest, ): client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = { "name": "accounts/sample1/products/sample2/regionalInventories/sample3" @@ -3459,180 +3584,171 @@ def test_delete_regional_inventory_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.delete_regional_inventory(request) -def test_delete_regional_inventory_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + regionalinventory.DeleteRegionalInventoryRequest, + dict, + ], +) +def test_delete_regional_inventory_rest_call_success(request_type): client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = { + "name": "accounts/sample1/products/sample2/regionalInventories/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "accounts/sample1/products/sample2/regionalInventories/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_regional_inventory(request) - client.delete_regional_inventory(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/inventories/v1beta/{name=accounts/*/products/*/regionalInventories/*}" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert response is None -def test_delete_regional_inventory_rest_flattened_error(transport: str = "rest"): - client = RegionalInventoryServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_regional_inventory_rest_interceptors(null_interceptor): + transport = transports.RegionalInventoryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.RegionalInventoryServiceRestInterceptor(), ) + client = RegionalInventoryServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RegionalInventoryServiceRestInterceptor, + "pre_delete_regional_inventory", + ) as pre: + pre.assert_not_called() + pb_message = regionalinventory.DeleteRegionalInventoryRequest.pb( + regionalinventory.DeleteRegionalInventoryRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = regionalinventory.DeleteRegionalInventoryRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.delete_regional_inventory( - regionalinventory.DeleteRegionalInventoryRequest(), - name="name_value", + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + -def test_delete_regional_inventory_rest_error(): +def test_initialize_client_w_rest(): client = RegionalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + assert client is not None -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.RegionalInventoryServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_regional_inventories_empty_call_rest(): + client = RegionalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.RegionalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = RegionalInventoryServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_regional_inventories), "__call__" + ) as call: + client.list_regional_inventories(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.RegionalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = RegionalInventoryServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.ListRegionalInventoriesRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = RegionalInventoryServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.RegionalInventoryServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_regional_inventory_empty_call_rest(): + client = RegionalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = RegionalInventoryServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_regional_inventory), "__call__" + ) as call: + client.insert_regional_inventory(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.RegionalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = RegionalInventoryServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.InsertRegionalInventoryRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.RegionalInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.RegionalInventoryServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_regional_inventory_empty_call_rest(): + client = RegionalInventoryServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.RegionalInventoryServiceGrpcTransport, - transports.RegionalInventoryServiceGrpcAsyncIOTransport, - transports.RegionalInventoryServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_regional_inventory), "__call__" + ) as call: + client.delete_regional_inventory(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = regionalinventory.DeleteRegionalInventoryRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = RegionalInventoryServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4226,36 +4342,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = RegionalInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = RegionalInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = RegionalInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/README.rst b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/README.rst new file mode 100644 index 000000000000..c4b5f2586c1a --- /dev/null +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`LfpInventoryServiceTransport` is the ABC for all transports. +- public child `LfpInventoryServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `LfpInventoryServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseLfpInventoryServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `LfpInventoryServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py index 68cd7f3ed614..5aed7328c0f1 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -273,15 +277,24 @@ def insert_lfp_inventory( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.insert_lfp_inventory: gapic_v1.method_async.wrap_method( + self.insert_lfp_inventory: self._wrap_method( self.insert_lfp_inventory, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("LfpInventoryServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py index 308746c7111d..14ac9ea2bc33 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_lfp_v1beta.types import lfpinventory + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseLfpInventoryServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_lfp_v1beta.types import lfpinventory - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import LfpInventoryServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -108,8 +105,8 @@ class LfpInventoryServiceRestStub: _interceptor: LfpInventoryServiceRestInterceptor -class LfpInventoryServiceRestTransport(LfpInventoryServiceTransport): - """REST backend transport for LfpInventoryService. +class LfpInventoryServiceRestTransport(_BaseLfpInventoryServiceRestTransport): + """REST backend synchronous transport for LfpInventoryService. Service for a `LFP partner `__ to @@ -120,7 +117,6 @@ class LfpInventoryServiceRestTransport(LfpInventoryServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -174,21 +170,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -199,19 +186,35 @@ def __init__( self._interceptor = interceptor or LfpInventoryServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _InsertLfpInventory(LfpInventoryServiceRestStub): + class _InsertLfpInventory( + _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory, + LfpInventoryServiceRestStub, + ): def __hash__(self): - return hash("InsertLfpInventory") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LfpInventoryServiceRestTransport.InsertLfpInventory") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -237,47 +240,36 @@ def __call__( Local Inventory for the merchant. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/lfp/v1beta/{parent=accounts/*}/lfpInventories:insert", - "body": "lfp_inventory", - }, - ] + http_options = ( + _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory._get_http_options() + ) request, metadata = self._interceptor.pre_insert_lfp_inventory( request, metadata ) - pb_request = lfpinventory.InsertLfpInventoryRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + LfpInventoryServiceRestTransport._InsertLfpInventory._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest_base.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest_base.py new file mode 100644 index 000000000000..a3e67ffeb594 --- /dev/null +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_inventory_service/transports/rest_base.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_lfp_v1beta.types import lfpinventory + +from .base import DEFAULT_CLIENT_INFO, LfpInventoryServiceTransport + + +class _BaseLfpInventoryServiceRestTransport(LfpInventoryServiceTransport): + """Base REST backend transport for LfpInventoryService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseInsertLfpInventory: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/lfp/v1beta/{parent=accounts/*}/lfpInventories:insert", + "body": "lfp_inventory", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lfpinventory.InsertLfpInventoryRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLfpInventoryServiceRestTransport._BaseInsertLfpInventory._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseLfpInventoryServiceRestTransport",) diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/README.rst b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/README.rst new file mode 100644 index 000000000000..5a2eb4c5a035 --- /dev/null +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`LfpSaleServiceTransport` is the ABC for all transports. +- public child `LfpSaleServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `LfpSaleServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseLfpSaleServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `LfpSaleServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py index f6fe418dafdc..f8df8912c3a0 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -269,15 +273,24 @@ def insert_lfp_sale( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.insert_lfp_sale: gapic_v1.method_async.wrap_method( + self.insert_lfp_sale: self._wrap_method( self.insert_lfp_sale, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("LfpSaleServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py index 4606fec0da09..f01a9cf78957 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_lfp_v1beta.types import lfpsale + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseLfpSaleServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_lfp_v1beta.types import lfpsale - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import LfpSaleServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -104,8 +101,8 @@ class LfpSaleServiceRestStub: _interceptor: LfpSaleServiceRestInterceptor -class LfpSaleServiceRestTransport(LfpSaleServiceTransport): - """REST backend transport for LfpSaleService. +class LfpSaleServiceRestTransport(_BaseLfpSaleServiceRestTransport): + """REST backend synchronous transport for LfpSaleService. Service for a `LFP partner `__ to @@ -116,7 +113,6 @@ class LfpSaleServiceRestTransport(LfpSaleServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -170,21 +166,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -195,19 +182,34 @@ def __init__( self._interceptor = interceptor or LfpSaleServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _InsertLfpSale(LfpSaleServiceRestStub): + class _InsertLfpSale( + _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale, LfpSaleServiceRestStub + ): def __hash__(self): - return hash("InsertLfpSale") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LfpSaleServiceRestTransport.InsertLfpSale") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -234,45 +236,32 @@ def __call__( A sale for the merchant. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/lfp/v1beta/{parent=accounts/*}/lfpSales:insert", - "body": "lfp_sale", - }, - ] + http_options = ( + _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_http_options() + ) request, metadata = self._interceptor.pre_insert_lfp_sale(request, metadata) - pb_request = lfpsale.InsertLfpSaleRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = LfpSaleServiceRestTransport._InsertLfpSale._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest_base.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest_base.py new file mode 100644 index 000000000000..d00c4889f51a --- /dev/null +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_sale_service/transports/rest_base.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_lfp_v1beta.types import lfpsale + +from .base import DEFAULT_CLIENT_INFO, LfpSaleServiceTransport + + +class _BaseLfpSaleServiceRestTransport(LfpSaleServiceTransport): + """Base REST backend transport for LfpSaleService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseInsertLfpSale: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/lfp/v1beta/{parent=accounts/*}/lfpSales:insert", + "body": "lfp_sale", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lfpsale.InsertLfpSaleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLfpSaleServiceRestTransport._BaseInsertLfpSale._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseLfpSaleServiceRestTransport",) diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/README.rst b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/README.rst new file mode 100644 index 000000000000..ed35abffa51e --- /dev/null +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`LfpStoreServiceTransport` is the ABC for all transports. +- public child `LfpStoreServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `LfpStoreServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseLfpStoreServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `LfpStoreServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py index 9440773d90db..f15ccebf5497 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -229,6 +230,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -353,30 +357,39 @@ def list_lfp_stores( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_lfp_store: gapic_v1.method_async.wrap_method( + self.get_lfp_store: self._wrap_method( self.get_lfp_store, default_timeout=None, client_info=client_info, ), - self.insert_lfp_store: gapic_v1.method_async.wrap_method( + self.insert_lfp_store: self._wrap_method( self.insert_lfp_store, default_timeout=None, client_info=client_info, ), - self.delete_lfp_store: gapic_v1.method_async.wrap_method( + self.delete_lfp_store: self._wrap_method( self.delete_lfp_store, default_timeout=None, client_info=client_info, ), - self.list_lfp_stores: gapic_v1.method_async.wrap_method( + self.list_lfp_stores: self._wrap_method( self.list_lfp_stores, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("LfpStoreServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py index cbd0643bc6ea..63c289cfdd69 100644 --- a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_lfp_v1beta.types import lfpstore + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseLfpStoreServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_lfp_v1beta.types import lfpstore - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import LfpStoreServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -182,8 +178,8 @@ class LfpStoreServiceRestStub: _interceptor: LfpStoreServiceRestInterceptor -class LfpStoreServiceRestTransport(LfpStoreServiceTransport): - """REST backend transport for LfpStoreService. +class LfpStoreServiceRestTransport(_BaseLfpStoreServiceRestTransport): + """REST backend synchronous transport for LfpStoreService. Service for a `LFP partner `__ to @@ -194,7 +190,6 @@ class LfpStoreServiceRestTransport(LfpStoreServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -248,21 +243,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -273,19 +259,33 @@ def __init__( self._interceptor = interceptor or LfpStoreServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _DeleteLfpStore(LfpStoreServiceRestStub): + class _DeleteLfpStore( + _BaseLfpStoreServiceRestTransport._BaseDeleteLfpStore, LfpStoreServiceRestStub + ): def __hash__(self): - return hash("DeleteLfpStore") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LfpStoreServiceRestTransport.DeleteLfpStore") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -308,40 +308,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/lfp/v1beta/{name=accounts/*/lfpStores/*}", - }, - ] + http_options = ( + _BaseLfpStoreServiceRestTransport._BaseDeleteLfpStore._get_http_options() + ) request, metadata = self._interceptor.pre_delete_lfp_store( request, metadata ) - pb_request = lfpstore.DeleteLfpStoreRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseLfpStoreServiceRestTransport._BaseDeleteLfpStore._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLfpStoreServiceRestTransport._BaseDeleteLfpStore._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = LfpStoreServiceRestTransport._DeleteLfpStore._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -349,19 +338,33 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetLfpStore(LfpStoreServiceRestStub): + class _GetLfpStore( + _BaseLfpStoreServiceRestTransport._BaseGetLfpStore, LfpStoreServiceRestStub + ): def __hash__(self): - return hash("GetLfpStore") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LfpStoreServiceRestTransport.GetLfpStore") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -394,38 +397,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/lfp/v1beta/{name=accounts/*/lfpStores/*}", - }, - ] + http_options = ( + _BaseLfpStoreServiceRestTransport._BaseGetLfpStore._get_http_options() + ) request, metadata = self._interceptor.pre_get_lfp_store(request, metadata) - pb_request = lfpstore.GetLfpStoreRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseLfpStoreServiceRestTransport._BaseGetLfpStore._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLfpStoreServiceRestTransport._BaseGetLfpStore._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = LfpStoreServiceRestTransport._GetLfpStore._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -441,19 +433,34 @@ def __call__( resp = self._interceptor.post_get_lfp_store(resp) return resp - class _InsertLfpStore(LfpStoreServiceRestStub): + class _InsertLfpStore( + _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore, LfpStoreServiceRestStub + ): def __hash__(self): - return hash("InsertLfpStore") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LfpStoreServiceRestTransport.InsertLfpStore") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -487,47 +494,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/lfp/v1beta/{parent=accounts/*}/lfpStores:insert", - "body": "lfp_store", - }, - ] + http_options = ( + _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore._get_http_options() + ) request, metadata = self._interceptor.pre_insert_lfp_store( request, metadata ) - pb_request = lfpstore.InsertLfpStoreRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = LfpStoreServiceRestTransport._InsertLfpStore._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -543,21 +537,33 @@ def __call__( resp = self._interceptor.post_insert_lfp_store(resp) return resp - class _ListLfpStores(LfpStoreServiceRestStub): + class _ListLfpStores( + _BaseLfpStoreServiceRestTransport._BaseListLfpStores, LfpStoreServiceRestStub + ): def __hash__(self): - return hash("ListLfpStores") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "targetAccount": 0, - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("LfpStoreServiceRestTransport.ListLfpStores") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -586,38 +592,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/lfp/v1beta/{parent=accounts/*}/lfpStores", - }, - ] + http_options = ( + _BaseLfpStoreServiceRestTransport._BaseListLfpStores._get_http_options() + ) request, metadata = self._interceptor.pre_list_lfp_stores(request, metadata) - pb_request = lfpstore.ListLfpStoresRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseLfpStoreServiceRestTransport._BaseListLfpStores._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseLfpStoreServiceRestTransport._BaseListLfpStores._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = LfpStoreServiceRestTransport._ListLfpStores._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest_base.py b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest_base.py new file mode 100644 index 000000000000..11ec0d0b6739 --- /dev/null +++ b/packages/google-shopping-merchant-lfp/google/shopping/merchant_lfp_v1beta/services/lfp_store_service/transports/rest_base.py @@ -0,0 +1,292 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_lfp_v1beta.types import lfpstore + +from .base import DEFAULT_CLIENT_INFO, LfpStoreServiceTransport + + +class _BaseLfpStoreServiceRestTransport(LfpStoreServiceTransport): + """Base REST backend transport for LfpStoreService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseDeleteLfpStore: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/lfp/v1beta/{name=accounts/*/lfpStores/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lfpstore.DeleteLfpStoreRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLfpStoreServiceRestTransport._BaseDeleteLfpStore._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetLfpStore: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/lfp/v1beta/{name=accounts/*/lfpStores/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lfpstore.GetLfpStoreRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLfpStoreServiceRestTransport._BaseGetLfpStore._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertLfpStore: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/lfp/v1beta/{parent=accounts/*}/lfpStores:insert", + "body": "lfp_store", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lfpstore.InsertLfpStoreRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLfpStoreServiceRestTransport._BaseInsertLfpStore._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListLfpStores: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "targetAccount": 0, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/lfp/v1beta/{parent=accounts/*}/lfpStores", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lfpstore.ListLfpStoresRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLfpStoreServiceRestTransport._BaseListLfpStores._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseLfpStoreServiceRestTransport",) diff --git a/packages/google-shopping-merchant-lfp/setup.py b/packages/google-shopping-merchant-lfp/setup.py index c1e6ee144039..fd3d3bf22fe6 100644 --- a/packages/google-shopping-merchant-lfp/setup.py +++ b/packages/google-shopping-merchant-lfp/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-lfp" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py index 4bd3d2796892..ab1c151906d3 100644 --- a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py +++ b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_inventory_service.py @@ -22,28 +22,37 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_lfp_v1beta.services.lfp_inventory_service import ( LfpInventoryServiceAsyncClient, @@ -53,10 +62,24 @@ from google.shopping.merchant_lfp_v1beta.types import lfpinventory +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1246,27 +1269,6 @@ def test_insert_lfp_inventory(request_type, transport: str = "grpc"): assert response.feed_label == "feed_label_value" -def test_insert_lfp_inventory_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_lfp_inventory), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_lfp_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpinventory.InsertLfpInventoryRequest() - - def test_insert_lfp_inventory_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1336,42 +1338,6 @@ def test_insert_lfp_inventory_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_lfp_inventory_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_lfp_inventory), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - lfpinventory.LfpInventory( - name="name_value", - target_account=1491, - store_code="store_code_value", - offer_id="offer_id_value", - region_code="region_code_value", - content_language="content_language_value", - gtin="gtin_value", - availability="availability_value", - quantity=895, - pickup_method="pickup_method_value", - pickup_sla="pickup_sla_value", - feed_label="feed_label_value", - ) - ) - response = await client.insert_lfp_inventory() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpinventory.InsertLfpInventoryRequest() - - @pytest.mark.asyncio async def test_insert_lfp_inventory_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1380,7 +1346,7 @@ async def test_insert_lfp_inventory_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LfpInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1419,7 +1385,7 @@ async def test_insert_lfp_inventory_async( transport: str = "grpc_asyncio", request_type=lfpinventory.InsertLfpInventoryRequest ): client = LfpInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1511,7 +1477,7 @@ def test_insert_lfp_inventory_field_headers(): @pytest.mark.asyncio async def test_insert_lfp_inventory_field_headers_async(): client = LfpInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1542,151 +1508,6 @@ async def test_insert_lfp_inventory_field_headers_async(): ) in kw["metadata"] -@pytest.mark.parametrize( - "request_type", - [ - lfpinventory.InsertLfpInventoryRequest, - dict, - ], -) -def test_insert_lfp_inventory_rest(request_type): - client = LfpInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["lfp_inventory"] = { - "name": "name_value", - "target_account": 1491, - "store_code": "store_code_value", - "offer_id": "offer_id_value", - "region_code": "region_code_value", - "content_language": "content_language_value", - "gtin": "gtin_value", - "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, - "availability": "availability_value", - "quantity": 895, - "collection_time": {"seconds": 751, "nanos": 543}, - "pickup_method": "pickup_method_value", - "pickup_sla": "pickup_sla_value", - "feed_label": "feed_label_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = lfpinventory.InsertLfpInventoryRequest.meta.fields["lfp_inventory"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["lfp_inventory"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["lfp_inventory"][field])): - del request_init["lfp_inventory"][field][i][subfield] - else: - del request_init["lfp_inventory"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpinventory.LfpInventory( - name="name_value", - target_account=1491, - store_code="store_code_value", - offer_id="offer_id_value", - region_code="region_code_value", - content_language="content_language_value", - gtin="gtin_value", - availability="availability_value", - quantity=895, - pickup_method="pickup_method_value", - pickup_sla="pickup_sla_value", - feed_label="feed_label_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = lfpinventory.LfpInventory.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_lfp_inventory(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, lfpinventory.LfpInventory) - assert response.name == "name_value" - assert response.target_account == 1491 - assert response.store_code == "store_code_value" - assert response.offer_id == "offer_id_value" - assert response.region_code == "region_code_value" - assert response.content_language == "content_language_value" - assert response.gtin == "gtin_value" - assert response.availability == "availability_value" - assert response.quantity == 895 - assert response.pickup_method == "pickup_method_value" - assert response.pickup_sla == "pickup_sla_value" - assert response.feed_label == "feed_label_value" - - def test_insert_lfp_inventory_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1819,102 +1640,15 @@ def test_insert_lfp_inventory_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_lfp_inventory_rest_interceptors(null_interceptor): - transport = transports.LfpInventoryServiceRestTransport( +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.LfpInventoryServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LfpInventoryServiceRestInterceptor(), ) - client = LfpInventoryServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LfpInventoryServiceRestInterceptor, "post_insert_lfp_inventory" - ) as post, mock.patch.object( - transports.LfpInventoryServiceRestInterceptor, "pre_insert_lfp_inventory" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = lfpinventory.InsertLfpInventoryRequest.pb( - lfpinventory.InsertLfpInventoryRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = lfpinventory.LfpInventory.to_json( - lfpinventory.LfpInventory() - ) - - request = lfpinventory.InsertLfpInventoryRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = lfpinventory.LfpInventory() - - client.insert_lfp_inventory( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_insert_lfp_inventory_rest_bad_request( - transport: str = "rest", request_type=lfpinventory.InsertLfpInventoryRequest -): - client = LfpInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_lfp_inventory(request) - - -def test_insert_lfp_inventory_rest_error(): - client = LfpInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.LfpInventoryServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = LfpInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + with pytest.raises(ValueError): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -1998,18 +1732,355 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = LfpInventoryServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_lfp_inventory_empty_call_grpc(): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_lfp_inventory), "__call__" + ) as call: + call.return_value = lfpinventory.LfpInventory() + client.insert_lfp_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpinventory.InsertLfpInventoryRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = LfpInventoryServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = LfpInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_lfp_inventory_empty_call_grpc_asyncio(): + client = LfpInventoryServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_lfp_inventory), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + lfpinventory.LfpInventory( + name="name_value", + target_account=1491, + store_code="store_code_value", + offer_id="offer_id_value", + region_code="region_code_value", + content_language="content_language_value", + gtin="gtin_value", + availability="availability_value", + quantity=895, + pickup_method="pickup_method_value", + pickup_sla="pickup_sla_value", + feed_label="feed_label_value", + ) + ) + await client.insert_lfp_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpinventory.InsertLfpInventoryRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = LfpInventoryServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_insert_lfp_inventory_rest_bad_request( + request_type=lfpinventory.InsertLfpInventoryRequest, +): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_lfp_inventory(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + lfpinventory.InsertLfpInventoryRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = LfpInventoryServiceClient.get_transport_class(transport_name)( +def test_insert_lfp_inventory_rest_call_success(request_type): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["lfp_inventory"] = { + "name": "name_value", + "target_account": 1491, + "store_code": "store_code_value", + "offer_id": "offer_id_value", + "region_code": "region_code_value", + "content_language": "content_language_value", + "gtin": "gtin_value", + "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, + "availability": "availability_value", + "quantity": 895, + "collection_time": {"seconds": 751, "nanos": 543}, + "pickup_method": "pickup_method_value", + "pickup_sla": "pickup_sla_value", + "feed_label": "feed_label_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = lfpinventory.InsertLfpInventoryRequest.meta.fields["lfp_inventory"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["lfp_inventory"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["lfp_inventory"][field])): + del request_init["lfp_inventory"][field][i][subfield] + else: + del request_init["lfp_inventory"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpinventory.LfpInventory( + name="name_value", + target_account=1491, + store_code="store_code_value", + offer_id="offer_id_value", + region_code="region_code_value", + content_language="content_language_value", + gtin="gtin_value", + availability="availability_value", + quantity=895, + pickup_method="pickup_method_value", + pickup_sla="pickup_sla_value", + feed_label="feed_label_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lfpinventory.LfpInventory.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_lfp_inventory(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, lfpinventory.LfpInventory) + assert response.name == "name_value" + assert response.target_account == 1491 + assert response.store_code == "store_code_value" + assert response.offer_id == "offer_id_value" + assert response.region_code == "region_code_value" + assert response.content_language == "content_language_value" + assert response.gtin == "gtin_value" + assert response.availability == "availability_value" + assert response.quantity == 895 + assert response.pickup_method == "pickup_method_value" + assert response.pickup_sla == "pickup_sla_value" + assert response.feed_label == "feed_label_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_insert_lfp_inventory_rest_interceptors(null_interceptor): + transport = transports.LfpInventoryServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.LfpInventoryServiceRestInterceptor(), ) - assert transport.kind == transport_name + client = LfpInventoryServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LfpInventoryServiceRestInterceptor, "post_insert_lfp_inventory" + ) as post, mock.patch.object( + transports.LfpInventoryServiceRestInterceptor, "pre_insert_lfp_inventory" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = lfpinventory.InsertLfpInventoryRequest.pb( + lfpinventory.InsertLfpInventoryRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = lfpinventory.LfpInventory.to_json(lfpinventory.LfpInventory()) + req.return_value.content = return_value + + request = lfpinventory.InsertLfpInventoryRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = lfpinventory.LfpInventory() + + client.insert_lfp_inventory( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_lfp_inventory_empty_call_rest(): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_lfp_inventory), "__call__" + ) as call: + client.insert_lfp_inventory(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpinventory.InsertLfpInventoryRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2592,36 +2663,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = LfpInventoryServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = LfpInventoryServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = LfpInventoryServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py index 03b007c66aba..72d6b89c1669 100644 --- a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py +++ b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_sale_service.py @@ -22,28 +22,37 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_lfp_v1beta.services.lfp_sale_service import ( LfpSaleServiceAsyncClient, @@ -53,10 +62,24 @@ from google.shopping.merchant_lfp_v1beta.types import lfpsale +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1176,25 +1199,6 @@ def test_insert_lfp_sale(request_type, transport: str = "grpc"): assert response.feed_label == "feed_label_value" -def test_insert_lfp_sale_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpSaleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.insert_lfp_sale), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_lfp_sale() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpsale.InsertLfpSaleRequest() - - def test_insert_lfp_sale_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1258,38 +1262,6 @@ def test_insert_lfp_sale_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_lfp_sale_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpSaleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.insert_lfp_sale), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - lfpsale.LfpSale( - name="name_value", - target_account=1491, - store_code="store_code_value", - offer_id="offer_id_value", - region_code="region_code_value", - content_language="content_language_value", - gtin="gtin_value", - quantity=895, - uid="uid_value", - feed_label="feed_label_value", - ) - ) - response = await client.insert_lfp_sale() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpsale.InsertLfpSaleRequest() - - @pytest.mark.asyncio async def test_insert_lfp_sale_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1298,7 +1270,7 @@ async def test_insert_lfp_sale_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LfpSaleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1337,7 +1309,7 @@ async def test_insert_lfp_sale_async( transport: str = "grpc_asyncio", request_type=lfpsale.InsertLfpSaleRequest ): client = LfpSaleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1421,7 +1393,7 @@ def test_insert_lfp_sale_field_headers(): @pytest.mark.asyncio async def test_insert_lfp_sale_field_headers_async(): client = LfpSaleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1448,145 +1420,6 @@ async def test_insert_lfp_sale_field_headers_async(): ) in kw["metadata"] -@pytest.mark.parametrize( - "request_type", - [ - lfpsale.InsertLfpSaleRequest, - dict, - ], -) -def test_insert_lfp_sale_rest(request_type): - client = LfpSaleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["lfp_sale"] = { - "name": "name_value", - "target_account": 1491, - "store_code": "store_code_value", - "offer_id": "offer_id_value", - "region_code": "region_code_value", - "content_language": "content_language_value", - "gtin": "gtin_value", - "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, - "quantity": 895, - "sale_time": {"seconds": 751, "nanos": 543}, - "uid": "uid_value", - "feed_label": "feed_label_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = lfpsale.InsertLfpSaleRequest.meta.fields["lfp_sale"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["lfp_sale"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["lfp_sale"][field])): - del request_init["lfp_sale"][field][i][subfield] - else: - del request_init["lfp_sale"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpsale.LfpSale( - name="name_value", - target_account=1491, - store_code="store_code_value", - offer_id="offer_id_value", - region_code="region_code_value", - content_language="content_language_value", - gtin="gtin_value", - quantity=895, - uid="uid_value", - feed_label="feed_label_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = lfpsale.LfpSale.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_lfp_sale(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, lfpsale.LfpSale) - assert response.name == "name_value" - assert response.target_account == 1491 - assert response.store_code == "store_code_value" - assert response.offer_id == "offer_id_value" - assert response.region_code == "region_code_value" - assert response.content_language == "content_language_value" - assert response.gtin == "gtin_value" - assert response.quantity == 895 - assert response.uid == "uid_value" - assert response.feed_label == "feed_label_value" - - def test_insert_lfp_sale_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1715,98 +1548,15 @@ def test_insert_lfp_sale_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_lfp_sale_rest_interceptors(null_interceptor): - transport = transports.LfpSaleServiceRestTransport( +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.LfpSaleServiceGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LfpSaleServiceRestInterceptor(), ) - client = LfpSaleServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LfpSaleServiceRestInterceptor, "post_insert_lfp_sale" - ) as post, mock.patch.object( - transports.LfpSaleServiceRestInterceptor, "pre_insert_lfp_sale" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = lfpsale.InsertLfpSaleRequest.pb(lfpsale.InsertLfpSaleRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = lfpsale.LfpSale.to_json(lfpsale.LfpSale()) - - request = lfpsale.InsertLfpSaleRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = lfpsale.LfpSale() - - client.insert_lfp_sale( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_insert_lfp_sale_rest_bad_request( - transport: str = "rest", request_type=lfpsale.InsertLfpSaleRequest -): - client = LfpSaleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_lfp_sale(request) - - -def test_insert_lfp_sale_rest_error(): - client = LfpSaleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.LfpSaleServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = LfpSaleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + with pytest.raises(ValueError): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) # It is an error to provide a credentials file and a transport instance. @@ -1890,18 +1640,337 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = LfpSaleServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_lfp_sale_empty_call_grpc(): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_lfp_sale), "__call__") as call: + call.return_value = lfpsale.LfpSale() + client.insert_lfp_sale(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpsale.InsertLfpSaleRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = LfpSaleServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = LfpSaleServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_lfp_sale_empty_call_grpc_asyncio(): + client = LfpSaleServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_lfp_sale), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + lfpsale.LfpSale( + name="name_value", + target_account=1491, + store_code="store_code_value", + offer_id="offer_id_value", + region_code="region_code_value", + content_language="content_language_value", + gtin="gtin_value", + quantity=895, + uid="uid_value", + feed_label="feed_label_value", + ) + ) + await client.insert_lfp_sale(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpsale.InsertLfpSaleRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = LfpSaleServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_insert_lfp_sale_rest_bad_request(request_type=lfpsale.InsertLfpSaleRequest): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_lfp_sale(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + lfpsale.InsertLfpSaleRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = LfpSaleServiceClient.get_transport_class(transport_name)( +def test_insert_lfp_sale_rest_call_success(request_type): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["lfp_sale"] = { + "name": "name_value", + "target_account": 1491, + "store_code": "store_code_value", + "offer_id": "offer_id_value", + "region_code": "region_code_value", + "content_language": "content_language_value", + "gtin": "gtin_value", + "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, + "quantity": 895, + "sale_time": {"seconds": 751, "nanos": 543}, + "uid": "uid_value", + "feed_label": "feed_label_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = lfpsale.InsertLfpSaleRequest.meta.fields["lfp_sale"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["lfp_sale"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["lfp_sale"][field])): + del request_init["lfp_sale"][field][i][subfield] + else: + del request_init["lfp_sale"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpsale.LfpSale( + name="name_value", + target_account=1491, + store_code="store_code_value", + offer_id="offer_id_value", + region_code="region_code_value", + content_language="content_language_value", + gtin="gtin_value", + quantity=895, + uid="uid_value", + feed_label="feed_label_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lfpsale.LfpSale.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_lfp_sale(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, lfpsale.LfpSale) + assert response.name == "name_value" + assert response.target_account == 1491 + assert response.store_code == "store_code_value" + assert response.offer_id == "offer_id_value" + assert response.region_code == "region_code_value" + assert response.content_language == "content_language_value" + assert response.gtin == "gtin_value" + assert response.quantity == 895 + assert response.uid == "uid_value" + assert response.feed_label == "feed_label_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_insert_lfp_sale_rest_interceptors(null_interceptor): + transport = transports.LfpSaleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.LfpSaleServiceRestInterceptor(), + ) + client = LfpSaleServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LfpSaleServiceRestInterceptor, "post_insert_lfp_sale" + ) as post, mock.patch.object( + transports.LfpSaleServiceRestInterceptor, "pre_insert_lfp_sale" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = lfpsale.InsertLfpSaleRequest.pb(lfpsale.InsertLfpSaleRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = lfpsale.LfpSale.to_json(lfpsale.LfpSale()) + req.return_value.content = return_value + + request = lfpsale.InsertLfpSaleRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = lfpsale.LfpSale() + + client.insert_lfp_sale( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_lfp_sale_empty_call_rest(): + client = LfpSaleServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_lfp_sale), "__call__") as call: + client.insert_lfp_sale(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpsale.InsertLfpSaleRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2474,36 +2543,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = LfpSaleServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = LfpSaleServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = LfpSaleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py index 871ddd443b2e..76127f5386b9 100644 --- a/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py +++ b/packages/google-shopping-merchant-lfp/tests/unit/gapic/merchant_lfp_v1beta/test_lfp_store_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_lfp_v1beta.services.lfp_store_service import ( LfpStoreServiceAsyncClient, LfpStoreServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_lfp_v1beta.types import lfpstore +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1200,25 +1223,6 @@ def test_get_lfp_store(request_type, transport: str = "grpc"): assert response.matching_state_hint == "matching_state_hint_value" -def test_get_lfp_store_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_lfp_store), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_lfp_store() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.GetLfpStoreRequest() - - def test_get_lfp_store_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1282,39 +1286,6 @@ def test_get_lfp_store_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_lfp_store_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_lfp_store), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - lfpstore.LfpStore( - name="name_value", - target_account=1491, - store_code="store_code_value", - store_address="store_address_value", - store_name="store_name_value", - phone_number="phone_number_value", - website_uri="website_uri_value", - gcid_category=["gcid_category_value"], - place_id="place_id_value", - matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, - matching_state_hint="matching_state_hint_value", - ) - ) - response = await client.get_lfp_store() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.GetLfpStoreRequest() - - @pytest.mark.asyncio async def test_get_lfp_store_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1323,7 +1294,7 @@ async def test_get_lfp_store_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1362,7 +1333,7 @@ async def test_get_lfp_store_async( transport: str = "grpc_asyncio", request_type=lfpstore.GetLfpStoreRequest ): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1451,7 +1422,7 @@ def test_get_lfp_store_field_headers(): @pytest.mark.asyncio async def test_get_lfp_store_field_headers_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1519,7 +1490,7 @@ def test_get_lfp_store_flattened_error(): @pytest.mark.asyncio async def test_get_lfp_store_flattened_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1546,7 +1517,7 @@ async def test_get_lfp_store_flattened_async(): @pytest.mark.asyncio async def test_get_lfp_store_flattened_error_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1617,25 +1588,6 @@ def test_insert_lfp_store(request_type, transport: str = "grpc"): assert response.matching_state_hint == "matching_state_hint_value" -def test_insert_lfp_store_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.insert_lfp_store), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_lfp_store() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.InsertLfpStoreRequest() - - def test_insert_lfp_store_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1701,39 +1653,6 @@ def test_insert_lfp_store_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_lfp_store_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.insert_lfp_store), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - lfpstore.LfpStore( - name="name_value", - target_account=1491, - store_code="store_code_value", - store_address="store_address_value", - store_name="store_name_value", - phone_number="phone_number_value", - website_uri="website_uri_value", - gcid_category=["gcid_category_value"], - place_id="place_id_value", - matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, - matching_state_hint="matching_state_hint_value", - ) - ) - response = await client.insert_lfp_store() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.InsertLfpStoreRequest() - - @pytest.mark.asyncio async def test_insert_lfp_store_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1742,7 +1661,7 @@ async def test_insert_lfp_store_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1781,7 +1700,7 @@ async def test_insert_lfp_store_async( transport: str = "grpc_asyncio", request_type=lfpstore.InsertLfpStoreRequest ): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1870,7 +1789,7 @@ def test_insert_lfp_store_field_headers(): @pytest.mark.asyncio async def test_insert_lfp_store_field_headers_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1943,7 +1862,7 @@ def test_insert_lfp_store_flattened_error(): @pytest.mark.asyncio async def test_insert_lfp_store_flattened_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1974,7 +1893,7 @@ async def test_insert_lfp_store_flattened_async(): @pytest.mark.asyncio async def test_insert_lfp_store_flattened_error_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2020,25 +1939,6 @@ def test_delete_lfp_store(request_type, transport: str = "grpc"): assert response is None -def test_delete_lfp_store_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_lfp_store), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_lfp_store() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.DeleteLfpStoreRequest() - - def test_delete_lfp_store_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2104,25 +2004,6 @@ def test_delete_lfp_store_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_lfp_store_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_lfp_store), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_lfp_store() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.DeleteLfpStoreRequest() - - @pytest.mark.asyncio async def test_delete_lfp_store_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2131,7 +2012,7 @@ async def test_delete_lfp_store_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2170,7 +2051,7 @@ async def test_delete_lfp_store_async( transport: str = "grpc_asyncio", request_type=lfpstore.DeleteLfpStoreRequest ): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2231,7 +2112,7 @@ def test_delete_lfp_store_field_headers(): @pytest.mark.asyncio async def test_delete_lfp_store_field_headers_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2299,7 +2180,7 @@ def test_delete_lfp_store_flattened_error(): @pytest.mark.asyncio async def test_delete_lfp_store_flattened_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2326,7 +2207,7 @@ async def test_delete_lfp_store_flattened_async(): @pytest.mark.asyncio async def test_delete_lfp_store_flattened_error_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2374,25 +2255,6 @@ def test_list_lfp_stores(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_lfp_stores_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_lfp_stores), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_lfp_stores() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.ListLfpStoresRequest() - - def test_list_lfp_stores_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2458,29 +2320,6 @@ def test_list_lfp_stores_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_lfp_stores_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_lfp_stores), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - lfpstore.ListLfpStoresResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_lfp_stores() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == lfpstore.ListLfpStoresRequest() - - @pytest.mark.asyncio async def test_list_lfp_stores_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2489,7 +2328,7 @@ async def test_list_lfp_stores_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2528,7 +2367,7 @@ async def test_list_lfp_stores_async( transport: str = "grpc_asyncio", request_type=lfpstore.ListLfpStoresRequest ): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2594,7 +2433,7 @@ def test_list_lfp_stores_field_headers(): @pytest.mark.asyncio async def test_list_lfp_stores_field_headers_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2664,7 +2503,7 @@ def test_list_lfp_stores_flattened_error(): @pytest.mark.asyncio async def test_list_lfp_stores_flattened_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2693,7 +2532,7 @@ async def test_list_lfp_stores_flattened_async(): @pytest.mark.asyncio async def test_list_lfp_stores_flattened_error_async(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2803,7 +2642,7 @@ def test_list_lfp_stores_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_lfp_stores_async_pager(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2853,7 +2692,7 @@ async def test_list_lfp_stores_async_pager(): @pytest.mark.asyncio async def test_list_lfp_stores_async_pages(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2899,69 +2738,6 @@ async def test_list_lfp_stores_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - lfpstore.GetLfpStoreRequest, - dict, - ], -) -def test_get_lfp_store_rest(request_type): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/lfpStores/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpstore.LfpStore( - name="name_value", - target_account=1491, - store_code="store_code_value", - store_address="store_address_value", - store_name="store_name_value", - phone_number="phone_number_value", - website_uri="website_uri_value", - gcid_category=["gcid_category_value"], - place_id="place_id_value", - matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, - matching_state_hint="matching_state_hint_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = lfpstore.LfpStore.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_lfp_store(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, lfpstore.LfpStore) - assert response.name == "name_value" - assert response.target_account == 1491 - assert response.store_code == "store_code_value" - assert response.store_address == "store_address_value" - assert response.store_name == "store_name_value" - assert response.phone_number == "phone_number_value" - assert response.website_uri == "website_uri_value" - assert response.gcid_category == ["gcid_category_value"] - assert response.place_id == "place_id_value" - assert ( - response.matching_state - == lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED - ) - assert response.matching_state_hint == "matching_state_hint_value" - - def test_get_lfp_store_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3079,85 +2855,8 @@ def test_get_lfp_store_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_lfp_store_rest_interceptors(null_interceptor): - transport = transports.LfpStoreServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LfpStoreServiceRestInterceptor(), - ) - client = LfpStoreServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LfpStoreServiceRestInterceptor, "post_get_lfp_store" - ) as post, mock.patch.object( - transports.LfpStoreServiceRestInterceptor, "pre_get_lfp_store" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = lfpstore.GetLfpStoreRequest.pb(lfpstore.GetLfpStoreRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = lfpstore.LfpStore.to_json(lfpstore.LfpStore()) - - request = lfpstore.GetLfpStoreRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = lfpstore.LfpStore() - - client.get_lfp_store( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_lfp_store_rest_bad_request( - transport: str = "rest", request_type=lfpstore.GetLfpStoreRequest -): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/lfpStores/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_lfp_store(request) - - -def test_get_lfp_store_rest_flattened(): - client = LfpStoreServiceClient( +def test_get_lfp_store_rest_flattened(): + client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) @@ -3212,155 +2911,6 @@ def test_get_lfp_store_rest_flattened_error(transport: str = "rest"): ) -def test_get_lfp_store_rest_error(): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - lfpstore.InsertLfpStoreRequest, - dict, - ], -) -def test_insert_lfp_store_rest(request_type): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["lfp_store"] = { - "name": "name_value", - "target_account": 1491, - "store_code": "store_code_value", - "store_address": "store_address_value", - "store_name": "store_name_value", - "phone_number": "phone_number_value", - "website_uri": "website_uri_value", - "gcid_category": ["gcid_category_value1", "gcid_category_value2"], - "place_id": "place_id_value", - "matching_state": 1, - "matching_state_hint": "matching_state_hint_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = lfpstore.InsertLfpStoreRequest.meta.fields["lfp_store"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["lfp_store"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["lfp_store"][field])): - del request_init["lfp_store"][field][i][subfield] - else: - del request_init["lfp_store"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpstore.LfpStore( - name="name_value", - target_account=1491, - store_code="store_code_value", - store_address="store_address_value", - store_name="store_name_value", - phone_number="phone_number_value", - website_uri="website_uri_value", - gcid_category=["gcid_category_value"], - place_id="place_id_value", - matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, - matching_state_hint="matching_state_hint_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = lfpstore.LfpStore.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_lfp_store(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, lfpstore.LfpStore) - assert response.name == "name_value" - assert response.target_account == 1491 - assert response.store_code == "store_code_value" - assert response.store_address == "store_address_value" - assert response.store_name == "store_name_value" - assert response.phone_number == "phone_number_value" - assert response.website_uri == "website_uri_value" - assert response.gcid_category == ["gcid_category_value"] - assert response.place_id == "place_id_value" - assert ( - response.matching_state - == lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED - ) - assert response.matching_state_hint == "matching_state_hint_value" - - def test_insert_lfp_store_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3491,93 +3041,16 @@ def test_insert_lfp_store_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_lfp_store_rest_interceptors(null_interceptor): - transport = transports.LfpStoreServiceRestTransport( +def test_insert_lfp_store_rest_flattened(): + client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LfpStoreServiceRestInterceptor(), + transport="rest", ) - client = LfpStoreServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LfpStoreServiceRestInterceptor, "post_insert_lfp_store" - ) as post, mock.patch.object( - transports.LfpStoreServiceRestInterceptor, "pre_insert_lfp_store" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = lfpstore.InsertLfpStoreRequest.pb(lfpstore.InsertLfpStoreRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = lfpstore.LfpStore.to_json(lfpstore.LfpStore()) - - request = lfpstore.InsertLfpStoreRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = lfpstore.LfpStore() - - client.insert_lfp_store( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_insert_lfp_store_rest_bad_request( - transport: str = "rest", request_type=lfpstore.InsertLfpStoreRequest -): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_lfp_store(request) - - -def test_insert_lfp_store_rest_flattened(): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpstore.LfpStore() + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpstore.LfpStore() # get arguments that satisfy an http rule for this method sample_request = {"parent": "accounts/sample1"} @@ -3627,47 +3100,6 @@ def test_insert_lfp_store_rest_flattened_error(transport: str = "rest"): ) -def test_insert_lfp_store_rest_error(): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - lfpstore.DeleteLfpStoreRequest, - dict, - ], -) -def test_delete_lfp_store_rest(request_type): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/lfpStores/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_lfp_store(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_lfp_store_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3786,77 +3218,6 @@ def test_delete_lfp_store_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_lfp_store_rest_interceptors(null_interceptor): - transport = transports.LfpStoreServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.LfpStoreServiceRestInterceptor(), - ) - client = LfpStoreServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.LfpStoreServiceRestInterceptor, "pre_delete_lfp_store" - ) as pre: - pre.assert_not_called() - pb_message = lfpstore.DeleteLfpStoreRequest.pb(lfpstore.DeleteLfpStoreRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = lfpstore.DeleteLfpStoreRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_lfp_store( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_lfp_store_rest_bad_request( - transport: str = "rest", request_type=lfpstore.DeleteLfpStoreRequest -): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/lfpStores/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_lfp_store(request) - - def test_delete_lfp_store_rest_flattened(): client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3911,52 +3272,6 @@ def test_delete_lfp_store_rest_flattened_error(transport: str = "rest"): ) -def test_delete_lfp_store_rest_error(): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - lfpstore.ListLfpStoresRequest, - dict, - ], -) -def test_list_lfp_stores_rest(request_type): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpstore.ListLfpStoresResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = lfpstore.ListLfpStoresResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_lfp_stores(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListLfpStoresPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_lfp_stores_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4111,6 +3426,977 @@ def test_list_lfp_stores_rest_unset_required_fields(): ) +def test_list_lfp_stores_rest_flattened(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpstore.ListLfpStoresResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = lfpstore.ListLfpStoresResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_lfp_stores(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/lfp/v1beta/{parent=accounts/*}/lfpStores" % client.transport._host, + args[1], + ) + + +def test_list_lfp_stores_rest_flattened_error(transport: str = "rest"): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_lfp_stores( + lfpstore.ListLfpStoresRequest(), + parent="parent_value", + ) + + +def test_list_lfp_stores_rest_pager(transport: str = "rest"): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + lfpstore.ListLfpStoresResponse( + lfp_stores=[ + lfpstore.LfpStore(), + lfpstore.LfpStore(), + lfpstore.LfpStore(), + ], + next_page_token="abc", + ), + lfpstore.ListLfpStoresResponse( + lfp_stores=[], + next_page_token="def", + ), + lfpstore.ListLfpStoresResponse( + lfp_stores=[ + lfpstore.LfpStore(), + ], + next_page_token="ghi", + ), + lfpstore.ListLfpStoresResponse( + lfp_stores=[ + lfpstore.LfpStore(), + lfpstore.LfpStore(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(lfpstore.ListLfpStoresResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_lfp_stores(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, lfpstore.LfpStore) for i in results) + + pages = list(client.list_lfp_stores(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.LfpStoreServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.LfpStoreServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LfpStoreServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.LfpStoreServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = LfpStoreServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = LfpStoreServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.LfpStoreServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LfpStoreServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.LfpStoreServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = LfpStoreServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.LfpStoreServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.LfpStoreServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.LfpStoreServiceGrpcTransport, + transports.LfpStoreServiceGrpcAsyncIOTransport, + transports.LfpStoreServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = LfpStoreServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_lfp_store_empty_call_grpc(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_lfp_store), "__call__") as call: + call.return_value = lfpstore.LfpStore() + client.get_lfp_store(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.GetLfpStoreRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_lfp_store_empty_call_grpc(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_lfp_store), "__call__") as call: + call.return_value = lfpstore.LfpStore() + client.insert_lfp_store(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.InsertLfpStoreRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_lfp_store_empty_call_grpc(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_lfp_store), "__call__") as call: + call.return_value = None + client.delete_lfp_store(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.DeleteLfpStoreRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_lfp_stores_empty_call_grpc(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_lfp_stores), "__call__") as call: + call.return_value = lfpstore.ListLfpStoresResponse() + client.list_lfp_stores(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.ListLfpStoresRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = LfpStoreServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = LfpStoreServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_lfp_store_empty_call_grpc_asyncio(): + client = LfpStoreServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_lfp_store), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + lfpstore.LfpStore( + name="name_value", + target_account=1491, + store_code="store_code_value", + store_address="store_address_value", + store_name="store_name_value", + phone_number="phone_number_value", + website_uri="website_uri_value", + gcid_category=["gcid_category_value"], + place_id="place_id_value", + matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, + matching_state_hint="matching_state_hint_value", + ) + ) + await client.get_lfp_store(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.GetLfpStoreRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_lfp_store_empty_call_grpc_asyncio(): + client = LfpStoreServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_lfp_store), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + lfpstore.LfpStore( + name="name_value", + target_account=1491, + store_code="store_code_value", + store_address="store_address_value", + store_name="store_name_value", + phone_number="phone_number_value", + website_uri="website_uri_value", + gcid_category=["gcid_category_value"], + place_id="place_id_value", + matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, + matching_state_hint="matching_state_hint_value", + ) + ) + await client.insert_lfp_store(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.InsertLfpStoreRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_lfp_store_empty_call_grpc_asyncio(): + client = LfpStoreServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_lfp_store), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_lfp_store(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.DeleteLfpStoreRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_lfp_stores_empty_call_grpc_asyncio(): + client = LfpStoreServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_lfp_stores), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + lfpstore.ListLfpStoresResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_lfp_stores(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.ListLfpStoresRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = LfpStoreServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_lfp_store_rest_bad_request(request_type=lfpstore.GetLfpStoreRequest): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/lfpStores/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_lfp_store(request) + + +@pytest.mark.parametrize( + "request_type", + [ + lfpstore.GetLfpStoreRequest, + dict, + ], +) +def test_get_lfp_store_rest_call_success(request_type): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/lfpStores/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpstore.LfpStore( + name="name_value", + target_account=1491, + store_code="store_code_value", + store_address="store_address_value", + store_name="store_name_value", + phone_number="phone_number_value", + website_uri="website_uri_value", + gcid_category=["gcid_category_value"], + place_id="place_id_value", + matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, + matching_state_hint="matching_state_hint_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lfpstore.LfpStore.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_lfp_store(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, lfpstore.LfpStore) + assert response.name == "name_value" + assert response.target_account == 1491 + assert response.store_code == "store_code_value" + assert response.store_address == "store_address_value" + assert response.store_name == "store_name_value" + assert response.phone_number == "phone_number_value" + assert response.website_uri == "website_uri_value" + assert response.gcid_category == ["gcid_category_value"] + assert response.place_id == "place_id_value" + assert ( + response.matching_state + == lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED + ) + assert response.matching_state_hint == "matching_state_hint_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_lfp_store_rest_interceptors(null_interceptor): + transport = transports.LfpStoreServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.LfpStoreServiceRestInterceptor(), + ) + client = LfpStoreServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LfpStoreServiceRestInterceptor, "post_get_lfp_store" + ) as post, mock.patch.object( + transports.LfpStoreServiceRestInterceptor, "pre_get_lfp_store" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = lfpstore.GetLfpStoreRequest.pb(lfpstore.GetLfpStoreRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = lfpstore.LfpStore.to_json(lfpstore.LfpStore()) + req.return_value.content = return_value + + request = lfpstore.GetLfpStoreRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = lfpstore.LfpStore() + + client.get_lfp_store( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_insert_lfp_store_rest_bad_request(request_type=lfpstore.InsertLfpStoreRequest): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_lfp_store(request) + + +@pytest.mark.parametrize( + "request_type", + [ + lfpstore.InsertLfpStoreRequest, + dict, + ], +) +def test_insert_lfp_store_rest_call_success(request_type): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["lfp_store"] = { + "name": "name_value", + "target_account": 1491, + "store_code": "store_code_value", + "store_address": "store_address_value", + "store_name": "store_name_value", + "phone_number": "phone_number_value", + "website_uri": "website_uri_value", + "gcid_category": ["gcid_category_value1", "gcid_category_value2"], + "place_id": "place_id_value", + "matching_state": 1, + "matching_state_hint": "matching_state_hint_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = lfpstore.InsertLfpStoreRequest.meta.fields["lfp_store"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["lfp_store"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["lfp_store"][field])): + del request_init["lfp_store"][field][i][subfield] + else: + del request_init["lfp_store"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpstore.LfpStore( + name="name_value", + target_account=1491, + store_code="store_code_value", + store_address="store_address_value", + store_name="store_name_value", + phone_number="phone_number_value", + website_uri="website_uri_value", + gcid_category=["gcid_category_value"], + place_id="place_id_value", + matching_state=lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED, + matching_state_hint="matching_state_hint_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lfpstore.LfpStore.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_lfp_store(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, lfpstore.LfpStore) + assert response.name == "name_value" + assert response.target_account == 1491 + assert response.store_code == "store_code_value" + assert response.store_address == "store_address_value" + assert response.store_name == "store_name_value" + assert response.phone_number == "phone_number_value" + assert response.website_uri == "website_uri_value" + assert response.gcid_category == ["gcid_category_value"] + assert response.place_id == "place_id_value" + assert ( + response.matching_state + == lfpstore.LfpStore.StoreMatchingState.STORE_MATCHING_STATE_MATCHED + ) + assert response.matching_state_hint == "matching_state_hint_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_insert_lfp_store_rest_interceptors(null_interceptor): + transport = transports.LfpStoreServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.LfpStoreServiceRestInterceptor(), + ) + client = LfpStoreServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LfpStoreServiceRestInterceptor, "post_insert_lfp_store" + ) as post, mock.patch.object( + transports.LfpStoreServiceRestInterceptor, "pre_insert_lfp_store" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = lfpstore.InsertLfpStoreRequest.pb(lfpstore.InsertLfpStoreRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = lfpstore.LfpStore.to_json(lfpstore.LfpStore()) + req.return_value.content = return_value + + request = lfpstore.InsertLfpStoreRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = lfpstore.LfpStore() + + client.insert_lfp_store( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_lfp_store_rest_bad_request(request_type=lfpstore.DeleteLfpStoreRequest): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/lfpStores/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_lfp_store(request) + + +@pytest.mark.parametrize( + "request_type", + [ + lfpstore.DeleteLfpStoreRequest, + dict, + ], +) +def test_delete_lfp_store_rest_call_success(request_type): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/lfpStores/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_lfp_store(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_lfp_store_rest_interceptors(null_interceptor): + transport = transports.LfpStoreServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.LfpStoreServiceRestInterceptor(), + ) + client = LfpStoreServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.LfpStoreServiceRestInterceptor, "pre_delete_lfp_store" + ) as pre: + pre.assert_not_called() + pb_message = lfpstore.DeleteLfpStoreRequest.pb(lfpstore.DeleteLfpStoreRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = lfpstore.DeleteLfpStoreRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_lfp_store( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_list_lfp_stores_rest_bad_request(request_type=lfpstore.ListLfpStoresRequest): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_lfp_stores(request) + + +@pytest.mark.parametrize( + "request_type", + [ + lfpstore.ListLfpStoresRequest, + dict, + ], +) +def test_list_lfp_stores_rest_call_success(request_type): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lfpstore.ListLfpStoresResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lfpstore.ListLfpStoresResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_lfp_stores(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListLfpStoresPager) + assert response.next_page_token == "next_page_token_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) def test_list_lfp_stores_rest_interceptors(null_interceptor): transport = transports.LfpStoreServiceRestTransport( @@ -4120,6 +4406,7 @@ def test_list_lfp_stores_rest_interceptors(null_interceptor): else transports.LfpStoreServiceRestInterceptor(), ) client = LfpStoreServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -4139,12 +4426,12 @@ def test_list_lfp_stores_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = lfpstore.ListLfpStoresResponse.to_json( + return_value = lfpstore.ListLfpStoresResponse.to_json( lfpstore.ListLfpStoresResponse() ) + req.return_value.content = return_value request = lfpstore.ListLfpStoresRequest() metadata = [ @@ -4166,251 +4453,91 @@ def test_list_lfp_stores_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_lfp_stores_rest_bad_request( - transport: str = "rest", request_type=lfpstore.ListLfpStoresRequest -): +def test_initialize_client_w_rest(): client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_lfp_stores(request) + assert client is not None -def test_list_lfp_stores_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_lfp_store_empty_call_rest(): client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = lfpstore.ListLfpStoresResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = lfpstore.ListLfpStoresResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_lfp_stores(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/lfp/v1beta/{parent=accounts/*}/lfpStores" % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_lfp_store), "__call__") as call: + client.get_lfp_store(request=None) -def test_list_lfp_stores_rest_flattened_error(transport: str = "rest"): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.GetLfpStoreRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_lfp_stores( - lfpstore.ListLfpStoresRequest(), - parent="parent_value", - ) + assert args[0] == request_msg -def test_list_lfp_stores_rest_pager(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_lfp_store_empty_call_rest(): client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - lfpstore.ListLfpStoresResponse( - lfp_stores=[ - lfpstore.LfpStore(), - lfpstore.LfpStore(), - lfpstore.LfpStore(), - ], - next_page_token="abc", - ), - lfpstore.ListLfpStoresResponse( - lfp_stores=[], - next_page_token="def", - ), - lfpstore.ListLfpStoresResponse( - lfp_stores=[ - lfpstore.LfpStore(), - ], - next_page_token="ghi", - ), - lfpstore.ListLfpStoresResponse( - lfp_stores=[ - lfpstore.LfpStore(), - lfpstore.LfpStore(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(lfpstore.ListLfpStoresResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_lfp_stores(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, lfpstore.LfpStore) for i in results) - - pages = list(client.list_lfp_stores(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.LfpStoreServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_lfp_store), "__call__") as call: + client.insert_lfp_store(request=None) - # It is an error to provide a credentials file and a transport instance. - transport = transports.LfpStoreServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = LfpStoreServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.InsertLfpStoreRequest() - # It is an error to provide an api_key and a transport instance. - transport = transports.LfpStoreServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = LfpStoreServiceClient( - client_options=options, - transport=transport, - ) + assert args[0] == request_msg - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = LfpStoreServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - # It is an error to provide scopes and a transport instance. - transport = transports.LfpStoreServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_lfp_store_empty_call_rest(): + client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = LfpStoreServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_lfp_store), "__call__") as call: + client.delete_lfp_store(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.LfpStoreServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = LfpStoreServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.DeleteLfpStoreRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.LfpStoreServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.LfpStoreServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_lfp_stores_empty_call_rest(): + client = LfpStoreServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.LfpStoreServiceGrpcTransport, - transports.LfpStoreServiceGrpcAsyncIOTransport, - transports.LfpStoreServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_lfp_stores), "__call__") as call: + client.list_lfp_stores(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lfpstore.ListLfpStoresRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = LfpStoreServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -5000,36 +5127,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = LfpStoreServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = LfpStoreServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = LfpStoreServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/README.rst b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/README.rst new file mode 100644 index 000000000000..e82a831890a4 --- /dev/null +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`NotificationsApiServiceTransport` is the ABC for all transports. +- public child `NotificationsApiServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `NotificationsApiServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseNotificationsApiServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `NotificationsApiServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py index 3688003b828c..fce42dccdbf0 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -420,35 +424,44 @@ def list_notification_subscriptions( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_notification_subscription: gapic_v1.method_async.wrap_method( + self.get_notification_subscription: self._wrap_method( self.get_notification_subscription, default_timeout=None, client_info=client_info, ), - self.create_notification_subscription: gapic_v1.method_async.wrap_method( + self.create_notification_subscription: self._wrap_method( self.create_notification_subscription, default_timeout=None, client_info=client_info, ), - self.update_notification_subscription: gapic_v1.method_async.wrap_method( + self.update_notification_subscription: self._wrap_method( self.update_notification_subscription, default_timeout=None, client_info=client_info, ), - self.delete_notification_subscription: gapic_v1.method_async.wrap_method( + self.delete_notification_subscription: self._wrap_method( self.delete_notification_subscription, default_timeout=None, client_info=client_info, ), - self.list_notification_subscriptions: gapic_v1.method_async.wrap_method( + self.list_notification_subscriptions: self._wrap_method( self.list_notification_subscriptions, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("NotificationsApiServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py index ac7e87c230e6..61128c9b493e 100644 --- a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_notifications_v1beta.types import notificationsapi + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseNotificationsApiServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_notifications_v1beta.types import notificationsapi - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import NotificationsApiServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -232,8 +228,8 @@ class NotificationsApiServiceRestStub: _interceptor: NotificationsApiServiceRestInterceptor -class NotificationsApiServiceRestTransport(NotificationsApiServiceTransport): - """REST backend transport for NotificationsApiService. +class NotificationsApiServiceRestTransport(_BaseNotificationsApiServiceRestTransport): + """REST backend synchronous transport for NotificationsApiService. Service to manage notification subscriptions for merchants @@ -242,7 +238,6 @@ class NotificationsApiServiceRestTransport(NotificationsApiServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -296,21 +291,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -321,19 +307,37 @@ def __init__( self._interceptor = interceptor or NotificationsApiServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _CreateNotificationSubscription(NotificationsApiServiceRestStub): + class _CreateNotificationSubscription( + _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription, + NotificationsApiServiceRestStub, + ): def __hash__(self): - return hash("CreateNotificationSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "NotificationsApiServiceRestTransport.CreateNotificationSubscription" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -364,49 +368,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/notifications/v1beta/{parent=accounts/*}/notificationsubscriptions", - "body": "notification_subscription", - }, - ] + http_options = ( + _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription._get_http_options() + ) request, metadata = self._interceptor.pre_create_notification_subscription( request, metadata ) - pb_request = notificationsapi.CreateNotificationSubscriptionRequest.pb( - request + transcoded_request = _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = NotificationsApiServiceRestTransport._CreateNotificationSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -422,19 +411,36 @@ def __call__( resp = self._interceptor.post_create_notification_subscription(resp) return resp - class _DeleteNotificationSubscription(NotificationsApiServiceRestStub): + class _DeleteNotificationSubscription( + _BaseNotificationsApiServiceRestTransport._BaseDeleteNotificationSubscription, + NotificationsApiServiceRestStub, + ): def __hash__(self): - return hash("DeleteNotificationSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "NotificationsApiServiceRestTransport.DeleteNotificationSubscription" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -458,42 +464,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/notifications/v1beta/{name=accounts/*/notificationsubscriptions/*}", - }, - ] + http_options = ( + _BaseNotificationsApiServiceRestTransport._BaseDeleteNotificationSubscription._get_http_options() + ) request, metadata = self._interceptor.pre_delete_notification_subscription( request, metadata ) - pb_request = notificationsapi.DeleteNotificationSubscriptionRequest.pb( - request + transcoded_request = _BaseNotificationsApiServiceRestTransport._BaseDeleteNotificationSubscription._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseNotificationsApiServiceRestTransport._BaseDeleteNotificationSubscription._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = NotificationsApiServiceRestTransport._DeleteNotificationSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -501,19 +494,36 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetNotificationSubscription(NotificationsApiServiceRestStub): + class _GetNotificationSubscription( + _BaseNotificationsApiServiceRestTransport._BaseGetNotificationSubscription, + NotificationsApiServiceRestStub, + ): def __hash__(self): - return hash("GetNotificationSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "NotificationsApiServiceRestTransport.GetNotificationSubscription" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -544,40 +554,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/notifications/v1beta/{name=accounts/*/notificationsubscriptions/*}", - }, - ] + http_options = ( + _BaseNotificationsApiServiceRestTransport._BaseGetNotificationSubscription._get_http_options() + ) request, metadata = self._interceptor.pre_get_notification_subscription( request, metadata ) - pb_request = notificationsapi.GetNotificationSubscriptionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseNotificationsApiServiceRestTransport._BaseGetNotificationSubscription._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseNotificationsApiServiceRestTransport._BaseGetNotificationSubscription._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = NotificationsApiServiceRestTransport._GetNotificationSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -593,19 +592,36 @@ def __call__( resp = self._interceptor.post_get_notification_subscription(resp) return resp - class _ListNotificationSubscriptions(NotificationsApiServiceRestStub): + class _ListNotificationSubscriptions( + _BaseNotificationsApiServiceRestTransport._BaseListNotificationSubscriptions, + NotificationsApiServiceRestStub, + ): def __hash__(self): - return hash("ListNotificationSubscriptions") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "NotificationsApiServiceRestTransport.ListNotificationSubscriptions" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -635,42 +651,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/notifications/v1beta/{parent=accounts/*}/notificationsubscriptions", - }, - ] + http_options = ( + _BaseNotificationsApiServiceRestTransport._BaseListNotificationSubscriptions._get_http_options() + ) request, metadata = self._interceptor.pre_list_notification_subscriptions( request, metadata ) - pb_request = notificationsapi.ListNotificationSubscriptionsRequest.pb( - request + transcoded_request = _BaseNotificationsApiServiceRestTransport._BaseListNotificationSubscriptions._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseNotificationsApiServiceRestTransport._BaseListNotificationSubscriptions._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = NotificationsApiServiceRestTransport._ListNotificationSubscriptions._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -686,19 +689,37 @@ def __call__( resp = self._interceptor.post_list_notification_subscriptions(resp) return resp - class _UpdateNotificationSubscription(NotificationsApiServiceRestStub): + class _UpdateNotificationSubscription( + _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription, + NotificationsApiServiceRestStub, + ): def __hash__(self): - return hash("UpdateNotificationSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + return hash( + "NotificationsApiServiceRestTransport.UpdateNotificationSubscription" + ) - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -729,49 +750,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/notifications/v1beta/{notification_subscription.name=accounts/*/notificationsubscriptions/*}", - "body": "notification_subscription", - }, - ] + http_options = ( + _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription._get_http_options() + ) request, metadata = self._interceptor.pre_update_notification_subscription( request, metadata ) - pb_request = notificationsapi.UpdateNotificationSubscriptionRequest.pb( - request + transcoded_request = _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription._get_transcoded_request( + http_options, request ) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = NotificationsApiServiceRestTransport._UpdateNotificationSubscription._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest_base.py b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest_base.py new file mode 100644 index 000000000000..631d288fcdd6 --- /dev/null +++ b/packages/google-shopping-merchant-notifications/google/shopping/merchant_notifications_v1beta/services/notifications_api_service/transports/rest_base.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_notifications_v1beta.types import notificationsapi + +from .base import DEFAULT_CLIENT_INFO, NotificationsApiServiceTransport + + +class _BaseNotificationsApiServiceRestTransport(NotificationsApiServiceTransport): + """Base REST backend transport for NotificationsApiService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateNotificationSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/notifications/v1beta/{parent=accounts/*}/notificationsubscriptions", + "body": "notification_subscription", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = notificationsapi.CreateNotificationSubscriptionRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNotificationsApiServiceRestTransport._BaseCreateNotificationSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteNotificationSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/notifications/v1beta/{name=accounts/*/notificationsubscriptions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = notificationsapi.DeleteNotificationSubscriptionRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNotificationsApiServiceRestTransport._BaseDeleteNotificationSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetNotificationSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/notifications/v1beta/{name=accounts/*/notificationsubscriptions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = notificationsapi.GetNotificationSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNotificationsApiServiceRestTransport._BaseGetNotificationSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListNotificationSubscriptions: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/notifications/v1beta/{parent=accounts/*}/notificationsubscriptions", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = notificationsapi.ListNotificationSubscriptionsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNotificationsApiServiceRestTransport._BaseListNotificationSubscriptions._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateNotificationSubscription: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/notifications/v1beta/{notification_subscription.name=accounts/*/notificationsubscriptions/*}", + "body": "notification_subscription", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = notificationsapi.UpdateNotificationSubscriptionRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseNotificationsApiServiceRestTransport._BaseUpdateNotificationSubscription._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseNotificationsApiServiceRestTransport",) diff --git a/packages/google-shopping-merchant-notifications/setup.py b/packages/google-shopping-merchant-notifications/setup.py index 5b968b1d5347..c86790568d0e 100644 --- a/packages/google-shopping-merchant-notifications/setup.py +++ b/packages/google-shopping-merchant-notifications/setup.py @@ -51,6 +51,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-notifications" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -93,6 +94,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py b/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py index 7e6fe3b73458..e6dd003ff60b 100644 --- a/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py +++ b/packages/google-shopping-merchant-notifications/tests/unit/gapic/merchant_notifications_v1beta/test_notifications_api_service.py @@ -22,19 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import field_mask_pb2 # type: ignore +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + from google.shopping.merchant_notifications_v1beta.services.notifications_api_service import ( NotificationsApiServiceAsyncClient, NotificationsApiServiceClient, @@ -53,10 +62,24 @@ from google.shopping.merchant_notifications_v1beta.types import notificationsapi +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1236,27 +1259,6 @@ def test_get_notification_subscription(request_type, transport: str = "grpc"): assert response.call_back_uri == "call_back_uri_value" -def test_get_notification_subscription_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_notification_subscription), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.GetNotificationSubscriptionRequest() - - def test_get_notification_subscription_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1327,33 +1329,6 @@ def test_get_notification_subscription_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_notification_subscription_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_notification_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - notificationsapi.NotificationSubscription( - name="name_value", - registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, - call_back_uri="call_back_uri_value", - ) - ) - response = await client.get_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.GetNotificationSubscriptionRequest() - - @pytest.mark.asyncio async def test_get_notification_subscription_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1362,7 +1337,7 @@ async def test_get_notification_subscription_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1402,7 +1377,7 @@ async def test_get_notification_subscription_async( request_type=notificationsapi.GetNotificationSubscriptionRequest, ): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1479,7 +1454,7 @@ def test_get_notification_subscription_field_headers(): @pytest.mark.asyncio async def test_get_notification_subscription_field_headers_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1553,7 +1528,7 @@ def test_get_notification_subscription_flattened_error(): @pytest.mark.asyncio async def test_get_notification_subscription_flattened_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1584,7 +1559,7 @@ async def test_get_notification_subscription_flattened_async(): @pytest.mark.asyncio async def test_get_notification_subscription_flattened_error_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1642,27 +1617,6 @@ def test_create_notification_subscription(request_type, transport: str = "grpc") assert response.call_back_uri == "call_back_uri_value" -def test_create_notification_subscription_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_notification_subscription), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.CreateNotificationSubscriptionRequest() - - def test_create_notification_subscription_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1733,33 +1687,6 @@ def test_create_notification_subscription_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_notification_subscription_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_notification_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - notificationsapi.NotificationSubscription( - name="name_value", - registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, - call_back_uri="call_back_uri_value", - ) - ) - response = await client.create_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.CreateNotificationSubscriptionRequest() - - @pytest.mark.asyncio async def test_create_notification_subscription_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1768,7 +1695,7 @@ async def test_create_notification_subscription_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1808,7 +1735,7 @@ async def test_create_notification_subscription_async( request_type=notificationsapi.CreateNotificationSubscriptionRequest, ): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1885,7 +1812,7 @@ def test_create_notification_subscription_field_headers(): @pytest.mark.asyncio async def test_create_notification_subscription_field_headers_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1968,7 +1895,7 @@ def test_create_notification_subscription_flattened_error(): @pytest.mark.asyncio async def test_create_notification_subscription_flattened_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2005,7 +1932,7 @@ async def test_create_notification_subscription_flattened_async(): @pytest.mark.asyncio async def test_create_notification_subscription_flattened_error_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2066,27 +1993,6 @@ def test_update_notification_subscription(request_type, transport: str = "grpc") assert response.call_back_uri == "call_back_uri_value" -def test_update_notification_subscription_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_notification_subscription), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.UpdateNotificationSubscriptionRequest() - - def test_update_notification_subscription_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2153,33 +2059,6 @@ def test_update_notification_subscription_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_notification_subscription_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_notification_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - notificationsapi.NotificationSubscription( - name="name_value", - registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, - call_back_uri="call_back_uri_value", - ) - ) - response = await client.update_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.UpdateNotificationSubscriptionRequest() - - @pytest.mark.asyncio async def test_update_notification_subscription_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2188,7 +2067,7 @@ async def test_update_notification_subscription_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2228,7 +2107,7 @@ async def test_update_notification_subscription_async( request_type=notificationsapi.UpdateNotificationSubscriptionRequest, ): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2305,7 +2184,7 @@ def test_update_notification_subscription_field_headers(): @pytest.mark.asyncio async def test_update_notification_subscription_field_headers_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2388,7 +2267,7 @@ def test_update_notification_subscription_flattened_error(): @pytest.mark.asyncio async def test_update_notification_subscription_flattened_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2425,7 +2304,7 @@ async def test_update_notification_subscription_flattened_async(): @pytest.mark.asyncio async def test_update_notification_subscription_flattened_error_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2475,27 +2354,6 @@ def test_delete_notification_subscription(request_type, transport: str = "grpc") assert response is None -def test_delete_notification_subscription_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_notification_subscription), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.DeleteNotificationSubscriptionRequest() - - def test_delete_notification_subscription_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2566,27 +2424,6 @@ def test_delete_notification_subscription_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_notification_subscription_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_notification_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_notification_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.DeleteNotificationSubscriptionRequest() - - @pytest.mark.asyncio async def test_delete_notification_subscription_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2595,7 +2432,7 @@ async def test_delete_notification_subscription_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2635,7 +2472,7 @@ async def test_delete_notification_subscription_async( request_type=notificationsapi.DeleteNotificationSubscriptionRequest, ): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2700,7 +2537,7 @@ def test_delete_notification_subscription_field_headers(): @pytest.mark.asyncio async def test_delete_notification_subscription_field_headers_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2772,7 +2609,7 @@ def test_delete_notification_subscription_flattened_error(): @pytest.mark.asyncio async def test_delete_notification_subscription_flattened_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2801,7 +2638,7 @@ async def test_delete_notification_subscription_flattened_async(): @pytest.mark.asyncio async def test_delete_notification_subscription_flattened_error_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2851,27 +2688,6 @@ def test_list_notification_subscriptions(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_notification_subscriptions_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notification_subscriptions), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_notification_subscriptions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.ListNotificationSubscriptionsRequest() - - def test_list_notification_subscriptions_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2944,31 +2760,6 @@ def test_list_notification_subscriptions_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_notification_subscriptions_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notification_subscriptions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - notificationsapi.ListNotificationSubscriptionsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_notification_subscriptions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == notificationsapi.ListNotificationSubscriptionsRequest() - - @pytest.mark.asyncio async def test_list_notification_subscriptions_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2977,7 +2768,7 @@ async def test_list_notification_subscriptions_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3017,7 +2808,7 @@ async def test_list_notification_subscriptions_async( request_type=notificationsapi.ListNotificationSubscriptionsRequest, ): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3087,7 +2878,7 @@ def test_list_notification_subscriptions_field_headers(): @pytest.mark.asyncio async def test_list_notification_subscriptions_field_headers_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3161,7 +2952,7 @@ def test_list_notification_subscriptions_flattened_error(): @pytest.mark.asyncio async def test_list_notification_subscriptions_flattened_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3192,7 +2983,7 @@ async def test_list_notification_subscriptions_flattened_async(): @pytest.mark.asyncio async def test_list_notification_subscriptions_flattened_error_async(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3310,7 +3101,7 @@ def test_list_notification_subscriptions_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_notification_subscriptions_async_pager(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3364,7 +3155,7 @@ async def test_list_notification_subscriptions_async_pager(): @pytest.mark.asyncio async def test_list_notification_subscriptions_async_pages(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3412,62 +3203,14 @@ async def test_list_notification_subscriptions_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - notificationsapi.GetNotificationSubscriptionRequest, - dict, - ], -) -def test_get_notification_subscription_rest(request_type): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = notificationsapi.NotificationSubscription( - name="name_value", - registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, - call_back_uri="call_back_uri_value", - all_managed_accounts=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = notificationsapi.NotificationSubscription.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_notification_subscription(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, notificationsapi.NotificationSubscription) - assert response.name == "name_value" - assert ( - response.registered_event - == notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE - ) - assert response.call_back_uri == "call_back_uri_value" - - -def test_get_notification_subscription_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +def test_get_notification_subscription_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) # Should wrap all calls on client creation assert wrapper_fn.call_count > 0 @@ -3586,90 +3329,6 @@ def test_get_notification_subscription_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_notification_subscription_rest_interceptors(null_interceptor): - transport = transports.NotificationsApiServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.NotificationsApiServiceRestInterceptor(), - ) - client = NotificationsApiServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "post_get_notification_subscription", - ) as post, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "pre_get_notification_subscription", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = notificationsapi.GetNotificationSubscriptionRequest.pb( - notificationsapi.GetNotificationSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = notificationsapi.NotificationSubscription.to_json( - notificationsapi.NotificationSubscription() - ) - - request = notificationsapi.GetNotificationSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = notificationsapi.NotificationSubscription() - - client.get_notification_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_notification_subscription_rest_bad_request( - transport: str = "rest", - request_type=notificationsapi.GetNotificationSubscriptionRequest, -): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_notification_subscription(request) - - def test_get_notification_subscription_rest_flattened(): client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3727,140 +3386,6 @@ def test_get_notification_subscription_rest_flattened_error(transport: str = "re ) -def test_get_notification_subscription_rest_error(): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - notificationsapi.CreateNotificationSubscriptionRequest, - dict, - ], -) -def test_create_notification_subscription_rest(request_type): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["notification_subscription"] = { - "all_managed_accounts": True, - "target_account": "target_account_value", - "name": "name_value", - "registered_event": 1, - "call_back_uri": "call_back_uri_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = notificationsapi.CreateNotificationSubscriptionRequest.meta.fields[ - "notification_subscription" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init[ - "notification_subscription" - ].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range( - 0, len(request_init["notification_subscription"][field]) - ): - del request_init["notification_subscription"][field][i][subfield] - else: - del request_init["notification_subscription"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = notificationsapi.NotificationSubscription( - name="name_value", - registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, - call_back_uri="call_back_uri_value", - all_managed_accounts=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = notificationsapi.NotificationSubscription.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_notification_subscription(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, notificationsapi.NotificationSubscription) - assert response.name == "name_value" - assert ( - response.registered_event - == notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE - ) - assert response.call_back_uri == "call_back_uri_value" - - def test_create_notification_subscription_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3996,90 +3521,6 @@ def test_create_notification_subscription_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_notification_subscription_rest_interceptors(null_interceptor): - transport = transports.NotificationsApiServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.NotificationsApiServiceRestInterceptor(), - ) - client = NotificationsApiServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "post_create_notification_subscription", - ) as post, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "pre_create_notification_subscription", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = notificationsapi.CreateNotificationSubscriptionRequest.pb( - notificationsapi.CreateNotificationSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = notificationsapi.NotificationSubscription.to_json( - notificationsapi.NotificationSubscription() - ) - - request = notificationsapi.CreateNotificationSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = notificationsapi.NotificationSubscription() - - client.create_notification_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_notification_subscription_rest_bad_request( - transport: str = "rest", - request_type=notificationsapi.CreateNotificationSubscriptionRequest, -): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_notification_subscription(request) - - def test_create_notification_subscription_rest_flattened(): client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4143,144 +3584,6 @@ def test_create_notification_subscription_rest_flattened_error(transport: str = ) -def test_create_notification_subscription_rest_error(): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - notificationsapi.UpdateNotificationSubscriptionRequest, - dict, - ], -) -def test_update_notification_subscription_rest(request_type): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "notification_subscription": { - "name": "accounts/sample1/notificationsubscriptions/sample2" - } - } - request_init["notification_subscription"] = { - "all_managed_accounts": True, - "target_account": "target_account_value", - "name": "accounts/sample1/notificationsubscriptions/sample2", - "registered_event": 1, - "call_back_uri": "call_back_uri_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = notificationsapi.UpdateNotificationSubscriptionRequest.meta.fields[ - "notification_subscription" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init[ - "notification_subscription" - ].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range( - 0, len(request_init["notification_subscription"][field]) - ): - del request_init["notification_subscription"][field][i][subfield] - else: - del request_init["notification_subscription"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = notificationsapi.NotificationSubscription( - name="name_value", - registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, - call_back_uri="call_back_uri_value", - all_managed_accounts=True, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = notificationsapi.NotificationSubscription.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_notification_subscription(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, notificationsapi.NotificationSubscription) - assert response.name == "name_value" - assert ( - response.registered_event - == notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE - ) - assert response.call_back_uri == "call_back_uri_value" - - def test_update_notification_subscription_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4407,104 +3710,16 @@ def test_update_notification_subscription_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_notification_subscription_rest_interceptors(null_interceptor): - transport = transports.NotificationsApiServiceRestTransport( +def test_update_notification_subscription_rest_flattened(): + client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.NotificationsApiServiceRestInterceptor(), + transport="rest", ) - client = NotificationsApiServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "post_update_notification_subscription", - ) as post, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "pre_update_notification_subscription", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = notificationsapi.UpdateNotificationSubscriptionRequest.pb( - notificationsapi.UpdateNotificationSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = notificationsapi.NotificationSubscription.to_json( - notificationsapi.NotificationSubscription() - ) - - request = notificationsapi.UpdateNotificationSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = notificationsapi.NotificationSubscription() - - client.update_notification_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_notification_subscription_rest_bad_request( - transport: str = "rest", - request_type=notificationsapi.UpdateNotificationSubscriptionRequest, -): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = { - "notification_subscription": { - "name": "accounts/sample1/notificationsubscriptions/sample2" - } - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_notification_subscription(request) - - -def test_update_notification_subscription_rest_flattened(): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = notificationsapi.NotificationSubscription() + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notificationsapi.NotificationSubscription() # get arguments that satisfy an http rule for this method sample_request = { @@ -4562,47 +3777,6 @@ def test_update_notification_subscription_rest_flattened_error(transport: str = ) -def test_update_notification_subscription_rest_error(): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - notificationsapi.DeleteNotificationSubscriptionRequest, - dict, - ], -) -def test_delete_notification_subscription_rest(request_type): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_notification_subscription(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_notification_subscription_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -4726,81 +3900,6 @@ def test_delete_notification_subscription_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_notification_subscription_rest_interceptors(null_interceptor): - transport = transports.NotificationsApiServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.NotificationsApiServiceRestInterceptor(), - ) - client = NotificationsApiServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "pre_delete_notification_subscription", - ) as pre: - pre.assert_not_called() - pb_message = notificationsapi.DeleteNotificationSubscriptionRequest.pb( - notificationsapi.DeleteNotificationSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = notificationsapi.DeleteNotificationSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_notification_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_notification_subscription_rest_bad_request( - transport: str = "rest", - request_type=notificationsapi.DeleteNotificationSubscriptionRequest, -): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_notification_subscription(request) - - def test_delete_notification_subscription_rest_flattened(): client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4856,54 +3955,6 @@ def test_delete_notification_subscription_rest_flattened_error(transport: str = ) -def test_delete_notification_subscription_rest_error(): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - notificationsapi.ListNotificationSubscriptionsRequest, - dict, - ], -) -def test_list_notification_subscriptions_rest(request_type): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = notificationsapi.ListNotificationSubscriptionsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = notificationsapi.ListNotificationSubscriptionsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_notification_subscriptions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNotificationSubscriptionsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_notification_subscriptions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -5047,56 +4098,1072 @@ def test_list_notification_subscriptions_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_notification_subscriptions_rest_interceptors(null_interceptor): - transport = transports.NotificationsApiServiceRestTransport( +def test_list_notification_subscriptions_rest_flattened(): + client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.NotificationsApiServiceRestInterceptor(), + transport="rest", ) - client = NotificationsApiServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "post_list_notification_subscriptions", - ) as post, mock.patch.object( - transports.NotificationsApiServiceRestInterceptor, - "pre_list_notification_subscriptions", - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = notificationsapi.ListNotificationSubscriptionsRequest.pb( - notificationsapi.ListNotificationSubscriptionsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - notificationsapi.ListNotificationSubscriptionsResponse.to_json( - notificationsapi.ListNotificationSubscriptionsResponse() - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notificationsapi.ListNotificationSubscriptionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", ) + mock_args.update(sample_request) - request = notificationsapi.ListNotificationSubscriptionsRequest() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = notificationsapi.ListNotificationSubscriptionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_notification_subscriptions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/notifications/v1beta/{parent=accounts/*}/notificationsubscriptions" + % client.transport._host, + args[1], + ) + + +def test_list_notification_subscriptions_rest_flattened_error(transport: str = "rest"): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_notification_subscriptions( + notificationsapi.ListNotificationSubscriptionsRequest(), + parent="parent_value", + ) + + +def test_list_notification_subscriptions_rest_pager(transport: str = "rest"): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + notificationsapi.ListNotificationSubscriptionsResponse( + notification_subscriptions=[ + notificationsapi.NotificationSubscription(), + notificationsapi.NotificationSubscription(), + notificationsapi.NotificationSubscription(), + ], + next_page_token="abc", + ), + notificationsapi.ListNotificationSubscriptionsResponse( + notification_subscriptions=[], + next_page_token="def", + ), + notificationsapi.ListNotificationSubscriptionsResponse( + notification_subscriptions=[ + notificationsapi.NotificationSubscription(), + ], + next_page_token="ghi", + ), + notificationsapi.ListNotificationSubscriptionsResponse( + notification_subscriptions=[ + notificationsapi.NotificationSubscription(), + notificationsapi.NotificationSubscription(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + notificationsapi.ListNotificationSubscriptionsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_notification_subscriptions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, notificationsapi.NotificationSubscription) for i in results + ) + + pages = list( + client.list_notification_subscriptions(request=sample_request).pages + ) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.NotificationsApiServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.NotificationsApiServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = NotificationsApiServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.NotificationsApiServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = NotificationsApiServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = NotificationsApiServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.NotificationsApiServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = NotificationsApiServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.NotificationsApiServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = NotificationsApiServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.NotificationsApiServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.NotificationsApiServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.NotificationsApiServiceGrpcTransport, + transports.NotificationsApiServiceGrpcAsyncIOTransport, + transports.NotificationsApiServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = NotificationsApiServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_notification_subscription_empty_call_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_subscription), "__call__" + ) as call: + call.return_value = notificationsapi.NotificationSubscription() + client.get_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.GetNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_notification_subscription_empty_call_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_subscription), "__call__" + ) as call: + call.return_value = notificationsapi.NotificationSubscription() + client.create_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.CreateNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_notification_subscription_empty_call_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_subscription), "__call__" + ) as call: + call.return_value = notificationsapi.NotificationSubscription() + client.update_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.UpdateNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_notification_subscription_empty_call_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_subscription), "__call__" + ) as call: + call.return_value = None + client.delete_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.DeleteNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_notification_subscriptions_empty_call_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_subscriptions), "__call__" + ) as call: + call.return_value = notificationsapi.ListNotificationSubscriptionsResponse() + client.list_notification_subscriptions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.ListNotificationSubscriptionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = NotificationsApiServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = NotificationsApiServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_notification_subscription_empty_call_grpc_asyncio(): + client = NotificationsApiServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notificationsapi.NotificationSubscription( + name="name_value", + registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, + call_back_uri="call_back_uri_value", + ) + ) + await client.get_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.GetNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_notification_subscription_empty_call_grpc_asyncio(): + client = NotificationsApiServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notificationsapi.NotificationSubscription( + name="name_value", + registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, + call_back_uri="call_back_uri_value", + ) + ) + await client.create_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.CreateNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_notification_subscription_empty_call_grpc_asyncio(): + client = NotificationsApiServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notificationsapi.NotificationSubscription( + name="name_value", + registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, + call_back_uri="call_back_uri_value", + ) + ) + await client.update_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.UpdateNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_notification_subscription_empty_call_grpc_asyncio(): + client = NotificationsApiServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_notification_subscription(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.DeleteNotificationSubscriptionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_notification_subscriptions_empty_call_grpc_asyncio(): + client = NotificationsApiServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notificationsapi.ListNotificationSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_notification_subscriptions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.ListNotificationSubscriptionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = NotificationsApiServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_notification_subscription_rest_bad_request( + request_type=notificationsapi.GetNotificationSubscriptionRequest, +): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_notification_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + notificationsapi.GetNotificationSubscriptionRequest, + dict, + ], +) +def test_get_notification_subscription_rest_call_success(request_type): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notificationsapi.NotificationSubscription( + name="name_value", + registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, + call_back_uri="call_back_uri_value", + all_managed_accounts=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = notificationsapi.NotificationSubscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_notification_subscription(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, notificationsapi.NotificationSubscription) + assert response.name == "name_value" + assert ( + response.registered_event + == notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE + ) + assert response.call_back_uri == "call_back_uri_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_notification_subscription_rest_interceptors(null_interceptor): + transport = transports.NotificationsApiServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NotificationsApiServiceRestInterceptor(), + ) + client = NotificationsApiServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "post_get_notification_subscription", + ) as post, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "pre_get_notification_subscription", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = notificationsapi.GetNotificationSubscriptionRequest.pb( + notificationsapi.GetNotificationSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = notificationsapi.NotificationSubscription.to_json( + notificationsapi.NotificationSubscription() + ) + req.return_value.content = return_value + + request = notificationsapi.GetNotificationSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = notificationsapi.NotificationSubscription() + + client.get_notification_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_notification_subscription_rest_bad_request( + request_type=notificationsapi.CreateNotificationSubscriptionRequest, +): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_notification_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + notificationsapi.CreateNotificationSubscriptionRequest, + dict, + ], +) +def test_create_notification_subscription_rest_call_success(request_type): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["notification_subscription"] = { + "all_managed_accounts": True, + "target_account": "target_account_value", + "name": "name_value", + "registered_event": 1, + "call_back_uri": "call_back_uri_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = notificationsapi.CreateNotificationSubscriptionRequest.meta.fields[ + "notification_subscription" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "notification_subscription" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range( + 0, len(request_init["notification_subscription"][field]) + ): + del request_init["notification_subscription"][field][i][subfield] + else: + del request_init["notification_subscription"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notificationsapi.NotificationSubscription( + name="name_value", + registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, + call_back_uri="call_back_uri_value", + all_managed_accounts=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = notificationsapi.NotificationSubscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_notification_subscription(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, notificationsapi.NotificationSubscription) + assert response.name == "name_value" + assert ( + response.registered_event + == notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE + ) + assert response.call_back_uri == "call_back_uri_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_notification_subscription_rest_interceptors(null_interceptor): + transport = transports.NotificationsApiServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NotificationsApiServiceRestInterceptor(), + ) + client = NotificationsApiServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "post_create_notification_subscription", + ) as post, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "pre_create_notification_subscription", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = notificationsapi.CreateNotificationSubscriptionRequest.pb( + notificationsapi.CreateNotificationSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = notificationsapi.NotificationSubscription.to_json( + notificationsapi.NotificationSubscription() + ) + req.return_value.content = return_value + + request = notificationsapi.CreateNotificationSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = notificationsapi.NotificationSubscription() + + client.create_notification_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_notification_subscription_rest_bad_request( + request_type=notificationsapi.UpdateNotificationSubscriptionRequest, +): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "notification_subscription": { + "name": "accounts/sample1/notificationsubscriptions/sample2" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_notification_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + notificationsapi.UpdateNotificationSubscriptionRequest, + dict, + ], +) +def test_update_notification_subscription_rest_call_success(request_type): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "notification_subscription": { + "name": "accounts/sample1/notificationsubscriptions/sample2" + } + } + request_init["notification_subscription"] = { + "all_managed_accounts": True, + "target_account": "target_account_value", + "name": "accounts/sample1/notificationsubscriptions/sample2", + "registered_event": 1, + "call_back_uri": "call_back_uri_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = notificationsapi.UpdateNotificationSubscriptionRequest.meta.fields[ + "notification_subscription" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "notification_subscription" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range( + 0, len(request_init["notification_subscription"][field]) + ): + del request_init["notification_subscription"][field][i][subfield] + else: + del request_init["notification_subscription"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notificationsapi.NotificationSubscription( + name="name_value", + registered_event=notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE, + call_back_uri="call_back_uri_value", + all_managed_accounts=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = notificationsapi.NotificationSubscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_notification_subscription(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, notificationsapi.NotificationSubscription) + assert response.name == "name_value" + assert ( + response.registered_event + == notificationsapi.NotificationSubscription.NotificationEventType.PRODUCT_STATUS_CHANGE + ) + assert response.call_back_uri == "call_back_uri_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_notification_subscription_rest_interceptors(null_interceptor): + transport = transports.NotificationsApiServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NotificationsApiServiceRestInterceptor(), + ) + client = NotificationsApiServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "post_update_notification_subscription", + ) as post, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "pre_update_notification_subscription", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = notificationsapi.UpdateNotificationSubscriptionRequest.pb( + notificationsapi.UpdateNotificationSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = notificationsapi.NotificationSubscription.to_json( + notificationsapi.NotificationSubscription() + ) + req.return_value.content = return_value + + request = notificationsapi.UpdateNotificationSubscriptionRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = notificationsapi.ListNotificationSubscriptionsResponse() + post.return_value = notificationsapi.NotificationSubscription() - client.list_notification_subscriptions( + client.update_notification_subscription( request, metadata=[ ("key", "val"), @@ -5108,15 +5175,119 @@ def test_list_notification_subscriptions_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_notification_subscriptions_rest_bad_request( - transport: str = "rest", - request_type=notificationsapi.ListNotificationSubscriptionsRequest, +def test_delete_notification_subscription_rest_bad_request( + request_type=notificationsapi.DeleteNotificationSubscriptionRequest, ): client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_notification_subscription(request) + + +@pytest.mark.parametrize( + "request_type", + [ + notificationsapi.DeleteNotificationSubscriptionRequest, + dict, + ], +) +def test_delete_notification_subscription_rest_call_success(request_type): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/notificationsubscriptions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_notification_subscription(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_notification_subscription_rest_interceptors(null_interceptor): + transport = transports.NotificationsApiServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.NotificationsApiServiceRestInterceptor(), ) + client = NotificationsApiServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "pre_delete_notification_subscription", + ) as pre: + pre.assert_not_called() + pb_message = notificationsapi.DeleteNotificationSubscriptionRequest.pb( + notificationsapi.DeleteNotificationSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = notificationsapi.DeleteNotificationSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_notification_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + +def test_list_notification_subscriptions_rest_bad_request( + request_type=notificationsapi.ListNotificationSubscriptionsRequest, +): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) # send a request that will satisfy transcoding request_init = {"parent": "accounts/sample1"} request = request_type(**request_init) @@ -5126,244 +5297,231 @@ def test_list_notification_subscriptions_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.list_notification_subscriptions(request) -def test_list_notification_subscriptions_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + notificationsapi.ListNotificationSubscriptionsRequest, + dict, + ], +) +def test_list_notification_subscriptions_rest_call_success(request_type): client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = notificationsapi.ListNotificationSubscriptionsResponse() + return_value = notificationsapi.ListNotificationSubscriptionsResponse( + next_page_token="next_page_token_value", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", + # Convert return value to protobuf type + return_value = notificationsapi.ListNotificationSubscriptionsResponse.pb( + return_value ) - mock_args.update(sample_request) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_notification_subscriptions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotificationSubscriptionsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_notification_subscriptions_rest_interceptors(null_interceptor): + transport = transports.NotificationsApiServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.NotificationsApiServiceRestInterceptor(), + ) + client = NotificationsApiServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "post_list_notification_subscriptions", + ) as post, mock.patch.object( + transports.NotificationsApiServiceRestInterceptor, + "pre_list_notification_subscriptions", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = notificationsapi.ListNotificationSubscriptionsRequest.pb( + notificationsapi.ListNotificationSubscriptionsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = notificationsapi.ListNotificationSubscriptionsResponse.pb( - return_value + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = notificationsapi.ListNotificationSubscriptionsResponse.to_json( + notificationsapi.ListNotificationSubscriptionsResponse() ) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + req.return_value.content = return_value - client.list_notification_subscriptions(**mock_args) + request = notificationsapi.ListNotificationSubscriptionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = notificationsapi.ListNotificationSubscriptionsResponse() - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/notifications/v1beta/{parent=accounts/*}/notificationsubscriptions" - % client.transport._host, - args[1], + client.list_notification_subscriptions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() + -def test_list_notification_subscriptions_rest_flattened_error(transport: str = "rest"): +def test_initialize_client_w_rest(): client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_notification_subscriptions( - notificationsapi.ListNotificationSubscriptionsRequest(), - parent="parent_value", - ) + assert client is not None -def test_list_notification_subscriptions_rest_pager(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_notification_subscription_empty_call_rest(): client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - notificationsapi.ListNotificationSubscriptionsResponse( - notification_subscriptions=[ - notificationsapi.NotificationSubscription(), - notificationsapi.NotificationSubscription(), - notificationsapi.NotificationSubscription(), - ], - next_page_token="abc", - ), - notificationsapi.ListNotificationSubscriptionsResponse( - notification_subscriptions=[], - next_page_token="def", - ), - notificationsapi.ListNotificationSubscriptionsResponse( - notification_subscriptions=[ - notificationsapi.NotificationSubscription(), - ], - next_page_token="ghi", - ), - notificationsapi.ListNotificationSubscriptionsResponse( - notification_subscriptions=[ - notificationsapi.NotificationSubscription(), - notificationsapi.NotificationSubscription(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - notificationsapi.ListNotificationSubscriptionsResponse.to_json(x) - for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_notification_subscriptions(request=sample_request) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_subscription), "__call__" + ) as call: + client.get_notification_subscription(request=None) - results = list(pager) - assert len(results) == 6 - assert all( - isinstance(i, notificationsapi.NotificationSubscription) for i in results - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.GetNotificationSubscriptionRequest() - pages = list( - client.list_notification_subscriptions(request=sample_request).pages - ) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + assert args[0] == request_msg -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.NotificationsApiServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_notification_subscription_empty_call_rest(): + client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.NotificationsApiServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = NotificationsApiServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_subscription), "__call__" + ) as call: + client.create_notification_subscription(request=None) - # It is an error to provide an api_key and a transport instance. - transport = transports.NotificationsApiServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = NotificationsApiServiceClient( - client_options=options, - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.CreateNotificationSubscriptionRequest() - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = NotificationsApiServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + assert args[0] == request_msg - # It is an error to provide scopes and a transport instance. - transport = transports.NotificationsApiServiceGrpcTransport( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_notification_subscription_empty_call_rest(): + client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = NotificationsApiServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_subscription), "__call__" + ) as call: + client.update_notification_subscription(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.NotificationsApiServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = NotificationsApiServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.UpdateNotificationSubscriptionRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.NotificationsApiServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.NotificationsApiServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_notification_subscription_empty_call_rest(): + client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_subscription), "__call__" + ) as call: + client.delete_notification_subscription(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.NotificationsApiServiceGrpcTransport, - transports.NotificationsApiServiceGrpcAsyncIOTransport, - transports.NotificationsApiServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.DeleteNotificationSubscriptionRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = NotificationsApiServiceClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_notification_subscriptions_empty_call_rest(): + client = NotificationsApiServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_subscriptions), "__call__" + ) as call: + client.list_notification_subscriptions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = notificationsapi.ListNotificationSubscriptionsRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -5960,36 +6118,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = NotificationsApiServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = NotificationsApiServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = NotificationsApiServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/README.rst b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/README.rst new file mode 100644 index 000000000000..fa031e4be3c9 --- /dev/null +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ProductInputsServiceTransport` is the ABC for all transports. +- public child `ProductInputsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ProductInputsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseProductInputsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ProductInputsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/grpc_asyncio.py index baa48ff8b70e..27866595f4d4 100644 --- a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -310,20 +314,29 @@ def delete_product_input( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.insert_product_input: gapic_v1.method_async.wrap_method( + self.insert_product_input: self._wrap_method( self.insert_product_input, default_timeout=None, client_info=client_info, ), - self.delete_product_input: gapic_v1.method_async.wrap_method( + self.delete_product_input: self._wrap_method( self.delete_product_input, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("ProductInputsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest.py index f5d9521f55b8..728fa2bcdb9f 100644 --- a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest.py +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_products_v1beta.types import productinputs + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseProductInputsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from google.shopping.merchant_products_v1beta.types import productinputs - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import ProductInputsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -126,8 +122,8 @@ class ProductInputsServiceRestStub: _interceptor: ProductInputsServiceRestInterceptor -class ProductInputsServiceRestTransport(ProductInputsServiceTransport): - """REST backend transport for ProductInputsService. +class ProductInputsServiceRestTransport(_BaseProductInputsServiceRestTransport): + """REST backend synchronous transport for ProductInputsService. Service to use ProductInput resource. This service works for products with online channel only. @@ -137,7 +133,6 @@ class ProductInputsServiceRestTransport(ProductInputsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -191,21 +186,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -216,21 +202,34 @@ def __init__( self._interceptor = interceptor or ProductInputsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _DeleteProductInput(ProductInputsServiceRestStub): + class _DeleteProductInput( + _BaseProductInputsServiceRestTransport._BaseDeleteProductInput, + ProductInputsServiceRestStub, + ): def __hash__(self): - return hash("DeleteProductInput") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "dataSource": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProductInputsServiceRestTransport.DeleteProductInput") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -253,40 +252,31 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/products/v1beta/{name=accounts/*/productInputs/*}", - }, - ] + http_options = ( + _BaseProductInputsServiceRestTransport._BaseDeleteProductInput._get_http_options() + ) request, metadata = self._interceptor.pre_delete_product_input( request, metadata ) - pb_request = productinputs.DeleteProductInputRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseProductInputsServiceRestTransport._BaseDeleteProductInput._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProductInputsServiceRestTransport._BaseDeleteProductInput._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ( + ProductInputsServiceRestTransport._DeleteProductInput._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -294,21 +284,35 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _InsertProductInput(ProductInputsServiceRestStub): + class _InsertProductInput( + _BaseProductInputsServiceRestTransport._BaseInsertProductInput, + ProductInputsServiceRestStub, + ): def __hash__(self): - return hash("InsertProductInput") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "dataSource": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProductInputsServiceRestTransport.InsertProductInput") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -361,47 +365,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/products/v1beta/{parent=accounts/*}/productInputs:insert", - "body": "product_input", - }, - ] + http_options = ( + _BaseProductInputsServiceRestTransport._BaseInsertProductInput._get_http_options() + ) request, metadata = self._interceptor.pre_insert_product_input( request, metadata ) - pb_request = productinputs.InsertProductInputRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseProductInputsServiceRestTransport._BaseInsertProductInput._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseProductInputsServiceRestTransport._BaseInsertProductInput._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProductInputsServiceRestTransport._BaseInsertProductInput._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ( + ProductInputsServiceRestTransport._InsertProductInput._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest_base.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest_base.py new file mode 100644 index 000000000000..d20a5d6bdb99 --- /dev/null +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/product_inputs_service/transports/rest_base.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.shopping.merchant_products_v1beta.types import productinputs + +from .base import DEFAULT_CLIENT_INFO, ProductInputsServiceTransport + + +class _BaseProductInputsServiceRestTransport(ProductInputsServiceTransport): + """Base REST backend transport for ProductInputsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseDeleteProductInput: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "dataSource": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/products/v1beta/{name=accounts/*/productInputs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = productinputs.DeleteProductInputRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProductInputsServiceRestTransport._BaseDeleteProductInput._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertProductInput: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "dataSource": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/products/v1beta/{parent=accounts/*}/productInputs:insert", + "body": "product_input", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = productinputs.InsertProductInputRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProductInputsServiceRestTransport._BaseInsertProductInput._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseProductInputsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/README.rst b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/README.rst new file mode 100644 index 000000000000..c1cbe3d98697 --- /dev/null +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ProductsServiceTransport` is the ABC for all transports. +- public child `ProductsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ProductsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseProductsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ProductsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/grpc_asyncio.py index 777f78d87850..e7c30db8e068 100644 --- a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -307,20 +311,29 @@ def list_products( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_product: gapic_v1.method_async.wrap_method( + self.get_product: self._wrap_method( self.get_product, default_timeout=None, client_info=client_info, ), - self.list_products: gapic_v1.method_async.wrap_method( + self.list_products: self._wrap_method( self.list_products, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("ProductsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest.py index c8996eaf4e1c..99b50e2d557b 100644 --- a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest.py +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_products_v1beta.types import products + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseProductsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_products_v1beta.types import products - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import ProductsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -133,8 +130,8 @@ class ProductsServiceRestStub: _interceptor: ProductsServiceRestInterceptor -class ProductsServiceRestTransport(ProductsServiceTransport): - """REST backend transport for ProductsService. +class ProductsServiceRestTransport(_BaseProductsServiceRestTransport): + """REST backend synchronous transport for ProductsService. Service to use Product resource. This service works for products with online channel only. @@ -144,7 +141,6 @@ class ProductsServiceRestTransport(ProductsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -198,21 +194,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -223,19 +210,33 @@ def __init__( self._interceptor = interceptor or ProductsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetProduct(ProductsServiceRestStub): + class _GetProduct( + _BaseProductsServiceRestTransport._BaseGetProduct, ProductsServiceRestStub + ): def __hash__(self): - return hash("GetProduct") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProductsServiceRestTransport.GetProduct") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -279,38 +280,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/products/v1beta/{name=accounts/*/products/*}", - }, - ] + http_options = ( + _BaseProductsServiceRestTransport._BaseGetProduct._get_http_options() + ) request, metadata = self._interceptor.pre_get_product(request, metadata) - pb_request = products.GetProductRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseProductsServiceRestTransport._BaseGetProduct._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProductsServiceRestTransport._BaseGetProduct._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ProductsServiceRestTransport._GetProduct._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -326,19 +316,33 @@ def __call__( resp = self._interceptor.post_get_product(resp) return resp - class _ListProducts(ProductsServiceRestStub): + class _ListProducts( + _BaseProductsServiceRestTransport._BaseListProducts, ProductsServiceRestStub + ): def __hash__(self): - return hash("ListProducts") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ProductsServiceRestTransport.ListProducts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -367,38 +371,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/products/v1beta/{parent=accounts/*}/products", - }, - ] + http_options = ( + _BaseProductsServiceRestTransport._BaseListProducts._get_http_options() + ) request, metadata = self._interceptor.pre_list_products(request, metadata) - pb_request = products.ListProductsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseProductsServiceRestTransport._BaseListProducts._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseProductsServiceRestTransport._BaseListProducts._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = ProductsServiceRestTransport._ListProducts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest_base.py b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest_base.py new file mode 100644 index 000000000000..deb8ddfe0928 --- /dev/null +++ b/packages/google-shopping-merchant-products/google/shopping/merchant_products_v1beta/services/products_service/transports/rest_base.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_products_v1beta.types import products + +from .base import DEFAULT_CLIENT_INFO, ProductsServiceTransport + + +class _BaseProductsServiceRestTransport(ProductsServiceTransport): + """Base REST backend transport for ProductsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetProduct: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/products/v1beta/{name=accounts/*/products/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = products.GetProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProductsServiceRestTransport._BaseGetProduct._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListProducts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/products/v1beta/{parent=accounts/*}/products", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = products.ListProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseProductsServiceRestTransport._BaseListProducts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseProductsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-products/setup.py b/packages/google-shopping-merchant-products/setup.py index 7edd0edd53d9..1af4ea8d2cf0 100644 --- a/packages/google-shopping-merchant-products/setup.py +++ b/packages/google-shopping-merchant-products/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-products" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_product_inputs_service.py b/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_product_inputs_service.py index d625be3942fc..27d40946c0dd 100644 --- a/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_product_inputs_service.py +++ b/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_product_inputs_service.py @@ -22,29 +22,38 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types from google.type import interval_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_products_v1beta.services.product_inputs_service import ( ProductInputsServiceAsyncClient, @@ -57,10 +66,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1240,27 +1263,6 @@ def test_insert_product_input(request_type, transport: str = "grpc"): assert response.version_number == 1518 -def test_insert_product_input_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_product_input), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == productinputs.InsertProductInputRequest() - - def test_insert_product_input_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1332,37 +1334,6 @@ def test_insert_product_input_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_product_input_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_product_input), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - productinputs.ProductInput( - name="name_value", - product="product_value", - channel=types.Channel.ChannelEnum.ONLINE, - offer_id="offer_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - version_number=1518, - ) - ) - response = await client.insert_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == productinputs.InsertProductInputRequest() - - @pytest.mark.asyncio async def test_insert_product_input_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1371,7 +1342,7 @@ async def test_insert_product_input_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1411,7 +1382,7 @@ async def test_insert_product_input_async( request_type=productinputs.InsertProductInputRequest, ): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1493,7 +1464,7 @@ def test_insert_product_input_field_headers(): @pytest.mark.asyncio async def test_insert_product_input_field_headers_async(): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1559,27 +1530,6 @@ def test_delete_product_input(request_type, transport: str = "grpc"): assert response is None -def test_delete_product_input_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_product_input), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == productinputs.DeleteProductInputRequest() - - def test_delete_product_input_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1651,27 +1601,6 @@ def test_delete_product_input_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_product_input_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_product_input), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_product_input() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == productinputs.DeleteProductInputRequest() - - @pytest.mark.asyncio async def test_delete_product_input_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1680,7 +1609,7 @@ async def test_delete_product_input_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1720,7 +1649,7 @@ async def test_delete_product_input_async( request_type=productinputs.DeleteProductInputRequest, ): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1785,7 +1714,7 @@ def test_delete_product_input_field_headers(): @pytest.mark.asyncio async def test_delete_product_input_field_headers_async(): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1857,7 +1786,7 @@ def test_delete_product_input_flattened_error(): @pytest.mark.asyncio async def test_delete_product_input_flattened_async(): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1886,7 +1815,7 @@ async def test_delete_product_input_flattened_async(): @pytest.mark.asyncio async def test_delete_product_input_flattened_error_async(): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1898,325 +1827,155 @@ async def test_delete_product_input_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - productinputs.InsertProductInputRequest, - dict, - ], -) -def test_insert_product_input_rest(request_type): +def test_insert_product_input_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.insert_product_input in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.insert_product_input + ] = mock_rpc + + request = {} + client.insert_product_input(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.insert_product_input(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_insert_product_input_rest_required_fields( + request_type=productinputs.InsertProductInputRequest, +): + transport_class = transports.ProductInputsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["data_source"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "dataSource" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).insert_product_input._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "dataSource" in jsonified_request + assert jsonified_request["dataSource"] == request_init["data_source"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["dataSource"] = "data_source_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).insert_product_input._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("data_source",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "dataSource" in jsonified_request + assert jsonified_request["dataSource"] == "data_source_value" + client = ProductInputsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) + request = request_type(**request_init) - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request_init["product_input"] = { - "name": "name_value", - "product": "product_value", - "channel": 1, - "offer_id": "offer_id_value", - "content_language": "content_language_value", - "feed_label": "feed_label_value", - "version_number": 1518, - "attributes": { - "identifier_exists": True, - "is_bundle": True, - "title": "title_value", - "description": "description_value", - "link": "link_value", - "mobile_link": "mobile_link_value", - "canonical_link": "canonical_link_value", - "image_link": "image_link_value", - "additional_image_links": [ - "additional_image_links_value1", - "additional_image_links_value2", - ], - "expiration_date": {"seconds": 751, "nanos": 543}, - "disclosure_date": {}, - "adult": True, - "age_group": "age_group_value", - "availability": "availability_value", - "availability_date": {}, - "brand": "brand_value", - "color": "color_value", - "condition": "condition_value", - "gender": "gender_value", - "google_product_category": "google_product_category_value", - "gtin": "gtin_value", - "item_group_id": "item_group_id_value", - "material": "material_value", - "mpn": "mpn_value", - "pattern": "pattern_value", - "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, - "installment": { - "months": 665, - "amount": {}, - "downpayment": {}, - "credit_type": "credit_type_value", - }, - "subscription_cost": {"period": 1, "period_length": 1380, "amount": {}}, - "loyalty_points": { - "name": "name_value", - "points_value": 1305, - "ratio": 0.543, - }, - "loyalty_programs": [ - { - "program_label": "program_label_value", - "tier_label": "tier_label_value", - "price": {}, - "cashback_for_future_use": {}, - "loyalty_points": 1546, - } - ], - "product_types": ["product_types_value1", "product_types_value2"], - "sale_price": {}, - "sale_price_effective_date": {"start_time": {}, "end_time": {}}, - "sell_on_google_quantity": 2470, - "product_height": {"value": 0.541, "unit": "unit_value"}, - "product_length": {}, - "product_width": {}, - "product_weight": {"value": 0.541, "unit": "unit_value"}, - "shipping": [ - { - "price": {}, - "country": "country_value", - "region": "region_value", - "service": "service_value", - "location_id": 1157, - "location_group_name": "location_group_name_value", - "postal_code": "postal_code_value", - "min_handling_time": 1782, - "max_handling_time": 1784, - "min_transit_time": 1718, - "max_transit_time": 1720, - } - ], - "free_shipping_threshold": [ - {"country": "country_value", "price_threshold": {}} - ], - "shipping_weight": {"value": 0.541, "unit": "unit_value"}, - "shipping_length": {"value": 0.541, "unit": "unit_value"}, - "shipping_width": {}, - "shipping_height": {}, - "max_handling_time": 1784, - "min_handling_time": 1782, - "shipping_label": "shipping_label_value", - "transit_time_label": "transit_time_label_value", - "size": "size_value", - "size_system": "size_system_value", - "size_types": ["size_types_value1", "size_types_value2"], - "taxes": [ - { - "rate": 0.428, - "country": "country_value", - "region": "region_value", - "tax_ship": True, - "location_id": 1157, - "postal_code": "postal_code_value", - } - ], - "tax_category": "tax_category_value", - "energy_efficiency_class": "energy_efficiency_class_value", - "min_energy_efficiency_class": "min_energy_efficiency_class_value", - "max_energy_efficiency_class": "max_energy_efficiency_class_value", - "unit_pricing_measure": {"value": 0.541, "unit": "unit_value"}, - "unit_pricing_base_measure": {"value": 541, "unit": "unit_value"}, - "multipack": 970, - "ads_grouping": "ads_grouping_value", - "ads_labels": ["ads_labels_value1", "ads_labels_value2"], - "ads_redirect": "ads_redirect_value", - "cost_of_goods_sold": {}, - "product_details": [ - { - "section_name": "section_name_value", - "attribute_name": "attribute_name_value", - "attribute_value": "attribute_value_value", - } - ], - "product_highlights": [ - "product_highlights_value1", - "product_highlights_value2", - ], - "display_ads_id": "display_ads_id_value", - "display_ads_similar_ids": [ - "display_ads_similar_ids_value1", - "display_ads_similar_ids_value2", - ], - "display_ads_title": "display_ads_title_value", - "display_ads_link": "display_ads_link_value", - "display_ads_value": 0.1801, - "promotion_ids": ["promotion_ids_value1", "promotion_ids_value2"], - "pickup_method": "pickup_method_value", - "pickup_sla": "pickup_sla_value", - "link_template": "link_template_value", - "mobile_link_template": "mobile_link_template_value", - "custom_label_0": "custom_label_0_value", - "custom_label_1": "custom_label_1_value", - "custom_label_2": "custom_label_2_value", - "custom_label_3": "custom_label_3_value", - "custom_label_4": "custom_label_4_value", - "included_destinations": [ - "included_destinations_value1", - "included_destinations_value2", - ], - "excluded_destinations": [ - "excluded_destinations_value1", - "excluded_destinations_value2", - ], - "shopping_ads_excluded_countries": [ - "shopping_ads_excluded_countries_value1", - "shopping_ads_excluded_countries_value2", - ], - "external_seller_id": "external_seller_id_value", - "pause": "pause_value", - "lifestyle_image_links": [ - "lifestyle_image_links_value1", - "lifestyle_image_links_value2", - ], - "cloud_export_additional_properties": [ - { - "property_name": "property_name_value", - "text_value": ["text_value_value1", "text_value_value2"], - "bool_value": True, - "int_value": [968, 969], - "float_value": [0.11710000000000001, 0.11720000000000001], - "min_value": 0.96, - "max_value": 0.962, - "unit_code": "unit_code_value", - } - ], - "virtual_model_link": "virtual_model_link_value", - "certifications": [ - { - "certification_authority": "certification_authority_value", - "certification_name": "certification_name_value", - "certification_code": "certification_code_value", - "certification_value": "certification_value_value", - } - ], - "structured_title": { - "digital_source_type": "digital_source_type_value", - "content": "content_value", - }, - "structured_description": { - "digital_source_type": "digital_source_type_value", - "content": "content_value", - }, - "auto_pricing_min_price": {}, - }, - "custom_attributes": [ - {"name": "name_value", "value": "value_value", "group_values": {}} - ], - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + # Designate an appropriate value for the returned response. + return_value = productinputs.ProductInput() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result - # Determine if the message type is proto-plus or protobuf - test_field = productinputs.InsertProductInputRequest.meta.fields["product_input"] + response_value = Response() + response_value.status_code = 200 - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + # Convert return value to protobuf type + return_value = productinputs.ProductInput.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields + response = client.insert_product_input(request) - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] + expected_params = [ + ( + "dataSource", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params - subfields_not_in_runtime = [] - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["product_input"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value +def test_insert_product_input_rest_unset_required_fields(): + transport = transports.ProductInputsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) + unset_fields = transport.insert_product_input._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("dataSource",)) + & set( + ( + "parent", + "productInput", + "dataSource", + ) + ) + ) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["product_input"][field])): - del request_init["product_input"][field][i][subfield] - else: - del request_init["product_input"][field][subfield] - request = request_type(**request_init) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = productinputs.ProductInput( - name="name_value", - product="product_value", - channel=types.Channel.ChannelEnum.ONLINE, - offer_id="offer_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - version_number=1518, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = productinputs.ProductInput.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_product_input(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, productinputs.ProductInput) - assert response.name == "name_value" - assert response.product == "product_value" - assert response.channel == types.Channel.ChannelEnum.ONLINE - assert response.offer_id == "offer_id_value" - assert response.content_language == "content_language_value" - assert response.feed_label == "feed_label_value" - assert response.version_number == 1518 - - -def test_insert_product_input_rest_use_cached_wrapped_rpc(): +def test_delete_product_input_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -2231,7 +1990,7 @@ def test_insert_product_input_rest_use_cached_wrapped_rpc(): # Ensure method has been cached assert ( - client._transport.insert_product_input in client._transport._wrapped_methods + client._transport.delete_product_input in client._transport._wrapped_methods ) # Replace cached wrapped function with mock @@ -2240,29 +1999,29 @@ def test_insert_product_input_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.insert_product_input + client._transport.delete_product_input ] = mock_rpc request = {} - client.insert_product_input(request) + client.delete_product_input(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.insert_product_input(request) + client.delete_product_input(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_insert_product_input_rest_required_fields( - request_type=productinputs.InsertProductInputRequest, +def test_delete_product_input_rest_required_fields( + request_type=productinputs.DeleteProductInputRequest, ): transport_class = transports.ProductInputsServiceRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request_init["data_source"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) @@ -2275,26 +2034,26 @@ def test_insert_product_input_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).insert_product_input._get_unset_required_fields(jsonified_request) + ).delete_product_input._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present assert "dataSource" in jsonified_request assert jsonified_request["dataSource"] == request_init["data_source"] - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" jsonified_request["dataSource"] = "data_source_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).insert_product_input._get_unset_required_fields(jsonified_request) + ).delete_product_input._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set(("data_source",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" assert "dataSource" in jsonified_request assert jsonified_request["dataSource"] == "data_source_value" @@ -2305,7 +2064,7 @@ def test_insert_product_input_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = productinputs.ProductInput() + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -2317,23 +2076,19 @@ def test_insert_product_input_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "delete", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = productinputs.ProductInput.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.insert_product_input(request) + response = client.delete_product_input(request) expected_params = [ ( @@ -2346,291 +2101,654 @@ def test_insert_product_input_rest_required_fields( assert expected_params == actual_params -def test_insert_product_input_rest_unset_required_fields(): +def test_delete_product_input_rest_unset_required_fields(): transport = transports.ProductInputsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.insert_product_input._get_unset_required_fields({}) + unset_fields = transport.delete_product_input._get_unset_required_fields({}) assert set(unset_fields) == ( set(("dataSource",)) & set( ( - "parent", - "productInput", + "name", "dataSource", ) ) ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_product_input_rest_interceptors(null_interceptor): - transport = transports.ProductInputsServiceRestTransport( +def test_delete_product_input_rest_flattened(): + client = ProductInputsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ProductInputsServiceRestInterceptor(), + transport="rest", ) - client = ProductInputsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ProductInputsServiceRestInterceptor, "post_insert_product_input" - ) as post, mock.patch.object( - transports.ProductInputsServiceRestInterceptor, "pre_insert_product_input" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = productinputs.InsertProductInputRequest.pb( - productinputs.InsertProductInputRequest() + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "accounts/sample1/productInputs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } + mock_args.update(sample_request) - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = productinputs.ProductInput.to_json( - productinputs.ProductInput() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_product_input(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/products/v1beta/{name=accounts/*/productInputs/*}" + % client.transport._host, + args[1], ) - request = productinputs.InsertProductInputRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = productinputs.ProductInput() - client.insert_product_input( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], +def test_delete_product_input_rest_flattened_error(transport: str = "rest"): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_input( + productinputs.DeleteProductInputRequest(), + name="name_value", ) - pre.assert_called_once() - post.assert_called_once() +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductInputsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductInputsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductInputsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductInputsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductInputsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductInputsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductInputsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductInputsServiceGrpcTransport, + transports.ProductInputsServiceGrpcAsyncIOTransport, + transports.ProductInputsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = ProductInputsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_product_input_empty_call_grpc(): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_product_input), "__call__" + ) as call: + call.return_value = productinputs.ProductInput() + client.insert_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = productinputs.InsertProductInputRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_product_input_empty_call_grpc(): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_input), "__call__" + ) as call: + call.return_value = None + client.delete_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = productinputs.DeleteProductInputRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ProductInputsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ProductInputsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_product_input_empty_call_grpc_asyncio(): + client = ProductInputsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_product_input), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + productinputs.ProductInput( + name="name_value", + product="product_value", + channel=types.Channel.ChannelEnum.ONLINE, + offer_id="offer_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + version_number=1518, + ) + ) + await client.insert_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = productinputs.InsertProductInputRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_product_input_empty_call_grpc_asyncio(): + client = ProductInputsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_input), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product_input(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = productinputs.DeleteProductInputRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ProductInputsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_insert_product_input_rest_bad_request( + request_type=productinputs.InsertProductInputRequest, +): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_product_input(request) + + +@pytest.mark.parametrize( + "request_type", + [ + productinputs.InsertProductInputRequest, + dict, + ], +) +def test_insert_product_input_rest_call_success(request_type): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request_init["product_input"] = { + "name": "name_value", + "product": "product_value", + "channel": 1, + "offer_id": "offer_id_value", + "content_language": "content_language_value", + "feed_label": "feed_label_value", + "version_number": 1518, + "attributes": { + "identifier_exists": True, + "is_bundle": True, + "title": "title_value", + "description": "description_value", + "link": "link_value", + "mobile_link": "mobile_link_value", + "canonical_link": "canonical_link_value", + "image_link": "image_link_value", + "additional_image_links": [ + "additional_image_links_value1", + "additional_image_links_value2", + ], + "expiration_date": {"seconds": 751, "nanos": 543}, + "disclosure_date": {}, + "adult": True, + "age_group": "age_group_value", + "availability": "availability_value", + "availability_date": {}, + "brand": "brand_value", + "color": "color_value", + "condition": "condition_value", + "gender": "gender_value", + "google_product_category": "google_product_category_value", + "gtin": "gtin_value", + "item_group_id": "item_group_id_value", + "material": "material_value", + "mpn": "mpn_value", + "pattern": "pattern_value", + "price": {"amount_micros": 1408, "currency_code": "currency_code_value"}, + "installment": { + "months": 665, + "amount": {}, + "downpayment": {}, + "credit_type": "credit_type_value", + }, + "subscription_cost": {"period": 1, "period_length": 1380, "amount": {}}, + "loyalty_points": { + "name": "name_value", + "points_value": 1305, + "ratio": 0.543, + }, + "loyalty_programs": [ + { + "program_label": "program_label_value", + "tier_label": "tier_label_value", + "price": {}, + "cashback_for_future_use": {}, + "loyalty_points": 1546, + } + ], + "product_types": ["product_types_value1", "product_types_value2"], + "sale_price": {}, + "sale_price_effective_date": {"start_time": {}, "end_time": {}}, + "sell_on_google_quantity": 2470, + "product_height": {"value": 0.541, "unit": "unit_value"}, + "product_length": {}, + "product_width": {}, + "product_weight": {"value": 0.541, "unit": "unit_value"}, + "shipping": [ + { + "price": {}, + "country": "country_value", + "region": "region_value", + "service": "service_value", + "location_id": 1157, + "location_group_name": "location_group_name_value", + "postal_code": "postal_code_value", + "min_handling_time": 1782, + "max_handling_time": 1784, + "min_transit_time": 1718, + "max_transit_time": 1720, + } + ], + "free_shipping_threshold": [ + {"country": "country_value", "price_threshold": {}} + ], + "shipping_weight": {"value": 0.541, "unit": "unit_value"}, + "shipping_length": {"value": 0.541, "unit": "unit_value"}, + "shipping_width": {}, + "shipping_height": {}, + "max_handling_time": 1784, + "min_handling_time": 1782, + "shipping_label": "shipping_label_value", + "transit_time_label": "transit_time_label_value", + "size": "size_value", + "size_system": "size_system_value", + "size_types": ["size_types_value1", "size_types_value2"], + "taxes": [ + { + "rate": 0.428, + "country": "country_value", + "region": "region_value", + "tax_ship": True, + "location_id": 1157, + "postal_code": "postal_code_value", + } + ], + "tax_category": "tax_category_value", + "energy_efficiency_class": "energy_efficiency_class_value", + "min_energy_efficiency_class": "min_energy_efficiency_class_value", + "max_energy_efficiency_class": "max_energy_efficiency_class_value", + "unit_pricing_measure": {"value": 0.541, "unit": "unit_value"}, + "unit_pricing_base_measure": {"value": 541, "unit": "unit_value"}, + "multipack": 970, + "ads_grouping": "ads_grouping_value", + "ads_labels": ["ads_labels_value1", "ads_labels_value2"], + "ads_redirect": "ads_redirect_value", + "cost_of_goods_sold": {}, + "product_details": [ + { + "section_name": "section_name_value", + "attribute_name": "attribute_name_value", + "attribute_value": "attribute_value_value", + } + ], + "product_highlights": [ + "product_highlights_value1", + "product_highlights_value2", + ], + "display_ads_id": "display_ads_id_value", + "display_ads_similar_ids": [ + "display_ads_similar_ids_value1", + "display_ads_similar_ids_value2", + ], + "display_ads_title": "display_ads_title_value", + "display_ads_link": "display_ads_link_value", + "display_ads_value": 0.1801, + "promotion_ids": ["promotion_ids_value1", "promotion_ids_value2"], + "pickup_method": "pickup_method_value", + "pickup_sla": "pickup_sla_value", + "link_template": "link_template_value", + "mobile_link_template": "mobile_link_template_value", + "custom_label_0": "custom_label_0_value", + "custom_label_1": "custom_label_1_value", + "custom_label_2": "custom_label_2_value", + "custom_label_3": "custom_label_3_value", + "custom_label_4": "custom_label_4_value", + "included_destinations": [ + "included_destinations_value1", + "included_destinations_value2", + ], + "excluded_destinations": [ + "excluded_destinations_value1", + "excluded_destinations_value2", + ], + "shopping_ads_excluded_countries": [ + "shopping_ads_excluded_countries_value1", + "shopping_ads_excluded_countries_value2", + ], + "external_seller_id": "external_seller_id_value", + "pause": "pause_value", + "lifestyle_image_links": [ + "lifestyle_image_links_value1", + "lifestyle_image_links_value2", + ], + "cloud_export_additional_properties": [ + { + "property_name": "property_name_value", + "text_value": ["text_value_value1", "text_value_value2"], + "bool_value": True, + "int_value": [968, 969], + "float_value": [0.11710000000000001, 0.11720000000000001], + "min_value": 0.96, + "max_value": 0.962, + "unit_code": "unit_code_value", + } + ], + "virtual_model_link": "virtual_model_link_value", + "certifications": [ + { + "certification_authority": "certification_authority_value", + "certification_name": "certification_name_value", + "certification_code": "certification_code_value", + "certification_value": "certification_value_value", + } + ], + "structured_title": { + "digital_source_type": "digital_source_type_value", + "content": "content_value", + }, + "structured_description": { + "digital_source_type": "digital_source_type_value", + "content": "content_value", + }, + "auto_pricing_min_price": {}, + }, + "custom_attributes": [ + {"name": "name_value", "value": "value_value", "group_values": {}} + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = productinputs.InsertProductInputRequest.meta.fields["product_input"] -def test_insert_product_input_rest_bad_request( - transport: str = "rest", request_type=productinputs.InsertProductInputRequest -): - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_product_input(request) + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] -def test_insert_product_input_rest_error(): - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) + subfields_not_in_runtime = [] + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["product_input"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value -@pytest.mark.parametrize( - "request_type", - [ - productinputs.DeleteProductInputRequest, - dict, - ], -) -def test_delete_product_input_rest(request_type): - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/productInputs/sample2"} + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_input"][field])): + del request_init["product_input"][field][i][subfield] + else: + del request_init["product_input"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_product_input(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_product_input_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.delete_product_input in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + return_value = productinputs.ProductInput( + name="name_value", + product="product_value", + channel=types.Channel.ChannelEnum.ONLINE, + offer_id="offer_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + version_number=1518, ) - client._transport._wrapped_methods[ - client._transport.delete_product_input - ] = mock_rpc - - request = {} - client.delete_product_input(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_product_input(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_delete_product_input_rest_required_fields( - request_type=productinputs.DeleteProductInputRequest, -): - transport_class = transports.ProductInputsServiceRestTransport - - request_init = {} - request_init["name"] = "" - request_init["data_source"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - assert "dataSource" not in jsonified_request - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_product_input._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "dataSource" in jsonified_request - assert jsonified_request["dataSource"] == request_init["data_source"] - - jsonified_request["name"] = "name_value" - jsonified_request["dataSource"] = "data_source_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_product_input._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("data_source",)) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - assert "dataSource" in jsonified_request - assert jsonified_request["dataSource"] == "data_source_value" - - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = None - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.delete_product_input(request) - - expected_params = [ - ( - "dataSource", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_delete_product_input_rest_unset_required_fields(): - transport = transports.ProductInputsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.delete_product_input._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("dataSource",)) - & set( - ( - "name", - "dataSource", - ) - ) - ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = productinputs.ProductInput.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_product_input(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, productinputs.ProductInput) + assert response.name == "name_value" + assert response.product == "product_value" + assert response.channel == types.Channel.ChannelEnum.ONLINE + assert response.offer_id == "offer_id_value" + assert response.content_language == "content_language_value" + assert response.feed_label == "feed_label_value" + assert response.version_number == 1518 @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_product_input_rest_interceptors(null_interceptor): +def test_insert_product_input_rest_interceptors(null_interceptor): transport = transports.ProductInputsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -2638,16 +2756,20 @@ def test_delete_product_input_rest_interceptors(null_interceptor): else transports.ProductInputsServiceRestInterceptor(), ) client = ProductInputsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.ProductInputsServiceRestInterceptor, "pre_delete_product_input" + transports.ProductInputsServiceRestInterceptor, "post_insert_product_input" + ) as post, mock.patch.object( + transports.ProductInputsServiceRestInterceptor, "pre_insert_product_input" ) as pre: pre.assert_not_called() - pb_message = productinputs.DeleteProductInputRequest.pb( - productinputs.DeleteProductInputRequest() + post.assert_not_called() + pb_message = productinputs.InsertProductInputRequest.pb( + productinputs.InsertProductInputRequest() ) transcode.return_value = { "method": "post", @@ -2656,18 +2778,20 @@ def test_delete_product_input_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = productinputs.ProductInput.to_json(productinputs.ProductInput()) + req.return_value.content = return_value - request = productinputs.DeleteProductInputRequest() + request = productinputs.InsertProductInputRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = productinputs.ProductInput() - client.delete_product_input( + client.insert_product_input( request, metadata=[ ("key", "val"), @@ -2676,16 +2800,15 @@ def test_delete_product_input_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() def test_delete_product_input_rest_bad_request( - transport: str = "rest", request_type=productinputs.DeleteProductInputRequest + request_type=productinputs.DeleteProductInputRequest, ): client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"name": "accounts/sample1/productInputs/sample2"} request = request_type(**request_init) @@ -2695,178 +2818,146 @@ def test_delete_product_input_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.delete_product_input(request) -def test_delete_product_input_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + productinputs.DeleteProductInputRequest, + dict, + ], +) +def test_delete_product_input_rest_call_success(request_type): client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/productInputs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = None - # get arguments that satisfy an http rule for this method - sample_request = {"name": "accounts/sample1/productInputs/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_product_input(request) - client.delete_product_input(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/products/v1beta/{name=accounts/*/productInputs/*}" - % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert response is None -def test_delete_product_input_rest_flattened_error(transport: str = "rest"): - client = ProductInputsServiceClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_input_rest_interceptors(null_interceptor): + transport = transports.ProductInputsServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None + if null_interceptor + else transports.ProductInputsServiceRestInterceptor(), ) + client = ProductInputsServiceClient(transport=transport) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_product_input( - productinputs.DeleteProductInputRequest(), - name="name_value", + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ProductInputsServiceRestInterceptor, "pre_delete_product_input" + ) as pre: + pre.assert_not_called() + pb_message = productinputs.DeleteProductInputRequest.pb( + productinputs.DeleteProductInputRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + req.return_value = mock.Mock() + req.return_value.status_code = 200 -def test_delete_product_input_rest_error(): - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - + request = productinputs.DeleteProductInputRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + client.delete_product_input( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.ProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ProductInputsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + pre.assert_called_once() - # It is an error to provide an api_key and a transport instance. - transport = transports.ProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + +def test_initialize_client_w_rest(): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ProductInputsServiceClient( - client_options=options, - transport=transport, - ) + assert client is not None - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ProductInputsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - # It is an error to provide scopes and a transport instance. - transport = transports.ProductInputsServiceGrpcTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_product_input_empty_call_rest(): + client = ProductInputsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ProductInputsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_product_input), "__call__" + ) as call: + client.insert_product_input(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ProductInputsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = productinputs.InsertProductInputRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ProductInputsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.ProductInputsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_product_input_empty_call_rest(): + client = ProductInputsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ProductInputsServiceGrpcTransport, - transports.ProductInputsServiceGrpcAsyncIOTransport, - transports.ProductInputsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_input), "__call__" + ) as call: + client.delete_product_input(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = productinputs.DeleteProductInputRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = ProductInputsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3470,36 +3561,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = ProductInputsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ProductInputsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = ProductInputsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_products_service.py b/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_products_service.py index b34f09fb80a5..0beabb21e643 100644 --- a/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_products_service.py +++ b/packages/google-shopping-merchant-products/tests/unit/gapic/merchant_products_v1beta/test_products_service.py @@ -22,20 +22,12 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format -from google.shopping.type.types import types import grpc from grpc.experimental import aio from proto.marshal.rules import wrappers @@ -44,6 +36,23 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.shopping.type.types import types + from google.shopping.merchant_products_v1beta.services.products_service import ( ProductsServiceAsyncClient, ProductsServiceClient, @@ -53,10 +62,24 @@ from google.shopping.merchant_products_v1beta.types import products, products_common +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1190,25 +1213,6 @@ def test_get_product(request_type, transport: str = "grpc"): assert response.version_number == 1518 -def test_get_product_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_product), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == products.GetProductRequest() - - def test_get_product_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1272,35 +1276,6 @@ def test_get_product_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_product_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_product), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - products.Product( - name="name_value", - channel=types.Channel.ChannelEnum.ONLINE, - offer_id="offer_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - data_source="data_source_value", - version_number=1518, - ) - ) - response = await client.get_product() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == products.GetProductRequest() - - @pytest.mark.asyncio async def test_get_product_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1309,7 +1284,7 @@ async def test_get_product_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1348,7 +1323,7 @@ async def test_get_product_async( transport: str = "grpc_asyncio", request_type=products.GetProductRequest ): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1426,7 +1401,7 @@ def test_get_product_field_headers(): @pytest.mark.asyncio async def test_get_product_field_headers_async(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1494,7 +1469,7 @@ def test_get_product_flattened_error(): @pytest.mark.asyncio async def test_get_product_flattened_async(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1521,7 +1496,7 @@ async def test_get_product_flattened_async(): @pytest.mark.asyncio async def test_get_product_flattened_error_async(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1569,25 +1544,6 @@ def test_list_products(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_products_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_products), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_products() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == products.ListProductsRequest() - - def test_list_products_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1653,29 +1609,6 @@ def test_list_products_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_products_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_products), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - products.ListProductsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_products() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == products.ListProductsRequest() - - @pytest.mark.asyncio async def test_list_products_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1684,7 +1617,7 @@ async def test_list_products_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1723,7 +1656,7 @@ async def test_list_products_async( transport: str = "grpc_asyncio", request_type=products.ListProductsRequest ): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1789,7 +1722,7 @@ def test_list_products_field_headers(): @pytest.mark.asyncio async def test_list_products_field_headers_async(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1859,7 +1792,7 @@ def test_list_products_flattened_error(): @pytest.mark.asyncio async def test_list_products_flattened_async(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1888,7 +1821,7 @@ async def test_list_products_flattened_async(): @pytest.mark.asyncio async def test_list_products_flattened_error_async(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1998,7 +1931,7 @@ def test_list_products_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_products_async_pager(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2048,7 +1981,7 @@ async def test_list_products_async_pager(): @pytest.mark.asyncio async def test_list_products_async_pages(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2094,58 +2027,6 @@ async def test_list_products_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - products.GetProductRequest, - dict, - ], -) -def test_get_product_rest(request_type): - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = products.Product( - name="name_value", - channel=types.Channel.ChannelEnum.ONLINE, - offer_id="offer_id_value", - content_language="content_language_value", - feed_label="feed_label_value", - data_source="data_source_value", - version_number=1518, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = products.Product.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_product(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, products.Product) - assert response.name == "name_value" - assert response.channel == types.Channel.ChannelEnum.ONLINE - assert response.offer_id == "offer_id_value" - assert response.content_language == "content_language_value" - assert response.feed_label == "feed_label_value" - assert response.data_source == "data_source_value" - assert response.version_number == 1518 - - def test_get_product_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2263,83 +2144,6 @@ def test_get_product_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_product_rest_interceptors(null_interceptor): - transport = transports.ProductsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ProductsServiceRestInterceptor(), - ) - client = ProductsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ProductsServiceRestInterceptor, "post_get_product" - ) as post, mock.patch.object( - transports.ProductsServiceRestInterceptor, "pre_get_product" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = products.GetProductRequest.pb(products.GetProductRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = products.Product.to_json(products.Product()) - - request = products.GetProductRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = products.Product() - - client.get_product( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_product_rest_bad_request( - transport: str = "rest", request_type=products.GetProductRequest -): - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/products/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_product(request) - - def test_get_product_rest_flattened(): client = ProductsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2396,67 +2200,21 @@ def test_get_product_rest_flattened_error(transport: str = "rest"): ) -def test_get_product_rest_error(): - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_list_products_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - products.ListProductsRequest, - dict, - ], -) -def test_list_products_rest(request_type): - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = products.ListProductsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = products.ListProductsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_products(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListProductsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_products_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_products in client._transport._wrapped_methods + # Ensure method has been cached + assert client._transport.list_products in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -2574,85 +2332,6 @@ def test_list_products_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_products_rest_interceptors(null_interceptor): - transport = transports.ProductsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ProductsServiceRestInterceptor(), - ) - client = ProductsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ProductsServiceRestInterceptor, "post_list_products" - ) as post, mock.patch.object( - transports.ProductsServiceRestInterceptor, "pre_list_products" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = products.ListProductsRequest.pb(products.ListProductsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = products.ListProductsResponse.to_json( - products.ListProductsResponse() - ) - - request = products.ListProductsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = products.ListProductsResponse() - - client.list_products( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_products_rest_bad_request( - transport: str = "rest", request_type=products.ListProductsRequest -): - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_products(request) - - def test_list_products_rest_flattened(): client = ProductsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2862,18 +2541,432 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = ProductsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_product_empty_call_grpc(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_product), "__call__") as call: + call.return_value = products.Product() + client.get_product(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = products.GetProductRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_products_empty_call_grpc(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_products), "__call__") as call: + call.return_value = products.ListProductsResponse() + client.list_products(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = products.ListProductsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ProductsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ProductsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_product_empty_call_grpc_asyncio(): + client = ProductsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_product), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + products.Product( + name="name_value", + channel=types.Channel.ChannelEnum.ONLINE, + offer_id="offer_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + data_source="data_source_value", + version_number=1518, + ) + ) + await client.get_product(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = products.GetProductRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_products_empty_call_grpc_asyncio(): + client = ProductsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_products), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + products.ListProductsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_products(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = products.ListProductsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ProductsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_product_rest_bad_request(request_type=products.GetProductRequest): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_product(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + products.GetProductRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = ProductsServiceClient.get_transport_class(transport_name)( +def test_get_product_rest_call_success(request_type): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/products/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = products.Product( + name="name_value", + channel=types.Channel.ChannelEnum.ONLINE, + offer_id="offer_id_value", + content_language="content_language_value", + feed_label="feed_label_value", + data_source="data_source_value", + version_number=1518, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = products.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, products.Product) + assert response.name == "name_value" + assert response.channel == types.Channel.ChannelEnum.ONLINE + assert response.offer_id == "offer_id_value" + assert response.content_language == "content_language_value" + assert response.feed_label == "feed_label_value" + assert response.data_source == "data_source_value" + assert response.version_number == 1518 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_rest_interceptors(null_interceptor): + transport = transports.ProductsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ProductsServiceRestInterceptor(), + ) + client = ProductsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ProductsServiceRestInterceptor, "post_get_product" + ) as post, mock.patch.object( + transports.ProductsServiceRestInterceptor, "pre_get_product" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = products.GetProductRequest.pb(products.GetProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = products.Product.to_json(products.Product()) + req.return_value.content = return_value + + request = products.GetProductRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = products.Product() + + client.get_product( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_rest_bad_request(request_type=products.ListProductsRequest): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_products(request) + + +@pytest.mark.parametrize( + "request_type", + [ + products.ListProductsRequest, + dict, + ], +) +def test_list_products_rest_call_success(request_type): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = products.ListProductsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = products.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_products(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ProductsServiceRestInterceptor(), + ) + client = ProductsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ProductsServiceRestInterceptor, "post_list_products" + ) as post, mock.patch.object( + transports.ProductsServiceRestInterceptor, "pre_list_products" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = products.ListProductsRequest.pb(products.ListProductsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = products.ListProductsResponse.to_json( + products.ListProductsResponse() + ) + req.return_value.content = return_value + + request = products.ListProductsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = products.ListProductsResponse() + + client.list_products( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_product_empty_call_rest(): + client = ProductsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_product), "__call__") as call: + client.get_product(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = products.GetProductRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_products_empty_call_rest(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_products), "__call__") as call: + client.list_products(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = products.ListProductsRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -3452,36 +3545,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = ProductsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ProductsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = ProductsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst new file mode 100644 index 000000000000..8e430c8e2e3a --- /dev/null +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`PromotionsServiceTransport` is the ABC for all transports. +- public child `PromotionsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `PromotionsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BasePromotionsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `PromotionsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py index f6f071ffddcf..75776592ea82 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -226,6 +227,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -333,25 +337,34 @@ def list_promotions( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.insert_promotion: gapic_v1.method_async.wrap_method( + self.insert_promotion: self._wrap_method( self.insert_promotion, default_timeout=None, client_info=client_info, ), - self.get_promotion: gapic_v1.method_async.wrap_method( + self.get_promotion: self._wrap_method( self.get_promotion, default_timeout=None, client_info=client_info, ), - self.list_promotions: gapic_v1.method_async.wrap_method( + self.list_promotions: self._wrap_method( self.list_promotions, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("PromotionsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py index c0fc68529e1d..9d91e27b1130 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_promotions_v1beta.types import promotions + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BasePromotionsServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_promotions_v1beta.types import promotions - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import PromotionsServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -170,8 +167,8 @@ class PromotionsServiceRestStub: _interceptor: PromotionsServiceRestInterceptor -class PromotionsServiceRestTransport(PromotionsServiceTransport): - """REST backend transport for PromotionsService. +class PromotionsServiceRestTransport(_BasePromotionsServiceRestTransport): + """REST backend synchronous transport for PromotionsService. Service to manage promotions for products. @@ -180,7 +177,6 @@ class PromotionsServiceRestTransport(PromotionsServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -234,21 +230,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -259,19 +246,33 @@ def __init__( self._interceptor = interceptor or PromotionsServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _GetPromotion(PromotionsServiceRestStub): + class _GetPromotion( + _BasePromotionsServiceRestTransport._BaseGetPromotion, PromotionsServiceRestStub + ): def __hash__(self): - return hash("GetPromotion") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PromotionsServiceRestTransport.GetPromotion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -311,38 +312,27 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/promotions/v1beta/{name=accounts/*/promotions/*}", - }, - ] + http_options = ( + _BasePromotionsServiceRestTransport._BaseGetPromotion._get_http_options() + ) request, metadata = self._interceptor.pre_get_promotion(request, metadata) - pb_request = promotions.GetPromotionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = PromotionsServiceRestTransport._GetPromotion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -358,19 +348,35 @@ def __call__( resp = self._interceptor.post_get_promotion(resp) return resp - class _InsertPromotion(PromotionsServiceRestStub): + class _InsertPromotion( + _BasePromotionsServiceRestTransport._BaseInsertPromotion, + PromotionsServiceRestStub, + ): def __hash__(self): - return hash("InsertPromotion") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PromotionsServiceRestTransport.InsertPromotion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -410,47 +416,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/promotions/v1beta/{parent=accounts/*}/promotions:insert", - "body": "*", - }, - ] + http_options = ( + _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_http_options() + ) request, metadata = self._interceptor.pre_insert_promotion( request, metadata ) - pb_request = promotions.InsertPromotionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = PromotionsServiceRestTransport._InsertPromotion._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -466,19 +459,34 @@ def __call__( resp = self._interceptor.post_insert_promotion(resp) return resp - class _ListPromotions(PromotionsServiceRestStub): + class _ListPromotions( + _BasePromotionsServiceRestTransport._BaseListPromotions, + PromotionsServiceRestStub, + ): def __hash__(self): - return hash("ListPromotions") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("PromotionsServiceRestTransport.ListPromotions") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -504,38 +512,27 @@ def __call__( Response message for the ``ListPromotions`` method. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/promotions/v1beta/{parent=accounts/*}/promotions", - }, - ] + http_options = ( + _BasePromotionsServiceRestTransport._BaseListPromotions._get_http_options() + ) request, metadata = self._interceptor.pre_list_promotions(request, metadata) - pb_request = promotions.ListPromotionsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BasePromotionsServiceRestTransport._BaseListPromotions._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BasePromotionsServiceRestTransport._BaseListPromotions._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = PromotionsServiceRestTransport._ListPromotions._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py new file mode 100644 index 000000000000..ac3d21eb3341 --- /dev/null +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_promotions_v1beta.types import promotions + +from .base import DEFAULT_CLIENT_INFO, PromotionsServiceTransport + + +class _BasePromotionsServiceRestTransport(PromotionsServiceTransport): + """Base REST backend transport for PromotionsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetPromotion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/promotions/v1beta/{name=accounts/*/promotions/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = promotions.GetPromotionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePromotionsServiceRestTransport._BaseGetPromotion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertPromotion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/promotions/v1beta/{parent=accounts/*}/promotions:insert", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = promotions.InsertPromotionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListPromotions: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/promotions/v1beta/{parent=accounts/*}/promotions", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = promotions.ListPromotionsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePromotionsServiceRestTransport._BaseListPromotions._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BasePromotionsServiceRestTransport",) diff --git a/packages/google-shopping-merchant-promotions/setup.py b/packages/google-shopping-merchant-promotions/setup.py index 7e8adf132ed5..ef159a1bd624 100644 --- a/packages/google-shopping-merchant-promotions/setup.py +++ b/packages/google-shopping-merchant-promotions/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-promotions" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py b/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py index acfb2ea13911..136525c92c1d 100644 --- a/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py +++ b/packages/google-shopping-merchant-promotions/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py @@ -22,29 +22,38 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account -from google.protobuf import json_format from google.protobuf import timestamp_pb2 # type: ignore from google.shopping.type.types import types from google.type import interval_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from google.shopping.merchant_promotions_v1beta.services.promotions_service import ( PromotionsServiceAsyncClient, @@ -58,10 +67,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1209,25 +1232,6 @@ def test_insert_promotion(request_type, transport: str = "grpc"): assert response.version_number == 1518 -def test_insert_promotion_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.insert_promotion), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.insert_promotion() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.InsertPromotionRequest() - - def test_insert_promotion_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1295,35 +1299,6 @@ def test_insert_promotion_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_insert_promotion_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.insert_promotion), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - promotions.Promotion( - name="name_value", - promotion_id="promotion_id_value", - content_language="content_language_value", - target_country="target_country_value", - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source="data_source_value", - version_number=1518, - ) - ) - response = await client.insert_promotion() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.InsertPromotionRequest() - - @pytest.mark.asyncio async def test_insert_promotion_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1332,7 +1307,7 @@ async def test_insert_promotion_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1371,7 +1346,7 @@ async def test_insert_promotion_async( transport: str = "grpc_asyncio", request_type=promotions.InsertPromotionRequest ): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1449,7 +1424,7 @@ def test_insert_promotion_field_headers(): @pytest.mark.asyncio async def test_insert_promotion_field_headers_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1526,25 +1501,6 @@ def test_get_promotion(request_type, transport: str = "grpc"): assert response.version_number == 1518 -def test_get_promotion_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_promotion), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_promotion() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.GetPromotionRequest() - - def test_get_promotion_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1608,35 +1564,6 @@ def test_get_promotion_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_promotion_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_promotion), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - promotions.Promotion( - name="name_value", - promotion_id="promotion_id_value", - content_language="content_language_value", - target_country="target_country_value", - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source="data_source_value", - version_number=1518, - ) - ) - response = await client.get_promotion() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.GetPromotionRequest() - - @pytest.mark.asyncio async def test_get_promotion_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1645,7 +1572,7 @@ async def test_get_promotion_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1684,7 +1611,7 @@ async def test_get_promotion_async( transport: str = "grpc_asyncio", request_type=promotions.GetPromotionRequest ): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1762,7 +1689,7 @@ def test_get_promotion_field_headers(): @pytest.mark.asyncio async def test_get_promotion_field_headers_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1832,7 +1759,7 @@ def test_get_promotion_flattened_error(): @pytest.mark.asyncio async def test_get_promotion_flattened_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1861,7 +1788,7 @@ async def test_get_promotion_flattened_async(): @pytest.mark.asyncio async def test_get_promotion_flattened_error_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1909,25 +1836,6 @@ def test_list_promotions(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_promotions_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_promotions), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_promotions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.ListPromotionsRequest() - - def test_list_promotions_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1993,29 +1901,6 @@ def test_list_promotions_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_promotions_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_promotions), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - promotions.ListPromotionsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_promotions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.ListPromotionsRequest() - - @pytest.mark.asyncio async def test_list_promotions_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2024,7 +1909,7 @@ async def test_list_promotions_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2063,7 +1948,7 @@ async def test_list_promotions_async( transport: str = "grpc_asyncio", request_type=promotions.ListPromotionsRequest ): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2129,7 +2014,7 @@ def test_list_promotions_field_headers(): @pytest.mark.asyncio async def test_list_promotions_field_headers_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2199,7 +2084,7 @@ def test_list_promotions_flattened_error(): @pytest.mark.asyncio async def test_list_promotions_flattened_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2228,7 +2113,7 @@ async def test_list_promotions_flattened_async(): @pytest.mark.asyncio async def test_list_promotions_flattened_error_async(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2338,7 +2223,7 @@ def test_list_promotions_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_promotions_async_pager(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2388,7 +2273,7 @@ async def test_list_promotions_async_pager(): @pytest.mark.asyncio async def test_list_promotions_async_pages(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2434,58 +2319,6 @@ async def test_list_promotions_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - promotions.InsertPromotionRequest, - dict, - ], -) -def test_insert_promotion_rest(request_type): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = promotions.Promotion( - name="name_value", - promotion_id="promotion_id_value", - content_language="content_language_value", - target_country="target_country_value", - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source="data_source_value", - version_number=1518, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.insert_promotion(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == "name_value" - assert response.promotion_id == "promotion_id_value" - assert response.content_language == "content_language_value" - assert response.target_country == "target_country_value" - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == "data_source_value" - assert response.version_number == 1518 - - def test_insert_promotion_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -2621,158 +2454,21 @@ def test_insert_promotion_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_promotion_rest_interceptors(null_interceptor): - transport = transports.PromotionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.PromotionsServiceRestInterceptor(), - ) - client = PromotionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.PromotionsServiceRestInterceptor, "post_insert_promotion" - ) as post, mock.patch.object( - transports.PromotionsServiceRestInterceptor, "pre_insert_promotion" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = promotions.InsertPromotionRequest.pb( - promotions.InsertPromotionRequest() +def test_get_promotion_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = promotions.Promotion.to_json(promotions.Promotion()) - request = promotions.InsertPromotionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = promotions.Promotion() + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - client.insert_promotion( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_insert_promotion_rest_bad_request( - transport: str = "rest", request_type=promotions.InsertPromotionRequest -): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.insert_promotion(request) - - -def test_insert_promotion_rest_error(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - promotions.GetPromotionRequest, - dict, - ], -) -def test_get_promotion_rest(request_type): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/promotions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = promotions.Promotion( - name="name_value", - promotion_id="promotion_id_value", - content_language="content_language_value", - target_country="target_country_value", - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source="data_source_value", - version_number=1518, - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_promotion(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == "name_value" - assert response.promotion_id == "promotion_id_value" - assert response.content_language == "content_language_value" - assert response.target_country == "target_country_value" - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == "data_source_value" - assert response.version_number == 1518 - - -def test_get_promotion_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_promotion in client._transport._wrapped_methods + # Ensure method has been cached + assert client._transport.get_promotion in client._transport._wrapped_methods # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -2877,83 +2573,6 @@ def test_get_promotion_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_promotion_rest_interceptors(null_interceptor): - transport = transports.PromotionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.PromotionsServiceRestInterceptor(), - ) - client = PromotionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.PromotionsServiceRestInterceptor, "post_get_promotion" - ) as post, mock.patch.object( - transports.PromotionsServiceRestInterceptor, "pre_get_promotion" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = promotions.GetPromotionRequest.pb(promotions.GetPromotionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = promotions.Promotion.to_json(promotions.Promotion()) - - request = promotions.GetPromotionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = promotions.Promotion() - - client.get_promotion( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_promotion_rest_bad_request( - transport: str = "rest", request_type=promotions.GetPromotionRequest -): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "accounts/sample1/promotions/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_promotion(request) - - def test_get_promotion_rest_flattened(): client = PromotionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -3011,52 +2630,6 @@ def test_get_promotion_rest_flattened_error(transport: str = "rest"): ) -def test_get_promotion_rest_error(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - promotions.ListPromotionsRequest, - dict, - ], -) -def test_list_promotions_rest(request_type): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = promotions.ListPromotionsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = promotions.ListPromotionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_promotions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPromotionsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_promotions_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -3191,6 +2764,728 @@ def test_list_promotions_rest_unset_required_fields(): ) +def test_list_promotions_rest_flattened(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = promotions.ListPromotionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "accounts/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = promotions.ListPromotionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_promotions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/promotions/v1beta/{parent=accounts/*}/promotions" + % client.transport._host, + args[1], + ) + + +def test_list_promotions_rest_flattened_error(transport: str = "rest"): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_promotions( + promotions.ListPromotionsRequest(), + parent="parent_value", + ) + + +def test_list_promotions_rest_pager(transport: str = "rest"): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + promotions.Promotion(), + ], + next_page_token="abc", + ), + promotions.ListPromotionsResponse( + promotions=[], + next_page_token="def", + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + ], + next_page_token="ghi", + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(promotions.ListPromotionsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "accounts/sample1"} + + pager = client.list_promotions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, promotions.Promotion) for i in results) + + pages = list(client.list_promotions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PromotionsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PromotionsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PromotionsServiceGrpcTransport, + transports.PromotionsServiceGrpcAsyncIOTransport, + transports.PromotionsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = PromotionsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_promotion_empty_call_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_promotion), "__call__") as call: + call.return_value = promotions.Promotion() + client.insert_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.InsertPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_promotion_empty_call_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_promotion), "__call__") as call: + call.return_value = promotions.Promotion() + client.get_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.GetPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_promotions_empty_call_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_promotions), "__call__") as call: + call.return_value = promotions.ListPromotionsResponse() + client.list_promotions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.ListPromotionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = PromotionsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_promotion_empty_call_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_promotion), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + promotions.Promotion( + name="name_value", + promotion_id="promotion_id_value", + content_language="content_language_value", + target_country="target_country_value", + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source="data_source_value", + version_number=1518, + ) + ) + await client.insert_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.InsertPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_promotion_empty_call_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_promotion), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + promotions.Promotion( + name="name_value", + promotion_id="promotion_id_value", + content_language="content_language_value", + target_country="target_country_value", + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source="data_source_value", + version_number=1518, + ) + ) + await client.get_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.GetPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_promotions_empty_call_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_promotions), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + promotions.ListPromotionsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_promotions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.ListPromotionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = PromotionsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_insert_promotion_rest_bad_request( + request_type=promotions.InsertPromotionRequest, +): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_promotion(request) + + +@pytest.mark.parametrize( + "request_type", + [ + promotions.InsertPromotionRequest, + dict, + ], +) +def test_insert_promotion_rest_call_success(request_type): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = promotions.Promotion( + name="name_value", + promotion_id="promotion_id_value", + content_language="content_language_value", + target_country="target_country_value", + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source="data_source_value", + version_number=1518, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.insert_promotion(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == "name_value" + assert response.promotion_id == "promotion_id_value" + assert response.content_language == "content_language_value" + assert response.target_country == "target_country_value" + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == "data_source_value" + assert response.version_number == 1518 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_insert_promotion_rest_interceptors(null_interceptor): + transport = transports.PromotionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PromotionsServiceRestInterceptor(), + ) + client = PromotionsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PromotionsServiceRestInterceptor, "post_insert_promotion" + ) as post, mock.patch.object( + transports.PromotionsServiceRestInterceptor, "pre_insert_promotion" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = promotions.InsertPromotionRequest.pb( + promotions.InsertPromotionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = promotions.Promotion.to_json(promotions.Promotion()) + req.return_value.content = return_value + + request = promotions.InsertPromotionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = promotions.Promotion() + + client.insert_promotion( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_promotion_rest_bad_request(request_type=promotions.GetPromotionRequest): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/promotions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_promotion(request) + + +@pytest.mark.parametrize( + "request_type", + [ + promotions.GetPromotionRequest, + dict, + ], +) +def test_get_promotion_rest_call_success(request_type): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "accounts/sample1/promotions/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = promotions.Promotion( + name="name_value", + promotion_id="promotion_id_value", + content_language="content_language_value", + target_country="target_country_value", + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source="data_source_value", + version_number=1518, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_promotion(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == "name_value" + assert response.promotion_id == "promotion_id_value" + assert response.content_language == "content_language_value" + assert response.target_country == "target_country_value" + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == "data_source_value" + assert response.version_number == 1518 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_promotion_rest_interceptors(null_interceptor): + transport = transports.PromotionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PromotionsServiceRestInterceptor(), + ) + client = PromotionsServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PromotionsServiceRestInterceptor, "post_get_promotion" + ) as post, mock.patch.object( + transports.PromotionsServiceRestInterceptor, "pre_get_promotion" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = promotions.GetPromotionRequest.pb(promotions.GetPromotionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = promotions.Promotion.to_json(promotions.Promotion()) + req.return_value.content = return_value + + request = promotions.GetPromotionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = promotions.Promotion() + + client.get_promotion( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_promotions_rest_bad_request( + request_type=promotions.ListPromotionsRequest, +): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_promotions(request) + + +@pytest.mark.parametrize( + "request_type", + [ + promotions.ListPromotionsRequest, + dict, + ], +) +def test_list_promotions_rest_call_success(request_type): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = promotions.ListPromotionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.ListPromotionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_promotions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPromotionsPager) + assert response.next_page_token == "next_page_token_value" + + @pytest.mark.parametrize("null_interceptor", [True, False]) def test_list_promotions_rest_interceptors(null_interceptor): transport = transports.PromotionsServiceRestTransport( @@ -3200,6 +3495,7 @@ def test_list_promotions_rest_interceptors(null_interceptor): else transports.PromotionsServiceRestInterceptor(), ) client = PromotionsServiceClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -3221,12 +3517,12 @@ def test_list_promotions_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = promotions.ListPromotionsResponse.to_json( + return_value = promotions.ListPromotionsResponse.to_json( promotions.ListPromotionsResponse() ) + req.return_value.content = return_value request = promotions.ListPromotionsRequest() metadata = [ @@ -3248,252 +3544,71 @@ def test_list_promotions_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_promotions_rest_bad_request( - transport: str = "rest", request_type=promotions.ListPromotionsRequest -): +def test_initialize_client_w_rest(): client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_promotions(request) + assert client is not None -def test_list_promotions_rest_flattened(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_promotion_empty_call_rest(): client = PromotionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = promotions.ListPromotionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "accounts/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = promotions.ListPromotionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_promotions(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/promotions/v1beta/{parent=accounts/*}/promotions" - % client.transport._host, - args[1], - ) - + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.insert_promotion), "__call__") as call: + client.insert_promotion(request=None) -def test_list_promotions_rest_flattened_error(transport: str = "rest"): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.InsertPromotionRequest() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_promotions( - promotions.ListPromotionsRequest(), - parent="parent_value", - ) + assert args[0] == request_msg -def test_list_promotions_rest_pager(transport: str = "rest"): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_promotion_empty_call_rest(): client = PromotionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - promotions.Promotion(), - ], - next_page_token="abc", - ), - promotions.ListPromotionsResponse( - promotions=[], - next_page_token="def", - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - ], - next_page_token="ghi", - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(promotions.ListPromotionsResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "accounts/sample1"} - - pager = client.list_promotions(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, promotions.Promotion) for i in results) - - pages = list(client.list_promotions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_promotion), "__call__") as call: + client.get_promotion(request=None) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = PromotionsServiceClient(transport=transport) - assert client.transport is transport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.GetPromotionRequest() + assert args[0] == request_msg -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - transport = transports.PromotionsServiceGrpcAsyncIOTransport( +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_promotions_empty_call_rest(): + client = PromotionsServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize( - "transport_class", - [ - transports.PromotionsServiceGrpcTransport, - transports.PromotionsServiceGrpcAsyncIOTransport, - transports.PromotionsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_promotions), "__call__") as call: + client.list_promotions(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.ListPromotionsRequest() -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = PromotionsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + assert args[0] == request_msg def test_transport_grpc_default(): @@ -4076,36 +4191,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = PromotionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst new file mode 100644 index 000000000000..06b6eb4da828 --- /dev/null +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`QuotaServiceTransport` is the ABC for all transports. +- public child `QuotaServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `QuotaServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseQuotaServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `QuotaServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py index 30f1d27c3421..7e3d06377006 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -227,6 +228,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -271,15 +275,24 @@ def list_quota_groups( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.list_quota_groups: gapic_v1.method_async.wrap_method( + self.list_quota_groups: self._wrap_method( self.list_quota_groups, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("QuotaServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py index 426c8fb5ab38..f2f450459f06 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_quota_v1beta.types import quota + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseQuotaServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_quota_v1beta.types import quota - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import QuotaServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -106,8 +103,8 @@ class QuotaServiceRestStub: _interceptor: QuotaServiceRestInterceptor -class QuotaServiceRestTransport(QuotaServiceTransport): - """REST backend transport for QuotaService. +class QuotaServiceRestTransport(_BaseQuotaServiceRestTransport): + """REST backend synchronous transport for QuotaService. Service to get method call quota information per Merchant API method. @@ -117,7 +114,6 @@ class QuotaServiceRestTransport(QuotaServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -171,21 +167,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -196,19 +183,33 @@ def __init__( self._interceptor = interceptor or QuotaServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _ListQuotaGroups(QuotaServiceRestStub): + class _ListQuotaGroups( + _BaseQuotaServiceRestTransport._BaseListQuotaGroups, QuotaServiceRestStub + ): def __hash__(self): - return hash("ListQuotaGroups") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("QuotaServiceRestTransport.ListQuotaGroups") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -237,40 +238,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/quota/v1beta/{parent=accounts/*}/quotas", - }, - ] + http_options = ( + _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_http_options() + ) request, metadata = self._interceptor.pre_list_quota_groups( request, metadata ) - pb_request = quota.ListQuotaGroupsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = QuotaServiceRestTransport._ListQuotaGroups._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py new file mode 100644 index 000000000000..93ce65140753 --- /dev/null +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_quota_v1beta.types import quota + +from .base import DEFAULT_CLIENT_INFO, QuotaServiceTransport + + +class _BaseQuotaServiceRestTransport(QuotaServiceTransport): + """Base REST backend transport for QuotaService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseListQuotaGroups: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/quota/v1beta/{parent=accounts/*}/quotas", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = quota.ListQuotaGroupsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseQuotaServiceRestTransport",) diff --git a/packages/google-shopping-merchant-quota/setup.py b/packages/google-shopping-merchant-quota/setup.py index 237b5e06efaf..88372d82ef49 100644 --- a/packages/google-shopping-merchant-quota/setup.py +++ b/packages/google-shopping-merchant-quota/setup.py @@ -48,6 +48,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-quota" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -90,6 +91,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py b/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py index 8ec35cf70b33..6d693f42056b 100644 --- a/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py +++ b/packages/google-shopping-merchant-quota/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_quota_v1beta.services.quota_service import ( QuotaServiceAsyncClient, QuotaServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_quota_v1beta.types import quota +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1132,27 +1155,6 @@ def test_list_quota_groups(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_quota_groups_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_quota_groups() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == quota.ListQuotaGroupsRequest() - - def test_list_quota_groups_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1222,31 +1224,6 @@ def test_list_quota_groups_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_quota_groups_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - quota.ListQuotaGroupsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_quota_groups() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == quota.ListQuotaGroupsRequest() - - @pytest.mark.asyncio async def test_list_quota_groups_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1255,7 +1232,7 @@ async def test_list_quota_groups_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1294,7 +1271,7 @@ async def test_list_quota_groups_async( transport: str = "grpc_asyncio", request_type=quota.ListQuotaGroupsRequest ): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1364,7 +1341,7 @@ def test_list_quota_groups_field_headers(): @pytest.mark.asyncio async def test_list_quota_groups_field_headers_async(): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1438,7 +1415,7 @@ def test_list_quota_groups_flattened_error(): @pytest.mark.asyncio async def test_list_quota_groups_flattened_async(): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1469,7 +1446,7 @@ async def test_list_quota_groups_flattened_async(): @pytest.mark.asyncio async def test_list_quota_groups_flattened_error_async(): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1583,7 +1560,7 @@ def test_list_quota_groups_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_quota_groups_async_pager(): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1635,7 +1612,7 @@ async def test_list_quota_groups_async_pager(): @pytest.mark.asyncio async def test_list_quota_groups_async_pages(): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1683,46 +1660,6 @@ async def test_list_quota_groups_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - quota.ListQuotaGroupsRequest, - dict, - ], -) -def test_list_quota_groups_rest(request_type): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = quota.ListQuotaGroupsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = quota.ListQuotaGroupsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_quota_groups(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListQuotaGroupsPager) - assert response.next_page_token == "next_page_token_value" - - def test_list_quota_groups_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1859,85 +1796,6 @@ def test_list_quota_groups_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_quota_groups_rest_interceptors(null_interceptor): - transport = transports.QuotaServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.QuotaServiceRestInterceptor(), - ) - client = QuotaServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.QuotaServiceRestInterceptor, "post_list_quota_groups" - ) as post, mock.patch.object( - transports.QuotaServiceRestInterceptor, "pre_list_quota_groups" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = quota.ListQuotaGroupsRequest.pb(quota.ListQuotaGroupsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = quota.ListQuotaGroupsResponse.to_json( - quota.ListQuotaGroupsResponse() - ) - - request = quota.ListQuotaGroupsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = quota.ListQuotaGroupsResponse() - - client.list_quota_groups( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_quota_groups_rest_bad_request( - transport: str = "rest", request_type=quota.ListQuotaGroupsRequest -): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_quota_groups(request) - - def test_list_quota_groups_rest_flattened(): client = QuotaServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2147,18 +2005,237 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = QuotaServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_quota_groups_empty_call_grpc(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), "__call__" + ) as call: + call.return_value = quota.ListQuotaGroupsResponse() + client.list_quota_groups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = quota.ListQuotaGroupsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = QuotaServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_quota_groups_empty_call_grpc_asyncio(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + quota.ListQuotaGroupsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_quota_groups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = quota.ListQuotaGroupsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = QuotaServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_quota_groups_rest_bad_request(request_type=quota.ListQuotaGroupsRequest): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_quota_groups(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + quota.ListQuotaGroupsRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = QuotaServiceClient.get_transport_class(transport_name)( +def test_list_quota_groups_rest_call_success(request_type): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = quota.ListQuotaGroupsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = quota.ListQuotaGroupsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_quota_groups(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListQuotaGroupsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_quota_groups_rest_interceptors(null_interceptor): + transport = transports.QuotaServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.QuotaServiceRestInterceptor(), ) - assert transport.kind == transport_name + client = QuotaServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.QuotaServiceRestInterceptor, "post_list_quota_groups" + ) as post, mock.patch.object( + transports.QuotaServiceRestInterceptor, "pre_list_quota_groups" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = quota.ListQuotaGroupsRequest.pb(quota.ListQuotaGroupsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = quota.ListQuotaGroupsResponse.to_json( + quota.ListQuotaGroupsResponse() + ) + req.return_value.content = return_value + + request = quota.ListQuotaGroupsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = quota.ListQuotaGroupsResponse() + + client.list_quota_groups( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_quota_groups_empty_call_rest(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), "__call__" + ) as call: + client.list_quota_groups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = quota.ListQuotaGroupsRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2720,36 +2797,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = QuotaServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst new file mode 100644 index 000000000000..3ff494d6f149 --- /dev/null +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ReportServiceTransport` is the ABC for all transports. +- public child `ReportServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ReportServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseReportServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ReportServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py index f714e68e3286..881e4604c9c7 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -228,6 +229,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -272,15 +276,24 @@ def search( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.search: gapic_v1.method_async.wrap_method( + self.search: self._wrap_method( self.search, default_timeout=None, client_info=client_info, ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("ReportServiceGrpcAsyncIOTransport",) diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py index 055901232a8c..421e449776e6 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py @@ -16,31 +16,28 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from google.shopping.merchant_reports_v1beta.types import reports + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseReportServiceRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.shopping.merchant_reports_v1beta.types import reports - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import ReportServiceTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -104,8 +101,8 @@ class ReportServiceRestStub: _interceptor: ReportServiceRestInterceptor -class ReportServiceRestTransport(ReportServiceTransport): - """REST backend transport for ReportService. +class ReportServiceRestTransport(_BaseReportServiceRestTransport): + """REST backend synchronous transport for ReportService. Service for retrieving reports and insights about your products, their performance, and their competitive environment @@ -116,7 +113,6 @@ class ReportServiceRestTransport(ReportServiceTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -170,21 +166,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -195,19 +182,32 @@ def __init__( self._interceptor = interceptor or ReportServiceRestInterceptor() self._prep_wrapped_messages(client_info) - class _Search(ReportServiceRestStub): + class _Search(_BaseReportServiceRestTransport._BaseSearch, ReportServiceRestStub): def __hash__(self): - return hash("Search") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("ReportServiceRestTransport.Search") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -235,45 +235,36 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/reports/v1beta/{parent=accounts/*}/reports:search", - "body": "*", - }, - ] + http_options = ( + _BaseReportServiceRestTransport._BaseSearch._get_http_options() + ) request, metadata = self._interceptor.pre_search(request, metadata) - pb_request = reports.SearchRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseReportServiceRestTransport._BaseSearch._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseReportServiceRestTransport._BaseSearch._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseReportServiceRestTransport._BaseSearch._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = ReportServiceRestTransport._Search._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py new file mode 100644 index 000000000000..c09082060d60 --- /dev/null +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import json_format + +from google.shopping.merchant_reports_v1beta.types import reports + +from .base import DEFAULT_CLIENT_INFO, ReportServiceTransport + + +class _BaseReportServiceRestTransport(ReportServiceTransport): + """Base REST backend transport for ReportService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "merchantapi.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseSearch: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/reports/v1beta/{parent=accounts/*}/reports:search", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = reports.SearchRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseReportServiceRestTransport._BaseSearch._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseReportServiceRestTransport",) diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/types/reports.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/types/reports.py index ab35339ba41f..5b32972350bb 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/types/reports.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/types/reports.py @@ -703,11 +703,13 @@ class AggregatedReportingContextStatus(proto.Enum): Here's an example of how the aggregated status is computed: + ``` Free listings \| Shopping ads \| Status --------------|--------------|------------------------------ Approved \| Approved \| ELIGIBLE Approved \| Pending \| ELIGIBLE Approved \| Disapproved \| ELIGIBLE_LIMITED Pending \| Pending \| PENDING Disapproved \| Disapproved \| NOT_ELIGIBLE_OR_DISAPPROVED + ``` Values: AGGREGATED_REPORTING_CONTEXT_STATUS_UNSPECIFIED (0): diff --git a/packages/google-shopping-merchant-reports/scripts/client-post-processing/doc-formatting.yaml b/packages/google-shopping-merchant-reports/scripts/client-post-processing/doc-formatting.yaml new file mode 120000 index 000000000000..6e0991666f97 --- /dev/null +++ b/packages/google-shopping-merchant-reports/scripts/client-post-processing/doc-formatting.yaml @@ -0,0 +1 @@ +../../../../scripts/client-post-processing/doc-formatting.yaml \ No newline at end of file diff --git a/packages/google-shopping-merchant-reports/setup.py b/packages/google-shopping-merchant-reports/setup.py index 97aa3194c122..ae241c3f6800 100644 --- a/packages/google-shopping-merchant-reports/setup.py +++ b/packages/google-shopping-merchant-reports/setup.py @@ -49,6 +49,7 @@ "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-reports" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -91,6 +92,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py b/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py index fdc692e3c64d..a343efaa9d16 100644 --- a/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py +++ b/packages/google-shopping-merchant-reports/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py @@ -22,18 +22,11 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account +from google.api_core import api_core_version from google.protobuf import json_format import grpc from grpc.experimental import aio @@ -43,6 +36,22 @@ from requests import PreparedRequest, Request, Response from requests.sessions import Session +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account + from google.shopping.merchant_reports_v1beta.services.report_service import ( ReportServiceAsyncClient, ReportServiceClient, @@ -52,10 +61,24 @@ from google.shopping.merchant_reports_v1beta.types import reports +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + # If default endpoint is localhost, then default mtls endpoint will be the same. # This method modifies the default endpoint so the client can produce a different # mtls endpoint for endpoint testing purposes. @@ -1149,25 +1172,6 @@ def test_search(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_search_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.search() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == reports.SearchRequest() - - def test_search_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1235,36 +1239,13 @@ def test_search_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_search_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.search), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - reports.SearchResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.search() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == reports.SearchRequest() - - @pytest.mark.asyncio async def test_search_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1303,7 +1284,7 @@ async def test_search_async( transport: str = "grpc_asyncio", request_type=reports.SearchRequest ): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1369,7 +1350,7 @@ def test_search_field_headers(): @pytest.mark.asyncio async def test_search_field_headers_async(): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1439,7 +1420,7 @@ def test_search_flattened_error(): @pytest.mark.asyncio async def test_search_flattened_async(): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1468,7 +1449,7 @@ async def test_search_flattened_async(): @pytest.mark.asyncio async def test_search_flattened_error_async(): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1578,7 +1559,7 @@ def test_search_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_search_async_pager(): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1628,7 +1609,7 @@ async def test_search_async_pager(): @pytest.mark.asyncio async def test_search_async_pages(): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1672,46 +1653,6 @@ async def test_search_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - reports.SearchRequest, - dict, - ], -) -def test_search_rest(request_type): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = reports.SearchResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = reports.SearchResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.search(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.SearchPager) - assert response.next_page_token == "next_page_token_value" - - def test_search_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -1842,85 +1783,6 @@ def test_search_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_search_rest_interceptors(null_interceptor): - transport = transports.ReportServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ReportServiceRestInterceptor(), - ) - client = ReportServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ReportServiceRestInterceptor, "post_search" - ) as post, mock.patch.object( - transports.ReportServiceRestInterceptor, "pre_search" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = reports.SearchRequest.pb(reports.SearchRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = reports.SearchResponse.to_json( - reports.SearchResponse() - ) - - request = reports.SearchRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = reports.SearchResponse() - - client.search( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_search_rest_bad_request( - transport: str = "rest", request_type=reports.SearchRequest -): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "accounts/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.search(request) - - def test_search_rest_flattened(): client = ReportServiceClient( credentials=ga_credentials.AnonymousCredentials(), @@ -2131,18 +1993,229 @@ def test_transport_adc(transport_class): adc.assert_called_once() +def test_transport_kind_grpc(): + transport = ReportServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_empty_call_grpc(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search), "__call__") as call: + call.return_value = reports.SearchResponse() + client.search(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reports.SearchRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ReportServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_empty_call_grpc_asyncio(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + reports.SearchResponse( + next_page_token="next_page_token_value", + ) + ) + await client.search(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reports.SearchRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ReportServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_search_rest_bad_request(request_type=reports.SearchRequest): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.search(request) + + @pytest.mark.parametrize( - "transport_name", + "request_type", [ - "grpc", - "rest", + reports.SearchRequest, + dict, ], ) -def test_transport_kind(transport_name): - transport = ReportServiceClient.get_transport_class(transport_name)( +def test_search_rest_call_success(request_type): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "accounts/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = reports.SearchResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = reports.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.search(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_rest_interceptors(null_interceptor): + transport = transports.ReportServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ReportServiceRestInterceptor(), + ) + client = ReportServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ReportServiceRestInterceptor, "post_search" + ) as post, mock.patch.object( + transports.ReportServiceRestInterceptor, "pre_search" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = reports.SearchRequest.pb(reports.SearchRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = reports.SearchResponse.to_json(reports.SearchResponse()) + req.return_value.content = return_value + + request = reports.SearchRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = reports.SearchResponse() + + client.search( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_empty_call_rest(): + client = ReportServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.search), "__call__") as call: + client.search(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reports.SearchRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -2690,36 +2763,41 @@ def test_client_with_default_client_info(): prep.assert_called_once_with(client_info) +def test_transport_close_grpc(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = ReportServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/packages/google-shopping-type/setup.py b/packages/google-shopping-type/setup.py index e0c14fe5f9cf..c8c4ed59e373 100644 --- a/packages/google-shopping-type/setup.py +++ b/packages/google-shopping-type/setup.py @@ -46,6 +46,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-type" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -88,6 +89,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/README.rst b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/README.rst new file mode 100644 index 000000000000..1085202fe2c8 --- /dev/null +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`GrafeasTransport` is the ABC for all transports. +- public child `GrafeasGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `GrafeasGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseGrafeasRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `GrafeasRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py index 12f24288228c..4e5d15d67078 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import inspect from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings @@ -242,6 +243,9 @@ def __init__( ) # Wrap messages. This must be done after self._grpc_channel exists + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) self._prep_wrapped_messages(client_info) @property @@ -636,7 +640,7 @@ def list_note_occurrences( def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { - self.get_occurrence: gapic_v1.method_async.wrap_method( + self.get_occurrence: self._wrap_method( self.get_occurrence, default_retry=retries.AsyncRetry( initial=0.1, @@ -651,7 +655,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.list_occurrences: gapic_v1.method_async.wrap_method( + self.list_occurrences: self._wrap_method( self.list_occurrences, default_retry=retries.AsyncRetry( initial=0.1, @@ -666,7 +670,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.delete_occurrence: gapic_v1.method_async.wrap_method( + self.delete_occurrence: self._wrap_method( self.delete_occurrence, default_retry=retries.AsyncRetry( initial=0.1, @@ -681,22 +685,22 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.create_occurrence: gapic_v1.method_async.wrap_method( + self.create_occurrence: self._wrap_method( self.create_occurrence, default_timeout=30.0, client_info=client_info, ), - self.batch_create_occurrences: gapic_v1.method_async.wrap_method( + self.batch_create_occurrences: self._wrap_method( self.batch_create_occurrences, default_timeout=30.0, client_info=client_info, ), - self.update_occurrence: gapic_v1.method_async.wrap_method( + self.update_occurrence: self._wrap_method( self.update_occurrence, default_timeout=30.0, client_info=client_info, ), - self.get_occurrence_note: gapic_v1.method_async.wrap_method( + self.get_occurrence_note: self._wrap_method( self.get_occurrence_note, default_retry=retries.AsyncRetry( initial=0.1, @@ -711,7 +715,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.get_note: gapic_v1.method_async.wrap_method( + self.get_note: self._wrap_method( self.get_note, default_retry=retries.AsyncRetry( initial=0.1, @@ -726,7 +730,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.list_notes: gapic_v1.method_async.wrap_method( + self.list_notes: self._wrap_method( self.list_notes, default_retry=retries.AsyncRetry( initial=0.1, @@ -741,7 +745,7 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.delete_note: gapic_v1.method_async.wrap_method( + self.delete_note: self._wrap_method( self.delete_note, default_retry=retries.AsyncRetry( initial=0.1, @@ -756,22 +760,22 @@ def _prep_wrapped_messages(self, client_info): default_timeout=30.0, client_info=client_info, ), - self.create_note: gapic_v1.method_async.wrap_method( + self.create_note: self._wrap_method( self.create_note, default_timeout=30.0, client_info=client_info, ), - self.batch_create_notes: gapic_v1.method_async.wrap_method( + self.batch_create_notes: self._wrap_method( self.batch_create_notes, default_timeout=30.0, client_info=client_info, ), - self.update_note: gapic_v1.method_async.wrap_method( + self.update_note: self._wrap_method( self.update_note, default_timeout=30.0, client_info=client_info, ), - self.list_note_occurrences: gapic_v1.method_async.wrap_method( + self.list_note_occurrences: self._wrap_method( self.list_note_occurrences, default_retry=retries.AsyncRetry( initial=0.1, @@ -788,8 +792,17 @@ def _prep_wrapped_messages(self, client_info): ), } + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + def close(self): return self.grpc_channel.close() + @property + def kind(self) -> str: + return "grpc_asyncio" + __all__ = ("GrafeasGrpcAsyncIOTransport",) diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py index 00fff7011546..461bc835d063 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py @@ -16,33 +16,29 @@ import dataclasses import json # type: ignore -import re from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import empty_pb2 # type: ignore from google.protobuf import json_format -import grpc # type: ignore from requests import __version__ as requests_version +from grafeas.grafeas_v1.types import grafeas + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseGrafeasRestTransport + try: OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object, None] # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -from grafeas.grafeas_v1.types import grafeas - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import GrafeasTransport - DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, @@ -461,8 +457,8 @@ class GrafeasRestStub: _interceptor: GrafeasRestInterceptor -class GrafeasRestTransport(GrafeasTransport): - """REST backend transport for Grafeas. +class GrafeasRestTransport(_BaseGrafeasRestTransport): + """REST backend synchronous transport for Grafeas. `Grafeas `__ API. @@ -486,7 +482,6 @@ class GrafeasRestTransport(GrafeasTransport): and call it. It sends JSON representations of protocol buffers over HTTP/1.1 - """ def __init__( @@ -540,21 +535,12 @@ def __init__( # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - super().__init__( host=host, credentials=credentials, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, api_audience=api_audience, ) self._session = AuthorizedSession( @@ -565,19 +551,34 @@ def __init__( self._interceptor = interceptor or GrafeasRestInterceptor() self._prep_wrapped_messages(client_info) - class _BatchCreateNotes(GrafeasRestStub): + class _BatchCreateNotes( + _BaseGrafeasRestTransport._BaseBatchCreateNotes, GrafeasRestStub + ): def __hash__(self): - return hash("BatchCreateNotes") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.BatchCreateNotes") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -603,52 +604,40 @@ def __call__( Response for creating notes in batch. """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*}/notes:batchCreate", - "body": "*", - }, - { - "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}/notes:batchCreate", - "body": "*", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_http_options() + ) request, metadata = self._interceptor.pre_batch_create_notes( request, metadata ) - pb_request = grafeas.BatchCreateNotesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = ( + _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_request_body_json( + transcoded_request + ) ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = GrafeasRestTransport._BatchCreateNotes._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -664,19 +653,34 @@ def __call__( resp = self._interceptor.post_batch_create_notes(resp) return resp - class _BatchCreateOccurrences(GrafeasRestStub): + class _BatchCreateOccurrences( + _BaseGrafeasRestTransport._BaseBatchCreateOccurrences, GrafeasRestStub + ): def __hash__(self): - return hash("BatchCreateOccurrences") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.BatchCreateOccurrences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -705,52 +709,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*}/occurrences:batchCreate", - "body": "*", - }, - { - "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}/occurrences:batchCreate", - "body": "*", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_http_options() + ) request, metadata = self._interceptor.pre_batch_create_occurrences( request, metadata ) - pb_request = grafeas.BatchCreateOccurrencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_transcoded_request( + http_options, request + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = GrafeasRestTransport._BatchCreateOccurrences._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -766,21 +752,32 @@ def __call__( resp = self._interceptor.post_batch_create_occurrences(resp) return resp - class _CreateNote(GrafeasRestStub): + class _CreateNote(_BaseGrafeasRestTransport._BaseCreateNote, GrafeasRestStub): def __hash__(self): - return hash("CreateNote") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "noteId": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.CreateNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -808,50 +805,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*}/notes", - "body": "note", - }, - { - "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}/notes", - "body": "note", - }, - ] + http_options = _BaseGrafeasRestTransport._BaseCreateNote._get_http_options() request, metadata = self._interceptor.pre_create_note(request, metadata) - pb_request = grafeas.CreateNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseGrafeasRestTransport._BaseCreateNote._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseGrafeasRestTransport._BaseCreateNote._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseCreateNote._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = GrafeasRestTransport._CreateNote._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -867,19 +848,34 @@ def __call__( resp = self._interceptor.post_create_note(resp) return resp - class _CreateOccurrence(GrafeasRestStub): + class _CreateOccurrence( + _BaseGrafeasRestTransport._BaseCreateOccurrence, GrafeasRestStub + ): def __hash__(self): - return hash("CreateOccurrence") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.CreateOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -907,52 +903,40 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{parent=projects/*}/occurrences", - "body": "occurrence", - }, - { - "method": "post", - "uri": "/v1/{parent=projects/*/locations/*}/occurrences", - "body": "occurrence", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseCreateOccurrence._get_http_options() + ) request, metadata = self._interceptor.pre_create_occurrence( request, metadata ) - pb_request = grafeas.CreateOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseGrafeasRestTransport._BaseCreateOccurrence._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = ( + _BaseGrafeasRestTransport._BaseCreateOccurrence._get_request_body_json( + transcoded_request + ) ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseCreateOccurrence._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = GrafeasRestTransport._CreateOccurrence._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -968,19 +952,31 @@ def __call__( resp = self._interceptor.post_create_occurrence(resp) return resp - class _DeleteNote(GrafeasRestStub): + class _DeleteNote(_BaseGrafeasRestTransport._BaseDeleteNote, GrafeasRestStub): def __hash__(self): - return hash("DeleteNote") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.DeleteNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1002,42 +998,29 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1/{name=projects/*/notes/*}", - }, - { - "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/notes/*}", - }, - ] + http_options = _BaseGrafeasRestTransport._BaseDeleteNote._get_http_options() request, metadata = self._interceptor.pre_delete_note(request, metadata) - pb_request = grafeas.DeleteNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseGrafeasRestTransport._BaseDeleteNote._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseDeleteNote._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._DeleteNote._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1045,19 +1028,33 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _DeleteOccurrence(GrafeasRestStub): + class _DeleteOccurrence( + _BaseGrafeasRestTransport._BaseDeleteOccurrence, GrafeasRestStub + ): def __hash__(self): - return hash("DeleteOccurrence") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.DeleteOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1079,44 +1076,33 @@ def __call__( sent along with the request as metadata. """ - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1/{name=projects/*/occurrences/*}", - }, - { - "method": "delete", - "uri": "/v1/{name=projects/*/locations/*/occurrences/*}", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_http_options() + ) request, metadata = self._interceptor.pre_delete_occurrence( request, metadata ) - pb_request = grafeas.DeleteOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._DeleteOccurrence._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1124,19 +1110,31 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) - class _GetNote(GrafeasRestStub): + class _GetNote(_BaseGrafeasRestTransport._BaseGetNote, GrafeasRestStub): def __hash__(self): - return hash("GetNote") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.GetNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1164,42 +1162,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=projects/*/notes/*}", - }, - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/notes/*}", - }, - ] + http_options = _BaseGrafeasRestTransport._BaseGetNote._get_http_options() request, metadata = self._interceptor.pre_get_note(request, metadata) - pb_request = grafeas.GetNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseGrafeasRestTransport._BaseGetNote._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseGetNote._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._GetNote._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1215,19 +1200,31 @@ def __call__( resp = self._interceptor.post_get_note(resp) return resp - class _GetOccurrence(GrafeasRestStub): + class _GetOccurrence(_BaseGrafeasRestTransport._BaseGetOccurrence, GrafeasRestStub): def __hash__(self): - return hash("GetOccurrence") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.GetOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1255,42 +1252,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=projects/*/occurrences/*}", - }, - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/occurrences/*}", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseGetOccurrence._get_http_options() + ) request, metadata = self._interceptor.pre_get_occurrence(request, metadata) - pb_request = grafeas.GetOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseGrafeasRestTransport._BaseGetOccurrence._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseGetOccurrence._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._GetOccurrence._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1306,19 +1292,33 @@ def __call__( resp = self._interceptor.post_get_occurrence(resp) return resp - class _GetOccurrenceNote(GrafeasRestStub): + class _GetOccurrenceNote( + _BaseGrafeasRestTransport._BaseGetOccurrenceNote, GrafeasRestStub + ): def __hash__(self): - return hash("GetOccurrenceNote") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.GetOccurrenceNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1347,44 +1347,31 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=projects/*/occurrences/*}/notes", - }, - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/occurrences/*}/notes", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_http_options() + ) request, metadata = self._interceptor.pre_get_occurrence_note( request, metadata ) - pb_request = grafeas.GetOccurrenceNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._GetOccurrenceNote._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1400,19 +1387,33 @@ def __call__( resp = self._interceptor.post_get_occurrence_note(resp) return resp - class _ListNoteOccurrences(GrafeasRestStub): + class _ListNoteOccurrences( + _BaseGrafeasRestTransport._BaseListNoteOccurrences, GrafeasRestStub + ): def __hash__(self): - return hash("ListNoteOccurrences") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.ListNoteOccurrences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1441,44 +1442,29 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=projects/*/notes/*}/occurrences", - }, - { - "method": "get", - "uri": "/v1/{name=projects/*/locations/*/notes/*}/occurrences", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_http_options() + ) request, metadata = self._interceptor.pre_list_note_occurrences( request, metadata ) - pb_request = grafeas.ListNoteOccurrencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_transcoded_request( + http_options, request + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) + query_params = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_query_params_json( + transcoded_request ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._ListNoteOccurrences._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1494,19 +1480,31 @@ def __call__( resp = self._interceptor.post_list_note_occurrences(resp) return resp - class _ListNotes(GrafeasRestStub): + class _ListNotes(_BaseGrafeasRestTransport._BaseListNotes, GrafeasRestStub): def __hash__(self): - return hash("ListNotes") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.ListNotes") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1532,42 +1530,29 @@ def __call__( Response for listing notes. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=projects/*}/notes", - }, - { - "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/notes", - }, - ] + http_options = _BaseGrafeasRestTransport._BaseListNotes._get_http_options() request, metadata = self._interceptor.pre_list_notes(request, metadata) - pb_request = grafeas.ListNotesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseGrafeasRestTransport._BaseListNotes._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseListNotes._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._ListNotes._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1583,19 +1568,33 @@ def __call__( resp = self._interceptor.post_list_notes(resp) return resp - class _ListOccurrences(GrafeasRestStub): + class _ListOccurrences( + _BaseGrafeasRestTransport._BaseListOccurrences, GrafeasRestStub + ): def __hash__(self): - return hash("ListOccurrences") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.ListOccurrences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response def __call__( self, @@ -1621,44 +1620,33 @@ def __call__( Response for listing occurrences. """ - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{parent=projects/*}/occurrences", - }, - { - "method": "get", - "uri": "/v1/{parent=projects/*/locations/*}/occurrences", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseListOccurrences._get_http_options() + ) request, metadata = self._interceptor.pre_list_occurrences( request, metadata ) - pb_request = grafeas.ListOccurrencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] + transcoded_request = ( + _BaseGrafeasRestTransport._BaseListOccurrences._get_transcoded_request( + http_options, request + ) + ) # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseListOccurrences._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), + response = GrafeasRestTransport._ListOccurrences._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1674,19 +1662,32 @@ def __call__( resp = self._interceptor.post_list_occurrences(resp) return resp - class _UpdateNote(GrafeasRestStub): + class _UpdateNote(_BaseGrafeasRestTransport._BaseUpdateNote, GrafeasRestStub): def __hash__(self): - return hash("UpdateNote") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.UpdateNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -1714,50 +1715,34 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{name=projects/*/notes/*}", - "body": "note", - }, - { - "method": "patch", - "uri": "/v1/{name=projects/*/locations/*/notes/*}", - "body": "note", - }, - ] + http_options = _BaseGrafeasRestTransport._BaseUpdateNote._get_http_options() request, metadata = self._interceptor.pre_update_note(request, metadata) - pb_request = grafeas.UpdateNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseGrafeasRestTransport._BaseUpdateNote._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = _BaseGrafeasRestTransport._BaseUpdateNote._get_request_body_json( + transcoded_request ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseUpdateNote._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = GrafeasRestTransport._UpdateNote._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1773,19 +1758,34 @@ def __call__( resp = self._interceptor.post_update_note(resp) return resp - class _UpdateOccurrence(GrafeasRestStub): + class _UpdateOccurrence( + _BaseGrafeasRestTransport._BaseUpdateOccurrence, GrafeasRestStub + ): def __hash__(self): - return hash("UpdateOccurrence") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } + return hash("GrafeasRestTransport.UpdateOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response def __call__( self, @@ -1813,52 +1813,40 @@ def __call__( """ - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{name=projects/*/occurrences/*}", - "body": "occurrence", - }, - { - "method": "patch", - "uri": "/v1/{name=projects/*/locations/*/occurrences/*}", - "body": "occurrence", - }, - ] + http_options = ( + _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_http_options() + ) request, metadata = self._interceptor.pre_update_occurrence( request, metadata ) - pb_request = grafeas.UpdateOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body + transcoded_request = ( + _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_transcoded_request( + http_options, request + ) + ) - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True + body = ( + _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_request_body_json( + transcoded_request + ) ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, + query_params = ( + _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_query_params_json( + transcoded_request ) ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, + response = GrafeasRestTransport._UpdateOccurrence._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py new file mode 100644 index 000000000000..9b56c0b262bf --- /dev/null +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py @@ -0,0 +1,874 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from grafeas.grafeas_v1.types import grafeas + +from .base import DEFAULT_CLIENT_INFO, GrafeasTransport + + +class _BaseGrafeasRestTransport(GrafeasTransport): + """Base REST backend transport for Grafeas. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "containeranalysis.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'containeranalysis.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchCreateNotes: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*}/notes:batchCreate", + "body": "*", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/notes:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.BatchCreateNotesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchCreateOccurrences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*}/occurrences:batchCreate", + "body": "*", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/occurrences:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.BatchCreateOccurrencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "noteId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*}/notes", + "body": "note", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/notes", + "body": "note", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.CreateNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseCreateNote._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*}/occurrences", + "body": "occurrence", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/occurrences", + "body": "occurrence", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.CreateOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseCreateOccurrence._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/notes/*}", + }, + { + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/notes/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.DeleteNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseDeleteNote._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/occurrences/*}", + }, + { + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/occurrences/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.DeleteOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/notes/*}", + }, + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/notes/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.GetNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseGetNote._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/occurrences/*}", + }, + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/occurrences/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.GetOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseGetOccurrence._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOccurrenceNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/occurrences/*}/notes", + }, + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/occurrences/*}/notes", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.GetOccurrenceNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListNoteOccurrences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/notes/*}/occurrences", + }, + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/notes/*}/occurrences", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.ListNoteOccurrencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListNotes: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*}/notes", + }, + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/notes", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.ListNotesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseListNotes._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListOccurrences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*}/occurrences", + }, + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/occurrences", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.ListOccurrencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseListOccurrences._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{name=projects/*/notes/*}", + "body": "note", + }, + { + "method": "patch", + "uri": "/v1/{name=projects/*/locations/*/notes/*}", + "body": "note", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.UpdateNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseUpdateNote._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{name=projects/*/occurrences/*}", + "body": "occurrence", + }, + { + "method": "patch", + "uri": "/v1/{name=projects/*/locations/*/occurrences/*}", + "body": "occurrence", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.UpdateOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__ = ("_BaseGrafeasRestTransport",) diff --git a/packages/grafeas/setup.py b/packages/grafeas/setup.py index 77f4956769c6..96236b6dcd35 100644 --- a/packages/grafeas/setup.py +++ b/packages/grafeas/setup.py @@ -46,6 +46,7 @@ "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] +extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/grafeas" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -88,6 +89,7 @@ packages=packages, python_requires=">=3.7", install_requires=dependencies, + extras_require=extras, include_package_data=True, zip_safe=False, ) diff --git a/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py b/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py index 7974b1d1afdc..13faaea9b42b 100644 --- a/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py +++ b/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py @@ -22,12 +22,29 @@ except ImportError: # pragma: NO COVER import mock -from collections.abc import Iterable +from collections.abc import AsyncIterable, Iterable import json import math +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import api_core_version, client_options +from google.api_core import client_options from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries import google.auth @@ -36,17 +53,9 @@ from google.oauth2 import service_account from google.protobuf import any_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format from google.protobuf import struct_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session from grafeas.grafeas_v1.services.grafeas import ( GrafeasAsyncClient, @@ -79,10 +88,24 @@ ) +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + def client_cert_source_callback(): return b"cert bytes", b"key bytes" +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + @pytest.mark.parametrize( "request_type", [ @@ -127,25 +150,6 @@ def test_get_occurrence(request_type, transport: str = "grpc"): assert response.remediation == "remediation_value" -def test_get_occurrence_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_occurrence), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetOccurrenceRequest() - - def test_get_occurrence_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -209,33 +213,6 @@ def test_get_occurrence_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_occurrence_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_occurrence), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Occurrence( - name="name_value", - resource_uri="resource_uri_value", - note_name="note_name_value", - kind=common.NoteKind.VULNERABILITY, - remediation="remediation_value", - ) - ) - response = await client.get_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetOccurrenceRequest() - - @pytest.mark.asyncio async def test_get_occurrence_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -244,7 +221,7 @@ async def test_get_occurrence_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -283,7 +260,7 @@ async def test_get_occurrence_async( transport: str = "grpc_asyncio", request_type=grafeas.GetOccurrenceRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -357,7 +334,7 @@ def test_get_occurrence_field_headers(): @pytest.mark.asyncio async def test_get_occurrence_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -425,7 +402,7 @@ def test_get_occurrence_flattened_error(): @pytest.mark.asyncio async def test_get_occurrence_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -452,7 +429,7 @@ async def test_get_occurrence_flattened_async(): @pytest.mark.asyncio async def test_get_occurrence_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -500,25 +477,6 @@ def test_list_occurrences(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_occurrences_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_occurrences), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_occurrences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListOccurrencesRequest() - - def test_list_occurrences_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -588,29 +546,6 @@ def test_list_occurrences_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_occurrences_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_occurrences), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.ListOccurrencesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_occurrences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListOccurrencesRequest() - - @pytest.mark.asyncio async def test_list_occurrences_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -619,7 +554,7 @@ async def test_list_occurrences_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -658,7 +593,7 @@ async def test_list_occurrences_async( transport: str = "grpc_asyncio", request_type=grafeas.ListOccurrencesRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -724,7 +659,7 @@ def test_list_occurrences_field_headers(): @pytest.mark.asyncio async def test_list_occurrences_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -799,7 +734,7 @@ def test_list_occurrences_flattened_error(): @pytest.mark.asyncio async def test_list_occurrences_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -832,7 +767,7 @@ async def test_list_occurrences_flattened_async(): @pytest.mark.asyncio async def test_list_occurrences_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -943,7 +878,7 @@ def test_list_occurrences_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_occurrences_async_pager(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -993,7 +928,7 @@ async def test_list_occurrences_async_pager(): @pytest.mark.asyncio async def test_list_occurrences_async_pages(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1074,27 +1009,6 @@ def test_delete_occurrence(request_type, transport: str = "grpc"): assert response is None -def test_delete_occurrence_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.DeleteOccurrenceRequest() - - def test_delete_occurrence_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1162,27 +1076,6 @@ def test_delete_occurrence_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_occurrence_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.DeleteOccurrenceRequest() - - @pytest.mark.asyncio async def test_delete_occurrence_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1191,7 +1084,7 @@ async def test_delete_occurrence_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1230,7 +1123,7 @@ async def test_delete_occurrence_async( transport: str = "grpc_asyncio", request_type=grafeas.DeleteOccurrenceRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1295,7 +1188,7 @@ def test_delete_occurrence_field_headers(): @pytest.mark.asyncio async def test_delete_occurrence_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1367,7 +1260,7 @@ def test_delete_occurrence_flattened_error(): @pytest.mark.asyncio async def test_delete_occurrence_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1396,7 +1289,7 @@ async def test_delete_occurrence_flattened_async(): @pytest.mark.asyncio async def test_delete_occurrence_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1454,27 +1347,6 @@ def test_create_occurrence(request_type, transport: str = "grpc"): assert response.remediation == "remediation_value" -def test_create_occurrence_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.CreateOccurrenceRequest() - - def test_create_occurrence_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1542,35 +1414,6 @@ def test_create_occurrence_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_occurrence_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Occurrence( - name="name_value", - resource_uri="resource_uri_value", - note_name="note_name_value", - kind=common.NoteKind.VULNERABILITY, - remediation="remediation_value", - ) - ) - response = await client.create_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.CreateOccurrenceRequest() - - @pytest.mark.asyncio async def test_create_occurrence_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1579,7 +1422,7 @@ async def test_create_occurrence_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1618,7 +1461,7 @@ async def test_create_occurrence_async( transport: str = "grpc_asyncio", request_type=grafeas.CreateOccurrenceRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -1696,7 +1539,7 @@ def test_create_occurrence_field_headers(): @pytest.mark.asyncio async def test_create_occurrence_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -1773,7 +1616,7 @@ def test_create_occurrence_flattened_error(): @pytest.mark.asyncio async def test_create_occurrence_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1806,7 +1649,7 @@ async def test_create_occurrence_flattened_async(): @pytest.mark.asyncio async def test_create_occurrence_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -1854,27 +1697,6 @@ def test_batch_create_occurrences(request_type, transport: str = "grpc"): assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) -def test_batch_create_occurrences_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.batch_create_occurrences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.BatchCreateOccurrencesRequest() - - def test_batch_create_occurrences_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -1945,29 +1767,6 @@ def test_batch_create_occurrences_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_batch_create_occurrences_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.BatchCreateOccurrencesResponse() - ) - response = await client.batch_create_occurrences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.BatchCreateOccurrencesRequest() - - @pytest.mark.asyncio async def test_batch_create_occurrences_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -1976,7 +1775,7 @@ async def test_batch_create_occurrences_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2015,7 +1814,7 @@ async def test_batch_create_occurrences_async( transport: str = "grpc_asyncio", request_type=grafeas.BatchCreateOccurrencesRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2082,7 +1881,7 @@ def test_batch_create_occurrences_field_headers(): @pytest.mark.asyncio async def test_batch_create_occurrences_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2161,7 +1960,7 @@ def test_batch_create_occurrences_flattened_error(): @pytest.mark.asyncio async def test_batch_create_occurrences_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2196,7 +1995,7 @@ async def test_batch_create_occurrences_flattened_async(): @pytest.mark.asyncio async def test_batch_create_occurrences_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2255,27 +2054,6 @@ def test_update_occurrence(request_type, transport: str = "grpc"): assert response.remediation == "remediation_value" -def test_update_occurrence_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.UpdateOccurrenceRequest() - - def test_update_occurrence_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2344,45 +2122,16 @@ def test_update_occurrence_use_cached_wrapped_rpc(): @pytest.mark.asyncio -async def test_update_occurrence_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Occurrence( - name="name_value", - resource_uri="resource_uri_value", - note_name="note_name_value", - kind=common.NoteKind.VULNERABILITY, - remediation="remediation_value", - ) - ) - response = await client.update_occurrence() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.UpdateOccurrenceRequest() - - -@pytest.mark.asyncio -async def test_update_occurrence_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) +async def test_update_occurrence_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) # Should wrap all calls on client creation assert wrapper_fn.call_count > 0 @@ -2419,7 +2168,7 @@ async def test_update_occurrence_async( transport: str = "grpc_asyncio", request_type=grafeas.UpdateOccurrenceRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2497,7 +2246,7 @@ def test_update_occurrence_field_headers(): @pytest.mark.asyncio async def test_update_occurrence_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2579,7 +2328,7 @@ def test_update_occurrence_flattened_error(): @pytest.mark.asyncio async def test_update_occurrence_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -2616,7 +2365,7 @@ async def test_update_occurrence_flattened_async(): @pytest.mark.asyncio async def test_update_occurrence_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -2676,27 +2425,6 @@ def test_get_occurrence_note(request_type, transport: str = "grpc"): assert response.related_note_names == ["related_note_names_value"] -def test_get_occurrence_note_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_occurrence_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetOccurrenceNoteRequest() - - def test_get_occurrence_note_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -2766,35 +2494,6 @@ def test_get_occurrence_note_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_occurrence_note_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Note( - name="name_value", - short_description="short_description_value", - long_description="long_description_value", - kind=common.NoteKind.VULNERABILITY, - related_note_names=["related_note_names_value"], - ) - ) - response = await client.get_occurrence_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetOccurrenceNoteRequest() - - @pytest.mark.asyncio async def test_get_occurrence_note_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -2803,7 +2502,7 @@ async def test_get_occurrence_note_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2842,7 +2541,7 @@ async def test_get_occurrence_note_async( transport: str = "grpc_asyncio", request_type=grafeas.GetOccurrenceNoteRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -2920,7 +2619,7 @@ def test_get_occurrence_note_field_headers(): @pytest.mark.asyncio async def test_get_occurrence_note_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -2992,7 +2691,7 @@ def test_get_occurrence_note_flattened_error(): @pytest.mark.asyncio async def test_get_occurrence_note_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3021,7 +2720,7 @@ async def test_get_occurrence_note_flattened_async(): @pytest.mark.asyncio async def test_get_occurrence_note_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3077,25 +2776,6 @@ def test_get_note(request_type, transport: str = "grpc"): assert response.related_note_names == ["related_note_names_value"] -def test_get_note_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_note), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetNoteRequest() - - def test_get_note_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3159,40 +2839,13 @@ def test_get_note_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_get_note_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_note), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Note( - name="name_value", - short_description="short_description_value", - long_description="long_description_value", - kind=common.NoteKind.VULNERABILITY, - related_note_names=["related_note_names_value"], - ) - ) - response = await client.get_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetNoteRequest() - - @pytest.mark.asyncio async def test_get_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3231,7 +2884,7 @@ async def test_get_note_async( transport: str = "grpc_asyncio", request_type=grafeas.GetNoteRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3305,7 +2958,7 @@ def test_get_note_field_headers(): @pytest.mark.asyncio async def test_get_note_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3373,7 +3026,7 @@ def test_get_note_flattened_error(): @pytest.mark.asyncio async def test_get_note_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3400,7 +3053,7 @@ async def test_get_note_flattened_async(): @pytest.mark.asyncio async def test_get_note_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3448,25 +3101,6 @@ def test_list_notes(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_notes_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_notes), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_notes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListNotesRequest() - - def test_list_notes_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -3534,36 +3168,13 @@ def test_list_notes_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_notes_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_notes), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.ListNotesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_notes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListNotesRequest() - - @pytest.mark.asyncio async def test_list_notes_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3602,7 +3213,7 @@ async def test_list_notes_async( transport: str = "grpc_asyncio", request_type=grafeas.ListNotesRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -3668,7 +3279,7 @@ def test_list_notes_field_headers(): @pytest.mark.asyncio async def test_list_notes_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -3743,7 +3354,7 @@ def test_list_notes_flattened_error(): @pytest.mark.asyncio async def test_list_notes_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3776,7 +3387,7 @@ async def test_list_notes_flattened_async(): @pytest.mark.asyncio async def test_list_notes_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -3887,7 +3498,7 @@ def test_list_notes_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_notes_async_pager(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3937,7 +3548,7 @@ async def test_list_notes_async_pager(): @pytest.mark.asyncio async def test_list_notes_async_pages(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4016,25 +3627,6 @@ def test_delete_note(request_type, transport: str = "grpc"): assert response is None -def test_delete_note_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_note), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.DeleteNoteRequest() - - def test_delete_note_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -4098,25 +3690,6 @@ def test_delete_note_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_delete_note_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_note), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.DeleteNoteRequest() - - @pytest.mark.asyncio async def test_delete_note_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -4125,7 +3698,7 @@ async def test_delete_note_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4164,7 +3737,7 @@ async def test_delete_note_async( transport: str = "grpc_asyncio", request_type=grafeas.DeleteNoteRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4225,7 +3798,7 @@ def test_delete_note_field_headers(): @pytest.mark.asyncio async def test_delete_note_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -4293,7 +3866,7 @@ def test_delete_note_flattened_error(): @pytest.mark.asyncio async def test_delete_note_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4320,7 +3893,7 @@ async def test_delete_note_flattened_async(): @pytest.mark.asyncio async def test_delete_note_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -4376,25 +3949,6 @@ def test_create_note(request_type, transport: str = "grpc"): assert response.related_note_names == ["related_note_names_value"] -def test_create_note_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_note), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.create_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.CreateNoteRequest() - - def test_create_note_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -4460,33 +4014,6 @@ def test_create_note_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_create_note_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.create_note), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Note( - name="name_value", - short_description="short_description_value", - long_description="long_description_value", - kind=common.NoteKind.VULNERABILITY, - related_note_names=["related_note_names_value"], - ) - ) - response = await client.create_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.CreateNoteRequest() - - @pytest.mark.asyncio async def test_create_note_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -4495,7 +4022,7 @@ async def test_create_note_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4534,7 +4061,7 @@ async def test_create_note_async( transport: str = "grpc_asyncio", request_type=grafeas.CreateNoteRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4608,7 +4135,7 @@ def test_create_note_field_headers(): @pytest.mark.asyncio async def test_create_note_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -4686,7 +4213,7 @@ def test_create_note_flattened_error(): @pytest.mark.asyncio async def test_create_note_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4721,7 +4248,7 @@ async def test_create_note_flattened_async(): @pytest.mark.asyncio async def test_create_note_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -4770,27 +4297,6 @@ def test_batch_create_notes(request_type, transport: str = "grpc"): assert isinstance(response, grafeas.BatchCreateNotesResponse) -def test_batch_create_notes_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.batch_create_notes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.BatchCreateNotesRequest() - - def test_batch_create_notes_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -4860,29 +4366,6 @@ def test_batch_create_notes_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_batch_create_notes_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.BatchCreateNotesResponse() - ) - response = await client.batch_create_notes() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.BatchCreateNotesRequest() - - @pytest.mark.asyncio async def test_batch_create_notes_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -4891,7 +4374,7 @@ async def test_batch_create_notes_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4930,7 +4413,7 @@ async def test_batch_create_notes_async( transport: str = "grpc_asyncio", request_type=grafeas.BatchCreateNotesRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -4997,7 +4480,7 @@ def test_batch_create_notes_field_headers(): @pytest.mark.asyncio async def test_batch_create_notes_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -5076,7 +4559,7 @@ def test_batch_create_notes_flattened_error(): @pytest.mark.asyncio async def test_batch_create_notes_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -5111,7 +4594,7 @@ async def test_batch_create_notes_flattened_async(): @pytest.mark.asyncio async def test_batch_create_notes_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -5168,25 +4651,6 @@ def test_update_note(request_type, transport: str = "grpc"): assert response.related_note_names == ["related_note_names_value"] -def test_update_note_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_note), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.UpdateNoteRequest() - - def test_update_note_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -5250,33 +4714,6 @@ def test_update_note_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_update_note_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_note), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.Note( - name="name_value", - short_description="short_description_value", - long_description="long_description_value", - kind=common.NoteKind.VULNERABILITY, - related_note_names=["related_note_names_value"], - ) - ) - response = await client.update_note() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.UpdateNoteRequest() - - @pytest.mark.asyncio async def test_update_note_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -5285,7 +4722,7 @@ async def test_update_note_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -5324,7 +4761,7 @@ async def test_update_note_async( transport: str = "grpc_asyncio", request_type=grafeas.UpdateNoteRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -5398,7 +4835,7 @@ def test_update_note_field_headers(): @pytest.mark.asyncio async def test_update_note_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -5476,7 +4913,7 @@ def test_update_note_flattened_error(): @pytest.mark.asyncio async def test_update_note_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -5511,7 +4948,7 @@ async def test_update_note_flattened_async(): @pytest.mark.asyncio async def test_update_note_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -5563,27 +5000,6 @@ def test_list_note_occurrences(request_type, transport: str = "grpc"): assert response.next_page_token == "next_page_token_value" -def test_list_note_occurrences_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), "__call__" - ) as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_note_occurrences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListNoteOccurrencesRequest() - - def test_list_note_occurrences_non_empty_request_with_auto_populated_field(): # This test is a coverage failsafe to make sure that UUID4 fields are # automatically populated, according to AIP-4235, with non-empty requests. @@ -5658,31 +5074,6 @@ def test_list_note_occurrences_use_cached_wrapped_rpc(): assert mock_rpc.call_count == 2 -@pytest.mark.asyncio -async def test_list_note_occurrences_empty_call_async(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - grafeas.ListNoteOccurrencesResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_note_occurrences() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListNoteOccurrencesRequest() - - @pytest.mark.asyncio async def test_list_note_occurrences_async_use_cached_wrapped_rpc( transport: str = "grpc_asyncio", @@ -5691,7 +5082,7 @@ async def test_list_note_occurrences_async_use_cached_wrapped_rpc( # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -5730,7 +5121,7 @@ async def test_list_note_occurrences_async( transport: str = "grpc_asyncio", request_type=grafeas.ListNoteOccurrencesRequest ): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), transport=transport, ) @@ -5800,7 +5191,7 @@ def test_list_note_occurrences_field_headers(): @pytest.mark.asyncio async def test_list_note_occurrences_field_headers_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Any value that is part of the HTTP/1.1 URI should be sent as @@ -5879,7 +5270,7 @@ def test_list_note_occurrences_flattened_error(): @pytest.mark.asyncio async def test_list_note_occurrences_flattened_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -5914,7 +5305,7 @@ async def test_list_note_occurrences_flattened_async(): @pytest.mark.asyncio async def test_list_note_occurrences_flattened_error_async(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Attempting to call a method with both a request object and flattened @@ -6029,7 +5420,7 @@ def test_list_note_occurrences_pages(transport_name: str = "grpc"): @pytest.mark.asyncio async def test_list_note_occurrences_async_pager(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -6081,7 +5472,7 @@ async def test_list_note_occurrences_async_pager(): @pytest.mark.asyncio async def test_list_note_occurrences_async_pages(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), + credentials=async_anonymous_credentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -6129,54 +5520,6 @@ async def test_list_note_occurrences_async_pages(): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - grafeas.GetOccurrenceRequest, - dict, - ], -) -def test_get_occurrence_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence( - name="name_value", - resource_uri="resource_uri_value", - note_name="note_name_value", - kind=common.NoteKind.VULNERABILITY, - remediation="remediation_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_occurrence(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == "name_value" - assert response.resource_uri == "resource_uri_value" - assert response.note_name == "note_name_value" - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == "remediation_value" - - def test_get_occurrence_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -6294,81 +5637,6 @@ def test_get_occurrence_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_get_occurrence" - ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_get_occurrence" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.GetOccurrenceRequest.pb(grafeas.GetOccurrenceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Occurrence.to_json(grafeas.Occurrence()) - - request = grafeas.GetOccurrenceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Occurrence() - - client.get_occurrence( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_occurrence_rest_bad_request( - transport: str = "rest", request_type=grafeas.GetOccurrenceRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_occurrence(request) - - def test_get_occurrence_rest_flattened(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), @@ -6424,72 +5692,26 @@ def test_get_occurrence_rest_flattened_error(transport: str = "rest"): ) -def test_get_occurrence_rest_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - +def test_list_occurrences_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -@pytest.mark.parametrize( - "request_type", - [ - grafeas.ListOccurrencesRequest, - dict, - ], -) -def test_list_occurrences_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) + # Ensure method has been cached + assert client._transport.list_occurrences in client._transport._wrapped_methods - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.ListOccurrencesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.ListOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_occurrences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOccurrencesPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_occurrences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ client._transport.list_occurrences @@ -6608,83 +5830,6 @@ def test_list_occurrences_rest_unset_required_fields(): ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_occurrences_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_list_occurrences" - ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_list_occurrences" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.ListOccurrencesRequest.pb(grafeas.ListOccurrencesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.ListOccurrencesResponse.to_json( - grafeas.ListOccurrencesResponse() - ) - - request = grafeas.ListOccurrencesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.ListOccurrencesResponse() - - client.list_occurrences( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_occurrences_rest_bad_request( - transport: str = "rest", request_type=grafeas.ListOccurrencesRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_occurrences(request) - - def test_list_occurrences_rest_flattened(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), @@ -6803,41 +5948,6 @@ def test_list_occurrences_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -@pytest.mark.parametrize( - "request_type", - [ - grafeas.DeleteOccurrenceRequest, - dict, - ], -) -def test_delete_occurrence_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_occurrence(request) - - # Establish that the response is the type that we expect. - assert response is None - - def test_delete_occurrence_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -6956,77 +6066,6 @@ def test_delete_occurrence_rest_unset_required_fields(): assert set(unset_fields) == (set(()) & set(("name",))) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_delete_occurrence" - ) as pre: - pre.assert_not_called() - pb_message = grafeas.DeleteOccurrenceRequest.pb( - grafeas.DeleteOccurrenceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - - request = grafeas.DeleteOccurrenceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_occurrence( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - - -def test_delete_occurrence_rest_bad_request( - transport: str = "rest", request_type=grafeas.DeleteOccurrenceRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_occurrence(request) - - def test_delete_occurrence_rest_flattened(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7080,1567 +6119,1925 @@ def test_delete_occurrence_rest_flattened_error(transport: str = "rest"): ) -def test_delete_occurrence_rest_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_create_occurrence_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() -@pytest.mark.parametrize( - "request_type", - [ - grafeas.CreateOccurrenceRequest, - dict, - ], -) -def test_create_occurrence_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Ensure method has been cached + assert client._transport.create_occurrence in client._transport._wrapped_methods - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request_init["occurrence"] = { - "name": "name_value", - "resource_uri": "resource_uri_value", - "note_name": "note_name_value", - "kind": 1, - "remediation": "remediation_value", - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "vulnerability": { - "type_": "type__value", - "severity": 1, - "cvss_score": 0.1082, - "cvssv3": { - "base_score": 0.1046, - "exploitability_score": 0.21580000000000002, - "impact_score": 0.1273, - "attack_vector": 1, - "attack_complexity": 1, - "authentication": 1, - "privileges_required": 1, - "user_interaction": 1, - "scope": 1, - "confidentiality_impact": 1, - "integrity_impact": 1, - "availability_impact": 1, - }, - "package_issue": [ - { - "affected_cpe_uri": "affected_cpe_uri_value", - "affected_package": "affected_package_value", - "affected_version": { - "epoch": 527, - "name": "name_value", - "revision": "revision_value", - "inclusive": True, - "kind": 1, - "full_name": "full_name_value", - }, - "fixed_cpe_uri": "fixed_cpe_uri_value", - "fixed_package": "fixed_package_value", - "fixed_version": {}, - "fix_available": True, - "package_type": "package_type_value", - "effective_severity": 1, - "file_location": [{"file_path": "file_path_value"}], - } - ], - "short_description": "short_description_value", - "long_description": "long_description_value", - "related_urls": [{"url": "url_value", "label": "label_value"}], - "effective_severity": 1, - "fix_available": True, - "cvss_version": 1, - "cvss_v2": {}, - "vex_assessment": { - "cve": "cve_value", - "vulnerability_id": "vulnerability_id_value", - "related_uris": {}, - "note_name": "note_name_value", - "state": 1, - "impacts": ["impacts_value1", "impacts_value2"], - "remediations": [ - { - "remediation_type": 1, - "details": "details_value", - "remediation_uri": {}, - } - ], - "justification": {"justification_type": 1, "details": "details_value"}, - }, - "extra_details": "extra_details_value", - }, - "build": { - "provenance": { - "id": "id_value", - "project_id": "project_id_value", - "commands": [ - { - "name": "name_value", - "env": ["env_value1", "env_value2"], - "args": ["args_value1", "args_value2"], - "dir_": "dir__value", - "id": "id_value", - "wait_for": ["wait_for_value1", "wait_for_value2"], - } - ], - "built_artifacts": [ - { - "checksum": "checksum_value", - "id": "id_value", - "names": ["names_value1", "names_value2"], - } - ], - "create_time": {}, - "start_time": {}, - "end_time": {}, - "creator": "creator_value", - "logs_uri": "logs_uri_value", - "source_provenance": { - "artifact_storage_source_uri": "artifact_storage_source_uri_value", - "file_hashes": {}, - "context": { - "cloud_repo": { - "repo_id": { - "project_repo_id": { - "project_id": "project_id_value", - "repo_name": "repo_name_value", - }, - "uid": "uid_value", - }, - "revision_id": "revision_id_value", - "alias_context": {"kind": 1, "name": "name_value"}, - }, - "gerrit": { - "host_uri": "host_uri_value", - "gerrit_project": "gerrit_project_value", - "revision_id": "revision_id_value", - "alias_context": {}, - }, - "git": {"url": "url_value", "revision_id": "revision_id_value"}, - "labels": {}, - }, - "additional_contexts": {}, - }, - "trigger_id": "trigger_id_value", - "build_options": {}, - "builder_version": "builder_version_value", - }, - "provenance_bytes": "provenance_bytes_value", - "intoto_provenance": { - "builder_config": {"id": "id_value"}, - "recipe": { - "type_": "type__value", - "defined_in_material": 1971, - "entry_point": "entry_point_value", - "arguments": [ - { - "type_url": "type.googleapis.com/google.protobuf.Duration", - "value": b"\x08\x0c\x10\xdb\x07", - } - ], - "environment": {}, - }, - "metadata": { - "build_invocation_id": "build_invocation_id_value", - "build_started_on": {}, - "build_finished_on": {}, - "completeness": { - "arguments": True, - "environment": True, - "materials": True, - }, - "reproducible": True, - }, - "materials": ["materials_value1", "materials_value2"], - }, - "intoto_statement": { - "type_": "type__value", - "subject": [{"name": "name_value", "digest": {}}], - "predicate_type": "predicate_type_value", - "provenance": {}, - "slsa_provenance": { - "builder": {"id": "id_value"}, - "recipe": { - "type_": "type__value", - "defined_in_material": 1971, - "entry_point": "entry_point_value", - "arguments": {}, - "environment": {}, - }, - "metadata": { - "build_invocation_id": "build_invocation_id_value", - "build_started_on": {}, - "build_finished_on": {}, - "completeness": { - "arguments": True, - "environment": True, - "materials": True, - }, - "reproducible": True, - }, - "materials": [{"uri": "uri_value", "digest": {}}], - }, - "slsa_provenance_zero_two": { - "builder": {"id": "id_value"}, - "build_type": "build_type_value", - "invocation": { - "config_source": { - "uri": "uri_value", - "digest": {}, - "entry_point": "entry_point_value", - }, - "parameters": {"fields": {}}, - "environment": {}, - }, - "build_config": {}, - "metadata": { - "build_invocation_id": "build_invocation_id_value", - "build_started_on": {}, - "build_finished_on": {}, - "completeness": { - "parameters": True, - "environment": True, - "materials": True, - }, - "reproducible": True, - }, - "materials": [{"uri": "uri_value", "digest": {}}], - }, - }, - "in_toto_slsa_provenance_v1": { - "type_": "type__value", - "subject": {}, - "predicate_type": "predicate_type_value", - "predicate": { - "build_definition": { - "build_type": "build_type_value", - "external_parameters": {}, - "internal_parameters": {}, - "resolved_dependencies": [ - { - "name": "name_value", - "uri": "uri_value", - "digest": {}, - "content": b"content_blob", - "download_location": "download_location_value", - "media_type": "media_type_value", - "annotations": {}, - } - ], - }, - "run_details": { - "builder": { - "id": "id_value", - "version": {}, - "builder_dependencies": {}, - }, - "metadata": { - "invocation_id": "invocation_id_value", - "started_on": {}, - "finished_on": {}, - }, - "byproducts": {}, - }, - }, - }, - }, - "image": { - "fingerprint": { - "v1_name": "v1_name_value", - "v2_blob": ["v2_blob_value1", "v2_blob_value2"], - "v2_name": "v2_name_value", - }, - "distance": 843, - "layer_info": [ - {"directive": "directive_value", "arguments": "arguments_value"} - ], - "base_resource_url": "base_resource_url_value", - }, - "package": { - "name": "name_value", - "location": [ - {"cpe_uri": "cpe_uri_value", "version": {}, "path": "path_value"} - ], - "package_type": "package_type_value", - "cpe_uri": "cpe_uri_value", - "architecture": 1, - "license_": { - "expression": "expression_value", - "comments": "comments_value", - }, - "version": {}, - }, - "deployment": { - "user_email": "user_email_value", - "deploy_time": {}, - "undeploy_time": {}, - "config": "config_value", - "address": "address_value", - "resource_uri": ["resource_uri_value1", "resource_uri_value2"], - "platform": 1, - }, - "discovery": { - "continuous_analysis": 1, - "analysis_status": 1, - "analysis_completed": { - "analysis_type": ["analysis_type_value1", "analysis_type_value2"] - }, - "analysis_error": [ - {"code": 411, "message": "message_value", "details": {}} - ], - "analysis_status_error": {}, - "cpe": "cpe_value", - "last_scan_time": {}, - "archive_time": {}, - "sbom_status": {"sbom_state": 1, "error": "error_value"}, - "vulnerability_attestation": { - "last_attempt_time": {}, - "state": 1, - "error": "error_value", - }, - }, - "attestation": { - "serialized_payload": b"serialized_payload_blob", - "signatures": [ - {"signature": b"signature_blob", "public_key_id": "public_key_id_value"} - ], - "jwts": [{"compact_jwt": "compact_jwt_value"}], - }, - "upgrade": { - "package": "package_value", - "parsed_version": {}, - "distribution": { - "cpe_uri": "cpe_uri_value", - "classification": "classification_value", - "severity": "severity_value", - "cve": ["cve_value1", "cve_value2"], - }, - "windows_update": { - "identity": {"update_id": "update_id_value", "revision": 879}, - "title": "title_value", - "description": "description_value", - "categories": [ - {"category_id": "category_id_value", "name": "name_value"} - ], - "kb_article_ids": ["kb_article_ids_value1", "kb_article_ids_value2"], - "support_url": "support_url_value", - "last_published_timestamp": {}, - }, - }, - "compliance": { - "non_compliant_files": [ - { - "path": "path_value", - "display_command": "display_command_value", - "reason": "reason_value", - } - ], - "non_compliance_reason": "non_compliance_reason_value", - "version": { - "cpe_uri": "cpe_uri_value", - "benchmark_document": "benchmark_document_value", - "version": "version_value", - }, - }, - "dsse_attestation": { - "envelope": { - "payload": b"payload_blob", - "payload_type": "payload_type_value", - "signatures": [{"sig": b"sig_blob", "keyid": "keyid_value"}], - }, - "statement": {}, - }, - "sbom_reference": { - "payload": { - "type_": "type__value", - "predicate_type": "predicate_type_value", - "subject": {}, - "predicate": { - "referrer_id": "referrer_id_value", - "location": "location_value", - "mime_type": "mime_type_value", - "digest": {}, - }, - }, - "payload_type": "payload_type_value", - "signatures": {}, - }, - "envelope": {}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = grafeas.CreateOccurrenceRequest.meta.fields["occurrence"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["occurrence"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["occurrence"][field])): - del request_init["occurrence"][field][i][subfield] - else: - del request_init["occurrence"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence( - name="name_value", - resource_uri="resource_uri_value", - note_name="note_name_value", - kind=common.NoteKind.VULNERABILITY, - remediation="remediation_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_occurrence(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == "name_value" - assert response.resource_uri == "resource_uri_value" - assert response.note_name == "note_name_value" - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == "remediation_value" - - -def test_create_occurrence_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.create_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.create_occurrence - ] = mock_rpc - - request = {} - client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.create_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_create_occurrence_rest_required_fields( - request_type=grafeas.CreateOccurrenceRequest, -): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_occurrence._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_occurrence._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.create_occurrence(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_create_occurrence_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.create_occurrence._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "parent", - "occurrence", - ) - ) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_create_occurrence" - ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_create_occurrence" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.CreateOccurrenceRequest.pb( - grafeas.CreateOccurrenceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Occurrence.to_json(grafeas.Occurrence()) - - request = grafeas.CreateOccurrenceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Occurrence() - - client.create_occurrence( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_occurrence_rest_bad_request( - transport: str = "rest", request_type=grafeas.CreateOccurrenceRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_occurrence(request) - - -def test_create_occurrence_rest_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - occurrence=grafeas.Occurrence(name="name_value"), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.create_occurrence(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*}/occurrences" % client.transport._host, args[1] - ) - - -def test_create_occurrence_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_occurrence( - grafeas.CreateOccurrenceRequest(), - parent="parent_value", - occurrence=grafeas.Occurrence(name="name_value"), - ) - - -def test_create_occurrence_rest_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - grafeas.BatchCreateOccurrencesRequest, - dict, - ], -) -def test_batch_create_occurrences_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateOccurrencesResponse() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.batch_create_occurrences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) - - -def test_batch_create_occurrences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.batch_create_occurrences - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.batch_create_occurrences - ] = mock_rpc - - request = {} - client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.batch_create_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_batch_create_occurrences_rest_required_fields( - request_type=grafeas.BatchCreateOccurrencesRequest, -): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).batch_create_occurrences._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).batch_create_occurrences._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateOccurrencesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.batch_create_occurrences(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_batch_create_occurrences_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.batch_create_occurrences._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "parent", - "occurrences", - ) - ) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_batch_create_occurrences_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_batch_create_occurrences" - ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_batch_create_occurrences" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.BatchCreateOccurrencesRequest.pb( - grafeas.BatchCreateOccurrencesRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.BatchCreateOccurrencesResponse.to_json( - grafeas.BatchCreateOccurrencesResponse() - ) - - request = grafeas.BatchCreateOccurrencesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.BatchCreateOccurrencesResponse() - - client.batch_create_occurrences( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_batch_create_occurrences_rest_bad_request( - transport: str = "rest", request_type=grafeas.BatchCreateOccurrencesRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.batch_create_occurrences(request) - - -def test_batch_create_occurrences_rest_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateOccurrencesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - occurrences=[grafeas.Occurrence(name="name_value")], - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.batch_create_occurrences(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*}/occurrences:batchCreate" - % client.transport._host, - args[1], - ) - - -def test_batch_create_occurrences_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.batch_create_occurrences( - grafeas.BatchCreateOccurrencesRequest(), - parent="parent_value", - occurrences=[grafeas.Occurrence(name="name_value")], - ) - - -def test_batch_create_occurrences_rest_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - grafeas.UpdateOccurrenceRequest, - dict, - ], -) -def test_update_occurrence_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request_init["occurrence"] = { - "name": "name_value", - "resource_uri": "resource_uri_value", - "note_name": "note_name_value", - "kind": 1, - "remediation": "remediation_value", - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "vulnerability": { - "type_": "type__value", - "severity": 1, - "cvss_score": 0.1082, - "cvssv3": { - "base_score": 0.1046, - "exploitability_score": 0.21580000000000002, - "impact_score": 0.1273, - "attack_vector": 1, - "attack_complexity": 1, - "authentication": 1, - "privileges_required": 1, - "user_interaction": 1, - "scope": 1, - "confidentiality_impact": 1, - "integrity_impact": 1, - "availability_impact": 1, - }, - "package_issue": [ - { - "affected_cpe_uri": "affected_cpe_uri_value", - "affected_package": "affected_package_value", - "affected_version": { - "epoch": 527, - "name": "name_value", - "revision": "revision_value", - "inclusive": True, - "kind": 1, - "full_name": "full_name_value", - }, - "fixed_cpe_uri": "fixed_cpe_uri_value", - "fixed_package": "fixed_package_value", - "fixed_version": {}, - "fix_available": True, - "package_type": "package_type_value", - "effective_severity": 1, - "file_location": [{"file_path": "file_path_value"}], - } - ], - "short_description": "short_description_value", - "long_description": "long_description_value", - "related_urls": [{"url": "url_value", "label": "label_value"}], - "effective_severity": 1, - "fix_available": True, - "cvss_version": 1, - "cvss_v2": {}, - "vex_assessment": { - "cve": "cve_value", - "vulnerability_id": "vulnerability_id_value", - "related_uris": {}, - "note_name": "note_name_value", - "state": 1, - "impacts": ["impacts_value1", "impacts_value2"], - "remediations": [ - { - "remediation_type": 1, - "details": "details_value", - "remediation_uri": {}, - } - ], - "justification": {"justification_type": 1, "details": "details_value"}, - }, - "extra_details": "extra_details_value", - }, - "build": { - "provenance": { - "id": "id_value", - "project_id": "project_id_value", - "commands": [ - { - "name": "name_value", - "env": ["env_value1", "env_value2"], - "args": ["args_value1", "args_value2"], - "dir_": "dir__value", - "id": "id_value", - "wait_for": ["wait_for_value1", "wait_for_value2"], - } - ], - "built_artifacts": [ - { - "checksum": "checksum_value", - "id": "id_value", - "names": ["names_value1", "names_value2"], - } - ], - "create_time": {}, - "start_time": {}, - "end_time": {}, - "creator": "creator_value", - "logs_uri": "logs_uri_value", - "source_provenance": { - "artifact_storage_source_uri": "artifact_storage_source_uri_value", - "file_hashes": {}, - "context": { - "cloud_repo": { - "repo_id": { - "project_repo_id": { - "project_id": "project_id_value", - "repo_name": "repo_name_value", - }, - "uid": "uid_value", - }, - "revision_id": "revision_id_value", - "alias_context": {"kind": 1, "name": "name_value"}, - }, - "gerrit": { - "host_uri": "host_uri_value", - "gerrit_project": "gerrit_project_value", - "revision_id": "revision_id_value", - "alias_context": {}, - }, - "git": {"url": "url_value", "revision_id": "revision_id_value"}, - "labels": {}, - }, - "additional_contexts": {}, - }, - "trigger_id": "trigger_id_value", - "build_options": {}, - "builder_version": "builder_version_value", - }, - "provenance_bytes": "provenance_bytes_value", - "intoto_provenance": { - "builder_config": {"id": "id_value"}, - "recipe": { - "type_": "type__value", - "defined_in_material": 1971, - "entry_point": "entry_point_value", - "arguments": [ - { - "type_url": "type.googleapis.com/google.protobuf.Duration", - "value": b"\x08\x0c\x10\xdb\x07", - } - ], - "environment": {}, - }, - "metadata": { - "build_invocation_id": "build_invocation_id_value", - "build_started_on": {}, - "build_finished_on": {}, - "completeness": { - "arguments": True, - "environment": True, - "materials": True, - }, - "reproducible": True, - }, - "materials": ["materials_value1", "materials_value2"], - }, - "intoto_statement": { - "type_": "type__value", - "subject": [{"name": "name_value", "digest": {}}], - "predicate_type": "predicate_type_value", - "provenance": {}, - "slsa_provenance": { - "builder": {"id": "id_value"}, - "recipe": { - "type_": "type__value", - "defined_in_material": 1971, - "entry_point": "entry_point_value", - "arguments": {}, - "environment": {}, - }, - "metadata": { - "build_invocation_id": "build_invocation_id_value", - "build_started_on": {}, - "build_finished_on": {}, - "completeness": { - "arguments": True, - "environment": True, - "materials": True, - }, - "reproducible": True, - }, - "materials": [{"uri": "uri_value", "digest": {}}], - }, - "slsa_provenance_zero_two": { - "builder": {"id": "id_value"}, - "build_type": "build_type_value", - "invocation": { - "config_source": { - "uri": "uri_value", - "digest": {}, - "entry_point": "entry_point_value", - }, - "parameters": {"fields": {}}, - "environment": {}, - }, - "build_config": {}, - "metadata": { - "build_invocation_id": "build_invocation_id_value", - "build_started_on": {}, - "build_finished_on": {}, - "completeness": { - "parameters": True, - "environment": True, - "materials": True, - }, - "reproducible": True, - }, - "materials": [{"uri": "uri_value", "digest": {}}], - }, - }, - "in_toto_slsa_provenance_v1": { - "type_": "type__value", - "subject": {}, - "predicate_type": "predicate_type_value", - "predicate": { - "build_definition": { - "build_type": "build_type_value", - "external_parameters": {}, - "internal_parameters": {}, - "resolved_dependencies": [ - { - "name": "name_value", - "uri": "uri_value", - "digest": {}, - "content": b"content_blob", - "download_location": "download_location_value", - "media_type": "media_type_value", - "annotations": {}, - } - ], - }, - "run_details": { - "builder": { - "id": "id_value", - "version": {}, - "builder_dependencies": {}, - }, - "metadata": { - "invocation_id": "invocation_id_value", - "started_on": {}, - "finished_on": {}, - }, - "byproducts": {}, - }, - }, - }, - }, - "image": { - "fingerprint": { - "v1_name": "v1_name_value", - "v2_blob": ["v2_blob_value1", "v2_blob_value2"], - "v2_name": "v2_name_value", - }, - "distance": 843, - "layer_info": [ - {"directive": "directive_value", "arguments": "arguments_value"} - ], - "base_resource_url": "base_resource_url_value", - }, - "package": { - "name": "name_value", - "location": [ - {"cpe_uri": "cpe_uri_value", "version": {}, "path": "path_value"} - ], - "package_type": "package_type_value", - "cpe_uri": "cpe_uri_value", - "architecture": 1, - "license_": { - "expression": "expression_value", - "comments": "comments_value", - }, - "version": {}, - }, - "deployment": { - "user_email": "user_email_value", - "deploy_time": {}, - "undeploy_time": {}, - "config": "config_value", - "address": "address_value", - "resource_uri": ["resource_uri_value1", "resource_uri_value2"], - "platform": 1, - }, - "discovery": { - "continuous_analysis": 1, - "analysis_status": 1, - "analysis_completed": { - "analysis_type": ["analysis_type_value1", "analysis_type_value2"] - }, - "analysis_error": [ - {"code": 411, "message": "message_value", "details": {}} - ], - "analysis_status_error": {}, - "cpe": "cpe_value", - "last_scan_time": {}, - "archive_time": {}, - "sbom_status": {"sbom_state": 1, "error": "error_value"}, - "vulnerability_attestation": { - "last_attempt_time": {}, - "state": 1, - "error": "error_value", - }, - }, - "attestation": { - "serialized_payload": b"serialized_payload_blob", - "signatures": [ - {"signature": b"signature_blob", "public_key_id": "public_key_id_value"} - ], - "jwts": [{"compact_jwt": "compact_jwt_value"}], - }, - "upgrade": { - "package": "package_value", - "parsed_version": {}, - "distribution": { - "cpe_uri": "cpe_uri_value", - "classification": "classification_value", - "severity": "severity_value", - "cve": ["cve_value1", "cve_value2"], - }, - "windows_update": { - "identity": {"update_id": "update_id_value", "revision": 879}, - "title": "title_value", - "description": "description_value", - "categories": [ - {"category_id": "category_id_value", "name": "name_value"} + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_occurrence + ] = mock_rpc + + request = {} + client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_occurrence_rest_required_fields( + request_type=grafeas.CreateOccurrenceRequest, +): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_occurrence._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_occurrence._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_occurrence(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_occurrence_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_occurrence._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "occurrence", + ) + ) + ) + + +def test_create_occurrence_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + occurrence=grafeas.Occurrence(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_occurrence(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*}/occurrences" % client.transport._host, args[1] + ) + + +def test_create_occurrence_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_occurrence( + grafeas.CreateOccurrenceRequest(), + parent="parent_value", + occurrence=grafeas.Occurrence(name="name_value"), + ) + + +def test_batch_create_occurrences_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_occurrences + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_occurrences + ] = mock_rpc + + request = {} + client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_occurrences_rest_required_fields( + request_type=grafeas.BatchCreateOccurrencesRequest, +): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_occurrences._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_occurrences._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateOccurrencesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.batch_create_occurrences(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_occurrences_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_occurrences._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "occurrences", + ) + ) + ) + + +def test_batch_create_occurrences_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateOccurrencesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + occurrences=[grafeas.Occurrence(name="name_value")], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.batch_create_occurrences(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*}/occurrences:batchCreate" + % client.transport._host, + args[1], + ) + + +def test_batch_create_occurrences_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_occurrences( + grafeas.BatchCreateOccurrencesRequest(), + parent="parent_value", + occurrences=[grafeas.Occurrence(name="name_value")], + ) + + +def test_update_occurrence_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_occurrence + ] = mock_rpc + + request = {} + client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_occurrence_rest_required_fields( + request_type=grafeas.UpdateOccurrenceRequest, +): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_occurrence._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_occurrence._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_occurrence(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_occurrence_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_occurrence._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "name", + "occurrence", + ) + ) + ) + + +def test_update_occurrence_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/occurrences/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + occurrence=grafeas.Occurrence(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_occurrence(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1] + ) + + +def test_update_occurrence_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_occurrence( + grafeas.UpdateOccurrenceRequest(), + name="name_value", + occurrence=grafeas.Occurrence(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_get_occurrence_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_occurrence_note in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_occurrence_note + ] = mock_rpc + + request = {} + client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_occurrence_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_occurrence_note_rest_required_fields( + request_type=grafeas.GetOccurrenceNoteRequest, +): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_occurrence_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_occurrence_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_occurrence_note(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_occurrence_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_occurrence_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_occurrence_note_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/occurrences/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_occurrence_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/occurrences/*}/notes" % client.transport._host, + args[1], + ) + + +def test_get_occurrence_note_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_occurrence_note( + grafeas.GetOccurrenceNoteRequest(), + name="name_value", + ) + + +def test_get_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_note] = mock_rpc + + request = {} + client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_note_rest_required_fields(request_type=grafeas.GetNoteRequest): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_note(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_note_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/notes/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1] + ) + + +def test_get_note_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_note( + grafeas.GetNoteRequest(), + name="name_value", + ) + + +def test_list_notes_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_notes in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_notes] = mock_rpc + + request = {} + client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_notes_rest_required_fields(request_type=grafeas.ListNotesRequest): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_notes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_notes._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.ListNotesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_notes(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_notes_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_notes._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_notes_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.ListNotesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + filter="filter_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.ListNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_notes(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1] + ) + + +def test_list_notes_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_notes( + grafeas.ListNotesRequest(), + parent="parent_value", + filter="filter_value", + ) + + +def test_list_notes_rest_pager(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + grafeas.Note(), ], - "kb_article_ids": ["kb_article_ids_value1", "kb_article_ids_value2"], - "support_url": "support_url_value", - "last_published_timestamp": {}, - }, - }, - "compliance": { - "non_compliant_files": [ - { - "path": "path_value", - "display_command": "display_command_value", - "reason": "reason_value", - } - ], - "non_compliance_reason": "non_compliance_reason_value", - "version": { - "cpe_uri": "cpe_uri_value", - "benchmark_document": "benchmark_document_value", - "version": "version_value", - }, - }, - "dsse_attestation": { - "envelope": { - "payload": b"payload_blob", - "payload_type": "payload_type_value", - "signatures": [{"sig": b"sig_blob", "keyid": "keyid_value"}], - }, - "statement": {}, - }, - "sbom_reference": { - "payload": { - "type_": "type__value", - "predicate_type": "predicate_type_value", - "subject": {}, - "predicate": { - "referrer_id": "referrer_id_value", - "location": "location_value", - "mime_type": "mime_type_value", - "digest": {}, - }, - }, - "payload_type": "payload_type_value", - "signatures": {}, - }, - "envelope": {}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 + next_page_token="abc", + ), + grafeas.ListNotesResponse( + notes=[], + next_page_token="def", + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + ], + next_page_token="ghi", + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(grafeas.ListNotesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1"} + + pager = client.list_notes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Note) for i in results) + + pages = list(client.list_notes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_delete_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_note] = mock_rpc + + request = {} + client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_note_rest_required_fields(request_type=grafeas.DeleteNoteRequest): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_note(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_note_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/notes/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1] + ) + + +def test_delete_note_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_note( + grafeas.DeleteNoteRequest(), + name="name_value", + ) + + +def test_create_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_note] = mock_rpc + + request = {} + client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_note_rest_required_fields(request_type=grafeas.CreateNoteRequest): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["note_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "noteId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "noteId" in jsonified_request + assert jsonified_request["noteId"] == request_init["note_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["noteId"] = "note_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_note._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("note_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "noteId" in jsonified_request + assert jsonified_request["noteId"] == "note_id_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_note(request) + + expected_params = [ + ( + "noteId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_note._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("noteId",)) + & set( + ( + "parent", + "noteId", + "note", + ) + ) + ) + + +def test_create_note_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + note_id="note_id_value", + note=grafeas.Note(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1] + ) + + +def test_create_note_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_note( + grafeas.CreateNoteRequest(), + parent="parent_value", + note_id="note_id_value", + note=grafeas.Note(name="name_value"), + ) + + +def test_batch_create_notes_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_notes in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_notes + ] = mock_rpc + + request = {} + client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_notes_rest_required_fields( + request_type=grafeas.BatchCreateNotesRequest, +): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_notes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_notes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateNotesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.BatchCreateNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.batch_create_notes(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_notes_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_notes._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "notes", + ) + ) + ) + + +def test_batch_create_notes_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateNotesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + notes={"key_value": grafeas.Note(name="name_value")}, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.BatchCreateNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.batch_create_notes(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*}/notes:batchCreate" % client.transport._host, + args[1], + ) + + +def test_batch_create_notes_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_notes( + grafeas.BatchCreateNotesRequest(), + parent="parent_value", + notes={"key_value": grafeas.Note(name="name_value")}, + ) - # Determine if the message type is proto-plus or protobuf - test_field = grafeas.UpdateOccurrenceRequest.meta.fields["occurrence"] - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] +def test_update_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields + # Ensure method has been cached + assert client._transport.update_note in client._transport._wrapped_methods - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_note] = mock_rpc - subfields_not_in_runtime = [] + request = {} + client.update_note(request) - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["occurrence"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) + client.update_note(request) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["occurrence"][field])): - del request_init["occurrence"][field][i][subfield] - else: - del request_init["occurrence"][field][subfield] + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_note_rest_required_fields(request_type=grafeas.UpdateNoteRequest): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_note._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) request = request_type(**request_init) + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_note(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_note._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "name", + "note", + ) + ) + ) + + +def test_update_note_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence( + return_value = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/notes/sample2"} + + # get truthy value for each flattened field + mock_args = dict( name="name_value", - resource_uri="resource_uri_value", - note_name="note_name_value", - kind=common.NoteKind.VULNERABILITY, - remediation="remediation_value", + note=grafeas.Note(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) + mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) + return_value = grafeas.Note.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_occurrence(request) - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == "name_value" - assert response.resource_uri == "resource_uri_value" - assert response.note_name == "note_name_value" - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == "remediation_value" + client.update_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1] + ) -def test_update_occurrence_rest_use_cached_wrapped_rpc(): +def test_update_note_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_note( + grafeas.UpdateNoteRequest(), + name="name_value", + note=grafeas.Note(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_list_note_occurrences_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: @@ -8654,7 +8051,10 @@ def test_update_occurrence_rest_use_cached_wrapped_rpc(): wrapper_fn.reset_mock() # Ensure method has been cached - assert client._transport.update_occurrence in client._transport._wrapped_methods + assert ( + client._transport.list_note_occurrences + in client._transport._wrapped_methods + ) # Replace cached wrapped function with mock mock_rpc = mock.Mock() @@ -8662,24 +8062,24 @@ def test_update_occurrence_rest_use_cached_wrapped_rpc(): "foo" # operation_request.operation in compute client(s) expect a string. ) client._transport._wrapped_methods[ - client._transport.update_occurrence + client._transport.list_note_occurrences ] = mock_rpc request = {} - client.update_occurrence(request) + client.list_note_occurrences(request) # Establish that the underlying gRPC stub method was called. assert mock_rpc.call_count == 1 - client.update_occurrence(request) + client.list_note_occurrences(request) # Establish that a new wrapper was not created for this call assert wrapper_fn.call_count == 0 assert mock_rpc.call_count == 2 -def test_update_occurrence_rest_required_fields( - request_type=grafeas.UpdateOccurrenceRequest, +def test_list_note_occurrences_rest_required_fields( + request_type=grafeas.ListNoteOccurrencesRequest, ): transport_class = transports.GrafeasRestTransport @@ -8695,7 +8095,7 @@ def test_update_occurrence_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_occurrence._get_unset_required_fields(jsonified_request) + ).list_note_occurrences._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -8704,9 +8104,15 @@ def test_update_occurrence_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_occurrence._get_unset_required_fields(jsonified_request) + ).list_note_occurrences._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -8720,7 +8126,7 @@ def test_update_occurrence_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() + return_value = grafeas.ListNoteOccurrencesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -8732,682 +8138,1047 @@ def test_update_occurrence_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) + return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_occurrence(request) + response = client.list_note_occurrences(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_update_occurrence_rest_unset_required_fields(): +def test_list_note_occurrences_rest_unset_required_fields(): transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_occurrence._get_unset_required_fields({}) + unset_fields = transport.list_note_occurrences._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("updateMask",)) - & set( + set( ( - "name", - "occurrence", + "filter", + "pageSize", + "pageToken", ) ) + & set(("name",)) ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( +def test_list_note_occurrences_rest_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.ListNoteOccurrencesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/notes/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + filter="filter_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_note_occurrences(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/notes/*}/occurrences" % client.transport._host, + args[1], + ) + + +def test_list_note_occurrences_rest_flattened_error(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_note_occurrences( + grafeas.ListNoteOccurrencesRequest(), + name="name_value", + filter="filter_value", + ) + + +def test_list_note_occurrences_rest_pager(transport: str = "rest"): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token="abc", + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[], + next_page_token="def", + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token="ghi", + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + grafeas.ListNoteOccurrencesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"name": "projects/sample1/notes/sample2"} + + pager = client.list_note_occurrences(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Occurrence) for i in results) + + pages = list(client.list_note_occurrences(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.GrafeasGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.GrafeasGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GrafeasGrpcTransport, + transports.GrafeasGrpcAsyncIOTransport, + transports.GrafeasRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = GrafeasClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_occurrence), "__call__") as call: + call.return_value = grafeas.Occurrence() + client.get_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_occurrences_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_occurrences), "__call__") as call: + call.return_value = grafeas.ListOccurrencesResponse() + client.list_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_update_occurrence" - ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_update_occurrence" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.UpdateOccurrenceRequest.pb( - grafeas.UpdateOccurrenceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } + type(client.transport.delete_occurrence), "__call__" + ) as call: + call.return_value = None + client.delete_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteOccurrenceRequest() - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Occurrence.to_json(grafeas.Occurrence()) + assert args[0] == request_msg - request = grafeas.UpdateOccurrenceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Occurrence() - client.update_occurrence( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) - pre.assert_called_once() - post.assert_called_once() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), "__call__" + ) as call: + call.return_value = grafeas.Occurrence() + client.create_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateOccurrenceRequest() + assert args[0] == request_msg -def test_update_occurrence_rest_bad_request( - transport: str = "rest", request_type=grafeas.UpdateOccurrenceRequest -): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_occurrences_empty_call_grpc(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), "__call__" + ) as call: + call.return_value = grafeas.BatchCreateOccurrencesResponse() + client.batch_create_occurrences(request=None) - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_occurrence(request) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateOccurrencesRequest() + assert args[0] == request_msg -def test_update_occurrence_rest_flattened(): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_occurrence_empty_call_grpc(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), "__call__" + ) as call: + call.return_value = grafeas.Occurrence() + client.update_occurrence(request=None) - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/occurrences/sample2"} + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateOccurrenceRequest() - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - occurrence=grafeas.Occurrence(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) + assert args[0] == request_msg - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - client.update_occurrence(**mock_args) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1] - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), "__call__" + ) as call: + call.return_value = grafeas.Note() + client.get_occurrence_note(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceNoteRequest() -def test_update_occurrence_rest_flattened_error(transport: str = "rest"): + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_note_empty_call_grpc(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="grpc", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_occurrence( - grafeas.UpdateOccurrenceRequest(), - name="name_value", - occurrence=grafeas.Occurrence(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_note), "__call__") as call: + call.return_value = grafeas.Note() + client.get_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetNoteRequest() + + assert args[0] == request_msg -def test_update_occurrence_rest_error(): +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_notes_empty_call_grpc(): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_notes), "__call__") as call: + call.return_value = grafeas.ListNotesResponse() + client.list_notes(request=None) -@pytest.mark.parametrize( - "request_type", - [ - grafeas.GetOccurrenceNoteRequest, - dict, - ], -) -def test_get_occurrence_note_rest(request_type): + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_note_empty_call_grpc(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + transport="grpc", ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_note), "__call__") as call: + call.return_value = None + client.delete_note(request=None) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note( - name="name_value", - short_description="short_description_value", - long_description="long_description_value", - kind=common.NoteKind.VULNERABILITY, - related_note_names=["related_note_names_value"], - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteNoteRequest() - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + assert args[0] == request_msg - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_occurrence_note(request) - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == "name_value" - assert response.short_description == "short_description_value" - assert response.long_description == "long_description_value" - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ["related_note_names_value"] +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_note), "__call__") as call: + call.return_value = grafeas.Note() + client.create_note(request=None) -def test_get_occurrence_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateNoteRequest() - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + assert args[0] == request_msg - # Ensure method has been cached - assert ( - client._transport.get_occurrence_note in client._transport._wrapped_methods - ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.get_occurrence_note - ] = mock_rpc +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_notes_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) - request = {} - client.get_occurrence_note(request) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), "__call__" + ) as call: + call.return_value = grafeas.BatchCreateNotesResponse() + client.batch_create_notes(request=None) - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateNotesRequest() - client.get_occurrence_note(request) + assert args[0] == request_msg - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_note), "__call__") as call: + call.return_value = grafeas.Note() + client.update_note(request=None) -def test_get_occurrence_note_rest_required_fields( - request_type=grafeas.GetOccurrenceNoteRequest, -): - transport_class = transports.GrafeasRestTransport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateNoteRequest() - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_note_occurrences_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", ) - # verify fields with default values are dropped + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), "__call__" + ) as call: + call.return_value = grafeas.ListNoteOccurrencesResponse() + client.list_note_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNoteOccurrencesRequest() + + assert args[0] == request_msg - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_occurrence_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - # verify required fields with default values are now present +def test_transport_kind_grpc_asyncio(): + transport = GrafeasAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" - jsonified_request["name"] = "name_value" - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_occurrence_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) +def test_initialize_client_w_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_occurrence), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Occurrence( + name="name_value", + resource_uri="resource_uri_value", + note_name="note_name_value", + kind=common.NoteKind.VULNERABILITY, + remediation="remediation_value", + ) + ) + await client.get_occurrence(request=None) - response_value = Response() - response_value.status_code = 200 + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceRequest() - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + assert args[0] == request_msg - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_occurrence_note(request) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_occurrences_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_occurrences), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.ListOccurrencesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_occurrences(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListOccurrencesRequest() -def test_get_occurrence_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - unset_fields = transport.get_occurrence_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_occurrence(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteOccurrenceRequest() -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_occurrence_note_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - client = GrafeasClient(transport=transport) + + # Mock the actual call, and fake the request. with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_get_occurrence_note" - ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_get_occurrence_note" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.GetOccurrenceNoteRequest.pb( - grafeas.GetOccurrenceNoteRequest() + type(client.transport.create_occurrence), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Occurrence( + name="name_value", + resource_uri="resource_uri_value", + note_name="note_name_value", + kind=common.NoteKind.VULNERABILITY, + remediation="remediation_value", + ) ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } + await client.create_occurrence(request=None) - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Note.to_json(grafeas.Note()) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateOccurrenceRequest() - request = grafeas.GetOccurrenceNoteRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Note() + assert args[0] == request_msg - client.get_occurrence_note( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_create_occurrences_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.BatchCreateOccurrencesResponse() ) + await client.batch_create_occurrences(request=None) - pre.assert_called_once() - post.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateOccurrencesRequest() + assert args[0] == request_msg -def test_get_occurrence_note_rest_bad_request( - transport: str = "rest", request_type=grafeas.GetOccurrenceNoteRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/occurrences/sample2"} - request = request_type(**request_init) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Occurrence( + name="name_value", + resource_uri="resource_uri_value", + note_name="note_name_value", + kind=common.NoteKind.VULNERABILITY, + remediation="remediation_value", + ) + ) + await client.update_occurrence(request=None) - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_occurrence_note(request) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateOccurrenceRequest() + assert args[0] == request_msg -def test_get_occurrence_note_rest_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_occurrence_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Note( + name="name_value", + short_description="short_description_value", + long_description="long_description_value", + kind=common.NoteKind.VULNERABILITY, + related_note_names=["related_note_names_value"], + ) + ) + await client.get_occurrence_note(request=None) - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/occurrences/sample2"} + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceNoteRequest() - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + assert args[0] == request_msg - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - client.get_occurrence_note(**mock_args) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_note), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Note( + name="name_value", + short_description="short_description_value", + long_description="long_description_value", + kind=common.NoteKind.VULNERABILITY, + related_note_names=["related_note_names_value"], + ) + ) + await client.get_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetNoteRequest() - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/occurrences/*}/notes" % client.transport._host, - args[1], - ) + assert args[0] == request_msg -def test_get_occurrence_note_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_notes_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_occurrence_note( - grafeas.GetOccurrenceNoteRequest(), - name="name_value", + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_notes), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.ListNotesResponse( + next_page_token="next_page_token_value", + ) ) + await client.list_notes(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNotesRequest() -def test_get_occurrence_note_rest_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) + assert args[0] == request_msg -@pytest.mark.parametrize( - "request_type", - [ - grafeas.GetNoteRequest, - dict, - ], -) -def test_get_note_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/notes/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note( - name="name_value", - short_description="short_description_value", - long_description="long_description_value", - kind=common.NoteKind.VULNERABILITY, - related_note_names=["related_note_names_value"], - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_note), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_note(request=None) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteNoteRequest() - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_note(request) + assert args[0] == request_msg - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == "name_value" - assert response.short_description == "short_description_value" - assert response.long_description == "long_description_value" - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ["related_note_names_value"] +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) -def test_get_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_note), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Note( + name="name_value", + short_description="short_description_value", + long_description="long_description_value", + kind=common.NoteKind.VULNERABILITY, + related_note_names=["related_note_names_value"], + ) ) + await client.create_note(request=None) - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateNoteRequest() - # Ensure method has been cached - assert client._transport.get_note in client._transport._wrapped_methods + assert args[0] == request_msg - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_create_notes_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.BatchCreateNotesResponse() ) - client._transport._wrapped_methods[client._transport.get_note] = mock_rpc + await client.batch_create_notes(request=None) - request = {} - client.get_note(request) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateNotesRequest() - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 + assert args[0] == request_msg - client.get_note(request) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_note), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.Note( + name="name_value", + short_description="short_description_value", + long_description="long_description_value", + kind=common.NoteKind.VULNERABILITY, + related_note_names=["related_note_names_value"], + ) + ) + await client.update_note(request=None) -def test_get_note_rest_required_fields(request_type=grafeas.GetNoteRequest): - transport_class = transports.GrafeasRestTransport + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateNoteRequest() - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_note_occurrences_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", ) - # verify fields with default values are dropped + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + grafeas.ListNoteOccurrencesResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_note_occurrences(request=None) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNoteOccurrencesRequest() - # verify required fields with default values are now present + assert args[0] == request_msg - jsonified_request["name"] = "name_value" - unset_fields = transport_class( +def test_transport_kind_rest(): + transport = GrafeasClient.get_transport_class("rest")( credentials=ga_credentials.AnonymousCredentials() - ).get_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + ) + assert transport.kind == "rest" - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" +def test_get_occurrence_rest_bad_request(request_type=grafeas.GetOccurrenceRequest): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/occurrences/sample2"} request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_occurrence(request) - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value +@pytest.mark.parametrize( + "request_type", + [ + grafeas.GetOccurrenceRequest, + dict, + ], +) +def test_get_occurrence_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - response = client.get_note(request) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/occurrences/sample2"} + request = request_type(**request_init) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence( + name="name_value", + resource_uri="resource_uri_value", + note_name="note_name_value", + kind=common.NoteKind.VULNERABILITY, + remediation="remediation_value", + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_get_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_occurrence(request) - unset_fields = transport.get_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == "name_value" + assert response.resource_uri == "resource_uri_value" + assert response.note_name == "note_name_value" + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == "remediation_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_note_rest_interceptors(null_interceptor): +def test_get_occurrence_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_get_note" + transports.GrafeasRestInterceptor, "post_get_occurrence" ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_get_note" + transports.GrafeasRestInterceptor, "pre_get_occurrence" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = grafeas.GetNoteRequest.pb(grafeas.GetNoteRequest()) + pb_message = grafeas.GetOccurrenceRequest.pb(grafeas.GetOccurrenceRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -9415,20 +9186,20 @@ def test_get_note_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Note.to_json(grafeas.Note()) + return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) + req.return_value.content = return_value - request = grafeas.GetNoteRequest() + request = grafeas.GetOccurrenceRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = grafeas.Note() + post.return_value = grafeas.Occurrence() - client.get_note( + client.get_occurrence( request, metadata=[ ("key", "val"), @@ -9440,16 +9211,12 @@ def test_get_note_rest_interceptors(null_interceptor): post.assert_called_once() -def test_get_note_rest_bad_request( - transport: str = "rest", request_type=grafeas.GetNoteRequest -): +def test_list_occurrences_rest_bad_request(request_type=grafeas.ListOccurrencesRequest): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/notes/sample2"} + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -9457,85 +9224,25 @@ def test_get_note_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_note(request) - - -def test_get_note_rest_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/notes/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.request = mock.Mock() req.return_value = response_value - - client.get_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1] - ) - - -def test_get_note_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_note( - grafeas.GetNoteRequest(), - name="name_value", - ) - - -def test_get_note_rest_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) + client.list_occurrences(request) @pytest.mark.parametrize( "request_type", [ - grafeas.ListNotesRequest, + grafeas.ListOccurrencesRequest, dict, ], ) -def test_list_notes_rest(request_type): +def test_list_occurrences_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding @@ -9545,179 +9252,46 @@ def test_list_notes_rest(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grafeas.ListNotesResponse( + return_value = grafeas.ListOccurrencesResponse( next_page_token="next_page_token_value", ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = grafeas.ListNotesResponse.pb(return_value) + return_value = grafeas.ListOccurrencesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_notes(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNotesPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_notes_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_notes in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.list_notes] = mock_rpc - - request = {} - client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_notes_rest_required_fields(request_type=grafeas.ListNotesRequest): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_notes._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_notes._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.ListNotesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.list_notes(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_notes_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + response = client.list_occurrences(request) - unset_fields = transport.list_notes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListOccurrencesPager) + assert response.next_page_token == "next_page_token_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_notes_rest_interceptors(null_interceptor): +def test_list_occurrences_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_list_notes" + transports.GrafeasRestInterceptor, "post_list_occurrences" ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_list_notes" + transports.GrafeasRestInterceptor, "pre_list_occurrences" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = grafeas.ListNotesRequest.pb(grafeas.ListNotesRequest()) + pb_message = grafeas.ListOccurrencesRequest.pb(grafeas.ListOccurrencesRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -9725,22 +9299,22 @@ def test_list_notes_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.ListNotesResponse.to_json( - grafeas.ListNotesResponse() + return_value = grafeas.ListOccurrencesResponse.to_json( + grafeas.ListOccurrencesResponse() ) + req.return_value.content = return_value - request = grafeas.ListNotesRequest() + request = grafeas.ListOccurrencesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = grafeas.ListNotesResponse() + post.return_value = grafeas.ListOccurrencesResponse() - client.list_notes( + client.list_occurrences( request, metadata=[ ("key", "val"), @@ -9752,16 +9326,14 @@ def test_list_notes_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_notes_rest_bad_request( - transport: str = "rest", request_type=grafeas.ListNotesRequest +def test_delete_occurrence_rest_bad_request( + request_type=grafeas.DeleteOccurrenceRequest, ): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} + request_init = {"name": "projects/sample1/occurrences/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -9769,296 +9341,625 @@ def test_list_notes_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value - client.list_notes(request) + client.delete_occurrence(request) -def test_list_notes_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + grafeas.DeleteOccurrenceRequest, + dict, + ], +) +def test_delete_occurrence_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/occurrences/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grafeas.ListNotesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - filter="filter_value", - ) - mock_args.update(sample_request) + return_value = None # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.ListNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.delete_occurrence(request) - client.list_notes(**mock_args) + # Establish that the response is the type that we expect. + assert response is None - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1] + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_occurrence_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_delete_occurrence" + ) as pre: + pre.assert_not_called() + pb_message = grafeas.DeleteOccurrenceRequest.pb( + grafeas.DeleteOccurrenceRequest() ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + request = grafeas.DeleteOccurrenceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata -def test_list_notes_rest_flattened_error(transport: str = "rest"): + client.delete_occurrence( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_create_occurrence_rest_bad_request( + request_type=grafeas.CreateOccurrenceRequest, +): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_notes( - grafeas.ListNotesRequest(), - parent="parent_value", - filter="filter_value", - ) + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_occurrence(request) -def test_list_notes_rest_pager(transport: str = "rest"): +@pytest.mark.parametrize( + "request_type", + [ + grafeas.CreateOccurrenceRequest, + dict, + ], +) +def test_create_occurrence_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - grafeas.Note(), + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request_init["occurrence"] = { + "name": "name_value", + "resource_uri": "resource_uri_value", + "note_name": "note_name_value", + "kind": 1, + "remediation": "remediation_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "vulnerability": { + "type_": "type__value", + "severity": 1, + "cvss_score": 0.1082, + "cvssv3": { + "base_score": 0.1046, + "exploitability_score": 0.21580000000000002, + "impact_score": 0.1273, + "attack_vector": 1, + "attack_complexity": 1, + "authentication": 1, + "privileges_required": 1, + "user_interaction": 1, + "scope": 1, + "confidentiality_impact": 1, + "integrity_impact": 1, + "availability_impact": 1, + }, + "package_issue": [ + { + "affected_cpe_uri": "affected_cpe_uri_value", + "affected_package": "affected_package_value", + "affected_version": { + "epoch": 527, + "name": "name_value", + "revision": "revision_value", + "inclusive": True, + "kind": 1, + "full_name": "full_name_value", + }, + "fixed_cpe_uri": "fixed_cpe_uri_value", + "fixed_package": "fixed_package_value", + "fixed_version": {}, + "fix_available": True, + "package_type": "package_type_value", + "effective_severity": 1, + "file_location": [{"file_path": "file_path_value"}], + } + ], + "short_description": "short_description_value", + "long_description": "long_description_value", + "related_urls": [{"url": "url_value", "label": "label_value"}], + "effective_severity": 1, + "fix_available": True, + "cvss_version": 1, + "cvss_v2": {}, + "vex_assessment": { + "cve": "cve_value", + "vulnerability_id": "vulnerability_id_value", + "related_uris": {}, + "note_name": "note_name_value", + "state": 1, + "impacts": ["impacts_value1", "impacts_value2"], + "remediations": [ + { + "remediation_type": 1, + "details": "details_value", + "remediation_uri": {}, + } + ], + "justification": {"justification_type": 1, "details": "details_value"}, + }, + "extra_details": "extra_details_value", + }, + "build": { + "provenance": { + "id": "id_value", + "project_id": "project_id_value", + "commands": [ + { + "name": "name_value", + "env": ["env_value1", "env_value2"], + "args": ["args_value1", "args_value2"], + "dir_": "dir__value", + "id": "id_value", + "wait_for": ["wait_for_value1", "wait_for_value2"], + } ], - next_page_token="abc", - ), - grafeas.ListNotesResponse( - notes=[], - next_page_token="def", - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), + "built_artifacts": [ + { + "checksum": "checksum_value", + "id": "id_value", + "names": ["names_value1", "names_value2"], + } ], - next_page_token="ghi", - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), + "create_time": {}, + "start_time": {}, + "end_time": {}, + "creator": "creator_value", + "logs_uri": "logs_uri_value", + "source_provenance": { + "artifact_storage_source_uri": "artifact_storage_source_uri_value", + "file_hashes": {}, + "context": { + "cloud_repo": { + "repo_id": { + "project_repo_id": { + "project_id": "project_id_value", + "repo_name": "repo_name_value", + }, + "uid": "uid_value", + }, + "revision_id": "revision_id_value", + "alias_context": {"kind": 1, "name": "name_value"}, + }, + "gerrit": { + "host_uri": "host_uri_value", + "gerrit_project": "gerrit_project_value", + "revision_id": "revision_id_value", + "alias_context": {}, + }, + "git": {"url": "url_value", "revision_id": "revision_id_value"}, + "labels": {}, + }, + "additional_contexts": {}, + }, + "trigger_id": "trigger_id_value", + "build_options": {}, + "builder_version": "builder_version_value", + }, + "provenance_bytes": "provenance_bytes_value", + "intoto_provenance": { + "builder_config": {"id": "id_value"}, + "recipe": { + "type_": "type__value", + "defined_in_material": 1971, + "entry_point": "entry_point_value", + "arguments": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + "environment": {}, + }, + "metadata": { + "build_invocation_id": "build_invocation_id_value", + "build_started_on": {}, + "build_finished_on": {}, + "completeness": { + "arguments": True, + "environment": True, + "materials": True, + }, + "reproducible": True, + }, + "materials": ["materials_value1", "materials_value2"], + }, + "intoto_statement": { + "type_": "type__value", + "subject": [{"name": "name_value", "digest": {}}], + "predicate_type": "predicate_type_value", + "provenance": {}, + "slsa_provenance": { + "builder": {"id": "id_value"}, + "recipe": { + "type_": "type__value", + "defined_in_material": 1971, + "entry_point": "entry_point_value", + "arguments": {}, + "environment": {}, + }, + "metadata": { + "build_invocation_id": "build_invocation_id_value", + "build_started_on": {}, + "build_finished_on": {}, + "completeness": { + "arguments": True, + "environment": True, + "materials": True, + }, + "reproducible": True, + }, + "materials": [{"uri": "uri_value", "digest": {}}], + }, + "slsa_provenance_zero_two": { + "builder": {"id": "id_value"}, + "build_type": "build_type_value", + "invocation": { + "config_source": { + "uri": "uri_value", + "digest": {}, + "entry_point": "entry_point_value", + }, + "parameters": {"fields": {}}, + "environment": {}, + }, + "build_config": {}, + "metadata": { + "build_invocation_id": "build_invocation_id_value", + "build_started_on": {}, + "build_finished_on": {}, + "completeness": { + "parameters": True, + "environment": True, + "materials": True, + }, + "reproducible": True, + }, + "materials": [{"uri": "uri_value", "digest": {}}], + }, + }, + "in_toto_slsa_provenance_v1": { + "type_": "type__value", + "subject": {}, + "predicate_type": "predicate_type_value", + "predicate": { + "build_definition": { + "build_type": "build_type_value", + "external_parameters": {}, + "internal_parameters": {}, + "resolved_dependencies": [ + { + "name": "name_value", + "uri": "uri_value", + "digest": {}, + "content": b"content_blob", + "download_location": "download_location_value", + "media_type": "media_type_value", + "annotations": {}, + } + ], + }, + "run_details": { + "builder": { + "id": "id_value", + "version": {}, + "builder_dependencies": {}, + }, + "metadata": { + "invocation_id": "invocation_id_value", + "started_on": {}, + "finished_on": {}, + }, + "byproducts": {}, + }, + }, + }, + }, + "image": { + "fingerprint": { + "v1_name": "v1_name_value", + "v2_blob": ["v2_blob_value1", "v2_blob_value2"], + "v2_name": "v2_name_value", + }, + "distance": 843, + "layer_info": [ + {"directive": "directive_value", "arguments": "arguments_value"} + ], + "base_resource_url": "base_resource_url_value", + }, + "package": { + "name": "name_value", + "location": [ + {"cpe_uri": "cpe_uri_value", "version": {}, "path": "path_value"} + ], + "package_type": "package_type_value", + "cpe_uri": "cpe_uri_value", + "architecture": 1, + "license_": { + "expression": "expression_value", + "comments": "comments_value", + }, + "version": {}, + }, + "deployment": { + "user_email": "user_email_value", + "deploy_time": {}, + "undeploy_time": {}, + "config": "config_value", + "address": "address_value", + "resource_uri": ["resource_uri_value1", "resource_uri_value2"], + "platform": 1, + }, + "discovery": { + "continuous_analysis": 1, + "analysis_status": 1, + "analysis_completed": { + "analysis_type": ["analysis_type_value1", "analysis_type_value2"] + }, + "analysis_error": [ + {"code": 411, "message": "message_value", "details": {}} + ], + "analysis_status_error": {}, + "cpe": "cpe_value", + "last_scan_time": {}, + "archive_time": {}, + "sbom_status": {"sbom_state": 1, "error": "error_value"}, + "vulnerability_attestation": { + "last_attempt_time": {}, + "state": 1, + "error": "error_value", + }, + }, + "attestation": { + "serialized_payload": b"serialized_payload_blob", + "signatures": [ + {"signature": b"signature_blob", "public_key_id": "public_key_id_value"} + ], + "jwts": [{"compact_jwt": "compact_jwt_value"}], + }, + "upgrade": { + "package": "package_value", + "parsed_version": {}, + "distribution": { + "cpe_uri": "cpe_uri_value", + "classification": "classification_value", + "severity": "severity_value", + "cve": ["cve_value1", "cve_value2"], + }, + "windows_update": { + "identity": {"update_id": "update_id_value", "revision": 879}, + "title": "title_value", + "description": "description_value", + "categories": [ + {"category_id": "category_id_value", "name": "name_value"} ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(grafeas.ListNotesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1"} - - pager = client.list_notes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Note) for i in results) - - pages = list(client.list_notes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - grafeas.DeleteNoteRequest, - dict, - ], -) -def test_delete_note_rest(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/notes/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = None - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = "" - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_note(request) - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.delete_note] = mock_rpc - - request = {} - client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_delete_note_rest_required_fields(request_type=grafeas.DeleteNoteRequest): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + "kb_article_ids": ["kb_article_ids_value1", "kb_article_ids_value2"], + "support_url": "support_url_value", + "last_published_timestamp": {}, + }, + }, + "compliance": { + "non_compliant_files": [ + { + "path": "path_value", + "display_command": "display_command_value", + "reason": "reason_value", + } + ], + "non_compliance_reason": "non_compliance_reason_value", + "version": { + "cpe_uri": "cpe_uri_value", + "benchmark_document": "benchmark_document_value", + "version": "version_value", + }, + }, + "dsse_attestation": { + "envelope": { + "payload": b"payload_blob", + "payload_type": "payload_type_value", + "signatures": [{"sig": b"sig_blob", "keyid": "keyid_value"}], + }, + "statement": {}, + }, + "sbom_reference": { + "payload": { + "type_": "type__value", + "predicate_type": "predicate_type_value", + "subject": {}, + "predicate": { + "referrer_id": "referrer_id_value", + "location": "location_value", + "mime_type": "mime_type_value", + "digest": {}, + }, + }, + "payload_type": "payload_type_value", + "signatures": {}, + }, + "envelope": {}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 - # verify required fields with default values are now present + # Determine if the message type is proto-plus or protobuf + test_field = grafeas.CreateOccurrenceRequest.meta.fields["occurrence"] - jsonified_request["name"] = "name_value" + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] - # Designate an appropriate value for the returned response. - return_value = None - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result + subfields_not_in_runtime = [] - response_value = Response() - response_value.status_code = 200 - json_return_value = "" + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["occurrence"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) - response = client.delete_note(request) + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["occurrence"][field])): + del request_init["occurrence"][field][i][subfield] + else: + del request_init["occurrence"][field][subfield] + request = request_type(**request_init) - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence( + name="name_value", + resource_uri="resource_uri_value", + note_name="note_name_value", + kind=common.NoteKind.VULNERABILITY, + remediation="remediation_value", + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_delete_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_occurrence(request) - unset_fields = transport.delete_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == "name_value" + assert response.resource_uri == "resource_uri_value" + assert response.note_name == "note_name_value" + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == "remediation_value" @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_note_rest_interceptors(null_interceptor): +def test_create_occurrence_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_delete_note" + transports.GrafeasRestInterceptor, "post_create_occurrence" + ) as post, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_create_occurrence" ) as pre: pre.assert_not_called() - pb_message = grafeas.DeleteNoteRequest.pb(grafeas.DeleteNoteRequest()) + post.assert_not_called() + pb_message = grafeas.CreateOccurrenceRequest.pb( + grafeas.CreateOccurrenceRequest() + ) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -10066,18 +9967,20 @@ def test_delete_note_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() + return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) + req.return_value.content = return_value - request = grafeas.DeleteNoteRequest() + request = grafeas.CreateOccurrenceRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = grafeas.Occurrence() - client.delete_note( + client.create_occurrence( request, metadata=[ ("key", "val"), @@ -10086,18 +9989,17 @@ def test_delete_note_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() -def test_delete_note_rest_bad_request( - transport: str = "rest", request_type=grafeas.DeleteNoteRequest +def test_batch_create_occurrences_rest_bad_request( + request_type=grafeas.BatchCreateOccurrencesRequest, ): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/notes/sample2"} + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -10105,152 +10007,158 @@ def test_delete_note_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value - client.delete_note(request) + client.batch_create_occurrences(request) -def test_delete_note_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + grafeas.BatchCreateOccurrencesRequest, + dict, + ], +) +def test_batch_create_occurrences_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/notes/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) + return_value = grafeas.BatchCreateOccurrencesResponse() # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 - json_return_value = "" - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - client.delete_note(**mock_args) + # Convert return value to protobuf type + return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.batch_create_occurrences(request) - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1] - ) + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) -def test_delete_note_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_occurrences_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) + client = GrafeasClient(transport=transport) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_note( - grafeas.DeleteNoteRequest(), - name="name_value", + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "post_batch_create_occurrences" + ) as post, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_batch_create_occurrences" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.BatchCreateOccurrencesRequest.pb( + grafeas.BatchCreateOccurrencesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.BatchCreateOccurrencesResponse.to_json( + grafeas.BatchCreateOccurrencesResponse() + ) + req.return_value.content = return_value + + request = grafeas.BatchCreateOccurrencesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.BatchCreateOccurrencesResponse() + + client.batch_create_occurrences( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() + -def test_delete_note_rest_error(): +def test_update_occurrence_rest_bad_request( + request_type=grafeas.UpdateOccurrenceRequest, +): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/occurrences/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_occurrence(request) @pytest.mark.parametrize( "request_type", [ - grafeas.CreateNoteRequest, + grafeas.UpdateOccurrenceRequest, dict, ], ) -def test_create_note_rest(request_type): +def test_update_occurrence_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request_init["note"] = { - "name": "name_value", - "short_description": "short_description_value", - "long_description": "long_description_value", - "kind": 1, - "related_url": [{"url": "url_value", "label": "label_value"}], - "expiration_time": {"seconds": 751, "nanos": 543}, - "create_time": {}, - "update_time": {}, - "related_note_names": [ - "related_note_names_value1", - "related_note_names_value2", - ], - "vulnerability": { - "cvss_score": 0.1082, - "severity": 1, - "details": [ - { - "severity_name": "severity_name_value", - "description": "description_value", - "package_type": "package_type_value", - "affected_cpe_uri": "affected_cpe_uri_value", - "affected_package": "affected_package_value", - "affected_version_start": { - "epoch": 527, - "name": "name_value", - "revision": "revision_value", - "inclusive": True, - "kind": 1, - "full_name": "full_name_value", - }, - "affected_version_end": {}, - "fixed_cpe_uri": "fixed_cpe_uri_value", - "fixed_package": "fixed_package_value", - "fixed_version": {}, - "is_obsolete": True, - "source_update_time": {}, - "source": "source_value", - "vendor": "vendor_value", - } - ], - "cvss_v3": { - "base_score": 0.1046, - "exploitability_score": 0.21580000000000002, - "impact_score": 0.1273, - "attack_vector": 1, - "attack_complexity": 1, - "privileges_required": 1, - "user_interaction": 1, - "scope": 1, - "confidentiality_impact": 1, - "integrity_impact": 1, - "availability_impact": 1, - }, - "windows_details": [ - { - "cpe_uri": "cpe_uri_value", - "name": "name_value", - "description": "description_value", - "fixing_kbs": [{"name": "name_value", "url": "url_value"}], - } - ], - "source_update_time": {}, - "cvss_version": 1, - "cvss_v2": { + request_init = {"name": "projects/sample1/occurrences/sample2"} + request_init["occurrence"] = { + "name": "name_value", + "resource_uri": "resource_uri_value", + "note_name": "note_name_value", + "kind": 1, + "remediation": "remediation_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "vulnerability": { + "type_": "type__value", + "severity": 1, + "cvss_score": 0.1082, + "cvssv3": { "base_score": 0.1046, "exploitability_score": 0.21580000000000002, "impact_score": 0.1273, @@ -10264,55 +10172,298 @@ def test_create_note_rest(request_type): "integrity_impact": 1, "availability_impact": 1, }, + "package_issue": [ + { + "affected_cpe_uri": "affected_cpe_uri_value", + "affected_package": "affected_package_value", + "affected_version": { + "epoch": 527, + "name": "name_value", + "revision": "revision_value", + "inclusive": True, + "kind": 1, + "full_name": "full_name_value", + }, + "fixed_cpe_uri": "fixed_cpe_uri_value", + "fixed_package": "fixed_package_value", + "fixed_version": {}, + "fix_available": True, + "package_type": "package_type_value", + "effective_severity": 1, + "file_location": [{"file_path": "file_path_value"}], + } + ], + "short_description": "short_description_value", + "long_description": "long_description_value", + "related_urls": [{"url": "url_value", "label": "label_value"}], + "effective_severity": 1, + "fix_available": True, + "cvss_version": 1, + "cvss_v2": {}, + "vex_assessment": { + "cve": "cve_value", + "vulnerability_id": "vulnerability_id_value", + "related_uris": {}, + "note_name": "note_name_value", + "state": 1, + "impacts": ["impacts_value1", "impacts_value2"], + "remediations": [ + { + "remediation_type": 1, + "details": "details_value", + "remediation_uri": {}, + } + ], + "justification": {"justification_type": 1, "details": "details_value"}, + }, + "extra_details": "extra_details_value", + }, + "build": { + "provenance": { + "id": "id_value", + "project_id": "project_id_value", + "commands": [ + { + "name": "name_value", + "env": ["env_value1", "env_value2"], + "args": ["args_value1", "args_value2"], + "dir_": "dir__value", + "id": "id_value", + "wait_for": ["wait_for_value1", "wait_for_value2"], + } + ], + "built_artifacts": [ + { + "checksum": "checksum_value", + "id": "id_value", + "names": ["names_value1", "names_value2"], + } + ], + "create_time": {}, + "start_time": {}, + "end_time": {}, + "creator": "creator_value", + "logs_uri": "logs_uri_value", + "source_provenance": { + "artifact_storage_source_uri": "artifact_storage_source_uri_value", + "file_hashes": {}, + "context": { + "cloud_repo": { + "repo_id": { + "project_repo_id": { + "project_id": "project_id_value", + "repo_name": "repo_name_value", + }, + "uid": "uid_value", + }, + "revision_id": "revision_id_value", + "alias_context": {"kind": 1, "name": "name_value"}, + }, + "gerrit": { + "host_uri": "host_uri_value", + "gerrit_project": "gerrit_project_value", + "revision_id": "revision_id_value", + "alias_context": {}, + }, + "git": {"url": "url_value", "revision_id": "revision_id_value"}, + "labels": {}, + }, + "additional_contexts": {}, + }, + "trigger_id": "trigger_id_value", + "build_options": {}, + "builder_version": "builder_version_value", + }, + "provenance_bytes": "provenance_bytes_value", + "intoto_provenance": { + "builder_config": {"id": "id_value"}, + "recipe": { + "type_": "type__value", + "defined_in_material": 1971, + "entry_point": "entry_point_value", + "arguments": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + "environment": {}, + }, + "metadata": { + "build_invocation_id": "build_invocation_id_value", + "build_started_on": {}, + "build_finished_on": {}, + "completeness": { + "arguments": True, + "environment": True, + "materials": True, + }, + "reproducible": True, + }, + "materials": ["materials_value1", "materials_value2"], + }, + "intoto_statement": { + "type_": "type__value", + "subject": [{"name": "name_value", "digest": {}}], + "predicate_type": "predicate_type_value", + "provenance": {}, + "slsa_provenance": { + "builder": {"id": "id_value"}, + "recipe": { + "type_": "type__value", + "defined_in_material": 1971, + "entry_point": "entry_point_value", + "arguments": {}, + "environment": {}, + }, + "metadata": { + "build_invocation_id": "build_invocation_id_value", + "build_started_on": {}, + "build_finished_on": {}, + "completeness": { + "arguments": True, + "environment": True, + "materials": True, + }, + "reproducible": True, + }, + "materials": [{"uri": "uri_value", "digest": {}}], + }, + "slsa_provenance_zero_two": { + "builder": {"id": "id_value"}, + "build_type": "build_type_value", + "invocation": { + "config_source": { + "uri": "uri_value", + "digest": {}, + "entry_point": "entry_point_value", + }, + "parameters": {"fields": {}}, + "environment": {}, + }, + "build_config": {}, + "metadata": { + "build_invocation_id": "build_invocation_id_value", + "build_started_on": {}, + "build_finished_on": {}, + "completeness": { + "parameters": True, + "environment": True, + "materials": True, + }, + "reproducible": True, + }, + "materials": [{"uri": "uri_value", "digest": {}}], + }, + }, + "in_toto_slsa_provenance_v1": { + "type_": "type__value", + "subject": {}, + "predicate_type": "predicate_type_value", + "predicate": { + "build_definition": { + "build_type": "build_type_value", + "external_parameters": {}, + "internal_parameters": {}, + "resolved_dependencies": [ + { + "name": "name_value", + "uri": "uri_value", + "digest": {}, + "content": b"content_blob", + "download_location": "download_location_value", + "media_type": "media_type_value", + "annotations": {}, + } + ], + }, + "run_details": { + "builder": { + "id": "id_value", + "version": {}, + "builder_dependencies": {}, + }, + "metadata": { + "invocation_id": "invocation_id_value", + "started_on": {}, + "finished_on": {}, + }, + "byproducts": {}, + }, + }, + }, }, - "build": {"builder_version": "builder_version_value"}, "image": { - "resource_url": "resource_url_value", "fingerprint": { "v1_name": "v1_name_value", "v2_blob": ["v2_blob_value1", "v2_blob_value2"], "v2_name": "v2_name_value", }, + "distance": 843, + "layer_info": [ + {"directive": "directive_value", "arguments": "arguments_value"} + ], + "base_resource_url": "base_resource_url_value", }, "package": { "name": "name_value", - "distribution": [ - { - "cpe_uri": "cpe_uri_value", - "architecture": 1, - "latest_version": {}, - "maintainer": "maintainer_value", - "url": "url_value", - "description": "description_value", - } + "location": [ + {"cpe_uri": "cpe_uri_value", "version": {}, "path": "path_value"} ], "package_type": "package_type_value", "cpe_uri": "cpe_uri_value", - "architecture": 1, - "version": {}, - "maintainer": "maintainer_value", - "url": "url_value", - "description": "description_value", + "architecture": 1, "license_": { "expression": "expression_value", "comments": "comments_value", }, - "digest": [{"algo": "algo_value", "digest_bytes": b"digest_bytes_blob"}], + "version": {}, + }, + "deployment": { + "user_email": "user_email_value", + "deploy_time": {}, + "undeploy_time": {}, + "config": "config_value", + "address": "address_value", + "resource_uri": ["resource_uri_value1", "resource_uri_value2"], + "platform": 1, + }, + "discovery": { + "continuous_analysis": 1, + "analysis_status": 1, + "analysis_completed": { + "analysis_type": ["analysis_type_value1", "analysis_type_value2"] + }, + "analysis_error": [ + {"code": 411, "message": "message_value", "details": {}} + ], + "analysis_status_error": {}, + "cpe": "cpe_value", + "last_scan_time": {}, + "archive_time": {}, + "sbom_status": {"sbom_state": 1, "error": "error_value"}, + "vulnerability_attestation": { + "last_attempt_time": {}, + "state": 1, + "error": "error_value", + }, + }, + "attestation": { + "serialized_payload": b"serialized_payload_blob", + "signatures": [ + {"signature": b"signature_blob", "public_key_id": "public_key_id_value"} + ], + "jwts": [{"compact_jwt": "compact_jwt_value"}], }, - "deployment": {"resource_uri": ["resource_uri_value1", "resource_uri_value2"]}, - "discovery": {"analysis_kind": 1}, - "attestation": {"hint": {"human_readable_name": "human_readable_name_value"}}, "upgrade": { "package": "package_value", - "version": {}, - "distributions": [ - { - "cpe_uri": "cpe_uri_value", - "classification": "classification_value", - "severity": "severity_value", - "cve": ["cve_value1", "cve_value2"], - } - ], + "parsed_version": {}, + "distribution": { + "cpe_uri": "cpe_uri_value", + "classification": "classification_value", + "severity": "severity_value", + "cve": ["cve_value1", "cve_value2"], + }, "windows_update": { "identity": {"update_id": "update_id_value", "revision": 879}, "title": "title_value", @@ -10326,126 +10477,237 @@ def test_create_note_rest(request_type): }, }, "compliance": { - "title": "title_value", - "description": "description_value", - "version": [ + "non_compliant_files": [ { - "cpe_uri": "cpe_uri_value", - "benchmark_document": "benchmark_document_value", - "version": "version_value", + "path": "path_value", + "display_command": "display_command_value", + "reason": "reason_value", } ], - "rationale": "rationale_value", - "remediation": "remediation_value", - "cis_benchmark": {"profile_level": 1384, "severity": 1}, - "scan_instructions": b"scan_instructions_blob", - "impact": "impact_value", + "non_compliance_reason": "non_compliance_reason_value", + "version": { + "cpe_uri": "cpe_uri_value", + "benchmark_document": "benchmark_document_value", + "version": "version_value", + }, }, "dsse_attestation": { - "hint": {"human_readable_name": "human_readable_name_value"} - }, - "vulnerability_assessment": { - "title": "title_value", - "short_description": "short_description_value", - "long_description": "long_description_value", - "language_code": "language_code_value", - "publisher": { - "name": "name_value", - "issuing_authority": "issuing_authority_value", - "publisher_namespace": "publisher_namespace_value", - }, - "product": { - "name": "name_value", - "id": "id_value", - "generic_uri": "generic_uri_value", + "envelope": { + "payload": b"payload_blob", + "payload_type": "payload_type_value", + "signatures": [{"sig": b"sig_blob", "keyid": "keyid_value"}], }, - "assessment": { - "cve": "cve_value", - "vulnerability_id": "vulnerability_id_value", - "short_description": "short_description_value", - "long_description": "long_description_value", - "related_uris": {}, - "state": 1, - "impacts": ["impacts_value1", "impacts_value2"], - "justification": {"justification_type": 1, "details": "details_value"}, - "remediations": [ - { - "remediation_type": 1, - "details": "details_value", - "remediation_uri": {}, - } - ], + "statement": {}, + }, + "sbom_reference": { + "payload": { + "type_": "type__value", + "predicate_type": "predicate_type_value", + "subject": {}, + "predicate": { + "referrer_id": "referrer_id_value", + "location": "location_value", + "mime_type": "mime_type_value", + "digest": {}, + }, }, + "payload_type": "payload_type_value", + "signatures": {}, }, - "sbom_reference": {"format_": "format__value", "version": "version_value"}, + "envelope": {}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = grafeas.CreateNoteRequest.meta.fields["note"] + test_field = grafeas.UpdateOccurrenceRequest.meta.fields["occurrence"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["occurrence"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["occurrence"][field])): + del request_init["occurrence"][field][i][subfield] + else: + del request_init["occurrence"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence( + name="name_value", + resource_uri="resource_uri_value", + note_name="note_name_value", + kind=common.NoteKind.VULNERABILITY, + remediation="remediation_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_occurrence(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == "name_value" + assert response.resource_uri == "resource_uri_value" + assert response.note_name == "note_name_value" + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == "remediation_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_occurrence_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "post_update_occurrence" + ) as post, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_update_occurrence" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.UpdateOccurrenceRequest.pb( + grafeas.UpdateOccurrenceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) + req.return_value.content = return_value - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] + request = grafeas.UpdateOccurrenceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Occurrence() - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + client.update_occurrence( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields + pre.assert_called_once() + post.assert_called_once() - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - subfields_not_in_runtime = [] +def test_get_occurrence_note_rest_bad_request( + request_type=grafeas.GetOccurrenceNoteRequest, +): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/occurrences/sample2"} + request = request_type(**request_init) - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["note"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_occurrence_note(request) - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["note"][field])): - del request_init["note"][field][i][subfield] - else: - del request_init["note"][field][subfield] +@pytest.mark.parametrize( + "request_type", + [ + grafeas.GetOccurrenceNoteRequest, + dict, + ], +) +def test_get_occurrence_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/occurrences/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -10460,15 +10722,15 @@ def get_message_fields(field): ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = grafeas.Note.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_note(request) + response = client.get_occurrence_note(request) # Establish that the response is the type that we expect. assert isinstance(response, grafeas.Note) @@ -10479,167 +10741,149 @@ def get_message_fields(field): assert response.related_note_names == ["related_note_names_value"] -def test_create_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.create_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.create_note] = mock_rpc - - request = {} - client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.create_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_create_note_rest_required_fields(request_type=grafeas.CreateNoteRequest): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["parent"] = "" - request_init["note_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_occurrence_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) + client = GrafeasClient(transport=transport) - # verify fields with default values are dropped - assert "noteId" not in jsonified_request + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "post_get_occurrence_note" + ) as post, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_get_occurrence_note" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.GetOccurrenceNoteRequest.pb( + grafeas.GetOccurrenceNoteRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value - # verify required fields with default values are now present - assert "noteId" in jsonified_request - assert jsonified_request["noteId"] == request_init["note_id"] + request = grafeas.GetOccurrenceNoteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Note() - jsonified_request["parent"] = "parent_value" - jsonified_request["noteId"] = "note_id_value" + client.get_occurrence_note( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_note._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("note_id",)) - jsonified_request.update(unset_fields) + pre.assert_called_once() + post.assert_called_once() - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "noteId" in jsonified_request - assert jsonified_request["noteId"] == "note_id_value" +def test_get_note_rest_bad_request(request_type=grafeas.GetNoteRequest): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/notes/sample2"} request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_note(request) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_note(request) +@pytest.mark.parametrize( + "request_type", + [ + grafeas.GetNoteRequest, + dict, + ], +) +def test_get_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) - expected_params = [ - ( - "noteId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/notes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note( + name="name_value", + short_description="short_description_value", + long_description="long_description_value", + kind=common.NoteKind.VULNERABILITY, + related_note_names=["related_note_names_value"], + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_create_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_note(request) - unset_fields = transport.create_note._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("noteId",)) - & set( - ( - "parent", - "noteId", - "note", - ) - ) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == "name_value" + assert response.short_description == "short_description_value" + assert response.long_description == "long_description_value" + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ["related_note_names_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_note_rest_interceptors(null_interceptor): +def test_get_note_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_create_note" + transports.GrafeasRestInterceptor, "post_get_note" ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_create_note" + transports.GrafeasRestInterceptor, "pre_get_note" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = grafeas.CreateNoteRequest.pb(grafeas.CreateNoteRequest()) + pb_message = grafeas.GetNoteRequest.pb(grafeas.GetNoteRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -10647,12 +10891,12 @@ def test_create_note_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Note.to_json(grafeas.Note()) + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value - request = grafeas.CreateNoteRequest() + request = grafeas.GetNoteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -10660,7 +10904,7 @@ def test_create_note_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = grafeas.Note() - client.create_note( + client.get_note( request, metadata=[ ("key", "val"), @@ -10672,14 +10916,10 @@ def test_create_note_rest_interceptors(null_interceptor): post.assert_called_once() -def test_create_note_rest_bad_request( - transport: str = "rest", request_type=grafeas.CreateNoteRequest -): +def test_list_notes_rest_bad_request(request_type=grafeas.ListNotesRequest): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1"} request = request_type(**request_init) @@ -10689,268 +10929,555 @@ def test_create_note_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value - client.create_note(request) + client.list_notes(request) -def test_create_note_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + grafeas.ListNotesRequest, + dict, + ], +) +def test_list_notes_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - note_id="note_id_value", - note=grafeas.Note(name="name_value"), + return_value = grafeas.ListNotesResponse( + next_page_token="next_page_token_value", ) - mock_args.update(sample_request) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) + return_value = grafeas.ListNotesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.list_notes(request) - client.create_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1] - ) + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotesPager) + assert response.next_page_token == "next_page_token_value" -def test_create_note_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_notes_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) + client = GrafeasClient(transport=transport) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_note( - grafeas.CreateNoteRequest(), - parent="parent_value", - note_id="note_id_value", - note=grafeas.Note(name="name_value"), + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "post_list_notes" + ) as post, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_list_notes" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.ListNotesRequest.pb(grafeas.ListNotesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.ListNotesResponse.to_json(grafeas.ListNotesResponse()) + req.return_value.content = return_value + + request = grafeas.ListNotesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.ListNotesResponse() + + client.list_notes( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() -def test_create_note_rest_error(): + +def test_delete_note_rest_bad_request(request_type=grafeas.DeleteNoteRequest): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/notes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_note(request) @pytest.mark.parametrize( "request_type", [ - grafeas.BatchCreateNotesRequest, + grafeas.DeleteNoteRequest, dict, ], ) -def test_batch_create_notes_rest(request_type): +def test_delete_note_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} + request_init = {"name": "projects/sample1/notes/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateNotesResponse() + return_value = None # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.BatchCreateNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.batch_create_notes(request) + response = client.delete_note(request) # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateNotesResponse) + assert response is None -def test_batch_create_notes_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(transport=transport) - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_delete_note" + ) as pre: + pre.assert_not_called() + pb_message = grafeas.DeleteNoteRequest.pb(grafeas.DeleteNoteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = grafeas.DeleteNoteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata - # Ensure method has been cached - assert ( - client._transport.batch_create_notes in client._transport._wrapped_methods + client.delete_note( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.batch_create_notes - ] = mock_rpc + pre.assert_called_once() - request = {} - client.batch_create_notes(request) - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 +def test_create_note_rest_bad_request(request_type=grafeas.CreateNoteRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) - client.batch_create_notes(request) + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_note(request) - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 +@pytest.mark.parametrize( + "request_type", + [ + grafeas.CreateNoteRequest, + dict, + ], +) +def test_create_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request_init["note"] = { + "name": "name_value", + "short_description": "short_description_value", + "long_description": "long_description_value", + "kind": 1, + "related_url": [{"url": "url_value", "label": "label_value"}], + "expiration_time": {"seconds": 751, "nanos": 543}, + "create_time": {}, + "update_time": {}, + "related_note_names": [ + "related_note_names_value1", + "related_note_names_value2", + ], + "vulnerability": { + "cvss_score": 0.1082, + "severity": 1, + "details": [ + { + "severity_name": "severity_name_value", + "description": "description_value", + "package_type": "package_type_value", + "affected_cpe_uri": "affected_cpe_uri_value", + "affected_package": "affected_package_value", + "affected_version_start": { + "epoch": 527, + "name": "name_value", + "revision": "revision_value", + "inclusive": True, + "kind": 1, + "full_name": "full_name_value", + }, + "affected_version_end": {}, + "fixed_cpe_uri": "fixed_cpe_uri_value", + "fixed_package": "fixed_package_value", + "fixed_version": {}, + "is_obsolete": True, + "source_update_time": {}, + "source": "source_value", + "vendor": "vendor_value", + } + ], + "cvss_v3": { + "base_score": 0.1046, + "exploitability_score": 0.21580000000000002, + "impact_score": 0.1273, + "attack_vector": 1, + "attack_complexity": 1, + "privileges_required": 1, + "user_interaction": 1, + "scope": 1, + "confidentiality_impact": 1, + "integrity_impact": 1, + "availability_impact": 1, + }, + "windows_details": [ + { + "cpe_uri": "cpe_uri_value", + "name": "name_value", + "description": "description_value", + "fixing_kbs": [{"name": "name_value", "url": "url_value"}], + } + ], + "source_update_time": {}, + "cvss_version": 1, + "cvss_v2": { + "base_score": 0.1046, + "exploitability_score": 0.21580000000000002, + "impact_score": 0.1273, + "attack_vector": 1, + "attack_complexity": 1, + "authentication": 1, + "privileges_required": 1, + "user_interaction": 1, + "scope": 1, + "confidentiality_impact": 1, + "integrity_impact": 1, + "availability_impact": 1, + }, + }, + "build": {"builder_version": "builder_version_value"}, + "image": { + "resource_url": "resource_url_value", + "fingerprint": { + "v1_name": "v1_name_value", + "v2_blob": ["v2_blob_value1", "v2_blob_value2"], + "v2_name": "v2_name_value", + }, + }, + "package": { + "name": "name_value", + "distribution": [ + { + "cpe_uri": "cpe_uri_value", + "architecture": 1, + "latest_version": {}, + "maintainer": "maintainer_value", + "url": "url_value", + "description": "description_value", + } + ], + "package_type": "package_type_value", + "cpe_uri": "cpe_uri_value", + "architecture": 1, + "version": {}, + "maintainer": "maintainer_value", + "url": "url_value", + "description": "description_value", + "license_": { + "expression": "expression_value", + "comments": "comments_value", + }, + "digest": [{"algo": "algo_value", "digest_bytes": b"digest_bytes_blob"}], + }, + "deployment": {"resource_uri": ["resource_uri_value1", "resource_uri_value2"]}, + "discovery": {"analysis_kind": 1}, + "attestation": {"hint": {"human_readable_name": "human_readable_name_value"}}, + "upgrade": { + "package": "package_value", + "version": {}, + "distributions": [ + { + "cpe_uri": "cpe_uri_value", + "classification": "classification_value", + "severity": "severity_value", + "cve": ["cve_value1", "cve_value2"], + } + ], + "windows_update": { + "identity": {"update_id": "update_id_value", "revision": 879}, + "title": "title_value", + "description": "description_value", + "categories": [ + {"category_id": "category_id_value", "name": "name_value"} + ], + "kb_article_ids": ["kb_article_ids_value1", "kb_article_ids_value2"], + "support_url": "support_url_value", + "last_published_timestamp": {}, + }, + }, + "compliance": { + "title": "title_value", + "description": "description_value", + "version": [ + { + "cpe_uri": "cpe_uri_value", + "benchmark_document": "benchmark_document_value", + "version": "version_value", + } + ], + "rationale": "rationale_value", + "remediation": "remediation_value", + "cis_benchmark": {"profile_level": 1384, "severity": 1}, + "scan_instructions": b"scan_instructions_blob", + "impact": "impact_value", + }, + "dsse_attestation": { + "hint": {"human_readable_name": "human_readable_name_value"} + }, + "vulnerability_assessment": { + "title": "title_value", + "short_description": "short_description_value", + "long_description": "long_description_value", + "language_code": "language_code_value", + "publisher": { + "name": "name_value", + "issuing_authority": "issuing_authority_value", + "publisher_namespace": "publisher_namespace_value", + }, + "product": { + "name": "name_value", + "id": "id_value", + "generic_uri": "generic_uri_value", + }, + "assessment": { + "cve": "cve_value", + "vulnerability_id": "vulnerability_id_value", + "short_description": "short_description_value", + "long_description": "long_description_value", + "related_uris": {}, + "state": 1, + "impacts": ["impacts_value1", "impacts_value2"], + "justification": {"justification_type": 1, "details": "details_value"}, + "remediations": [ + { + "remediation_type": 1, + "details": "details_value", + "remediation_uri": {}, + } + ], + }, + }, + "sbom_reference": {"format_": "format__value", "version": "version_value"}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 -def test_batch_create_notes_rest_required_fields( - request_type=grafeas.BatchCreateNotesRequest, -): - transport_class = transports.GrafeasRestTransport + # Determine if the message type is proto-plus or protobuf + test_field = grafeas.CreateNoteRequest.meta.fields["note"] - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] - # verify fields with default values are dropped + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).batch_create_notes._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields - # verify required fields with default values are now present + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] - jsonified_request["parent"] = "parent_value" + subfields_not_in_runtime = [] - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).batch_create_notes._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["note"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["note"][field])): + del request_init["note"][field][i][subfield] + else: + del request_init["note"][field][subfield] request = request_type(**request_init) - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateNotesResponse() # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.BatchCreateNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.batch_create_notes(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note( + name="name_value", + short_description="short_description_value", + long_description="long_description_value", + kind=common.NoteKind.VULNERABILITY, + related_note_names=["related_note_names_value"], + ) + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 -def test_batch_create_notes_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_note(request) - unset_fields = transport.batch_create_notes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "parent", - "notes", - ) - ) - ) + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == "name_value" + assert response.short_description == "short_description_value" + assert response.long_description == "long_description_value" + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ["related_note_names_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_batch_create_notes_rest_interceptors(null_interceptor): +def test_create_note_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.GrafeasRestInterceptor, "post_batch_create_notes" + transports.GrafeasRestInterceptor, "post_create_note" ) as post, mock.patch.object( - transports.GrafeasRestInterceptor, "pre_batch_create_notes" + transports.GrafeasRestInterceptor, "pre_create_note" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = grafeas.BatchCreateNotesRequest.pb( - grafeas.BatchCreateNotesRequest() - ) + pb_message = grafeas.CreateNoteRequest.pb(grafeas.CreateNoteRequest()) transcode.return_value = { "method": "post", "uri": "my_uri", @@ -10958,22 +11485,20 @@ def test_batch_create_notes_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.BatchCreateNotesResponse.to_json( - grafeas.BatchCreateNotesResponse() - ) + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value - request = grafeas.BatchCreateNotesRequest() + request = grafeas.CreateNoteRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = grafeas.BatchCreateNotesResponse() + post.return_value = grafeas.Note() - client.batch_create_notes( + client.create_note( request, metadata=[ ("key", "val"), @@ -10986,13 +11511,11 @@ def test_batch_create_notes_rest_interceptors(null_interceptor): def test_batch_create_notes_rest_bad_request( - transport: str = "rest", request_type=grafeas.BatchCreateNotesRequest + request_type=grafeas.BatchCreateNotesRequest, ): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # send a request that will satisfy transcoding request_init = {"parent": "projects/sample1"} request = request_type(**request_init) @@ -11002,75 +11525,127 @@ def test_batch_create_notes_rest_bad_request( core_exceptions.BadRequest ): # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) response_value.status_code = 400 - response_value.request = Request() + response_value.request = mock.Mock() req.return_value = response_value client.batch_create_notes(request) -def test_batch_create_notes_rest_flattened(): +@pytest.mark.parametrize( + "request_type", + [ + grafeas.BatchCreateNotesRequest, + dict, + ], +) +def test_batch_create_notes_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. return_value = grafeas.BatchCreateNotesResponse() - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - notes={"key_value": grafeas.Note(name="name_value")}, - ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = grafeas.BatchCreateNotesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value + response = client.batch_create_notes(request) - client.batch_create_notes(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{parent=projects/*}/notes:batchCreate" % client.transport._host, - args[1], - ) + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateNotesResponse) -def test_batch_create_notes_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_notes_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) + client = GrafeasClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GrafeasRestInterceptor, "post_batch_create_notes" + ) as post, mock.patch.object( + transports.GrafeasRestInterceptor, "pre_batch_create_notes" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.BatchCreateNotesRequest.pb( + grafeas.BatchCreateNotesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.BatchCreateNotesResponse.to_json( + grafeas.BatchCreateNotesResponse() + ) + req.return_value.content = return_value + + request = grafeas.BatchCreateNotesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.BatchCreateNotesResponse() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.batch_create_notes( - grafeas.BatchCreateNotesRequest(), - parent="parent_value", - notes={"key_value": grafeas.Note(name="name_value")}, + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() + -def test_batch_create_notes_rest_error(): +def test_update_note_rest_bad_request(request_type=grafeas.UpdateNoteRequest): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/notes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_note(request) @pytest.mark.parametrize( @@ -11080,10 +11655,9 @@ def test_batch_create_notes_rest_error(): dict, ], ) -def test_update_note_rest(request_type): +def test_update_note_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding @@ -11362,13 +11936,13 @@ def get_message_fields(field): ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = grafeas.Note.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value response = client.update_note(request) @@ -11381,134 +11955,6 @@ def get_message_fields(field): assert response.related_note_names == ["related_note_names_value"] -def test_update_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.update_note] = mock_rpc - - request = {} - client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_note_rest_required_fields(request_type=grafeas.UpdateNoteRequest): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_note._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.update_note(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_update_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.update_note._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(("updateMask",)) - & set( - ( - "name", - "note", - ) - ) - ) - - @pytest.mark.parametrize("null_interceptor", [True, False]) def test_update_note_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( @@ -11516,6 +11962,7 @@ def test_update_note_rest_interceptors(null_interceptor): interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -11531,122 +11978,57 @@ def test_update_note_rest_interceptors(null_interceptor): transcode.return_value = { "method": "post", "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.Note.to_json(grafeas.Note()) - - request = grafeas.UpdateNoteRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Note() - - client.update_note( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_note_rest_bad_request( - transport: str = "rest", request_type=grafeas.UpdateNoteRequest -): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/notes/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_note(request) - - -def test_update_note_rest_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/notes/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - note=grafeas.Note(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1] - ) + "body": pb_message, + "query_params": pb_message, + } + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value -def test_update_note_rest_flattened_error(transport: str = "rest"): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) + request = grafeas.UpdateNoteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Note() - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): client.update_note( - grafeas.UpdateNoteRequest(), - name="name_value", - note=grafeas.Note(name="name_value"), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) + pre.assert_called_once() + post.assert_called_once() -def test_update_note_rest_error(): + +def test_list_note_occurrences_rest_bad_request( + request_type=grafeas.ListNoteOccurrencesRequest, +): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/notes/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_note_occurrences(request) @pytest.mark.parametrize( @@ -11656,10 +12038,9 @@ def test_update_note_rest_error(): dict, ], ) -def test_list_note_occurrences_rest(request_type): +def test_list_note_occurrences_rest_call_success(request_type): client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding @@ -11674,13 +12055,13 @@ def test_list_note_occurrences_rest(request_type): ) # Wrap the value into a proper Response obj - response_value = Response() + response_value = mock.Mock() response_value.status_code = 200 + # Convert return value to protobuf type return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") + response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value response = client.list_note_occurrences(request) @@ -11689,147 +12070,6 @@ def test_list_note_occurrences_rest(request_type): assert response.next_page_token == "next_page_token_value" -def test_list_note_occurrences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.list_note_occurrences - in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.list_note_occurrences - ] = mock_rpc - - request = {} - client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_note_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_note_occurrences_rest_required_fields( - request_type=grafeas.ListNoteOccurrencesRequest, -): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_note_occurrences._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_note_occurrences._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.ListNoteOccurrencesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.list_note_occurrences(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_note_occurrences_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_note_occurrences._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("name",)) - ) - - @pytest.mark.parametrize("null_interceptor", [True, False]) def test_list_note_occurrences_rest_interceptors(null_interceptor): transport = transports.GrafeasRestTransport( @@ -11837,6 +12077,7 @@ def test_list_note_occurrences_rest_interceptors(null_interceptor): interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), ) client = GrafeasClient(transport=transport) + with mock.patch.object( type(client.transport._session), "request" ) as req, mock.patch.object( @@ -11858,12 +12099,12 @@ def test_list_note_occurrences_rest_interceptors(null_interceptor): "query_params": pb_message, } - req.return_value = Response() + req.return_value = mock.Mock() req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = grafeas.ListNoteOccurrencesResponse.to_json( + return_value = grafeas.ListNoteOccurrencesResponse.to_json( grafeas.ListNoteOccurrencesResponse() ) + req.return_value.content = return_value request = grafeas.ListNoteOccurrencesRequest() metadata = [ @@ -11873,215 +12114,317 @@ def test_list_note_occurrences_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = grafeas.ListNoteOccurrencesResponse() - client.list_note_occurrences( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) + client.list_note_occurrences( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_initialize_client_w_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_occurrence), "__call__") as call: + client.get_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_occurrences_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_occurrences), "__call__") as call: + client.list_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), "__call__" + ) as call: + client.delete_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), "__call__" + ) as call: + client.create_occurrence(request=None) - pre.assert_called_once() - post.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateOccurrenceRequest() + assert args[0] == request_msg -def test_list_note_occurrences_rest_bad_request( - transport: str = "rest", request_type=grafeas.ListNoteOccurrencesRequest -): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_occurrences_empty_call_rest(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/notes/sample2"} - request = request_type(**request_init) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), "__call__" + ) as call: + client.batch_create_occurrences(request=None) - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_note_occurrences(request) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateOccurrencesRequest() + assert args[0] == request_msg -def test_list_note_occurrences_rest_flattened(): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_occurrence_empty_call_rest(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.ListNoteOccurrencesResponse() + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), "__call__" + ) as call: + client.update_occurrence(request=None) - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/notes/sample2"} + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateOccurrenceRequest() - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - filter="filter_value", - ) - mock_args.update(sample_request) + assert args[0] == request_msg - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - client.list_note_occurrences(**mock_args) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/notes/*}/occurrences" % client.transport._host, - args[1], - ) + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), "__call__" + ) as call: + client.get_occurrence_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceNoteRequest() + assert args[0] == request_msg -def test_list_note_occurrences_rest_flattened_error(transport: str = "rest"): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_note_empty_call_rest(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_note_occurrences( - grafeas.ListNoteOccurrencesRequest(), - name="name_value", - filter="filter_value", - ) + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_note), "__call__") as call: + client.get_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetNoteRequest() + assert args[0] == request_msg -def test_list_note_occurrences_rest_pager(transport: str = "rest"): + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_notes_empty_call_rest(): client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token="abc", - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[], - next_page_token="def", - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token="ghi", - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - ) - # Two responses for two calls - response = response + response + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_notes), "__call__") as call: + client.list_notes(request=None) - # Wrap the values into proper Response objs - response = tuple( - grafeas.ListNoteOccurrencesResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNotesRequest() - sample_request = {"name": "projects/sample1/notes/sample2"} + assert args[0] == request_msg - pager = client.list_note_occurrences(request=sample_request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Occurrence) for i in results) +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) - pages = list(client.list_note_occurrences(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_note), "__call__") as call: + client.delete_note(request=None) + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteNoteRequest() -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.GrafeasGrpcTransport( + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_note_empty_call_rest(): + client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - client = GrafeasClient(transport=transport) - assert client.transport is transport + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_note), "__call__") as call: + client.create_note(request=None) -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.GrafeasGrpcTransport( + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_notes_empty_call_rest(): + client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel - transport = transports.GrafeasGrpcAsyncIOTransport( + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), "__call__" + ) as call: + client.batch_create_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_note_empty_call_rest(): + client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_note), "__call__") as call: + client.update_note(request=None) -@pytest.mark.parametrize( - "transport_class", - [ - transports.GrafeasGrpcTransport, - transports.GrafeasGrpcAsyncIOTransport, - transports.GrafeasRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateNoteRequest() + assert args[0] == request_msg -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = GrafeasClient.get_transport_class(transport_name)( + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_note_occurrences_empty_call_rest(): + client = GrafeasClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - assert transport.kind == transport_name + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), "__call__" + ) as call: + client.list_note_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNoteOccurrencesRequest() + + assert args[0] == request_msg def test_transport_grpc_default(): @@ -12601,36 +12944,41 @@ def test_parse_common_location_path(): assert expected == actual +def test_transport_close_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + @pytest.mark.asyncio -async def test_transport_close_async(): +async def test_transport_close_grpc_asyncio(): client = GrafeasAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", + credentials=async_anonymous_credentials(), transport="grpc_asyncio" ) with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" + type(getattr(client.transport, "_grpc_channel")), "close" ) as close: async with client: close.assert_not_called() close.assert_called_once() -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() +def test_transport_close_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() def test_client_ctx(): diff --git a/scripts/client-post-processing/doc-formatting.yaml b/scripts/client-post-processing/doc-formatting.yaml index 9b0f45c4d4a0..332bb8ccb5b7 100644 --- a/scripts/client-post-processing/doc-formatting.yaml +++ b/scripts/client-post-processing/doc-formatting.yaml @@ -425,3 +425,74 @@ replacements: 1234567890. A value of 0 indicates no project number is found. count: 1 + - paths: [ + packages/google-maps-routing/google/maps/routing_v2/types/toll_passes.py, + ] + before: | + E-card provided by multiple banks used to pay + \ for tolls. All e-cards via banks are charged the + \ same so only one enum value is needed. E.g. + \ - Bank Mandiri + after: | + E-card provided by multiple banks used to pay + for tolls. All e-cards via banks are charged the + same so only one enum value is needed. E.g.\n + - Bank Mandiri + count: 1 + - paths: [ + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/async_client.py, + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/client.py, + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc.py, + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/email_preferences_service/transports/grpc_asyncio.py, + ] + before: name=accounts\/\*\/users\/me\/emailPreferences alias + after: "`name=accounts/*/users/me/emailPreferences` alias" + count: 8 + - paths: [ + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/async_client.py, + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/client.py, + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc.py, + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/services/online_return_policy_service/transports/grpc_asyncio.py, + ] + before: | + This API defines the following resource model: + \ --------------------------------------------------------\n + \ \[OnlineReturnPolicy\]\[google.shopping.merchant.accounts.v1.OnlineReturnPolicy\] + after: | + This API defines the following resource model: + - [OnlineReturnPolicy][google.shopping.merchant.accounts.v1.OnlineReturnPolicy] + count: 4 + - paths: [ + packages/google-shopping-merchant-accounts/google/shopping/merchant_accounts_v1beta/types/shippingsettings.py + ] + before: | + Required. This field is used for avoid async + \ issue. Make sure shipping setting data + \ didn't change between get call and insert call. + after: | + Required. This field is used for avoid async + issue. Make sure shipping setting data + didn't change between get call and insert call. + count: 1 + - paths: [ + packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/types/reports.py + ] + before: | + Here's an example of how the aggregated status is computed:\n + \ Free listings \\\| Shopping ads \\\| Status + \ --------------\|--------------\|------------------------------ + \ Approved \\\| Approved \\\| ELIGIBLE Approved \\\| Pending \\\| ELIGIBLE + \ Approved \\\| Disapproved \\\| ELIGIBLE_LIMITED Pending \\\| Pending \\\| + \ PENDING Disapproved \\\| Disapproved \\\| NOT_ELIGIBLE_OR_DISAPPROVED\n + \ Values: + after: | + Here's an example of how the aggregated status is computed:\n + ``` + Free listings \| Shopping ads \| Status + --------------|--------------|------------------------------ + Approved \| Approved \| ELIGIBLE Approved \| Pending \| ELIGIBLE + Approved \| Disapproved \| ELIGIBLE_LIMITED Pending \| Pending \| + PENDING Disapproved \| Disapproved \| NOT_ELIGIBLE_OR_DISAPPROVED + ```\n + Values: + count: 1