From 2bb2d8987da8a6138bef45c5fd278cb25235cfa7 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 23 Sep 2021 09:52:11 +0000 Subject: [PATCH] feat: add ImportCustomer (#90) - [ ] Regenerate this pull request now. PiperOrigin-RevId: 394721709 Source-Link: https://github.com/googleapis/googleapis/commit/bf57b2c88187c599bf669005d1d2ce80a40780df Source-Link: https://github.com/googleapis/googleapis-gen/commit/699e6d5fdcb12daac24587c0643016855ccb2e16 --- google/cloud/channel/__init__.py | 2 + google/cloud/channel_v1/__init__.py | 2 + google/cloud/channel_v1/gapic_metadata.json | 10 ++ .../cloud_channel_service/async_client.py | 65 +++++++ .../services/cloud_channel_service/client.py | 66 +++++++ .../cloud_channel_service/transports/base.py | 12 ++ .../cloud_channel_service/transports/grpc.py | 42 +++++ .../transports/grpc_asyncio.py | 42 +++++ google/cloud/channel_v1/types/__init__.py | 2 + google/cloud/channel_v1/types/customers.py | 8 +- google/cloud/channel_v1/types/service.py | 48 ++++++ scripts/fixup_channel_v1_keywords.py | 1 + .../channel_v1/test_cloud_channel_service.py | 163 ++++++++++++++++++ 13 files changed, 461 insertions(+), 2 deletions(-) diff --git a/google/cloud/channel/__init__.py b/google/cloud/channel/__init__.py index fbdc106..74333e9 100644 --- a/google/cloud/channel/__init__.py +++ b/google/cloud/channel/__init__.py @@ -77,6 +77,7 @@ from google.cloud.channel_v1.types.service import GetChannelPartnerLinkRequest from google.cloud.channel_v1.types.service import GetCustomerRequest from google.cloud.channel_v1.types.service import GetEntitlementRequest +from google.cloud.channel_v1.types.service import ImportCustomerRequest from google.cloud.channel_v1.types.service import ListChannelPartnerLinksRequest from google.cloud.channel_v1.types.service import ListChannelPartnerLinksResponse from google.cloud.channel_v1.types.service import ListCustomersRequest @@ -176,6 +177,7 @@ "GetChannelPartnerLinkRequest", "GetCustomerRequest", "GetEntitlementRequest", + "ImportCustomerRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", "ListCustomersRequest", diff --git a/google/cloud/channel_v1/__init__.py b/google/cloud/channel_v1/__init__.py index 73fb429..fec98e9 100644 --- a/google/cloud/channel_v1/__init__.py +++ b/google/cloud/channel_v1/__init__.py @@ -71,6 +71,7 @@ from .types.service import GetChannelPartnerLinkRequest from .types.service import GetCustomerRequest from .types.service import GetEntitlementRequest +from .types.service import ImportCustomerRequest from .types.service import ListChannelPartnerLinksRequest from .types.service import ListChannelPartnerLinksResponse from .types.service import ListCustomersRequest @@ -146,6 +147,7 @@ "GetChannelPartnerLinkRequest", "GetCustomerRequest", "GetEntitlementRequest", + "ImportCustomerRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", "ListCustomersRequest", diff --git a/google/cloud/channel_v1/gapic_metadata.json b/google/cloud/channel_v1/gapic_metadata.json index e0d0f40..9c71a5f 100644 --- a/google/cloud/channel_v1/gapic_metadata.json +++ b/google/cloud/channel_v1/gapic_metadata.json @@ -75,6 +75,11 @@ "get_entitlement" ] }, + "ImportCustomer": { + "methods": [ + "import_customer" + ] + }, "ListChannelPartnerLinks": { "methods": [ "list_channel_partner_links" @@ -250,6 +255,11 @@ "get_entitlement" ] }, + "ImportCustomer": { + "methods": [ + "import_customer" + ] + }, "ListChannelPartnerLinks": { "methods": [ "list_channel_partner_links" diff --git a/google/cloud/channel_v1/services/cloud_channel_service/async_client.py b/google/cloud/channel_v1/services/cloud_channel_service/async_client.py index 8325e23..6e1567e 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/async_client.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/async_client.py @@ -630,6 +630,71 @@ async def delete_customer( request, retry=retry, timeout=timeout, metadata=metadata, ) + async def import_customer( + self, + request: service.ImportCustomerRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customers.Customer: + r"""Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Args: + request (:class:`google.cloud.channel_v1.types.ImportCustomerRequest`): + The request object. Request message for + [CloudChannelService.ImportCustomer][google.cloud.channel.v1.CloudChannelService.ImportCustomer] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.channel_v1.types.Customer: + Entity representing a customer of a + reseller or distributor. + + """ + # Create or coerce a protobuf request object. + request = service.ImportCustomerRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_customer, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # 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),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + async def provision_cloud_identity( self, request: service.ProvisionCloudIdentityRequest = None, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/client.py b/google/cloud/channel_v1/services/cloud_channel_service/client.py index cafe721..1148c96 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/client.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/client.py @@ -863,6 +863,72 @@ def delete_customer( request, retry=retry, timeout=timeout, metadata=metadata, ) + def import_customer( + self, + request: service.ImportCustomerRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customers.Customer: + r"""Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Args: + request (google.cloud.channel_v1.types.ImportCustomerRequest): + The request object. Request message for + [CloudChannelService.ImportCustomer][google.cloud.channel.v1.CloudChannelService.ImportCustomer] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.channel_v1.types.Customer: + Entity representing a customer of a + reseller or distributor. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a service.ImportCustomerRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, service.ImportCustomerRequest): + request = service.ImportCustomerRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_customer] + + # 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),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + def provision_cloud_identity( self, request: service.ProvisionCloudIdentityRequest = None, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py index 70cc3bb..22509b7 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py @@ -179,6 +179,9 @@ def _prep_wrapped_messages(self, client_info): self.delete_customer: gapic_v1.method.wrap_method( self.delete_customer, default_timeout=None, client_info=client_info, ), + self.import_customer: gapic_v1.method.wrap_method( + self.import_customer, default_timeout=None, client_info=client_info, + ), self.provision_cloud_identity: gapic_v1.method.wrap_method( self.provision_cloud_identity, default_timeout=60.0, @@ -355,6 +358,15 @@ def delete_customer( ]: raise NotImplementedError() + @property + def import_customer( + self, + ) -> Callable[ + [service.ImportCustomerRequest], + Union[customers.Customer, Awaitable[customers.Customer]], + ]: + raise NotImplementedError() + @property def provision_cloud_identity( self, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py index 188afe1..2dde5ad 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py @@ -511,6 +511,48 @@ def delete_customer( ) return self._stubs["delete_customer"] + @property + def import_customer( + self, + ) -> Callable[[service.ImportCustomerRequest], customers.Customer]: + r"""Return a callable for the import customer method over gRPC. + + Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Returns: + Callable[[~.ImportCustomerRequest], + ~.Customer]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "import_customer" not in self._stubs: + self._stubs["import_customer"] = self.grpc_channel.unary_unary( + "/google.cloud.channel.v1.CloudChannelService/ImportCustomer", + request_serializer=service.ImportCustomerRequest.serialize, + response_deserializer=customers.Customer.deserialize, + ) + return self._stubs["import_customer"] + @property def provision_cloud_identity( self, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py index e58dfc7..a67eb66 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py @@ -518,6 +518,48 @@ def delete_customer( ) return self._stubs["delete_customer"] + @property + def import_customer( + self, + ) -> Callable[[service.ImportCustomerRequest], Awaitable[customers.Customer]]: + r"""Return a callable for the import customer method over gRPC. + + Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Returns: + Callable[[~.ImportCustomerRequest], + Awaitable[~.Customer]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "import_customer" not in self._stubs: + self._stubs["import_customer"] = self.grpc_channel.unary_unary( + "/google.cloud.channel.v1.CloudChannelService/ImportCustomer", + request_serializer=service.ImportCustomerRequest.serialize, + response_deserializer=customers.Customer.deserialize, + ) + return self._stubs["import_customer"] + @property def provision_cloud_identity( self, diff --git a/google/cloud/channel_v1/types/__init__.py b/google/cloud/channel_v1/types/__init__.py index 27aadd3..368114c 100644 --- a/google/cloud/channel_v1/types/__init__.py +++ b/google/cloud/channel_v1/types/__init__.py @@ -80,6 +80,7 @@ GetChannelPartnerLinkRequest, GetCustomerRequest, GetEntitlementRequest, + ImportCustomerRequest, ListChannelPartnerLinksRequest, ListChannelPartnerLinksResponse, ListCustomersRequest, @@ -180,6 +181,7 @@ "GetChannelPartnerLinkRequest", "GetCustomerRequest", "GetEntitlementRequest", + "ImportCustomerRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", "ListCustomersRequest", diff --git a/google/cloud/channel_v1/types/customers.py b/google/cloud/channel_v1/types/customers.py index 49df85e..b6d3b7f 100644 --- a/google/cloud/channel_v1/types/customers.py +++ b/google/cloud/channel_v1/types/customers.py @@ -50,7 +50,8 @@ class Customer(proto.Message): will receive a notification with credentials when you create an admin.google.com account. Secondary emails are also recovery email - addresses. + addresses. Alternate emails are optional when + you create Team customers. domain (str): Required. The customer's primary domain. Must match the primary contact email's domain. @@ -100,8 +101,10 @@ class ContactInfo(proto.Message): Attributes: first_name (str): The customer account contact's first name. + Optional for Team customers. last_name (str): The customer account contact's last name. + Optional for Team customers. display_name (str): Output only. The customer account contact's display name, formatted as a combination of the @@ -110,7 +113,8 @@ class ContactInfo(proto.Message): The customer account's contact email. Required for entitlements that create admin.google.com accounts, and serves as the - customer's username for those accounts. + customer's username for those accounts. Use this + email to invite Team customers. title (str): Optional. The customer account contact's job title. diff --git a/google/cloud/channel_v1/types/service.py b/google/cloud/channel_v1/types/service.py index 8e642ab..f578689 100644 --- a/google/cloud/channel_v1/types/service.py +++ b/google/cloud/channel_v1/types/service.py @@ -38,6 +38,7 @@ "CreateCustomerRequest", "UpdateCustomerRequest", "DeleteCustomerRequest", + "ImportCustomerRequest", "ProvisionCloudIdentityRequest", "ListEntitlementsRequest", "ListEntitlementsResponse", @@ -259,6 +260,53 @@ class DeleteCustomerRequest(proto.Message): name = proto.Field(proto.STRING, number=1,) +class ImportCustomerRequest(proto.Message): + r"""Request message for + [CloudChannelService.ImportCustomer][google.cloud.channel.v1.CloudChannelService.ImportCustomer] + + Attributes: + domain (str): + Required. Customer domain. + cloud_identity_id (str): + Required. Customer's Cloud Identity ID + parent (str): + Required. The resource name of the reseller's account. + Parent takes the format: accounts/{account_id} or + accounts/{account_id}/channelPartnerLinks/{channel_partner_id} + auth_token (str): + Optional. The super admin of the resold + customer generates this token to authorize a + reseller to access their Cloud Identity and + purchase entitlements on their behalf. You can + omit this token after authorization. See + https://support.google.com/a/answer/7643790 for + more details. + overwrite_if_exists (bool): + Required. Choose to overwrite an existing + customer if found. This must be set to true if + there is an existing customer with a conflicting + region code or domain. + channel_partner_id (str): + Optional. Cloud Identity ID of a channel + partner who will be the direct reseller for the + customer's order. This field is required for + 2-tier transfer scenarios and can be provided + via the request Parent binding as well. + customer (str): + Optional. Specifies the customer that will receive imported + Cloud Identity information. Format: + accounts/{account_id}/customers/{customer_id} + """ + + domain = proto.Field(proto.STRING, number=2, oneof="customer_identity",) + cloud_identity_id = proto.Field(proto.STRING, number=3, oneof="customer_identity",) + parent = proto.Field(proto.STRING, number=1,) + auth_token = proto.Field(proto.STRING, number=4,) + overwrite_if_exists = proto.Field(proto.BOOL, number=5,) + channel_partner_id = proto.Field(proto.STRING, number=6,) + customer = proto.Field(proto.STRING, number=7,) + + class ProvisionCloudIdentityRequest(proto.Message): r"""Request message for [CloudChannelService.ProvisionCloudIdentity][google.cloud.channel.v1.CloudChannelService.ProvisionCloudIdentity] diff --git a/scripts/fixup_channel_v1_keywords.py b/scripts/fixup_channel_v1_keywords.py index 2d4cfca..a21c4e8 100644 --- a/scripts/fixup_channel_v1_keywords.py +++ b/scripts/fixup_channel_v1_keywords.py @@ -52,6 +52,7 @@ class channelCallTransformer(cst.CSTTransformer): 'get_channel_partner_link': ('name', 'view', ), 'get_customer': ('name', ), 'get_entitlement': ('name', ), + 'import_customer': ('domain', 'cloud_identity_id', 'parent', 'overwrite_if_exists', 'auth_token', 'channel_partner_id', 'customer', ), 'list_channel_partner_links': ('parent', 'page_size', 'page_token', 'view', ), 'list_customers': ('parent', 'page_size', 'page_token', ), 'list_entitlements': ('parent', 'page_size', 'page_token', ), diff --git a/tests/unit/gapic/channel_v1/test_cloud_channel_service.py b/tests/unit/gapic/channel_v1/test_cloud_channel_service.py index 4a5be71..1f6cc1f 100644 --- a/tests/unit/gapic/channel_v1/test_cloud_channel_service.py +++ b/tests/unit/gapic/channel_v1/test_cloud_channel_service.py @@ -1719,6 +1719,168 @@ async def test_delete_customer_flattened_error_async(): ) +def test_import_customer( + transport: str = "grpc", request_type=service.ImportCustomerRequest +): + client = CloudChannelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_customer), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = customers.Customer( + name="name_value", + org_display_name="org_display_name_value", + alternate_email="alternate_email_value", + domain="domain_value", + cloud_identity_id="cloud_identity_id_value", + language_code="language_code_value", + channel_partner_id="channel_partner_id_value", + ) + response = client.import_customer(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == service.ImportCustomerRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, customers.Customer) + assert response.name == "name_value" + assert response.org_display_name == "org_display_name_value" + assert response.alternate_email == "alternate_email_value" + assert response.domain == "domain_value" + assert response.cloud_identity_id == "cloud_identity_id_value" + assert response.language_code == "language_code_value" + assert response.channel_partner_id == "channel_partner_id_value" + + +def test_import_customer_from_dict(): + test_import_customer(request_type=dict) + + +def test_import_customer_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 = CloudChannelServiceClient( + 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.import_customer), "__call__") as call: + client.import_customer() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == service.ImportCustomerRequest() + + +@pytest.mark.asyncio +async def test_import_customer_async( + transport: str = "grpc_asyncio", request_type=service.ImportCustomerRequest +): + client = CloudChannelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_customer), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + customers.Customer( + name="name_value", + org_display_name="org_display_name_value", + alternate_email="alternate_email_value", + domain="domain_value", + cloud_identity_id="cloud_identity_id_value", + language_code="language_code_value", + channel_partner_id="channel_partner_id_value", + ) + ) + response = await client.import_customer(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == service.ImportCustomerRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, customers.Customer) + assert response.name == "name_value" + assert response.org_display_name == "org_display_name_value" + assert response.alternate_email == "alternate_email_value" + assert response.domain == "domain_value" + assert response.cloud_identity_id == "cloud_identity_id_value" + assert response.language_code == "language_code_value" + assert response.channel_partner_id == "channel_partner_id_value" + + +@pytest.mark.asyncio +async def test_import_customer_async_from_dict(): + await test_import_customer_async(request_type=dict) + + +def test_import_customer_field_headers(): + client = CloudChannelServiceClient( + 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 = service.ImportCustomerRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_customer), "__call__") as call: + call.return_value = customers.Customer() + client.import_customer(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 + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_import_customer_field_headers_async(): + client = CloudChannelServiceAsyncClient( + 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 = service.ImportCustomerRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_customer), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(customers.Customer()) + await client.import_customer(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + def test_provision_cloud_identity( transport: str = "grpc", request_type=service.ProvisionCloudIdentityRequest ): @@ -7367,6 +7529,7 @@ def test_cloud_channel_service_base_transport(): "create_customer", "update_customer", "delete_customer", + "import_customer", "provision_cloud_identity", "list_entitlements", "list_transferable_skus",