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

Commit

Permalink
Add type hints to both test_user_directory files
Browse files Browse the repository at this point in the history
  • Loading branch information
David Robertson committed Sep 28, 2021
1 parent 707dc17 commit 495c308
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 37 deletions.
6 changes: 6 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ disallow_untyped_defs = True
[mypy-synapse.util.wheel_timer]
disallow_untyped_defs = True

[mypy-tests.handlers.test_user_directory]
disallow_untyped_defs = True

[mypy-tests.storage.test_user_directory]
disallow_untyped_defs = True

[mypy-pymacaroons.*]
ignore_missing_imports = True

Expand Down
2 changes: 1 addition & 1 deletion synapse/storage/databases/main/user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ async def get_user_in_directory(self, user_id: str) -> Optional[Dict[str, str]]:
desc="get_user_in_directory",
)

async def update_user_directory_stream_pos(self, stream_id: int) -> None:
async def update_user_directory_stream_pos(self, stream_id: Optional[int]) -> None:
await self.db_pool.simple_update_one(
table="user_directory_stream_pos",
keyvalues={},
Expand Down
65 changes: 39 additions & 26 deletions tests/handlers/test_user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@
# 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 unittest.mock import Mock
from unittest.mock import Mock, patch
from urllib.parse import quote

from twisted.internet import defer
from twisted.internet.testing import MemoryReactor

import synapse.rest.admin
from synapse.api.constants import UserTypes
from synapse.api.room_versions import RoomVersion, RoomVersions
from synapse.rest.client import login, room, user_directory
from synapse.server import HomeServer
from synapse.storage.roommember import ProfileInfo
from synapse.types import create_requester
from synapse.util import Clock

from tests import unittest
from tests.storage.test_user_directory import GetUserDirectoryTables
Expand All @@ -47,20 +50,19 @@ class UserDirectoryTestCase(unittest.HomeserverTestCase):
room.register_servlets,
]

def make_homeserver(self, reactor, clock):

def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
config = self.default_config()
config["update_user_directory"] = True
return self.setup_test_homeserver(config=config)

def prepare(self, reactor, clock, hs):
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
self.store = hs.get_datastore()
self.handler = hs.get_user_directory_handler()
self.event_builder_factory = self.hs.get_event_builder_factory()
self.event_creation_handler = self.hs.get_event_creation_handler()
self.user_dir_helper = GetUserDirectoryTables(self.store)

def test_handle_local_profile_change_with_support_user(self):
def test_handle_local_profile_change_with_support_user(self) -> None:
support_user_id = "@support:test"
self.get_success(
self.store.register_user(
Expand All @@ -73,7 +75,9 @@ def test_handle_local_profile_change_with_support_user(self):
)

self.get_success(
self.handler.handle_local_profile_change(support_user_id, None)
self.handler.handle_local_profile_change(
support_user_id, ProfileInfo("I love support me", None)
)
)
profile = self.get_success(self.store.get_user_in_directory(support_user_id))
self.assertTrue(profile is None)
Expand All @@ -86,7 +90,7 @@ def test_handle_local_profile_change_with_support_user(self):
profile = self.get_success(self.store.get_user_in_directory(regular_user_id))
self.assertTrue(profile["display_name"] == display_name)

def test_handle_local_profile_change_with_deactivated_user(self):
def test_handle_local_profile_change_with_deactivated_user(self) -> None:
# create user
r_user_id = "@regular:test"
self.get_success(
Expand Down Expand Up @@ -121,28 +125,37 @@ def test_handle_local_profile_change_with_deactivated_user(self):
profile = self.get_success(self.store.get_user_in_directory(r_user_id))
self.assertTrue(profile is None)

def test_handle_user_deactivated_support_user(self):
def test_handle_user_deactivated_support_user(self) -> None:
s_user_id = "@support:test"
self.get_success(
self.store.register_user(
user_id=s_user_id, password_hash=None, user_type=UserTypes.SUPPORT
)
)

self.store.remove_from_user_dir = Mock(return_value=defer.succeed(None))
self.get_success(self.handler.handle_local_user_deactivated(s_user_id))
self.store.remove_from_user_dir.not_called()
mock_remove_from_user_dir = Mock(return_value=defer.succeed(None))
with patch.object(
self.store, "remove_from_user_dir", mock_remove_from_user_dir
):
self.get_success(self.handler.handle_local_user_deactivated(s_user_id))
# BUG: the correct spelling is assert_not_called, but that makes the test fail
# and it's not clear that this is actually the behaviour we want.
mock_remove_from_user_dir.not_called()

def test_handle_user_deactivated_regular_user(self):
def test_handle_user_deactivated_regular_user(self) -> None:
r_user_id = "@regular:test"
self.get_success(
self.store.register_user(user_id=r_user_id, password_hash=None)
)
self.store.remove_from_user_dir = Mock(return_value=defer.succeed(None))
self.get_success(self.handler.handle_local_user_deactivated(r_user_id))
self.store.remove_from_user_dir.called_once_with(r_user_id)

def test_reactivation_makes_regular_user_searchable(self):
mock_remove_from_user_dir = Mock(return_value=defer.succeed(None))
with patch.object(
self.store, "remove_from_user_dir", mock_remove_from_user_dir
):
self.get_success(self.handler.handle_local_user_deactivated(r_user_id))
mock_remove_from_user_dir.assert_called_once_with(r_user_id)

def test_reactivation_makes_regular_user_searchable(self) -> None:
user = self.register_user("regular", "pass")
user_token = self.login(user, "pass")
admin_user = self.register_user("admin", "pass", admin=True)
Expand Down Expand Up @@ -180,7 +193,7 @@ def test_reactivation_makes_regular_user_searchable(self):
self.assertEqual(len(s["results"]), 1)
self.assertEqual(s["results"][0]["user_id"], user)

def test_private_room(self):
def test_private_room(self) -> None:
"""
A user can be searched for only by people that are either in a public
room, or that share a private chat.
Expand Down Expand Up @@ -246,7 +259,7 @@ def test_private_room(self):
s = self.get_success(self.handler.search_users(u1, "user3", 10))
self.assertEqual(len(s["results"]), 0)

def test_spam_checker(self):
def test_spam_checker(self) -> None:
"""
A user which fails the spam checks will not appear in search results.
"""
Expand Down Expand Up @@ -281,7 +294,7 @@ def test_spam_checker(self):
s = self.get_success(self.handler.search_users(u1, "user2", 10))
self.assertEqual(len(s["results"]), 1)

async def allow_all(user_profile):
async def allow_all(user_profile: ProfileInfo) -> bool:
# Allow all users.
return False

Expand All @@ -295,7 +308,7 @@ async def allow_all(user_profile):
self.assertEqual(len(s["results"]), 1)

# Configure a spam checker that filters all users.
async def block_all(user_profile):
async def block_all(user_profile: ProfileInfo) -> bool:
# All users are spammy.
return True

Expand All @@ -305,7 +318,7 @@ async def block_all(user_profile):
s = self.get_success(self.handler.search_users(u1, "user2", 10))
self.assertEqual(len(s["results"]), 0)

def test_legacy_spam_checker(self):
def test_legacy_spam_checker(self) -> None:
"""
A spam checker without the expected method should be ignored.
"""
Expand Down Expand Up @@ -345,7 +358,7 @@ def test_legacy_spam_checker(self):
s = self.get_success(self.handler.search_users(u1, "user2", 10))
self.assertEqual(len(s["results"]), 1)

def test_initial_share_all_users(self):
def test_initial_share_all_users(self) -> None:
"""
Search all users = True means that a user does not have to share a
private room with the searching user or be in a public room to be search
Expand Down Expand Up @@ -392,7 +405,7 @@ def test_initial_share_all_users(self):
}
}
)
def test_prefer_local_users(self):
def test_prefer_local_users(self) -> None:
"""Tests that local users are shown higher in search results when
user_directory.prefer_local_users is True.
"""
Expand Down Expand Up @@ -447,7 +460,7 @@ def _add_user_to_room(
room_id: str,
room_version: RoomVersion,
user_id: str,
):
) -> None:
# Add a user to the room.
builder = self.event_builder_factory.for_room_version(
room_version,
Expand Down Expand Up @@ -479,7 +492,7 @@ class TestUserDirSearchDisabled(unittest.HomeserverTestCase):
synapse.rest.admin.register_servlets_for_client_rest_resource,
]

def make_homeserver(self, reactor, clock):
def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
config = self.default_config()
config["update_user_directory"] = True
hs = self.setup_test_homeserver(config=config)
Expand All @@ -488,7 +501,7 @@ def make_homeserver(self, reactor, clock):

return hs

def test_disabling_room_list(self):
def test_disabling_room_list(self) -> None:
self.config.userdirectory.user_directory_search_enabled = True

# First we create a room with another user so that user dir is non-empty
Expand Down
24 changes: 15 additions & 9 deletions tests/storage/test_user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
# 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 typing import Dict, List, Tuple
from typing import Dict, List, Set, Tuple

from twisted.internet.testing import MemoryReactor

from synapse.rest import admin
from synapse.rest.client import login, room
from synapse.server import HomeServer
from synapse.storage import DataStore
from synapse.util import Clock

from tests.unittest import HomeserverTestCase, override_config

Expand All @@ -32,7 +36,9 @@ class GetUserDirectoryTables:
def __init__(self, store: DataStore):
self.store = store

def _compress_shared(self, shared: List[Dict[str, str]]):
def _compress_shared(
self, shared: List[Dict[str, str]]
) -> Set[Tuple[str, str, str]]:
"""
Compress a list of users who share rooms dicts to a list of tuples.
"""
Expand Down Expand Up @@ -72,11 +78,11 @@ class UserDirectoryInitialPopulationTestcase(HomeserverTestCase):
room.register_servlets,
]

def prepare(self, reactor, clock, hs):
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
self.store = hs.get_datastore()
self.user_dir_helper = GetUserDirectoryTables(self.store)

def _purge_and_rebuild_user_dir(self):
def _purge_and_rebuild_user_dir(self) -> None:
"""Nuke the user directory tables, start the background process to
repopulate them, and wait for the process to complete. This allows us
to inspect the outcome of the background process alone, without any of
Expand Down Expand Up @@ -146,7 +152,7 @@ def _purge_and_rebuild_user_dir(self):
self.store.db_pool.updates.do_next_background_update(100), by=0.1
)

def test_initial(self):
def test_initial(self) -> None:
"""
The user directory's initial handler correctly updates the search tables.
"""
Expand Down Expand Up @@ -200,7 +206,7 @@ def test_initial(self):


class UserDirectoryStoreTestCase(HomeserverTestCase):
def prepare(self, reactor, clock, hs):
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
self.store = hs.get_datastore()

# alice and bob are both in !room_id. bobby is not but shares
Expand All @@ -211,7 +217,7 @@ def prepare(self, reactor, clock, hs):
self.get_success(self.store.update_profile_in_user_dir(BELA, "Bela", None))
self.get_success(self.store.add_users_in_public_rooms("!room:id", (ALICE, BOB)))

def test_search_user_dir(self):
def test_search_user_dir(self) -> None:
# normally when alice searches the directory she should just find
# bob because bobby doesn't share a room with her.
r = self.get_success(self.store.search_user_dir(ALICE, "bob", 10))
Expand All @@ -222,7 +228,7 @@ def test_search_user_dir(self):
)

@override_config({"user_directory": {"search_all_users": True}})
def test_search_user_dir_all_users(self):
def test_search_user_dir_all_users(self) -> None:
r = self.get_success(self.store.search_user_dir(ALICE, "bob", 10))
self.assertFalse(r["limited"])
self.assertEqual(2, len(r["results"]))
Expand All @@ -236,7 +242,7 @@ def test_search_user_dir_all_users(self):
)

@override_config({"user_directory": {"search_all_users": True}})
def test_search_user_dir_stop_words(self):
def test_search_user_dir_stop_words(self) -> None:
"""Tests that a user can look up another user by searching for the start if its
display name even if that name happens to be a common English word that would
usually be ignored in full text searches.
Expand Down
4 changes: 3 additions & 1 deletion tests/unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from canonicaljson import json

from twisted.internet.defer import Deferred, ensureDeferred, succeed
from twisted.internet.testing import MemoryReactor
from twisted.python.failure import Failure
from twisted.python.threadpool import ThreadPool
from twisted.trial import unittest
Expand All @@ -46,6 +47,7 @@
)
from synapse.server import HomeServer
from synapse.types import UserID, create_requester
from synapse.util import Clock
from synapse.util.httpresourcetree import create_resource_tree
from synapse.util.ratelimitutils import FederationRateLimiter

Expand Down Expand Up @@ -371,7 +373,7 @@ def default_config(self):

return config

def prepare(self, reactor, clock, homeserver):
def prepare(self, reactor: MemoryReactor, clock: Clock, homeserver: HomeServer):
"""
Prepare for the test. This involves things like mocking out parts of
the homeserver, or building test data common across the whole test
Expand Down

0 comments on commit 495c308

Please sign in to comment.