summary refs log tree commit diff
path: root/tests/rest
diff options
context:
space:
mode:
Diffstat (limited to 'tests/rest')
-rw-r--r--tests/rest/admin/test_jwks.py8
-rw-r--r--tests/rest/admin/test_server_notice.py136
-rw-r--r--tests/rest/client/test_auth_issuer.py59
-rw-r--r--tests/rest/client/test_keys.py8
-rw-r--r--tests/rest/client/test_profile.py160
-rw-r--r--tests/rest/client/test_upgrade_room.py28
-rw-r--r--tests/rest/media/test_media_retention.py300
-rw-r--r--tests/rest/test_well_known.py8
8 files changed, 386 insertions, 321 deletions
diff --git a/tests/rest/admin/test_jwks.py b/tests/rest/admin/test_jwks.py
index 6c2b355aa8..3636ea3415 100644
--- a/tests/rest/admin/test_jwks.py
+++ b/tests/rest/admin/test_jwks.py
@@ -25,13 +25,7 @@ from twisted.web.resource import Resource
 from synapse.rest.synapse.client import build_synapse_client_resource_tree
 
 from tests.unittest import HomeserverTestCase, override_config, skip_unless
-
-try:
-    import authlib  # noqa: F401
-
-    HAS_AUTHLIB = True
-except ImportError:
-    HAS_AUTHLIB = False
+from tests.utils import HAS_AUTHLIB
 
 
 @skip_unless(HAS_AUTHLIB, "requires authlib")
diff --git a/tests/rest/admin/test_server_notice.py b/tests/rest/admin/test_server_notice.py
index ceba09ec46..ce5e3a5c1f 100644
--- a/tests/rest/admin/test_server_notice.py
+++ b/tests/rest/admin/test_server_notice.py
@@ -483,6 +483,33 @@ class ServerNoticeTestCase(unittest.HomeserverTestCase):
         # second room has new ID
         self.assertNotEqual(first_room_id, second_room_id)
 
+    @override_config(
+        {"server_notices": {"system_mxid_localpart": "notices", "auto_join": True}}
+    )
+    def test_auto_join(self) -> None:
+        """
+        Tests that the user get automatically joined to the notice room
+        when `auto_join` setting is used.
+        """
+        # user has no room memberships
+        self._check_invite_and_join_status(self.other_user, 0, 0)
+
+        # send server notice
+        server_notice_request_content = {
+            "user_id": self.other_user,
+            "content": {"msgtype": "m.text", "body": "test msg one"},
+        }
+
+        self.make_request(
+            "POST",
+            self.url,
+            access_token=self.admin_user_tok,
+            content=server_notice_request_content,
+        )
+
+        # user has joined the room
+        self._check_invite_and_join_status(self.other_user, 0, 1)
+
     @override_config({"server_notices": {"system_mxid_localpart": "notices"}})
     def test_update_notice_user_name_when_changed(self) -> None:
         """
@@ -575,6 +602,115 @@ class ServerNoticeTestCase(unittest.HomeserverTestCase):
         )
         self.assertEqual(notice_user_state["avatar_url"], new_avatar_url)
 
+    @override_config(
+        {
+            "server_notices": {
+                "system_mxid_localpart": "notices",
+                "room_avatar_url": "test/url",
+                "room_topic": "Test Topic",
+            }
+        }
+    )
+    def test_notice_room_avatar_and_topic(self) -> None:
+        """
+        Tests that using `room_avatar_url` and `room_topic` config properly sets
+        those properties for the created notice rooms.
+        """
+        server_notice_request_content = {
+            "user_id": self.other_user,
+            "content": {"msgtype": "m.text", "body": "test msg one"},
+        }
+
+        self.make_request(
+            "POST",
+            self.url,
+            access_token=self.admin_user_tok,
+            content=server_notice_request_content,
+        )
+
+        invited_rooms = self._check_invite_and_join_status(self.other_user, 1, 0)
+        notice_room_id = invited_rooms[0].room_id
+        self.helper.join(
+            room=notice_room_id, user=self.other_user, tok=self.other_user_token
+        )
+
+        room_avatar_state = self.helper.get_state(
+            notice_room_id,
+            "m.room.avatar",
+            self.other_user_token,
+            state_key="",
+        )
+        self.assertEqual(room_avatar_state["url"], "test/url")
+
+        room_topic_state = self.helper.get_state(
+            notice_room_id,
+            "m.room.topic",
+            self.other_user_token,
+            state_key="",
+        )
+        self.assertEqual(room_topic_state["topic"], "Test Topic")
+
+    @override_config(
+        {
+            "server_notices": {
+                "system_mxid_localpart": "notices",
+                "room_avatar_url": "test/url",
+            }
+        }
+    )
+    def test_update_room_avatar_when_changed(self) -> None:
+        """
+        Tests that existing server notices room avatar is updated when it is
+        different from the one in homeserver config.
+        """
+        server_notice_request_content = {
+            "user_id": self.other_user,
+            "content": {"msgtype": "m.text", "body": "test msg one"},
+        }
+
+        self.make_request(
+            "POST",
+            self.url,
+            access_token=self.admin_user_tok,
+            content=server_notice_request_content,
+        )
+
+        invited_rooms = self._check_invite_and_join_status(self.other_user, 1, 0)
+        notice_room_id = invited_rooms[0].room_id
+        self.helper.join(
+            room=notice_room_id, user=self.other_user, tok=self.other_user_token
+        )
+
+        room_avatar_state = self.helper.get_state(
+            notice_room_id,
+            "m.room.avatar",
+            self.other_user_token,
+            state_key="",
+        )
+        self.assertEqual(room_avatar_state["url"], "test/url")
+
+        # simulate a change in server config after a server restart.
+        new_avatar_url = "test/new-url"
+        self.server_notices_manager._config.servernotices.server_notices_room_avatar_url = (
+            new_avatar_url
+        )
+        self.server_notices_manager.get_or_create_notice_room_for_user.cache.invalidate_all()
+
+        self.make_request(
+            "POST",
+            self.url,
+            access_token=self.admin_user_tok,
+            content=server_notice_request_content,
+        )
+
+        room_avatar_state = self.helper.get_state(
+            notice_room_id,
+            "m.room.avatar",
+            self.other_user_token,
+            state_key="",
+        )
+        self.assertEqual(room_avatar_state["url"], new_avatar_url)
+
     def _check_invite_and_join_status(
         self, user_id: str, expected_invites: int, expected_memberships: int
     ) -> Sequence[RoomsForUser]:
diff --git a/tests/rest/client/test_auth_issuer.py b/tests/rest/client/test_auth_issuer.py
new file mode 100644
index 0000000000..964baeec32
--- /dev/null
+++ b/tests/rest/client/test_auth_issuer.py
@@ -0,0 +1,59 @@
+# Copyright 2023 The Matrix.org Foundation C.I.C.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from http import HTTPStatus
+
+from synapse.rest.client import auth_issuer
+
+from tests.unittest import HomeserverTestCase, override_config, skip_unless
+from tests.utils import HAS_AUTHLIB
+
+ISSUER = "https://account.example.com/"
+
+
+class AuthIssuerTestCase(HomeserverTestCase):
+    servlets = [
+        auth_issuer.register_servlets,
+    ]
+
+    def test_returns_404_when_msc3861_disabled(self) -> None:
+        # Make an unauthenticated request for the discovery info.
+        channel = self.make_request(
+            "GET",
+            "/_matrix/client/unstable/org.matrix.msc2965/auth_issuer",
+        )
+        self.assertEqual(channel.code, HTTPStatus.NOT_FOUND)
+
+    @skip_unless(HAS_AUTHLIB, "requires authlib")
+    @override_config(
+        {
+            "disable_registration": True,
+            "experimental_features": {
+                "msc3861": {
+                    "enabled": True,
+                    "issuer": ISSUER,
+                    "client_id": "David Lister",
+                    "client_auth_method": "client_secret_post",
+                    "client_secret": "Who shot Mister Burns?",
+                }
+            },
+        }
+    )
+    def test_returns_issuer_when_oidc_enabled(self) -> None:
+        # Make an unauthenticated request for the discovery info.
+        channel = self.make_request(
+            "GET",
+            "/_matrix/client/unstable/org.matrix.msc2965/auth_issuer",
+        )
+        self.assertEqual(channel.code, HTTPStatus.OK)
+        self.assertEqual(channel.json_body, {"issuer": ISSUER})
diff --git a/tests/rest/client/test_keys.py b/tests/rest/client/test_keys.py
index fb0f451a5c..e99160c5ac 100644
--- a/tests/rest/client/test_keys.py
+++ b/tests/rest/client/test_keys.py
@@ -36,13 +36,7 @@ from synapse.types import JsonDict, Requester, create_requester
 from tests import unittest
 from tests.http.server._base import make_request_with_cancellation_test
 from tests.unittest import override_config
-
-try:
-    import authlib  # noqa: F401
-
-    HAS_AUTHLIB = True
-except ImportError:
-    HAS_AUTHLIB = False
+from tests.utils import HAS_AUTHLIB
 
 
 class KeyQueryTestCase(unittest.HomeserverTestCase):
diff --git a/tests/rest/client/test_profile.py b/tests/rest/client/test_profile.py
index 13e36731a5..b9852928c0 100644
--- a/tests/rest/client/test_profile.py
+++ b/tests/rest/client/test_profile.py
@@ -318,6 +318,166 @@ class ProfileTestCase(unittest.HomeserverTestCase):
         )
         self.assertEqual(channel.code, 200, channel.result)
 
+    @unittest.override_config(
+        {"experimental_features": {"msc4069_profile_inhibit_propagation": True}}
+    )
+    def test_msc4069_inhibit_propagation(self) -> None:
+        """Tests to ensure profile update propagation can be inhibited."""
+        for prop in ["avatar_url", "displayname"]:
+            room_id = self.helper.create_room_as(tok=self.owner_tok)
+
+            channel = self.make_request(
+                "PUT",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                content={"membership": "join", prop: "mxc://my.server/existing"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            channel = self.make_request(
+                "PUT",
+                f"/profile/{self.owner}/{prop}?org.matrix.msc4069.propagate=false",
+                content={prop: "http://my.server/pic.gif"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            res = (
+                self._get_avatar_url()
+                if prop == "avatar_url"
+                else self._get_displayname()
+            )
+            self.assertEqual(res, "http://my.server/pic.gif")
+
+            channel = self.make_request(
+                "GET",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+            self.assertEqual(channel.json_body.get(prop), "mxc://my.server/existing")
+
+    def test_msc4069_inhibit_propagation_disabled(self) -> None:
+        """Tests to ensure profile update propagation inhibit flags are ignored when the
+        experimental flag is not enabled.
+        """
+        for prop in ["avatar_url", "displayname"]:
+            room_id = self.helper.create_room_as(tok=self.owner_tok)
+
+            channel = self.make_request(
+                "PUT",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                content={"membership": "join", prop: "mxc://my.server/existing"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            channel = self.make_request(
+                "PUT",
+                f"/profile/{self.owner}/{prop}?org.matrix.msc4069.propagate=false",
+                content={prop: "http://my.server/pic.gif"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            res = (
+                self._get_avatar_url()
+                if prop == "avatar_url"
+                else self._get_displayname()
+            )
+            self.assertEqual(res, "http://my.server/pic.gif")
+
+            channel = self.make_request(
+                "GET",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            # The ?propagate=false should be ignored by the server because the config flag
+            # isn't enabled.
+            self.assertEqual(channel.json_body.get(prop), "http://my.server/pic.gif")
+
+    def test_msc4069_inhibit_propagation_default(self) -> None:
+        """Tests to ensure profile update propagation happens by default."""
+        for prop in ["avatar_url", "displayname"]:
+            room_id = self.helper.create_room_as(tok=self.owner_tok)
+
+            channel = self.make_request(
+                "PUT",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                content={"membership": "join", prop: "mxc://my.server/existing"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            channel = self.make_request(
+                "PUT",
+                f"/profile/{self.owner}/{prop}",
+                content={prop: "http://my.server/pic.gif"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            res = (
+                self._get_avatar_url()
+                if prop == "avatar_url"
+                else self._get_displayname()
+            )
+            self.assertEqual(res, "http://my.server/pic.gif")
+
+            channel = self.make_request(
+                "GET",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            # The ?propagate=false should be ignored by the server because the config flag
+            # isn't enabled.
+            self.assertEqual(channel.json_body.get(prop), "http://my.server/pic.gif")
+
+    @unittest.override_config(
+        {"experimental_features": {"msc4069_profile_inhibit_propagation": True}}
+    )
+    def test_msc4069_inhibit_propagation_like_default(self) -> None:
+        """Tests to ensure clients can request explicit profile propagation."""
+        for prop in ["avatar_url", "displayname"]:
+            room_id = self.helper.create_room_as(tok=self.owner_tok)
+
+            channel = self.make_request(
+                "PUT",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                content={"membership": "join", prop: "mxc://my.server/existing"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            channel = self.make_request(
+                "PUT",
+                f"/profile/{self.owner}/{prop}?org.matrix.msc4069.propagate=true",
+                content={prop: "http://my.server/pic.gif"},
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            res = (
+                self._get_avatar_url()
+                if prop == "avatar_url"
+                else self._get_displayname()
+            )
+            self.assertEqual(res, "http://my.server/pic.gif")
+
+            channel = self.make_request(
+                "GET",
+                f"/rooms/{room_id}/state/m.room.member/{self.owner}",
+                access_token=self.owner_tok,
+            )
+            self.assertEqual(channel.code, 200, channel.result)
+
+            # The client requested ?propagate=true, so it should have happened.
+            self.assertEqual(channel.json_body.get(prop), "http://my.server/pic.gif")
+
     def _setup_local_files(self, names_and_props: Dict[str, Dict[str, Any]]) -> None:
         """Stores metadata about files in the database.
 
diff --git a/tests/rest/client/test_upgrade_room.py b/tests/rest/client/test_upgrade_room.py
index a497f41fb2..7038e42058 100644
--- a/tests/rest/client/test_upgrade_room.py
+++ b/tests/rest/client/test_upgrade_room.py
@@ -252,6 +252,34 @@ class UpgradeRoomTest(unittest.HomeserverTestCase):
         # We should now have an integer power level.
         self.assertEqual(new_power_levels["users"][self.creator], 100, new_power_levels)
 
+    def test_events_field_missing(self) -> None:
+        """Regression test for https://github.com/matrix-org/synapse/issues/16715."""
+        # Create a new room.
+        room_id = self.helper.create_room_as(
+            self.creator, tok=self.creator_token, room_version="10"
+        )
+        self.helper.join(room_id, self.other, tok=self.other_token)
+
+        # Retrieve the room's current power levels.
+        power_levels = self.helper.get_state(
+            room_id,
+            "m.room.power_levels",
+            tok=self.creator_token,
+        )
+
+        # Remove the events field and re-set the power levels.
+        del power_levels["events"]
+        self.helper.send_state(
+            room_id,
+            "m.room.power_levels",
+            body=power_levels,
+            tok=self.creator_token,
+        )
+
+        # Upgrade the room. Check the homeserver reports success.
+        channel = self._upgrade_room(room_id=room_id)
+        self.assertEqual(200, channel.code, channel.result)
+
     def test_space(self) -> None:
         """Test upgrading a space."""
 
diff --git a/tests/rest/media/test_media_retention.py b/tests/rest/media/test_media_retention.py
deleted file mode 100644
index 7f613f351b..0000000000
--- a/tests/rest/media/test_media_retention.py
+++ /dev/null
@@ -1,300 +0,0 @@
-#
-# This file is licensed under the Affero General Public License (AGPL) version 3.
-#
-# Copyright (C) 2023 New Vector, Ltd
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# See the GNU Affero General Public License for more details:
-# <https://www.gnu.org/licenses/agpl-3.0.html>.
-#
-# Originally licensed under the Apache License, Version 2.0:
-# <http://www.apache.org/licenses/LICENSE-2.0>.
-#
-# [This file includes modifications made by New Vector Limited]
-#
-#
-
-import io
-from typing import Iterable, Optional
-
-from matrix_common.types.mxc_uri import MXCUri
-
-from twisted.test.proto_helpers import MemoryReactor
-
-from synapse.rest import admin
-from synapse.rest.client import login, register, room
-from synapse.server import HomeServer
-from synapse.types import UserID
-from synapse.util import Clock
-
-from tests import unittest
-from tests.unittest import override_config
-from tests.utils import MockClock
-
-
-class MediaRetentionTestCase(unittest.HomeserverTestCase):
-    ONE_DAY_IN_MS = 24 * 60 * 60 * 1000
-    THIRTY_DAYS_IN_MS = 30 * ONE_DAY_IN_MS
-
-    servlets = [
-        room.register_servlets,
-        login.register_servlets,
-        register.register_servlets,
-        admin.register_servlets_for_client_rest_resource,
-    ]
-
-    def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
-        # We need to be able to test advancing time in the homeserver, so we
-        # replace the test homeserver's default clock with a MockClock, which
-        # supports advancing time.
-        return self.setup_test_homeserver(clock=MockClock())
-
-    def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
-        self.remote_server_name = "remote.homeserver"
-        self.store = hs.get_datastores().main
-
-        # Create a user to upload media with
-        test_user_id = self.register_user("alice", "password")
-
-        # Inject media (recently accessed, old access, never accessed, old access
-        # quarantined media) into both the local store and the remote cache, plus
-        # one additional local media that is marked as protected from quarantine.
-        media_repository = hs.get_media_repository()
-        test_media_content = b"example string"
-
-        def _create_media_and_set_attributes(
-            last_accessed_ms: Optional[int],
-            is_quarantined: Optional[bool] = False,
-            is_protected: Optional[bool] = False,
-        ) -> MXCUri:
-            # "Upload" some media to the local media store
-            mxc_uri: MXCUri = self.get_success(
-                media_repository.create_content(
-                    media_type="text/plain",
-                    upload_name=None,
-                    content=io.BytesIO(test_media_content),
-                    content_length=len(test_media_content),
-                    auth_user=UserID.from_string(test_user_id),
-                )
-            )
-
-            # Set the last recently accessed time for this media
-            if last_accessed_ms is not None:
-                self.get_success(
-                    self.store.update_cached_last_access_time(
-                        local_media=(mxc_uri.media_id,),
-                        remote_media=(),
-                        time_ms=last_accessed_ms,
-                    )
-                )
-
-            if is_quarantined:
-                # Mark this media as quarantined
-                self.get_success(
-                    self.store.quarantine_media_by_id(
-                        server_name=self.hs.config.server.server_name,
-                        media_id=mxc_uri.media_id,
-                        quarantined_by="@theadmin:test",
-                    )
-                )
-
-            if is_protected:
-                # Mark this media as protected from quarantine
-                self.get_success(
-                    self.store.mark_local_media_as_safe(
-                        media_id=mxc_uri.media_id,
-                        safe=True,
-                    )
-                )
-
-            return mxc_uri
-
-        def _cache_remote_media_and_set_attributes(
-            media_id: str,
-            last_accessed_ms: Optional[int],
-            is_quarantined: Optional[bool] = False,
-        ) -> MXCUri:
-            # Pretend to cache some remote media
-            self.get_success(
-                self.store.store_cached_remote_media(
-                    origin=self.remote_server_name,
-                    media_id=media_id,
-                    media_type="text/plain",
-                    media_length=1,
-                    time_now_ms=clock.time_msec(),
-                    upload_name="testfile.txt",
-                    filesystem_id="abcdefg12345",
-                )
-            )
-
-            # Set the last recently accessed time for this media
-            if last_accessed_ms is not None:
-                self.get_success(
-                    hs.get_datastores().main.update_cached_last_access_time(
-                        local_media=(),
-                        remote_media=((self.remote_server_name, media_id),),
-                        time_ms=last_accessed_ms,
-                    )
-                )
-
-            if is_quarantined:
-                # Mark this media as quarantined
-                self.get_success(
-                    self.store.quarantine_media_by_id(
-                        server_name=self.remote_server_name,
-                        media_id=media_id,
-                        quarantined_by="@theadmin:test",
-                    )
-                )
-
-            return MXCUri(self.remote_server_name, media_id)
-
-        # Start with the local media store
-        self.local_recently_accessed_media = _create_media_and_set_attributes(
-            last_accessed_ms=self.THIRTY_DAYS_IN_MS,
-        )
-        self.local_not_recently_accessed_media = _create_media_and_set_attributes(
-            last_accessed_ms=self.ONE_DAY_IN_MS,
-        )
-        self.local_not_recently_accessed_quarantined_media = (
-            _create_media_and_set_attributes(
-                last_accessed_ms=self.ONE_DAY_IN_MS,
-                is_quarantined=True,
-            )
-        )
-        self.local_not_recently_accessed_protected_media = (
-            _create_media_and_set_attributes(
-                last_accessed_ms=self.ONE_DAY_IN_MS,
-                is_protected=True,
-            )
-        )
-        self.local_never_accessed_media = _create_media_and_set_attributes(
-            last_accessed_ms=None,
-        )
-
-        # And now the remote media store
-        self.remote_recently_accessed_media = _cache_remote_media_and_set_attributes(
-            media_id="a",
-            last_accessed_ms=self.THIRTY_DAYS_IN_MS,
-        )
-        self.remote_not_recently_accessed_media = (
-            _cache_remote_media_and_set_attributes(
-                media_id="b",
-                last_accessed_ms=self.ONE_DAY_IN_MS,
-            )
-        )
-        self.remote_not_recently_accessed_quarantined_media = (
-            _cache_remote_media_and_set_attributes(
-                media_id="c",
-                last_accessed_ms=self.ONE_DAY_IN_MS,
-                is_quarantined=True,
-            )
-        )
-        # Remote media will always have a "last accessed" attribute, as it would not
-        # be fetched from the remote homeserver unless instigated by a user.
-
-    @override_config(
-        {
-            "media_retention": {
-                # Enable retention for local media
-                "local_media_lifetime": "30d"
-                # Cached remote media should not be purged
-            }
-        }
-    )
-    def test_local_media_retention(self) -> None:
-        """
-        Tests that local media that have not been accessed recently is purged, while
-        cached remote media is unaffected.
-        """
-        # Advance 31 days (in seconds)
-        self.reactor.advance(31 * 24 * 60 * 60)
-
-        # Check that media has been correctly purged.
-        # Local media accessed <30 days ago should still exist.
-        # Remote media should be unaffected.
-        self._assert_if_mxc_uris_purged(
-            purged=[
-                self.local_not_recently_accessed_media,
-                self.local_never_accessed_media,
-            ],
-            not_purged=[
-                self.local_recently_accessed_media,
-                self.local_not_recently_accessed_quarantined_media,
-                self.local_not_recently_accessed_protected_media,
-                self.remote_recently_accessed_media,
-                self.remote_not_recently_accessed_media,
-                self.remote_not_recently_accessed_quarantined_media,
-            ],
-        )
-
-    @override_config(
-        {
-            "media_retention": {
-                # Enable retention for cached remote media
-                "remote_media_lifetime": "30d"
-                # Local media should not be purged
-            }
-        }
-    )
-    def test_remote_media_cache_retention(self) -> None:
-        """
-        Tests that entries from the remote media cache that have not been accessed
-        recently is purged, while local media is unaffected.
-        """
-        # Advance 31 days (in seconds)
-        self.reactor.advance(31 * 24 * 60 * 60)
-
-        # Check that media has been correctly purged.
-        # Local media should be unaffected.
-        # Remote media accessed <30 days ago should still exist.
-        self._assert_if_mxc_uris_purged(
-            purged=[
-                self.remote_not_recently_accessed_media,
-            ],
-            not_purged=[
-                self.remote_recently_accessed_media,
-                self.local_recently_accessed_media,
-                self.local_not_recently_accessed_media,
-                self.local_not_recently_accessed_quarantined_media,
-                self.local_not_recently_accessed_protected_media,
-                self.remote_not_recently_accessed_quarantined_media,
-                self.local_never_accessed_media,
-            ],
-        )
-
-    def _assert_if_mxc_uris_purged(
-        self, purged: Iterable[MXCUri], not_purged: Iterable[MXCUri]
-    ) -> None:
-        def _assert_mxc_uri_purge_state(mxc_uri: MXCUri, expect_purged: bool) -> None:
-            """Given an MXC URI, assert whether it has been purged or not."""
-            if mxc_uri.server_name == self.hs.config.server.server_name:
-                found_media = bool(
-                    self.get_success(self.store.get_local_media(mxc_uri.media_id))
-                )
-            else:
-                found_media = bool(
-                    self.get_success(
-                        self.store.get_cached_remote_media(
-                            mxc_uri.server_name, mxc_uri.media_id
-                        )
-                    )
-                )
-
-            if expect_purged:
-                self.assertFalse(found_media, msg=f"{mxc_uri} unexpectedly not purged")
-            else:
-                self.assertTrue(
-                    found_media,
-                    msg=f"{mxc_uri} unexpectedly purged",
-                )
-
-        # Assert that the given MXC URIs have either been correctly purged or not.
-        for mxc_uri in purged:
-            _assert_mxc_uri_purge_state(mxc_uri, expect_purged=True)
-        for mxc_uri in not_purged:
-            _assert_mxc_uri_purge_state(mxc_uri, expect_purged=False)
diff --git a/tests/rest/test_well_known.py b/tests/rest/test_well_known.py
index 682aa63e5b..e166c13bc1 100644
--- a/tests/rest/test_well_known.py
+++ b/tests/rest/test_well_known.py
@@ -22,13 +22,7 @@ from twisted.web.resource import Resource
 from synapse.rest.well_known import well_known_resource
 
 from tests import unittest
-
-try:
-    import authlib  # noqa: F401
-
-    HAS_AUTHLIB = True
-except ImportError:
-    HAS_AUTHLIB = False
+from tests.utils import HAS_AUTHLIB
 
 
 class WellKnownTests(unittest.HomeserverTestCase):