From fdebf9b96e915a06fecaeb83c1ca59de077249a8 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 10 Mar 2021 16:22:26 -0800 Subject: [PATCH] fix: fix from_service_account_info for async clients (#44) * test: install pyopenssl for mtls testing Source-Author: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Source-Date: Tue Mar 2 12:27:56 2021 -0800 Source-Repo: googleapis/synthtool Source-Sha: 0780323da96d5a53925fe0547757181fe76e8f1e Source-Link: https://github.com/googleapis/synthtool/commit/0780323da96d5a53925fe0547757181fe76e8f1e --- .../alpha_analytics_data/async_client.py | 32 ++++- .../beta_analytics_data/async_client.py | 32 ++++- noxfile.py | 3 + synth.metadata | 124 +++++++++++++++++- tests/unit/gapic/data_v1alpha/__init__.py | 15 +++ .../data_v1alpha/test_alpha_analytics_data.py | 112 +++++++++++++++- tests/unit/gapic/data_v1beta/__init__.py | 15 +++ .../data_v1beta/test_beta_analytics_data.py | 112 +++++++++++++++- 8 files changed, 433 insertions(+), 12 deletions(-) diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py index cf5ba1b..7d5a1fe 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py @@ -76,8 +76,36 @@ class AlphaAnalyticsDataAsyncClient: AlphaAnalyticsDataClient.parse_common_location_path ) - from_service_account_info = AlphaAnalyticsDataClient.from_service_account_info - from_service_account_file = AlphaAnalyticsDataClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AlphaAnalyticsDataAsyncClient: The constructed client. + """ + return AlphaAnalyticsDataClient.from_service_account_info.__func__(AlphaAnalyticsDataAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AlphaAnalyticsDataAsyncClient: The constructed client. + """ + return AlphaAnalyticsDataClient.from_service_account_file.__func__(AlphaAnalyticsDataAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py b/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py index e4dd62c..523b0f4 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py @@ -77,8 +77,36 @@ class BetaAnalyticsDataAsyncClient: BetaAnalyticsDataClient.parse_common_location_path ) - from_service_account_info = BetaAnalyticsDataClient.from_service_account_info - from_service_account_file = BetaAnalyticsDataClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BetaAnalyticsDataAsyncClient: The constructed client. + """ + return BetaAnalyticsDataClient.from_service_account_info.__func__(BetaAnalyticsDataAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BetaAnalyticsDataAsyncClient: The constructed client. + """ + return BetaAnalyticsDataClient.from_service_account_file.__func__(BetaAnalyticsDataAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property diff --git a/noxfile.py b/noxfile.py index 1ee6cab..08d9470 100644 --- a/noxfile.py +++ b/noxfile.py @@ -123,6 +123,9 @@ def system(session): # Sanity check: Only run tests if the environment variable is set. if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): session.skip("Credentials must be set via environment variable") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") system_test_exists = os.path.exists(system_test_path) system_test_folder_exists = os.path.exists(system_test_folder_path) diff --git a/synth.metadata b/synth.metadata index fdccd7c..2e3e66a 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,22 +3,30 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-analytics-data", - "sha": "3b9a193edfba38c9e8f72580f400514fa283a79c" + "remote": "https://github.com/googleapis/python-analytics-data.git", + "sha": "58f834e80510abdcbb49801e2901e1ee44653396" + } + }, + { + "git": { + "name": "googleapis", + "remote": "https://github.com/googleapis/googleapis.git", + "sha": "8f117308d5bb55816953a0d6ad1a7d27a69a7d3f", + "internalRef": "361084441" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "0199c79b8324fba66476300824aa931788c47e2d" + "sha": "0780323da96d5a53925fe0547757181fe76e8f1e" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "0199c79b8324fba66476300824aa931788c47e2d" + "sha": "0780323da96d5a53925fe0547757181fe76e8f1e" } } ], @@ -41,5 +49,113 @@ "generator": "bazel" } } + ], + "generatedFiles": [ + ".coveragerc", + ".flake8", + ".github/CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE/bug_report.md", + ".github/ISSUE_TEMPLATE/feature_request.md", + ".github/ISSUE_TEMPLATE/support_request.md", + ".github/PULL_REQUEST_TEMPLATE.md", + ".github/header-checker-lint.yml", + ".github/release-please.yml", + ".github/snippet-bot.yml", + ".gitignore", + ".kokoro/build.sh", + ".kokoro/continuous/common.cfg", + ".kokoro/continuous/continuous.cfg", + ".kokoro/docker/docs/Dockerfile", + ".kokoro/docker/docs/fetch_gpg_keys.sh", + ".kokoro/docs/common.cfg", + ".kokoro/docs/docs-presubmit.cfg", + ".kokoro/docs/docs.cfg", + ".kokoro/populate-secrets.sh", + ".kokoro/presubmit/common.cfg", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/publish-docs.sh", + ".kokoro/release.sh", + ".kokoro/release/common.cfg", + ".kokoro/release/release.cfg", + ".kokoro/samples/lint/common.cfg", + ".kokoro/samples/lint/continuous.cfg", + ".kokoro/samples/lint/periodic.cfg", + ".kokoro/samples/lint/presubmit.cfg", + ".kokoro/samples/python3.6/common.cfg", + ".kokoro/samples/python3.6/continuous.cfg", + ".kokoro/samples/python3.6/periodic.cfg", + ".kokoro/samples/python3.6/presubmit.cfg", + ".kokoro/samples/python3.7/common.cfg", + ".kokoro/samples/python3.7/continuous.cfg", + ".kokoro/samples/python3.7/periodic.cfg", + ".kokoro/samples/python3.7/presubmit.cfg", + ".kokoro/samples/python3.8/common.cfg", + ".kokoro/samples/python3.8/continuous.cfg", + ".kokoro/samples/python3.8/periodic.cfg", + ".kokoro/samples/python3.8/presubmit.cfg", + ".kokoro/test-samples.sh", + ".kokoro/trampoline.sh", + ".kokoro/trampoline_v2.sh", + ".pre-commit-config.yaml", + ".trampolinerc", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.rst", + "LICENSE", + "MANIFEST.in", + "docs/_static/custom.css", + "docs/_templates/layout.html", + "docs/conf.py", + "docs/data_v1alpha/alpha_analytics_data.rst", + "docs/data_v1alpha/services.rst", + "docs/data_v1alpha/types.rst", + "docs/data_v1beta/beta_analytics_data.rst", + "docs/data_v1beta/services.rst", + "docs/data_v1beta/types.rst", + "docs/multiprocessing.rst", + "google/analytics/data/__init__.py", + "google/analytics/data/py.typed", + "google/analytics/data_v1alpha/__init__.py", + "google/analytics/data_v1alpha/py.typed", + "google/analytics/data_v1alpha/services/__init__.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/__init__.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/client.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/transports/__init__.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/transports/base.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc.py", + "google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc_asyncio.py", + "google/analytics/data_v1alpha/types/__init__.py", + "google/analytics/data_v1alpha/types/analytics_data_api.py", + "google/analytics/data_v1alpha/types/data.py", + "google/analytics/data_v1beta/__init__.py", + "google/analytics/data_v1beta/py.typed", + "google/analytics/data_v1beta/services/__init__.py", + "google/analytics/data_v1beta/services/beta_analytics_data/__init__.py", + "google/analytics/data_v1beta/services/beta_analytics_data/async_client.py", + "google/analytics/data_v1beta/services/beta_analytics_data/client.py", + "google/analytics/data_v1beta/services/beta_analytics_data/pagers.py", + "google/analytics/data_v1beta/services/beta_analytics_data/transports/__init__.py", + "google/analytics/data_v1beta/services/beta_analytics_data/transports/base.py", + "google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc.py", + "google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc_asyncio.py", + "google/analytics/data_v1beta/types/__init__.py", + "google/analytics/data_v1beta/types/analytics_data_api.py", + "google/analytics/data_v1beta/types/data.py", + "mypy.ini", + "noxfile.py", + "renovate.json", + "scripts/decrypt-secrets.sh", + "scripts/readme-gen/readme_gen.py", + "scripts/readme-gen/templates/README.tmpl.rst", + "scripts/readme-gen/templates/auth.tmpl.rst", + "scripts/readme-gen/templates/auth_api_key.tmpl.rst", + "scripts/readme-gen/templates/install_deps.tmpl.rst", + "scripts/readme-gen/templates/install_portaudio.tmpl.rst", + "setup.cfg", + "testing/.gitignore", + "tests/unit/gapic/data_v1alpha/__init__.py", + "tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py", + "tests/unit/gapic/data_v1beta/__init__.py", + "tests/unit/gapic/data_v1beta/test_beta_analytics_data.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/data_v1alpha/__init__.py b/tests/unit/gapic/data_v1alpha/__init__.py index 8b13789..42ffdf2 100644 --- a/tests/unit/gapic/data_v1alpha/__init__.py +++ b/tests/unit/gapic/data_v1alpha/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py b/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py index 59ff037..375f3eb 100644 --- a/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py +++ b/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py @@ -89,15 +89,19 @@ def test__get_default_mtls_endpoint(): ) -def test_alpha_analytics_data_client_from_service_account_info(): +@pytest.mark.parametrize( + "client_class", [AlphaAnalyticsDataClient, AlphaAnalyticsDataAsyncClient,] +) +def test_alpha_analytics_data_client_from_service_account_info(client_class): creds = credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: factory.return_value = creds info = {"valid": True} - client = AlphaAnalyticsDataClient.from_service_account_info(info) + client = client_class.from_service_account_info(info) assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "analyticsdata.googleapis.com:443" @@ -113,9 +117,11 @@ def test_alpha_analytics_data_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "analyticsdata.googleapis.com:443" @@ -486,6 +492,22 @@ def test_run_report_from_dict(): test_run_report(request_type=dict) +def test_run_report_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 = AlphaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.run_report), "__call__") as call: + client.run_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.RunReportRequest() + + @pytest.mark.asyncio async def test_run_report_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.RunReportRequest @@ -557,6 +579,22 @@ def test_run_pivot_report_from_dict(): test_run_pivot_report(request_type=dict) +def test_run_pivot_report_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 = AlphaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.run_pivot_report), "__call__") as call: + client.run_pivot_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.RunPivotReportRequest() + + @pytest.mark.asyncio async def test_run_pivot_report_async( transport: str = "grpc_asyncio", @@ -629,6 +667,24 @@ def test_batch_run_reports_from_dict(): test_batch_run_reports(request_type=dict) +def test_batch_run_reports_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 = AlphaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_run_reports), "__call__" + ) as call: + client.batch_run_reports() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.BatchRunReportsRequest() + + @pytest.mark.asyncio async def test_batch_run_reports_async( transport: str = "grpc_asyncio", @@ -703,6 +759,24 @@ def test_batch_run_pivot_reports_from_dict(): test_batch_run_pivot_reports(request_type=dict) +def test_batch_run_pivot_reports_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 = AlphaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_run_pivot_reports), "__call__" + ) as call: + client.batch_run_pivot_reports() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() + + @pytest.mark.asyncio async def test_batch_run_pivot_reports_async( transport: str = "grpc_asyncio", @@ -777,6 +851,22 @@ def test_get_metadata_from_dict(): test_get_metadata(request_type=dict) +def test_get_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 = AlphaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_metadata), "__call__") as call: + client.get_metadata() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.GetMetadataRequest() + + @pytest.mark.asyncio async def test_get_metadata_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.GetMetadataRequest @@ -976,6 +1066,24 @@ def test_run_realtime_report_from_dict(): test_run_realtime_report(request_type=dict) +def test_run_realtime_report_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 = AlphaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_realtime_report), "__call__" + ) as call: + client.run_realtime_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.RunRealtimeReportRequest() + + @pytest.mark.asyncio async def test_run_realtime_report_async( transport: str = "grpc_asyncio", diff --git a/tests/unit/gapic/data_v1beta/__init__.py b/tests/unit/gapic/data_v1beta/__init__.py index 8b13789..42ffdf2 100644 --- a/tests/unit/gapic/data_v1beta/__init__.py +++ b/tests/unit/gapic/data_v1beta/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py b/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py index a23ee2f..e43b775 100644 --- a/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py +++ b/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py @@ -90,15 +90,19 @@ def test__get_default_mtls_endpoint(): ) -def test_beta_analytics_data_client_from_service_account_info(): +@pytest.mark.parametrize( + "client_class", [BetaAnalyticsDataClient, BetaAnalyticsDataAsyncClient,] +) +def test_beta_analytics_data_client_from_service_account_info(client_class): creds = credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: factory.return_value = creds info = {"valid": True} - client = BetaAnalyticsDataClient.from_service_account_info(info) + client = client_class.from_service_account_info(info) assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "analyticsdata.googleapis.com:443" @@ -114,9 +118,11 @@ def test_beta_analytics_data_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "analyticsdata.googleapis.com:443" @@ -491,6 +497,22 @@ def test_run_report_from_dict(): test_run_report(request_type=dict) +def test_run_report_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 = BetaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.run_report), "__call__") as call: + client.run_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.RunReportRequest() + + @pytest.mark.asyncio async def test_run_report_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.RunReportRequest @@ -765,6 +787,22 @@ def test_run_pivot_report_from_dict(): test_run_pivot_report(request_type=dict) +def test_run_pivot_report_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 = BetaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.run_pivot_report), "__call__") as call: + client.run_pivot_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.RunPivotReportRequest() + + @pytest.mark.asyncio async def test_run_pivot_report_async( transport: str = "grpc_asyncio", @@ -890,6 +928,24 @@ def test_batch_run_reports_from_dict(): test_batch_run_reports(request_type=dict) +def test_batch_run_reports_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 = BetaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_run_reports), "__call__" + ) as call: + client.batch_run_reports() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.BatchRunReportsRequest() + + @pytest.mark.asyncio async def test_batch_run_reports_async( transport: str = "grpc_asyncio", @@ -1021,6 +1077,24 @@ def test_batch_run_pivot_reports_from_dict(): test_batch_run_pivot_reports(request_type=dict) +def test_batch_run_pivot_reports_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 = BetaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_run_pivot_reports), "__call__" + ) as call: + client.batch_run_pivot_reports() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() + + @pytest.mark.asyncio async def test_batch_run_pivot_reports_async( transport: str = "grpc_asyncio", @@ -1152,6 +1226,22 @@ def test_get_metadata_from_dict(): test_get_metadata(request_type=dict) +def test_get_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 = BetaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_metadata), "__call__") as call: + client.get_metadata() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.GetMetadataRequest() + + @pytest.mark.asyncio async def test_get_metadata_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.GetMetadataRequest @@ -1353,6 +1443,24 @@ def test_run_realtime_report_from_dict(): test_run_realtime_report(request_type=dict) +def test_run_realtime_report_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 = BetaAnalyticsDataClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_realtime_report), "__call__" + ) as call: + client.run_realtime_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == analytics_data_api.RunRealtimeReportRequest() + + @pytest.mark.asyncio async def test_run_realtime_report_async( transport: str = "grpc_asyncio",