forked from MirrorHub/synapse
Skip unit tests which require optional dependencies (#9031)
If we are lacking an optional dependency, skip the tests that rely on it.
This commit is contained in:
parent
eee3c3c52f
commit
8d3d264052
7 changed files with 91 additions and 14 deletions
1
changelog.d/9031.misc
Normal file
1
changelog.d/9031.misc
Normal file
|
@ -0,0 +1 @@
|
|||
Fix running unit tests when optional dependencies are not installed.
|
|
@ -24,7 +24,6 @@ import pymacaroons
|
|||
from twisted.web.resource import Resource
|
||||
|
||||
from synapse.api.errors import RedirectException
|
||||
from synapse.handlers.oidc_handler import OidcError
|
||||
from synapse.handlers.sso import MappingException
|
||||
from synapse.rest.client.v1 import login
|
||||
from synapse.rest.synapse.client.pick_username import pick_username_resource
|
||||
|
@ -34,6 +33,14 @@ from synapse.types import UserID
|
|||
from tests.test_utils import FakeResponse, simple_async_mock
|
||||
from tests.unittest import HomeserverTestCase, override_config
|
||||
|
||||
try:
|
||||
import authlib # noqa: F401
|
||||
|
||||
HAS_OIDC = True
|
||||
except ImportError:
|
||||
HAS_OIDC = False
|
||||
|
||||
|
||||
# These are a few constants that are used as config parameters in the tests.
|
||||
ISSUER = "https://issuer/"
|
||||
CLIENT_ID = "test-client-id"
|
||||
|
@ -113,6 +120,9 @@ async def get_json(url):
|
|||
|
||||
|
||||
class OidcHandlerTestCase(HomeserverTestCase):
|
||||
if not HAS_OIDC:
|
||||
skip = "requires OIDC"
|
||||
|
||||
def default_config(self):
|
||||
config = super().default_config()
|
||||
config["public_baseurl"] = BASE_URL
|
||||
|
@ -458,6 +468,8 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
self.assertRenderedError("fetch_error")
|
||||
|
||||
# Handle code exchange failure
|
||||
from synapse.handlers.oidc_handler import OidcError
|
||||
|
||||
self.handler._exchange_code = simple_async_mock(
|
||||
raises=OidcError("invalid_request")
|
||||
)
|
||||
|
@ -538,6 +550,8 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
body=b'{"error": "foo", "error_description": "bar"}',
|
||||
)
|
||||
)
|
||||
from synapse.handlers.oidc_handler import OidcError
|
||||
|
||||
exc = self.get_failure(self.handler._exchange_code(code), OidcError)
|
||||
self.assertEqual(exc.value.error, "foo")
|
||||
self.assertEqual(exc.value.error_description, "bar")
|
||||
|
@ -829,6 +843,9 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
|
||||
|
||||
class UsernamePickerTestCase(HomeserverTestCase):
|
||||
if not HAS_OIDC:
|
||||
skip = "requires OIDC"
|
||||
|
||||
servlets = [login.register_servlets]
|
||||
|
||||
def default_config(self):
|
||||
|
|
|
@ -4,7 +4,10 @@ import urllib.parse
|
|||
|
||||
from mock import Mock
|
||||
|
||||
import jwt
|
||||
try:
|
||||
import jwt
|
||||
except ImportError:
|
||||
jwt = None
|
||||
|
||||
import synapse.rest.admin
|
||||
from synapse.appservice import ApplicationService
|
||||
|
@ -460,6 +463,9 @@ class CASTestCase(unittest.HomeserverTestCase):
|
|||
|
||||
|
||||
class JWTTestCase(unittest.HomeserverTestCase):
|
||||
if not jwt:
|
||||
skip = "requires jwt"
|
||||
|
||||
servlets = [
|
||||
synapse.rest.admin.register_servlets_for_client_rest_resource,
|
||||
login.register_servlets,
|
||||
|
@ -628,6 +634,9 @@ class JWTTestCase(unittest.HomeserverTestCase):
|
|||
# RSS256, with a public key configured in synapse as "jwt_secret", and tokens
|
||||
# signed by the private key.
|
||||
class JWTPubKeyTestCase(unittest.HomeserverTestCase):
|
||||
if not jwt:
|
||||
skip = "requires jwt"
|
||||
|
||||
servlets = [
|
||||
login.register_servlets,
|
||||
]
|
||||
|
|
|
@ -26,8 +26,10 @@ from synapse.rest.oidc import OIDCResource
|
|||
from synapse.types import JsonDict, UserID
|
||||
|
||||
from tests import unittest
|
||||
from tests.handlers.test_oidc import HAS_OIDC
|
||||
from tests.rest.client.v1.utils import TEST_OIDC_CONFIG
|
||||
from tests.server import FakeChannel
|
||||
from tests.unittest import override_config, skip_unless
|
||||
|
||||
|
||||
class DummyRecaptchaChecker(UserInteractiveAuthChecker):
|
||||
|
@ -158,20 +160,22 @@ class UIAuthTests(unittest.HomeserverTestCase):
|
|||
|
||||
def default_config(self):
|
||||
config = super().default_config()
|
||||
|
||||
# we enable OIDC as a way of testing SSO flows
|
||||
oidc_config = {}
|
||||
oidc_config.update(TEST_OIDC_CONFIG)
|
||||
oidc_config["allow_existing_users"] = True
|
||||
|
||||
config["oidc_config"] = oidc_config
|
||||
config["public_baseurl"] = "https://synapse.test"
|
||||
|
||||
if HAS_OIDC:
|
||||
# we enable OIDC as a way of testing SSO flows
|
||||
oidc_config = {}
|
||||
oidc_config.update(TEST_OIDC_CONFIG)
|
||||
oidc_config["allow_existing_users"] = True
|
||||
config["oidc_config"] = oidc_config
|
||||
|
||||
return config
|
||||
|
||||
def create_resource_dict(self):
|
||||
resource_dict = super().create_resource_dict()
|
||||
# mount the OIDC resource at /_synapse/oidc
|
||||
resource_dict["/_synapse/oidc"] = OIDCResource(self.hs)
|
||||
if HAS_OIDC:
|
||||
# mount the OIDC resource at /_synapse/oidc
|
||||
resource_dict["/_synapse/oidc"] = OIDCResource(self.hs)
|
||||
return resource_dict
|
||||
|
||||
def prepare(self, reactor, clock, hs):
|
||||
|
@ -380,6 +384,8 @@ class UIAuthTests(unittest.HomeserverTestCase):
|
|||
# Note that *no auth* information is provided, not even a session iD!
|
||||
self.delete_device(self.user_tok, self.device_id, 200)
|
||||
|
||||
@skip_unless(HAS_OIDC, "requires OIDC")
|
||||
@override_config({"oidc_config": TEST_OIDC_CONFIG})
|
||||
def test_does_not_offer_password_for_sso_user(self):
|
||||
login_resp = self.helper.login_via_oidc("username")
|
||||
user_tok = login_resp["access_token"]
|
||||
|
@ -393,13 +399,13 @@ class UIAuthTests(unittest.HomeserverTestCase):
|
|||
self.assertEqual(flows, [{"stages": ["m.login.sso"]}])
|
||||
|
||||
def test_does_not_offer_sso_for_password_user(self):
|
||||
# now call the device deletion API: we should get the option to auth with SSO
|
||||
# and not password.
|
||||
channel = self.delete_device(self.user_tok, self.device_id, 401)
|
||||
|
||||
flows = channel.json_body["flows"]
|
||||
self.assertEqual(flows, [{"stages": ["m.login.password"]}])
|
||||
|
||||
@skip_unless(HAS_OIDC, "requires OIDC")
|
||||
@override_config({"oidc_config": TEST_OIDC_CONFIG})
|
||||
def test_offers_both_flows_for_upgraded_user(self):
|
||||
"""A user that had a password and then logged in with SSO should get both flows
|
||||
"""
|
||||
|
|
|
@ -26,8 +26,15 @@ from twisted.test.proto_helpers import AccumulatingProtocol
|
|||
from tests import unittest
|
||||
from tests.server import FakeTransport
|
||||
|
||||
try:
|
||||
import lxml
|
||||
except ImportError:
|
||||
lxml = None
|
||||
|
||||
|
||||
class URLPreviewTests(unittest.HomeserverTestCase):
|
||||
if not lxml:
|
||||
skip = "url preview feature requires lxml"
|
||||
|
||||
hijack_auth = True
|
||||
user_id = "@test:user"
|
||||
|
|
|
@ -20,8 +20,16 @@ from synapse.rest.media.v1.preview_url_resource import (
|
|||
|
||||
from . import unittest
|
||||
|
||||
try:
|
||||
import lxml
|
||||
except ImportError:
|
||||
lxml = None
|
||||
|
||||
|
||||
class PreviewTestCase(unittest.TestCase):
|
||||
if not lxml:
|
||||
skip = "url preview feature requires lxml"
|
||||
|
||||
def test_long_summarize(self):
|
||||
example_paras = [
|
||||
"""Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:
|
||||
|
@ -137,6 +145,9 @@ class PreviewTestCase(unittest.TestCase):
|
|||
|
||||
|
||||
class PreviewUrlTestCase(unittest.TestCase):
|
||||
if not lxml:
|
||||
skip = "url preview feature requires lxml"
|
||||
|
||||
def test_simple(self):
|
||||
html = """
|
||||
<html>
|
||||
|
|
|
@ -20,7 +20,7 @@ import hmac
|
|||
import inspect
|
||||
import logging
|
||||
import time
|
||||
from typing import Dict, Iterable, Optional, Tuple, Type, TypeVar, Union
|
||||
from typing import Callable, Dict, Iterable, Optional, Tuple, Type, TypeVar, Union
|
||||
|
||||
from mock import Mock, patch
|
||||
|
||||
|
@ -736,3 +736,29 @@ def override_config(extra_config):
|
|||
return func
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
TV = TypeVar("TV")
|
||||
|
||||
|
||||
def skip_unless(condition: bool, reason: str) -> Callable[[TV], TV]:
|
||||
"""A test decorator which will skip the decorated test unless a condition is set
|
||||
|
||||
For example:
|
||||
|
||||
class MyTestCase(TestCase):
|
||||
@skip_unless(HAS_FOO, "Cannot test without foo")
|
||||
def test_foo(self):
|
||||
...
|
||||
|
||||
Args:
|
||||
condition: If true, the test will be skipped
|
||||
reason: the reason to give for skipping the test
|
||||
"""
|
||||
|
||||
def decorator(f: TV) -> TV:
|
||||
if not condition:
|
||||
f.skip = reason # type: ignore
|
||||
return f
|
||||
|
||||
return decorator
|
||||
|
|
Loading…
Reference in a new issue