diff --git a/tests/appservice/test_api.py b/tests/appservice/test_api.py
new file mode 100644
index 0000000000..3e0db4dd98
--- /dev/null
+++ b/tests/appservice/test_api.py
@@ -0,0 +1,102 @@
+# Copyright 2022 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 typing import Any, List, Mapping
+from unittest.mock import Mock
+
+from twisted.test.proto_helpers import MemoryReactor
+
+from synapse.appservice import ApplicationService
+from synapse.server import HomeServer
+from synapse.types import JsonDict
+from synapse.util import Clock
+
+from tests import unittest
+
+PROTOCOL = "myproto"
+TOKEN = "myastoken"
+URL = "http://mytestservice"
+
+
+class ApplicationServiceApiTestCase(unittest.HomeserverTestCase):
+ def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer):
+ self.api = hs.get_application_service_api()
+ self.service = ApplicationService(
+ id="unique_identifier",
+ sender="@as:test",
+ url=URL,
+ token="unused",
+ hs_token=TOKEN,
+ hostname="myserver",
+ )
+
+ def test_query_3pe_authenticates_token(self):
+ """
+ Tests that 3pe queries to the appservice are authenticated
+ with the appservice's token.
+ """
+
+ SUCCESS_RESULT_USER = [
+ {
+ "protocol": PROTOCOL,
+ "userid": "@a:user",
+ "fields": {
+ "more": "fields",
+ },
+ }
+ ]
+ SUCCESS_RESULT_LOCATION = [
+ {
+ "protocol": PROTOCOL,
+ "alias": "#a:room",
+ "fields": {
+ "more": "fields",
+ },
+ }
+ ]
+
+ URL_USER = f"{URL}/_matrix/app/unstable/thirdparty/user/{PROTOCOL}"
+ URL_LOCATION = f"{URL}/_matrix/app/unstable/thirdparty/location/{PROTOCOL}"
+
+ self.request_url = None
+
+ async def get_json(url: str, args: Mapping[Any, Any]) -> List[JsonDict]:
+ if not args.get(b"access_token"):
+ raise RuntimeError("Access token not provided")
+
+ self.assertEqual(args.get(b"access_token"), TOKEN)
+ self.request_url = url
+ if url == URL_USER:
+ return SUCCESS_RESULT_USER
+ elif url == URL_LOCATION:
+ return SUCCESS_RESULT_LOCATION
+ else:
+ raise RuntimeError(
+ "URL provided was invalid. This should never be seen."
+ )
+
+ # We assign to a method, which mypy doesn't like.
+ self.api.get_json = Mock(side_effect=get_json) # type: ignore[assignment]
+
+ result = self.get_success(
+ self.api.query_3pe(self.service, "user", PROTOCOL, {b"some": [b"field"]})
+ )
+ self.assertEqual(self.request_url, URL_USER)
+ self.assertEqual(result, SUCCESS_RESULT_USER)
+ result = self.get_success(
+ self.api.query_3pe(
+ self.service, "location", PROTOCOL, {b"some": [b"field"]}
+ )
+ )
+ self.assertEqual(self.request_url, URL_LOCATION)
+ self.assertEqual(result, SUCCESS_RESULT_LOCATION)
diff --git a/tests/appservice/test_appservice.py b/tests/appservice/test_appservice.py
index edc584d0cf..7135362f76 100644
--- a/tests/appservice/test_appservice.py
+++ b/tests/appservice/test_appservice.py
@@ -23,7 +23,7 @@ from tests.test_utils import simple_async_mock
def _regex(regex: str, exclusive: bool = True) -> Namespace:
- return Namespace(exclusive, None, re.compile(regex))
+ return Namespace(exclusive, re.compile(regex))
class ApplicationServiceTestCase(unittest.TestCase):
diff --git a/tests/handlers/test_federation.py b/tests/handlers/test_federation.py
index e95dfdce20..ec00900621 100644
--- a/tests/handlers/test_federation.py
+++ b/tests/handlers/test_federation.py
@@ -50,7 +50,7 @@ class FederationTestCase(unittest.FederatingHomeserverTestCase):
hs = self.setup_test_homeserver(federation_http_client=None)
self.handler = hs.get_federation_handler()
self.store = hs.get_datastores().main
- self.state_store = hs.get_storage().state
+ self.state_storage = hs.get_storage().state
self._event_auth_handler = hs.get_event_auth_handler()
return hs
@@ -276,7 +276,11 @@ class FederationTestCase(unittest.FederatingHomeserverTestCase):
# federation handler wanting to backfill the fake event.
self.get_success(
federation_event_handler._process_received_pdu(
- self.OTHER_SERVER_NAME, event, state=current_state
+ self.OTHER_SERVER_NAME,
+ event,
+ state_ids={
+ (e.type, e.state_key): e.event_id for e in current_state
+ },
)
)
@@ -334,7 +338,7 @@ class FederationTestCase(unittest.FederatingHomeserverTestCase):
# mapping from (type, state_key) -> state_event_id
assert most_recent_prev_event_id is not None
prev_state_map = self.get_success(
- self.state_store.get_state_ids_for_event(most_recent_prev_event_id)
+ self.state_storage.get_state_ids_for_event(most_recent_prev_event_id)
)
# List of state event ID's
prev_state_ids = list(prev_state_map.values())
diff --git a/tests/handlers/test_room_summary.py b/tests/handlers/test_room_summary.py
index e74eb71774..0546655690 100644
--- a/tests/handlers/test_room_summary.py
+++ b/tests/handlers/test_room_summary.py
@@ -179,7 +179,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
result_children_ids.append(
[
(cs["room_id"], cs["state_key"])
- for cs in result_room.get("children_state")
+ for cs in result_room["children_state"]
]
)
@@ -772,7 +772,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": public_room,
"world_readable": False,
- "join_rules": JoinRules.PUBLIC,
+ "join_rule": JoinRules.PUBLIC,
},
),
(
@@ -780,7 +780,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": knock_room,
"world_readable": False,
- "join_rules": JoinRules.KNOCK,
+ "join_rule": JoinRules.KNOCK,
},
),
(
@@ -788,7 +788,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": not_invited_room,
"world_readable": False,
- "join_rules": JoinRules.INVITE,
+ "join_rule": JoinRules.INVITE,
},
),
(
@@ -796,7 +796,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": invited_room,
"world_readable": False,
- "join_rules": JoinRules.INVITE,
+ "join_rule": JoinRules.INVITE,
},
),
(
@@ -804,7 +804,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": restricted_room,
"world_readable": False,
- "join_rules": JoinRules.RESTRICTED,
+ "join_rule": JoinRules.RESTRICTED,
"allowed_room_ids": [],
},
),
@@ -813,7 +813,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": restricted_accessible_room,
"world_readable": False,
- "join_rules": JoinRules.RESTRICTED,
+ "join_rule": JoinRules.RESTRICTED,
"allowed_room_ids": [self.room],
},
),
@@ -822,7 +822,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": world_readable_room,
"world_readable": True,
- "join_rules": JoinRules.INVITE,
+ "join_rule": JoinRules.INVITE,
},
),
(
@@ -830,7 +830,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": joined_room,
"world_readable": False,
- "join_rules": JoinRules.INVITE,
+ "join_rule": JoinRules.INVITE,
},
),
)
@@ -911,7 +911,7 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
{
"room_id": fed_room,
"world_readable": False,
- "join_rules": JoinRules.INVITE,
+ "join_rule": JoinRules.INVITE,
},
)
diff --git a/tests/http/test_fedclient.py b/tests/http/test_fedclient.py
index 638babae69..006dbab093 100644
--- a/tests/http/test_fedclient.py
+++ b/tests/http/test_fedclient.py
@@ -26,7 +26,7 @@ from twisted.web.http import HTTPChannel
from synapse.api.errors import RequestSendFailed
from synapse.http.matrixfederationclient import (
- MAX_RESPONSE_SIZE,
+ JsonParser,
MatrixFederationHttpClient,
MatrixFederationRequest,
)
@@ -609,9 +609,9 @@ class FederationClientTests(HomeserverTestCase):
while not test_d.called:
protocol.dataReceived(b"a" * chunk_size)
sent += chunk_size
- self.assertLessEqual(sent, MAX_RESPONSE_SIZE)
+ self.assertLessEqual(sent, JsonParser.MAX_RESPONSE_SIZE)
- self.assertEqual(sent, MAX_RESPONSE_SIZE)
+ self.assertEqual(sent, JsonParser.MAX_RESPONSE_SIZE)
f = self.failureResultOf(test_d)
self.assertIsInstance(f.value, RequestSendFailed)
diff --git a/tests/push/test_push_rule_evaluator.py b/tests/push/test_push_rule_evaluator.py
index 5dba187076..9b623d0033 100644
--- a/tests/push/test_push_rule_evaluator.py
+++ b/tests/push/test_push_rule_evaluator.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, Optional, Union
+from typing import Dict, Optional, Set, Tuple, Union
import frozendict
@@ -26,7 +26,12 @@ from tests import unittest
class PushRuleEvaluatorTestCase(unittest.TestCase):
- def _get_evaluator(self, content: JsonDict) -> PushRuleEvaluatorForEvent:
+ def _get_evaluator(
+ self,
+ content: JsonDict,
+ relations: Optional[Dict[str, Set[Tuple[str, str]]]] = None,
+ relations_match_enabled: bool = False,
+ ) -> PushRuleEvaluatorForEvent:
event = FrozenEvent(
{
"event_id": "$event_id",
@@ -42,7 +47,12 @@ class PushRuleEvaluatorTestCase(unittest.TestCase):
sender_power_level = 0
power_levels: Dict[str, Union[int, Dict[str, int]]] = {}
return PushRuleEvaluatorForEvent(
- event, room_member_count, sender_power_level, power_levels
+ event,
+ room_member_count,
+ sender_power_level,
+ power_levels,
+ relations or set(),
+ relations_match_enabled,
)
def test_display_name(self) -> None:
@@ -276,3 +286,71 @@ class PushRuleEvaluatorTestCase(unittest.TestCase):
push_rule_evaluator.tweaks_for_actions(actions),
{"sound": "default", "highlight": True},
)
+
+ def test_relation_match(self) -> None:
+ """Test the relation_match push rule kind."""
+
+ # Check if the experimental feature is disabled.
+ evaluator = self._get_evaluator(
+ {}, {"m.annotation": {("@user:test", "m.reaction")}}
+ )
+ condition = {"kind": "relation_match"}
+ # Oddly, an unknown condition always matches.
+ self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
+
+ # A push rule evaluator with the experimental rule enabled.
+ evaluator = self._get_evaluator(
+ {}, {"m.annotation": {("@user:test", "m.reaction")}}, True
+ )
+
+ # Check just relation type.
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "rel_type": "m.annotation",
+ }
+ self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
+
+ # Check relation type and sender.
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "rel_type": "m.annotation",
+ "sender": "@user:test",
+ }
+ self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "rel_type": "m.annotation",
+ "sender": "@other:test",
+ }
+ self.assertFalse(evaluator.matches(condition, "@user:test", "foo"))
+
+ # Check relation type and event type.
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "rel_type": "m.annotation",
+ "type": "m.reaction",
+ }
+ self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
+
+ # Check just sender, this fails since rel_type is required.
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "sender": "@user:test",
+ }
+ self.assertFalse(evaluator.matches(condition, "@user:test", "foo"))
+
+ # Check sender glob.
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "rel_type": "m.annotation",
+ "sender": "@*:test",
+ }
+ self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
+
+ # Check event type glob.
+ condition = {
+ "kind": "org.matrix.msc3772.relation_match",
+ "rel_type": "m.annotation",
+ "event_type": "*.reaction",
+ }
+ self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
diff --git a/tests/rest/admin/test_admin.py b/tests/rest/admin/test_admin.py
index 40571b753a..82ac5991e6 100644
--- a/tests/rest/admin/test_admin.py
+++ b/tests/rest/admin/test_admin.py
@@ -14,7 +14,6 @@
import urllib.parse
from http import HTTPStatus
-from typing import List
from parameterized import parameterized
@@ -23,7 +22,7 @@ from twisted.test.proto_helpers import MemoryReactor
import synapse.rest.admin
from synapse.http.server import JsonResource
from synapse.rest.admin import VersionServlet
-from synapse.rest.client import groups, login, room
+from synapse.rest.client import login, room
from synapse.server import HomeServer
from synapse.util import Clock
@@ -49,93 +48,6 @@ class VersionTestCase(unittest.HomeserverTestCase):
)
-class DeleteGroupTestCase(unittest.HomeserverTestCase):
- servlets = [
- synapse.rest.admin.register_servlets_for_client_rest_resource,
- login.register_servlets,
- groups.register_servlets,
- ]
-
- def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
- self.admin_user = self.register_user("admin", "pass", admin=True)
- self.admin_user_tok = self.login("admin", "pass")
-
- self.other_user = self.register_user("user", "pass")
- self.other_user_token = self.login("user", "pass")
-
- @unittest.override_config({"experimental_features": {"groups_enabled": True}})
- def test_delete_group(self) -> None:
- # Create a new group
- channel = self.make_request(
- "POST",
- b"/create_group",
- access_token=self.admin_user_tok,
- content={"localpart": "test"},
- )
-
- self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
-
- group_id = channel.json_body["group_id"]
-
- self._check_group(group_id, expect_code=HTTPStatus.OK)
-
- # Invite/join another user
-
- url = "/groups/%s/admin/users/invite/%s" % (group_id, self.other_user)
- channel = self.make_request(
- "PUT", url.encode("ascii"), access_token=self.admin_user_tok, content={}
- )
- self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
-
- url = "/groups/%s/self/accept_invite" % (group_id,)
- channel = self.make_request(
- "PUT", url.encode("ascii"), access_token=self.other_user_token, content={}
- )
- self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
-
- # Check other user knows they're in the group
- self.assertIn(group_id, self._get_groups_user_is_in(self.admin_user_tok))
- self.assertIn(group_id, self._get_groups_user_is_in(self.other_user_token))
-
- # Now delete the group
- url = "/_synapse/admin/v1/delete_group/" + group_id
- channel = self.make_request(
- "POST",
- url.encode("ascii"),
- access_token=self.admin_user_tok,
- content={"localpart": "test"},
- )
-
- self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
-
- # Check group returns HTTPStatus.NOT_FOUND
- self._check_group(group_id, expect_code=HTTPStatus.NOT_FOUND)
-
- # Check users don't think they're in the group
- self.assertNotIn(group_id, self._get_groups_user_is_in(self.admin_user_tok))
- self.assertNotIn(group_id, self._get_groups_user_is_in(self.other_user_token))
-
- def _check_group(self, group_id: str, expect_code: int) -> None:
- """Assert that trying to fetch the given group results in the given
- HTTP status code
- """
-
- url = "/groups/%s/profile" % (group_id,)
- channel = self.make_request(
- "GET", url.encode("ascii"), access_token=self.admin_user_tok
- )
-
- self.assertEqual(expect_code, channel.code, msg=channel.json_body)
-
- def _get_groups_user_is_in(self, access_token: str) -> List[str]:
- """Returns the list of groups the user is in (given their access token)"""
- channel = self.make_request("GET", b"/joined_groups", access_token=access_token)
-
- self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
-
- return channel.json_body["groups"]
-
-
class QuarantineMediaTestCase(unittest.HomeserverTestCase):
"""Test /quarantine_media admin API."""
diff --git a/tests/rest/client/test_groups.py b/tests/rest/client/test_groups.py
deleted file mode 100644
index e067cf825c..0000000000
--- a/tests/rest/client/test_groups.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2021 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 synapse.rest.client import groups, room
-
-from tests import unittest
-from tests.unittest import override_config
-
-
-class GroupsTestCase(unittest.HomeserverTestCase):
- user_id = "@alice:test"
- room_creator_user_id = "@bob:test"
-
- servlets = [room.register_servlets, groups.register_servlets]
-
- @override_config({"enable_group_creation": True})
- def test_rooms_limited_by_visibility(self) -> None:
- group_id = "+spqr:test"
-
- # Alice creates a group
- channel = self.make_request("POST", "/create_group", {"localpart": "spqr"})
- self.assertEqual(channel.code, 200, msg=channel.text_body)
- self.assertEqual(channel.json_body, {"group_id": group_id})
-
- # Bob creates a private room
- room_id = self.helper.create_room_as(self.room_creator_user_id, is_public=False)
- self.helper.auth_user_id = self.room_creator_user_id
- self.helper.send_state(
- room_id, "m.room.name", {"name": "bob's secret room"}, tok=None
- )
- self.helper.auth_user_id = self.user_id
-
- # Alice adds the room to her group.
- channel = self.make_request(
- "PUT", f"/groups/{group_id}/admin/rooms/{room_id}", {}
- )
- self.assertEqual(channel.code, 200, msg=channel.text_body)
- self.assertEqual(channel.json_body, {})
-
- # Alice now tries to retrieve the room list of the space.
- channel = self.make_request("GET", f"/groups/{group_id}/rooms")
- self.assertEqual(channel.code, 200, msg=channel.text_body)
- self.assertEqual(
- channel.json_body, {"chunk": [], "total_room_count_estimate": 0}
- )
diff --git a/tests/storage/test_events.py b/tests/storage/test_events.py
index ef5e25873c..aaa3189b16 100644
--- a/tests/storage/test_events.py
+++ b/tests/storage/test_events.py
@@ -69,7 +69,7 @@ class ExtremPruneTestCase(HomeserverTestCase):
def persist_event(self, event, state=None):
"""Persist the event, with optional state"""
context = self.get_success(
- self.state.compute_event_context(event, old_state=state)
+ self.state.compute_event_context(event, state_ids_before_event=state)
)
self.get_success(self.persistence.persist_event(event, context))
@@ -103,9 +103,11 @@ class ExtremPruneTestCase(HomeserverTestCase):
RoomVersions.V6,
)
- state_before_gap = self.get_success(self.state.get_current_state(self.room_id))
+ state_before_gap = self.get_success(
+ self.state.get_current_state_ids(self.room_id)
+ )
- self.persist_event(remote_event_2, state=state_before_gap.values())
+ self.persist_event(remote_event_2, state=state_before_gap)
# Check the new extremity is just the new remote event.
self.assert_extremities([remote_event_2.event_id])
@@ -135,13 +137,14 @@ class ExtremPruneTestCase(HomeserverTestCase):
# setting. The state resolution across the old and new event will then
# include it, and so the resolved state won't match the new state.
state_before_gap = dict(
- self.get_success(self.state.get_current_state(self.room_id))
+ self.get_success(self.state.get_current_state_ids(self.room_id))
)
state_before_gap.pop(("m.room.history_visibility", ""))
context = self.get_success(
self.state.compute_event_context(
- remote_event_2, old_state=state_before_gap.values()
+ remote_event_2,
+ state_ids_before_event=state_before_gap,
)
)
@@ -177,9 +180,11 @@ class ExtremPruneTestCase(HomeserverTestCase):
RoomVersions.V6,
)
- state_before_gap = self.get_success(self.state.get_current_state(self.room_id))
+ state_before_gap = self.get_success(
+ self.state.get_current_state_ids(self.room_id)
+ )
- self.persist_event(remote_event_2, state=state_before_gap.values())
+ self.persist_event(remote_event_2, state=state_before_gap)
# Check the new extremity is just the new remote event.
self.assert_extremities([remote_event_2.event_id])
@@ -207,9 +212,11 @@ class ExtremPruneTestCase(HomeserverTestCase):
RoomVersions.V6,
)
- state_before_gap = self.get_success(self.state.get_current_state(self.room_id))
+ state_before_gap = self.get_success(
+ self.state.get_current_state_ids(self.room_id)
+ )
- self.persist_event(remote_event_2, state=state_before_gap.values())
+ self.persist_event(remote_event_2, state=state_before_gap)
# Check the new extremity is just the new remote event.
self.assert_extremities([self.remote_event_1.event_id, remote_event_2.event_id])
@@ -247,9 +254,11 @@ class ExtremPruneTestCase(HomeserverTestCase):
RoomVersions.V6,
)
- state_before_gap = self.get_success(self.state.get_current_state(self.room_id))
+ state_before_gap = self.get_success(
+ self.state.get_current_state_ids(self.room_id)
+ )
- self.persist_event(remote_event_2, state=state_before_gap.values())
+ self.persist_event(remote_event_2, state=state_before_gap)
# Check the new extremity is just the new remote event.
self.assert_extremities([remote_event_2.event_id])
@@ -289,9 +298,11 @@ class ExtremPruneTestCase(HomeserverTestCase):
RoomVersions.V6,
)
- state_before_gap = self.get_success(self.state.get_current_state(self.room_id))
+ state_before_gap = self.get_success(
+ self.state.get_current_state_ids(self.room_id)
+ )
- self.persist_event(remote_event_2, state=state_before_gap.values())
+ self.persist_event(remote_event_2, state=state_before_gap)
# Check the new extremity is just the new remote event.
self.assert_extremities([remote_event_2.event_id, local_message_event_id])
@@ -323,9 +334,11 @@ class ExtremPruneTestCase(HomeserverTestCase):
RoomVersions.V6,
)
- state_before_gap = self.get_success(self.state.get_current_state(self.room_id))
+ state_before_gap = self.get_success(
+ self.state.get_current_state_ids(self.room_id)
+ )
- self.persist_event(remote_event_2, state=state_before_gap.values())
+ self.persist_event(remote_event_2, state=state_before_gap)
# Check the new extremity is just the new remote event.
self.assert_extremities([local_message_event_id, remote_event_2.event_id])
diff --git a/tests/storage/test_monthly_active_users.py b/tests/storage/test_monthly_active_users.py
index 4c29ad79b6..e8b4a5644b 100644
--- a/tests/storage/test_monthly_active_users.py
+++ b/tests/storage/test_monthly_active_users.py
@@ -407,3 +407,86 @@ class MonthlyActiveUsersTestCase(unittest.HomeserverTestCase):
self.assertEqual(result[service1], 2)
self.assertEqual(result[service2], 1)
self.assertEqual(result[native], 1)
+
+ def test_get_monthly_active_users_by_service(self):
+ # (No users, no filtering) -> empty result
+ result = self.get_success(self.store.get_monthly_active_users_by_service())
+
+ self.assertEqual(len(result), 0)
+
+ # (Some users, no filtering) -> non-empty result
+ appservice1_user1 = "@appservice1_user1:example.com"
+ appservice2_user1 = "@appservice2_user1:example.com"
+ service1 = "service1"
+ service2 = "service2"
+ self.get_success(
+ self.store.register_user(
+ user_id=appservice1_user1, password_hash=None, appservice_id=service1
+ )
+ )
+ self.get_success(self.store.upsert_monthly_active_user(appservice1_user1))
+ self.get_success(
+ self.store.register_user(
+ user_id=appservice2_user1, password_hash=None, appservice_id=service2
+ )
+ )
+ self.get_success(self.store.upsert_monthly_active_user(appservice2_user1))
+
+ result = self.get_success(self.store.get_monthly_active_users_by_service())
+
+ self.assertEqual(len(result), 2)
+ self.assertIn((service1, appservice1_user1), result)
+ self.assertIn((service2, appservice2_user1), result)
+
+ # (Some users, end-timestamp filtering) -> non-empty result
+ appservice1_user2 = "@appservice1_user2:example.com"
+ timestamp1 = self.reactor.seconds()
+ self.reactor.advance(5)
+ timestamp2 = self.reactor.seconds()
+ self.get_success(
+ self.store.register_user(
+ user_id=appservice1_user2, password_hash=None, appservice_id=service1
+ )
+ )
+ self.get_success(self.store.upsert_monthly_active_user(appservice1_user2))
+
+ result = self.get_success(
+ self.store.get_monthly_active_users_by_service(
+ end_timestamp=round(timestamp1 * 1000)
+ )
+ )
+
+ self.assertEqual(len(result), 2)
+ self.assertNotIn((service1, appservice1_user2), result)
+
+ # (Some users, start-timestamp filtering) -> non-empty result
+ result = self.get_success(
+ self.store.get_monthly_active_users_by_service(
+ start_timestamp=round(timestamp2 * 1000)
+ )
+ )
+
+ self.assertEqual(len(result), 1)
+ self.assertIn((service1, appservice1_user2), result)
+
+ # (Some users, full-timestamp filtering) -> non-empty result
+ native_user1 = "@native_user1:example.com"
+ native = "native"
+ timestamp3 = self.reactor.seconds()
+ self.reactor.advance(100)
+ self.get_success(
+ self.store.register_user(
+ user_id=native_user1, password_hash=None, appservice_id=native
+ )
+ )
+ self.get_success(self.store.upsert_monthly_active_user(native_user1))
+
+ result = self.get_success(
+ self.store.get_monthly_active_users_by_service(
+ start_timestamp=round(timestamp2 * 1000),
+ end_timestamp=round(timestamp3 * 1000),
+ )
+ )
+
+ self.assertEqual(len(result), 1)
+ self.assertIn((service1, appservice1_user2), result)
diff --git a/tests/test_state.py b/tests/test_state.py
index c6baea3d76..84694d368d 100644
--- a/tests/test_state.py
+++ b/tests/test_state.py
@@ -442,7 +442,12 @@ class StateTestCase(unittest.TestCase):
]
context = yield defer.ensureDeferred(
- self.state.compute_event_context(event, old_state=old_state)
+ self.state.compute_event_context(
+ event,
+ state_ids_before_event={
+ (e.type, e.state_key): e.event_id for e in old_state
+ },
+ )
)
prev_state_ids = yield defer.ensureDeferred(context.get_prev_state_ids())
@@ -467,7 +472,12 @@ class StateTestCase(unittest.TestCase):
]
context = yield defer.ensureDeferred(
- self.state.compute_event_context(event, old_state=old_state)
+ self.state.compute_event_context(
+ event,
+ state_ids_before_event={
+ (e.type, e.state_key): e.event_id for e in old_state
+ },
+ )
)
prev_state_ids = yield defer.ensureDeferred(context.get_prev_state_ids())
diff --git a/tests/test_types.py b/tests/test_types.py
index 80888a744d..0b10dae848 100644
--- a/tests/test_types.py
+++ b/tests/test_types.py
@@ -13,7 +13,7 @@
# limitations under the License.
from synapse.api.errors import SynapseError
-from synapse.types import GroupID, RoomAlias, UserID, map_username_to_mxid_localpart
+from synapse.types import RoomAlias, UserID, map_username_to_mxid_localpart
from tests import unittest
@@ -62,25 +62,6 @@ class RoomAliasTestCase(unittest.HomeserverTestCase):
self.assertFalse(RoomAlias.is_valid(id_string))
-class GroupIDTestCase(unittest.TestCase):
- def test_parse(self):
- group_id = GroupID.from_string("+group/=_-.123:my.domain")
- self.assertEqual("group/=_-.123", group_id.localpart)
- self.assertEqual("my.domain", group_id.domain)
-
- def test_validate(self):
- bad_ids = ["$badsigil:domain", "+:empty"] + [
- "+group" + c + ":domain" for c in "A%?æ£"
- ]
- for id_string in bad_ids:
- try:
- GroupID.from_string(id_string)
- self.fail("Parsing '%s' should raise exception" % id_string)
- except SynapseError as exc:
- self.assertEqual(400, exc.code)
- self.assertEqual("M_INVALID_PARAM", exc.errcode)
-
-
class MapUsernameTestCase(unittest.TestCase):
def testPassThrough(self):
self.assertEqual(map_username_to_mxid_localpart("test1234"), "test1234")
|