Skip to content

Commit

Permalink
tests(google-sheets2): adapt to token retrieval by OAuth2Connector
Browse files Browse the repository at this point in the history
  • Loading branch information
davinov authored and luc-leonard committed Oct 14, 2020
1 parent b8f0b14 commit 224853a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 64 deletions.
42 changes: 6 additions & 36 deletions tests/google_sheets_2/test_google_sheets_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
import pytest
from pytest import fixture

import tests.general_helpers as helpers
from toucan_connectors.common import HttpError
from toucan_connectors.google_sheets_2.google_sheets_2_connector import (
GoogleSheets2Connector,
GoogleSheets2DataSource,
NoCredentialsError,
)
from toucan_connectors.oauth2_connector.oauth2connector import OAuth2Connector

import_path = 'toucan_connectors.google_sheets_2.google_sheets_2_connector'

Expand Down Expand Up @@ -61,7 +59,7 @@ def ds_without_sheet():
@pytest.mark.asyncio
async def test_authentified_fetch(mocker, con):
"""It should return a result from fetch if all is ok."""
mocker.patch(f'{import_path}.fetch', return_value=helpers.build_future(FAKE_SHEET))
mocker.patch(f'{import_path}.fetch', return_value=FAKE_SHEET)

result = await con._fetch('/foo')

Expand All @@ -70,15 +68,9 @@ async def test_authentified_fetch(mocker, con):

FAKE_SHEET_LIST_RESPONSE = {
'sheets': [
{
'properties': {'title': 'Foo'},
},
{
'properties': {'title': 'Bar'},
},
{
'properties': {'title': 'Baz'},
},
{'properties': {'title': 'Foo'}},
{'properties': {'title': 'Bar'}},
{'properties': {'title': 'Baz'}},
]
}

Expand Down Expand Up @@ -162,9 +154,7 @@ def test_set_columns(mocker, con, ds):

def test__run_fetch(mocker, con):
"""It should return a result from loops if all is ok."""
mocker.patch.object(
GoogleSheets2Connector, '_fetch', return_value=helpers.build_future(FAKE_SHEET)
)
mocker.patch.object(GoogleSheets2Connector, '_fetch', return_value=FAKE_SHEET)

result = con._run_fetch('/fudge')

Expand Down Expand Up @@ -201,21 +191,13 @@ def mock_api_responses(uri: str):
assert df.columns.tolist() == ['country', 'city']


def test_get_status_no_secrets(con, remove_secrets):
def test_get_status_no_secrets(mocker, con):
"""
It should fail if no secrets are provided
"""
assert con.get_status().status is False


def test_get_status_secrets_error(mocker, con):
"""
It should fail if secrets can't be retrieved
"""
mocker.patch(f'{import_path}.OAuth2Connector.get_access_token', side_effect=Exception)
assert con.get_status().status is False


def test_get_status_success(mocker, con):
"""
It should fail if no secrets are provided.
Expand Down Expand Up @@ -248,15 +230,3 @@ def test_get_decimal_separator(mocker, con, ds):
mocker.patch.object(GoogleSheets2Connector, '_run_fetch', return_value=fake_results)
df = con.get_df(ds)
assert df.to_dict() == {'Number': {1: 1.3, 2: 1.2}}


def test_delegate_oauth2_methods(mocker, con):
"""
It should proxy OAuth2Connectors methods
"""
mock_oauth2_connector = mocker.Mock(spec=OAuth2Connector)
con.__dict__['_oauth2_connector'] = mock_oauth2_connector
con.build_authorization_url()
mock_oauth2_connector.build_authorization_url.assert_called()
con.retrieve_tokens('toto')
mock_oauth2_connector.retrieve_tokens.assert_called_with('toto')
22 changes: 1 addition & 21 deletions tests/oauth2_connector/test_oauth2connector.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
from typing import Any
from unittest.mock import Mock

import pytest

from toucan_connectors.oauth2_connector.oauth2connector import (
NoOAuth2RefreshToken,
OAuth2Connector,
SecretsKeeper,
)
from toucan_connectors.oauth2_connector.oauth2connector import NoOAuth2RefreshToken, OAuth2Connector

FAKE_AUTHORIZATION_URL = 'http://localhost:4242/foobar'
FAKE_TOKEN_URL = 'http://service/token_endpoint'
SCOPE: str = 'openid email https://www.googleapis.com/auth/spreadsheets.readonly'


@pytest.fixture
def secrets_keeper():
class SimpleSecretsKeeper(SecretsKeeper):
def __init__(self):
self.store = {}

def load(self, key: str) -> Any:
return self.store[key]

def save(self, key: str, value: Any):
self.store[key] = value

return SimpleSecretsKeeper()


@pytest.fixture
def oauth2_connector(secrets_keeper):
return OAuth2Connector(
Expand Down
16 changes: 9 additions & 7 deletions toucan_connectors/google_sheets_2/google_sheets_2_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,14 @@ class GoogleSheets2DataSource(ToucanDataSource):
)

@classmethod
def get_form(cls, connector: 'GoogleSheets2Connector', current_config, **kwargs):
def get_form(cls, connector: 'GoogleSheets2Connector', current_config):
"""Retrieve a form filled with suggestions of available sheets."""
# Always add the suggestions for the available sheets
constraints = {}
with suppress(Exception):
partial_endpoint = current_config['spreadsheet_id']
final_url = f'{connector._baseroute}{partial_endpoint}'
secrets = kwargs.get('secrets')(auth_flow_id=connector.auth_flow_id)
data = connector._run_fetch(final_url, secrets['access_token'])
data = connector._run_fetch(final_url)
available_sheets = [str(x['properties']['title']) for x in data['sheets']]
constraints['sheet'] = strlist_to_enum('sheet', available_sheets)

Expand Down Expand Up @@ -99,17 +98,20 @@ def retrieve_tokens(self, authorization_response: str):
def get_access_token(self):
return self.__dict__['_oauth2_connector'].get_access_token()

async def _authentified_fetch(self, url):
async def _fetch(self, url, headers=None):
"""Build the final request along with headers."""
headers = {'Authorization': f'Bearer {self.get_access_token()}'}

async with ClientSession(headers=headers) as session:
return await fetch(url, session)

def _run_fetch(self, url):
"""Run loop."""
access_token = self.get_access_token()
if not access_token:
raise NoCredentialsError('No credentials')
headers = {'Authorization': f'Bearer {access_token}'}

loop = get_loop()
future = asyncio.ensure_future(self._authentified_fetch(url))
future = asyncio.ensure_future(self._fetch(url, headers))
return loop.run_until_complete(future)

def _retrieve_data(self, data_source: GoogleSheets2DataSource) -> pd.DataFrame:
Expand Down

0 comments on commit 224853a

Please sign in to comment.