Skip to content

Commit

Permalink
tests(oauth2): exclude local helpers from coverage
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 224853a commit 77bb46e
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 35 deletions.
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ exclude_lines =
# Files to exclude from consideration
omit =
# Utilities for OAuth2 connectors testing
toucan_connectors/oauth2_connector/quickstart
oauth_connector_quickstart.py
toucan_connectors/oauth2_connector/oauth2_authorization_webserver.py
28 changes: 21 additions & 7 deletions oauth_connector_quickstart.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
from toucan_connectors.google_sheets_2.google_sheets_2_connector import GoogleSheets2Connector, GoogleSheets2DataSource
from toucan_connectors.oauth2_connector.oauth2_authorization_webserver import get_authorization_response
from toucan_connectors.oauth2_connector.oauth2connector import JsonFileSecretsKeeper

from toucan_connectors.google_sheets_2.google_sheets_2_connector import (
GoogleSheets2Connector,
GoogleSheets2DataSource,
)
from toucan_connectors.oauth2_connector.oauth2_authorization_webserver import (
JsonFileSecretsKeeper,
get_authorization_response,
)

CLIENT_ID = ''
CLIENT_SECRET = ''
REDIRECT_URI = 'http://localhost:34097/'

google_sheets_conn = GoogleSheets2Connector(name='test', auth_flow_id='test', client_id=CLIENT_ID, client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI, secrets_keeper=JsonFileSecretsKeeper(filename="secrets.json"))
sample_data_source_ss = GoogleSheets2DataSource(name='test', domain='test-connector', spreadsheet_id='1L5YraXEToFv7p0HMke7gXI4IhJotdT0q5bk_PInI1hA')
google_sheets_conn = GoogleSheets2Connector(
name='test',
auth_flow_id='test',
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
secrets_keeper=JsonFileSecretsKeeper(filename="secrets.json"),
)
sample_data_source_ss = GoogleSheets2DataSource(
name='test',
domain='test-connector',
spreadsheet_id='1L5YraXEToFv7p0HMke7gXI4IhJotdT0q5bk_PInI1hA',
)

# authorization_response = get_authorization_response(google_sheets_conn.build_authorization_url(), 'localhost', 34097)
# google_sheets_conn.retrieve_tokens(authorization_response)
Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sonar.projectVersion=0.41.4

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
sonar.sources=./toucan_connectors
sonar.coverage.exclusions=./toucan_connectors/install_scripts/**/*,./toucan_connectors/oauth2_connector/quickstart/**/*
sonar.coverage.exclusions=./toucan_connectors/install_scripts,./toucan_connectors/oauth2_connector/oauth2_authorization_webserver.py
sonar.test.inclusions=./tests

# Encoding of the source code. Default is default system encoding
Expand Down
23 changes: 22 additions & 1 deletion tests/google_sheets_2/test_google_sheets_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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 @@ -191,13 +192,21 @@ def mock_api_responses(uri: str):
assert df.columns.tolist() == ['country', 'city']


def test_get_status_no_secrets(mocker, con):
def test_get_status_no_secrets(con, remove_secrets):
"""
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 @@ -230,3 +239,15 @@ 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')
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
"""
This provide a helper to test OAuth2 connectors locally
"""
import json
import webbrowser
import wsgiref.simple_server
import wsgiref.util
from sys import path
from typing import Any


class _RedirectWSGIApp(object):
Expand Down Expand Up @@ -44,3 +50,23 @@ def get_authorization_response(authorization_url, host, port):
local_server = wsgiref.simple_server.make_server(host, port, app)
local_server.handle_request()
return app.last_request_uri


class JsonFileSecretsKeeper:
def __init__(self, filename: str):
self.filename = filename

def load_file(self) -> dict:
if not path.exists(self.filename):
return {}
with open(self.filename, 'r') as f:
return json.load(f)

def save(self, key: str, value):
values = self.load_file()
values[key] = value
with open(self.filename, 'w') as f:
json.dump(values, f)

def load(self, key: str) -> Any:
return self.load_file()[key]
35 changes: 10 additions & 25 deletions toucan_connectors/oauth2_connector/oauth2connector.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
import json
from os import path
from abc import ABC, abstractmethod
from time import time
from typing import Any
from urllib import parse as url_parse

from authlib.integrations.requests_client import OAuth2Session


class SecretsKeeper:
class SecretsKeeper(ABC):
@abstractmethod
def save(self, key: str, value):
pass

def load(self, key: str) -> Any:
pass


class JsonFileSecretsKeeper:
def __init__(self, filename: str):
self.filename = filename

def load_file(self) -> dict:
if not path.exists(self.filename):
return {}
with open(self.filename, 'r') as f:
return json.load(f)

def save(self, key: str, value):
values = self.load_file()
values[key] = value
with open(self.filename, 'w') as f:
json.dump(values, f)
"""
Save secrets in a secrets repository
"""

@abstractmethod
def load(self, key: str) -> Any:
return self.load_file()[key]
"""
Load secrets from the secrets repository
"""


class OAuth2Connector:
Expand Down

0 comments on commit 77bb46e

Please sign in to comment.