Skip to content

Commit

Permalink
Fix async tests (spec-first#1558)
Browse files Browse the repository at this point in the history
* Use pytest-asyncio for async tests

* Fix async tests
  • Loading branch information
Ruwann committed Jun 24, 2022
1 parent 3c6e13c commit 6f9117c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
4 changes: 3 additions & 1 deletion connexion/security/security_handler_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,12 @@ def verify_multiple_schemes(self, schemes):
:rtype: types.FunctionType
"""

def wrapper(request):
async def wrapper(request):
token_info = {}
for scheme_name, func in schemes.items():
result = func(request)
while asyncio.iscoroutine(result):
result = await result
if result is self.no_value:
return self.no_value
token_info[scheme_name] = result
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def read_version(package):

tests_require = [
'pytest>=6,<7',
'pytest-asyncio>=0.18,<0.19',
'pre-commit>=2,<3',
'pytest-cov>=2,<3',
*flask_require,
Expand All @@ -57,7 +58,7 @@ class PyTest(TestCommand):
def initialize_options(self):
TestCommand.initialize_options(self)
self.cov = None
self.pytest_args = ['--cov', 'connexion', '--cov-report', 'term-missing', '-v']
self.pytest_args = ['--cov', 'connexion', '--cov-report', 'term-missing', '-v', "--asyncio-mode", "auto"]
self.cov_html = False

def finalize_options(self):
Expand Down
40 changes: 27 additions & 13 deletions tests/decorators/test_security.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
import json
from unittest.mock import MagicMock

Expand Down Expand Up @@ -63,16 +64,22 @@ async def get_tokeninfo_response(*args, **kwargs):
client.get = get_tokeninfo_response
monkeypatch.setattr(SecurityHandlerFactory, 'client', client)

with pytest.raises(OAuthScopeProblem, match="Provided token doesn't have the required scope"):
with pytest.raises(OAuthScopeProblem) as exc_info:
await wrapped_func(request)

assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Provided token doesn't have the required scope"

tokeninfo["scope"] += " admin"
assert await wrapped_func(request) is not None

tokeninfo["scope"] = ["foo", "bar"]
with pytest.raises(OAuthScopeProblem, match="Provided token doesn't have the required scope"):
with pytest.raises(OAuthScopeProblem) as exc_info:
await wrapped_func(request)

assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Provided token doesn't have the required scope"

tokeninfo["scope"].append("admin")
assert await wrapped_func(request) is not None

Expand Down Expand Up @@ -101,16 +108,22 @@ def token_info(token):
request = MagicMock()
request.headers = {"Authorization": "Bearer 123"}

with pytest.raises(OAuthScopeProblem, match="Provided token doesn't have the required scope"):
with pytest.raises(OAuthScopeProblem) as exc_info:
await wrapped_func(request)

assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Provided token doesn't have the required scope"

tokeninfo["scope"] += " admin"
assert await wrapped_func(request) is not None

tokeninfo["scope"] = ["foo", "bar"]
with pytest.raises(OAuthScopeProblem, match="Provided token doesn't have the required scope"):
with pytest.raises(OAuthScopeProblem) as exc_info:
await wrapped_func(request)

assert exc_info.value.status_code == 403
assert exc_info.value.detail == "Provided token doesn't have the required scope"

tokeninfo["scope"].append("admin")
assert await wrapped_func(request) is not None

Expand All @@ -127,7 +140,7 @@ def somefunc(username, password, required_scopes=None):
assert wrapped_func(request) is security_handler_factory.no_value


def test_verify_basic(security_handler_factory):
async def test_verify_basic(security_handler_factory):
def basic_info(username, password, required_scopes=None):
if username == 'foo' and password == 'bar':
return {'sub': 'foo'}
Expand All @@ -138,10 +151,10 @@ def basic_info(username, password, required_scopes=None):
request = MagicMock()
request.headers = {"Authorization": 'Basic Zm9vOmJhcg=='}

assert wrapped_func(request) is not None
assert await wrapped_func(request) is not None


def test_verify_apikey_query(security_handler_factory):
async def test_verify_apikey_query(security_handler_factory):
def apikey_info(apikey, required_scopes=None):
if apikey == 'foobar':
return {'sub': 'foo'}
Expand All @@ -152,10 +165,10 @@ def apikey_info(apikey, required_scopes=None):
request = MagicMock()
request.query = {"auth": 'foobar'}

assert wrapped_func(request) is not None
assert await wrapped_func(request) is not None


def test_verify_apikey_header(security_handler_factory):
async def test_verify_apikey_header(security_handler_factory):
def apikey_info(apikey, required_scopes=None):
if apikey == 'foobar':
return {'sub': 'foo'}
Expand All @@ -166,7 +179,7 @@ def apikey_info(apikey, required_scopes=None):
request = MagicMock()
request.headers = {"X-Auth": 'foobar'}

assert wrapped_func(request) is not None
assert await wrapped_func(request) is not None


async def test_multiple_schemes(security_handler_factory):
Expand All @@ -191,7 +204,7 @@ def apikey2_info(apikey, required_scopes=None):
request = MagicMock()
request.headers = {"X-Auth-1": 'foobar'}

assert wrapped_func(request) is security_handler_factory.no_value
assert await wrapped_func(request) is security_handler_factory.no_value

request = MagicMock()
request.headers = {"X-Auth-2": 'bar'}
Expand All @@ -214,13 +227,14 @@ def apikey2_info(apikey, required_scopes=None):

async def test_verify_security_oauthproblem(security_handler_factory):
"""Tests whether verify_security raises an OAuthProblem if there are no auth_funcs."""
security_func = security_handler_factory.verify_security([], [])
security_func = security_handler_factory.verify_security([])

request = MagicMock()
with pytest.raises(OAuthProblem) as exc_info:
await security_func(request)

assert str(exc_info.value) == '401 Unauthorized: No authorization token provided'
assert exc_info.value.status_code == 401
assert exc_info.value.detail == 'No authorization token provided'

@pytest.mark.parametrize(
'errors, most_specific',
Expand Down

0 comments on commit 6f9117c

Please sign in to comment.