Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show an error message on "Test Connection" failure for Google Spreadsheet Query Runner #6652

Merged
merged 1 commit into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion redash/query_runner/google_spreadsheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
try:
import google.auth
import gspread
from google.auth.exceptions import GoogleAuthError
from google.oauth2.service_account import Credentials
from gspread.exceptions import APIError
from gspread.exceptions import WorksheetNotFound as GSWorksheetNotFound
Expand Down Expand Up @@ -230,13 +231,17 @@ def _get_spreadsheet_service(self):
return spreadsheetservice

def test_connection(self):
service = self._get_spreadsheet_service()
test_spreadsheet_key = "1S0mld7LMbUad8LYlo13Os9f7eNjw57MqVC0YiCd1Jis"
try:
service = self._get_spreadsheet_service()
service.open_by_key(test_spreadsheet_key).worksheets()
except APIError as e:
logger.exception(e)
message = parse_api_error(e)
raise Exception(message)
except GoogleAuthError as e:
logger.exception(e)
raise Exception(str(e))

def run_query(self, query, user):
logger.debug("Spreadsheet is about to execute query: %s", query)
Expand Down
35 changes: 34 additions & 1 deletion tests/query_runner/test_google_spreadsheets.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import datetime
from unittest import TestCase

from mock import MagicMock
import pytest
from google.auth.exceptions import TransportError
from gspread.exceptions import APIError
from mock import MagicMock, patch

from redash.query_runner import TYPE_DATETIME, TYPE_FLOAT
from redash.query_runner.google_spreadsheets import (
TYPE_BOOLEAN,
TYPE_STRING,
GoogleSpreadsheet,
WorksheetNotFoundByTitleError,
WorksheetNotFoundError,
_get_columns_and_column_names,
Expand Down Expand Up @@ -171,3 +175,32 @@ def test_is_url_key(self):

_key = "key|0"
self.assertFalse(is_url_key(_key))


class TestConnection(TestCase):
@patch("redash.query_runner.google_spreadsheets.google.auth.default")
@patch("redash.query_runner.google_spreadsheets.gspread.Client")
def test_connect_succuess(self, mock_client, _mock_auth_default):
try:
qr_gspread = GoogleSpreadsheet({})
qr_gspread.test_connection()
mock_client().login.assert_called_once_with()
mock_client().open_by_key.assert_called_once()
except Exception:
self.fail("test_connection failed")

@patch("redash.query_runner.google_spreadsheets.google.auth.default")
def test_connect_fail_with_transport_error(self, mock_auth_default):
mock_auth_default.side_effect = TransportError("Connection Refused")
qr_gspread = GoogleSpreadsheet({})
with pytest.raises(Exception):
qr_gspread.test_connection()

@patch("redash.query_runner.google_spreadsheets.google.auth.default")
def test_connect_fail_with_api_error(self, mock_auth_default):
mock_response = MagicMock()
mock_response.json.return_value = {"error": {"message": "Sheet API is disabled"}}
mock_auth_default.side_effect = APIError(mock_response)
qr_gspread = GoogleSpreadsheet({})
with pytest.raises(Exception):
qr_gspread.test_connection()
Loading