From 785bef4b64430252846a90104b6e028f85182c0c Mon Sep 17 00:00:00 2001 From: Patrick Marlow Date: Mon, 2 Sep 2024 21:10:20 -0500 Subject: [PATCH] fix: inherited auth and scopes fix for dffx class --- src/dfcx_scrapi/tools/dataframe_functions.py | 22 +-- .../tools/test_dataframe_functions.py | 156 ++++++++++++++++++ 2 files changed, 158 insertions(+), 20 deletions(-) create mode 100644 tests/dfcx_scrapi/tools/test_dataframe_functions.py diff --git a/src/dfcx_scrapi/tools/dataframe_functions.py b/src/dfcx_scrapi/tools/dataframe_functions.py index 61ca74f9..d9a233a6 100644 --- a/src/dfcx_scrapi/tools/dataframe_functions.py +++ b/src/dfcx_scrapi/tools/dataframe_functions.py @@ -18,13 +18,11 @@ import logging import time from typing import Dict, List -import google.auth import gspread import pandas as pd import numpy as np from tabulate import tabulate from gspread_dataframe import set_with_dataframe -from oauth2client.service_account import ServiceAccountCredentials from google.cloud.dialogflowcx_v3beta1 import types @@ -69,25 +67,9 @@ def __init__( if scope: scopes += scope - if creds: - self.sheets_client = gspread.authorize(creds) - - elif creds_path: - creds = ServiceAccountCredentials.from_json_keyfile_name( - filename=creds_path, scopes=scopes - ) - self.sheets_client = gspread.authorize(creds) - - elif creds_dict: - creds = ServiceAccountCredentials.from_json_keyfile_dict( - keyfile_dict=creds_dict, scopes=scopes - ) - self.sheets_client = gspread.authorize(creds) - - else: - creds, _ = google.auth.default(scopes=scopes) - self.sheets_client = gspread.authorize(creds) + self.creds.scopes.extend(scopes) + self.sheets_client = gspread.authorize(self.creds) self.entities = EntityTypes(creds=self.creds) self.intents = Intents(creds=self.creds) self.flows = Flows(creds=self.creds) diff --git a/tests/dfcx_scrapi/tools/test_dataframe_functions.py b/tests/dfcx_scrapi/tools/test_dataframe_functions.py new file mode 100644 index 00000000..1fdf655e --- /dev/null +++ b/tests/dfcx_scrapi/tools/test_dataframe_functions.py @@ -0,0 +1,156 @@ +"""Test Class for Dataframe Function Methods in SCRAPI.""" + +# pylint: disable=redefined-outer-name + +# 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 +# +# https://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 pytest +from unittest.mock import MagicMock + +from google.oauth2.service_account import Credentials +from dfcx_scrapi.tools.dataframe_functions import DataframeFunctions + + +@pytest.fixture +def test_config(): + project_id = "my-project-id-1234" + email = "mock_email@testing.com" + creds_path = "/Users/path/to/creds/credentials.json" + creds_dict = { + "type": "service_account", + "project_id": project_id, + "private_key_id": "1234", + "private_key": "mock_key", + "client_email": f"mock-account@{project_id}.iam.gserviceaccount.com", + "client_id": "1234", + "universe_domain": "googleapis.com", + } + + mock_signer = MagicMock() + mock_signer.key_id = "mock_key_id" + mock_signer.sign.return_value = b"mock_signature" + + creds_object = Credentials( + signer=mock_signer, + token_uri="mock_token_uri", + service_account_email=email, + project_id=project_id, + quota_project_id=project_id, + scopes=[], + ) + + return { + "project_id": project_id, + "creds_path": creds_path, + "creds_dict": creds_dict, + "creds_object": creds_object, + } + + +@pytest.fixture +def mock_dffx_setup(monkeypatch, test_config): + """Fixture to create mock DataframeFunctions object w/ mocked clients.""" + + # mocking all other classes used by DFFX + mock_credentials_from_file = MagicMock( + return_value=test_config["creds_object"] + ) + + monkeypatch.setattr( + "google.oauth2.service_account.Credentials.from_service_account_file", + mock_credentials_from_file, + ) + + # mocking all other classes used by DFFX + def mock_scrapi_base_init(self, *args, **kwargs): + # Simulate the original behavior + if kwargs.get("creds_path"): + self.creds = Credentials.from_service_account_file( + kwargs.get("creds_path") + ) + elif kwargs.get("creds_dict"): + self.creds = Credentials.from_service_account_info( + kwargs.get("creds_dict") + ) + else: + self.creds = kwargs.get("creds") + + def mock_entities_init(self, *args, **kwargs): + pass + + def mock_intents_init(self, *args, **kwargs): + pass + + def mock_flows_init(self, *args, **kwargs): + pass + + def mock_pages_init(self, *args, **kwargs): + pass + + def mock_route_groups_init(self, *args, **kwargs): + pass + + monkeypatch.setattr( + "dfcx_scrapi.core.scrapi_base.ScrapiBase.__init__", + mock_scrapi_base_init, + ) + + monkeypatch.setattr( + "dfcx_scrapi.core.entity_types.EntityTypes.__init__", mock_entities_init + ) + + monkeypatch.setattr( + "dfcx_scrapi.core.intents.Intents.__init__", mock_intents_init + ) + + monkeypatch.setattr( + "dfcx_scrapi.core.flows.Flows.__init__", mock_flows_init + ) + + monkeypatch.setattr( + "dfcx_scrapi.core.pages.Pages.__init__", mock_pages_init + ) + + monkeypatch.setattr( + "dfcx_scrapi.core.transition_route_groups.TransitionRouteGroups.__init__", + mock_route_groups_init, + ) + + yield mock_credentials_from_file + + +# Test init with creds_path +def test_dffx_init_creds_path(mock_dffx_setup, test_config): + mock_creds = mock_dffx_setup + dffx = DataframeFunctions(creds_path=test_config["creds_path"]) + + assert dffx.creds == test_config["creds_object"] + mock_creds.assert_called_once_with(test_config["creds_path"]) + + +# Test init with creds_dict +def test_dffx_init_creds_dict(mock_dffx_setup, test_config): + mock_creds = mock_dffx_setup + dffx = DataframeFunctions(creds_path=test_config["creds_dict"]) + + assert dffx.creds == test_config["creds_object"] + mock_creds.assert_called_once_with(test_config["creds_dict"]) + + +# Test init with creds object +def test_dffx_init_creds_object(mock_dffx_setup, test_config): + dffx = DataframeFunctions(creds=test_config["creds_object"]) + + assert dffx.creds == test_config["creds_object"]