Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 0edd066

Browse files
committed
Skip unit tests which require optional dependencies
If we are lacking an optional dependency, skip the tests that rely on it.
1 parent 8f08021 commit 0edd066

File tree

7 files changed

+75
-14
lines changed

7 files changed

+75
-14
lines changed

changelog.d/9031.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix running unit tests when optional dependencies are not installed.

tests/handlers/test_oidc.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from twisted.web.resource import Resource
2525

2626
from synapse.api.errors import RedirectException
27-
from synapse.handlers.oidc_handler import OidcError
2827
from synapse.handlers.sso import MappingException
2928
from synapse.rest.client.v1 import login
3029
from synapse.rest.synapse.client.pick_username import pick_username_resource
@@ -34,6 +33,14 @@
3433
from tests.test_utils import FakeResponse, simple_async_mock
3534
from tests.unittest import HomeserverTestCase, override_config
3635

36+
try:
37+
import authlib
38+
39+
HAS_OIDC = True
40+
except ImportError:
41+
HAS_OIDC = False
42+
43+
3744
# These are a few constants that are used as config parameters in the tests.
3845
ISSUER = "https://issuer/"
3946
CLIENT_ID = "test-client-id"
@@ -113,6 +120,9 @@ async def get_json(url):
113120

114121

115122
class OidcHandlerTestCase(HomeserverTestCase):
123+
if not HAS_OIDC:
124+
skip = "requires OIDC"
125+
116126
def default_config(self):
117127
config = super().default_config()
118128
config["public_baseurl"] = BASE_URL
@@ -458,6 +468,8 @@ def test_callback(self):
458468
self.assertRenderedError("fetch_error")
459469

460470
# Handle code exchange failure
471+
from synapse.handlers.oidc_handler import OidcError
472+
461473
self.handler._exchange_code = simple_async_mock(
462474
raises=OidcError("invalid_request")
463475
)
@@ -538,6 +550,8 @@ def test_exchange_code(self):
538550
body=b'{"error": "foo", "error_description": "bar"}',
539551
)
540552
)
553+
from synapse.handlers.oidc_handler import OidcError
554+
541555
exc = self.get_failure(self.handler._exchange_code(code), OidcError)
542556
self.assertEqual(exc.value.error, "foo")
543557
self.assertEqual(exc.value.error_description, "bar")
@@ -829,6 +843,9 @@ def test_null_localpart(self):
829843

830844

831845
class UsernamePickerTestCase(HomeserverTestCase):
846+
if not HAS_OIDC:
847+
skip = "requires OIDC"
848+
832849
servlets = [login.register_servlets]
833850

834851
def default_config(self):

tests/rest/client/v1/test_login.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
from mock import Mock
66

7-
import jwt
7+
try:
8+
import jwt
9+
except ImportError:
10+
jwt = None
811

912
import synapse.rest.admin
1013
from synapse.appservice import ApplicationService
@@ -460,6 +463,9 @@ def test_deactivated_user(self):
460463

461464

462465
class JWTTestCase(unittest.HomeserverTestCase):
466+
if not jwt:
467+
skip = "requires jwt"
468+
463469
servlets = [
464470
synapse.rest.admin.register_servlets_for_client_rest_resource,
465471
login.register_servlets,
@@ -628,6 +634,9 @@ def test_login_no_token(self):
628634
# RSS256, with a public key configured in synapse as "jwt_secret", and tokens
629635
# signed by the private key.
630636
class JWTPubKeyTestCase(unittest.HomeserverTestCase):
637+
if not jwt:
638+
skip = "requires jwt"
639+
631640
servlets = [
632641
login.register_servlets,
633642
]

tests/rest/client/v2_alpha/test_auth.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@
2626
from synapse.types import JsonDict, UserID
2727

2828
from tests import unittest
29-
from tests.rest.client.v1.utils import TEST_OIDC_CONFIG
29+
from tests.handlers.test_oidc import HAS_OIDC
30+
from tests.rest.client.v1.utils import TEST_OIDC_CONFIG as BASE_OIDC_CONFIG
3031
from tests.server import FakeChannel
32+
from tests.test_utils import skip_unless
33+
from tests.unittest import override_config
3134

3235

3336
class DummyRecaptchaChecker(UserInteractiveAuthChecker):
@@ -147,6 +150,12 @@ def test_complete_operation_unknown_session(self):
147150
self.recaptcha(session, 400, session + "unknown")
148151

149152

153+
# we enable OIDC as a way of testing SSO flows
154+
TEST_OIDC_CONFIG = {}
155+
TEST_OIDC_CONFIG.update(BASE_OIDC_CONFIG)
156+
TEST_OIDC_CONFIG["allow_existing_users"] = True
157+
158+
150159
class UIAuthTests(unittest.HomeserverTestCase):
151160
servlets = [
152161
auth.register_servlets,
@@ -158,20 +167,14 @@ class UIAuthTests(unittest.HomeserverTestCase):
158167

159168
def default_config(self):
160169
config = super().default_config()
161-
162-
# we enable OIDC as a way of testing SSO flows
163-
oidc_config = {}
164-
oidc_config.update(TEST_OIDC_CONFIG)
165-
oidc_config["allow_existing_users"] = True
166-
167-
config["oidc_config"] = oidc_config
168170
config["public_baseurl"] = "https://synapse.test"
169171
return config
170172

171173
def create_resource_dict(self):
172174
resource_dict = super().create_resource_dict()
173-
# mount the OIDC resource at /_synapse/oidc
174-
resource_dict["/_synapse/oidc"] = OIDCResource(self.hs)
175+
if HAS_OIDC:
176+
# mount the OIDC resource at /_synapse/oidc
177+
resource_dict["/_synapse/oidc"] = OIDCResource(self.hs)
175178
return resource_dict
176179

177180
def prepare(self, reactor, clock, hs):
@@ -380,6 +383,8 @@ def test_can_reuse_session(self):
380383
# Note that *no auth* information is provided, not even a session iD!
381384
self.delete_device(self.user_tok, self.device_id, 200)
382385

386+
@skip_unless(HAS_OIDC, "requires OIDC")
387+
@override_config({"oidc_config": TEST_OIDC_CONFIG})
383388
def test_does_not_offer_password_for_sso_user(self):
384389
login_resp = self.helper.login_via_oidc("username")
385390
user_tok = login_resp["access_token"]
@@ -393,13 +398,13 @@ def test_does_not_offer_password_for_sso_user(self):
393398
self.assertEqual(flows, [{"stages": ["m.login.sso"]}])
394399

395400
def test_does_not_offer_sso_for_password_user(self):
396-
# now call the device deletion API: we should get the option to auth with SSO
397-
# and not password.
398401
channel = self.delete_device(self.user_tok, self.device_id, 401)
399402

400403
flows = channel.json_body["flows"]
401404
self.assertEqual(flows, [{"stages": ["m.login.password"]}])
402405

406+
@skip_unless(HAS_OIDC, "requires OIDC")
407+
@override_config({"oidc_config": TEST_OIDC_CONFIG})
403408
def test_offers_both_flows_for_upgraded_user(self):
404409
"""A user that had a password and then logged in with SSO should get both flows
405410
"""

tests/rest/media/v1/test_url_preview.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,15 @@
2626
from tests import unittest
2727
from tests.server import FakeTransport
2828

29+
try:
30+
import lxml
31+
except ImportError:
32+
lxml = None
33+
2934

3035
class URLPreviewTests(unittest.HomeserverTestCase):
36+
if not lxml:
37+
skip = "url preview feature requires lxml"
3138

3239
hijack_auth = True
3340
user_id = "@test:user"

tests/test_preview.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,16 @@
2020

2121
from . import unittest
2222

23+
try:
24+
import lxml
25+
except ImportError:
26+
lxml = None
27+
2328

2429
class PreviewTestCase(unittest.TestCase):
30+
if not lxml:
31+
skip = "url preview feature requires lxml"
32+
2533
def test_long_summarize(self):
2634
example_paras = [
2735
"""Tromsø (Norwegian pronunciation: [ˈtrʊmsœ] ( listen); Northern Sami:
@@ -137,6 +145,9 @@ def test_small_then_large_summarize(self):
137145

138146

139147
class PreviewUrlTestCase(unittest.TestCase):
148+
if not lxml:
149+
skip = "url preview feature requires lxml"
150+
140151
def test_simple(self):
141152
html = """
142153
<html>

tests/test_utils/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,14 @@ class FakeResponse:
119119
def deliverBody(self, protocol):
120120
protocol.dataReceived(self.body)
121121
protocol.connectionLost(Failure(ResponseDone()))
122+
123+
124+
def skip_unless(condition: bool, reason: str) -> Callable:
125+
"""A test decorator which will skip the decorated test unless a condition is set"""
126+
127+
def decorator(f: Callable):
128+
if not condition:
129+
f.skip = reason
130+
return f
131+
132+
return decorator

0 commit comments

Comments
 (0)