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

Commit 65ec757

Browse files
committed
wip tests
1 parent d9f3249 commit 65ec757

File tree

5 files changed

+186
-6
lines changed

5 files changed

+186
-6
lines changed

tests/handlers/test_appservice.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,20 +253,59 @@ async def get_3pe_protocol(service, unusedProtocol):
253253
},
254254
)
255255

256-
def test_notify_interested_services_ephemeral(self):
256+
def test_notify_interested_services_ephemeral_read_receipt(self):
257257
"""
258-
Test sending ephemeral events to the appservice handler are scheduled
258+
Test sending read receipts to the appservice handler are scheduled
259259
to be pushed out to interested appservices, and that the stream ID is
260260
updated accordingly.
261261
"""
262+
# Create an application service that is guaranteed to be interested in
263+
# any new events
262264
interested_service = self._mkservice(is_interested=True)
263265
services = [interested_service]
266+
self.mock_store.get_app_services.return_value = services
267+
268+
# State that this application service has received up until stream ID 579
269+
self.mock_store.get_type_stream_id_for_appservice.return_value = make_awaitable(
270+
579
271+
)
264272

273+
# Set up a dummy event that should be sent to the application service
274+
event = Mock(event_id="event_1")
275+
self.event_source.sources.receipt.get_new_events_as.return_value = (
276+
make_awaitable(([event], None))
277+
)
278+
279+
self.handler.notify_interested_services_ephemeral(
280+
"receipt_key", 580, ["@fakerecipient:example.com"]
281+
)
282+
self.mock_scheduler.submit_ephemeral_events_for_as.assert_called_once_with(
283+
interested_service, [event]
284+
)
285+
self.mock_store.set_type_stream_id_for_appservice.assert_called_once_with(
286+
interested_service,
287+
"read_receipt",
288+
580,
289+
)
290+
291+
def test_notify_interested_services_ephemeral_to_device(self):
292+
"""
293+
Test sending read receipts to the appservice handler are scheduled
294+
to be pushed out to interested appservices, and that the stream ID is
295+
updated accordingly.
296+
"""
297+
# Create an application service that is guaranteed to be interested in
298+
# any new events
299+
interested_service = self._mkservice(is_interested=True)
300+
services = [interested_service]
265301
self.mock_store.get_app_services.return_value = services
302+
303+
# State that this application service has received up until stream ID 579
266304
self.mock_store.get_type_stream_id_for_appservice.return_value = make_awaitable(
267305
579
268306
)
269307

308+
# Set up a dummy event that should be sent to the application service
270309
event = Mock(event_id="event_1")
271310
self.event_source.sources.receipt.get_new_events_as.return_value = (
272311
make_awaitable(([event], None))
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Copyright 2019 The Matrix.org Foundation C.I.C.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from typing import Dict, Iterable, Optional, Tuple, Union
16+
from unittest.mock import Mock
17+
18+
import synapse.rest.admin
19+
import synapse.storage
20+
from synapse.appservice import ApplicationService
21+
from synapse.rest.client import login, receipts, room
22+
from synapse.util.stringutils import random_string
23+
24+
from tests import unittest
25+
26+
27+
class ApplicationServiceEphemeralEventsTestCase(unittest.HomeserverTestCase):
28+
servlets = [
29+
synapse.rest.admin.register_servlets_for_client_rest_resource,
30+
login.register_servlets,
31+
room.register_servlets,
32+
receipts.register_servlets,
33+
]
34+
35+
def prepare(self, reactor, clock, hs):
36+
# Mock the application service scheduler so that we can track any outgoing transactions
37+
self.mock_scheduler = Mock()
38+
39+
hs.get_application_service_handler().scheduler = self.mock_scheduler
40+
41+
self.user1 = self.register_user("user1", "password")
42+
self.token1 = self.login("user1", "password")
43+
44+
self.user2 = self.register_user("user2", "password")
45+
self.token2 = self.login("user2", "password")
46+
47+
def test_application_services_receive_read_receipts(self):
48+
"""
49+
Test that when an application service sends a read receipt in a room with
50+
another user, and that is in an application service's user namespace, that
51+
application service will receive that read receipt.
52+
"""
53+
(
54+
interested_service,
55+
_,
56+
) = self._register_interested_and_uninterested_application_services()
57+
58+
# Create a room with both user1 and user2
59+
room_id = self.helper.create_room_as(
60+
self.user1, tok=self.token1, is_public=True
61+
)
62+
self.helper.join(room_id, self.user2, tok=self.token2)
63+
64+
# Have user2 send a message into the room
65+
response_dict = self.helper.send(room_id, body="read me", tok=self.token2)
66+
67+
# Have user1 send a read receipt for the message with an empty body
68+
channel = self.make_request(
69+
"POST",
70+
"/rooms/%s/receipt/m.read/%s" % (room_id, response_dict["event_id"]),
71+
access_token=self.token1,
72+
)
73+
self.assertEqual(channel.code, 200)
74+
75+
# user2 should have been the recipient of that read receipt.
76+
# Check if our application service - that is interested in user2 - received
77+
# the read receipt as part of an AS transaction.
78+
#
79+
# The uninterested application service should not have been notified.
80+
service, events = self.mock_scheduler.submit_ephemeral_events_for_as.call_args[
81+
0
82+
]
83+
self.assertEqual(service, interested_service)
84+
self.assertEqual(events[0]["type"], "m.receipt")
85+
self.assertEqual(events[0]["room_id"], room_id)
86+
87+
# Assert that this was a read receipt from user1
88+
read_receipts = list(events[0]["content"].values())
89+
self.assertIn(self.user1, read_receipts[0]["m.read"])
90+
91+
def _register_interested_and_uninterested_application_services(
92+
self,
93+
) -> Tuple[ApplicationService, ApplicationService]:
94+
# Create an application service with exclusive interest in user2
95+
interested_service = self._make_application_service(
96+
namespaces={
97+
ApplicationService.NS_USERS: [
98+
{
99+
"regex": "@user2:.+",
100+
"exclusive": True,
101+
}
102+
],
103+
},
104+
)
105+
uninterested_service = self._make_application_service()
106+
107+
# Register this application service, along with another, uninterested one
108+
services = [
109+
uninterested_service,
110+
interested_service,
111+
]
112+
self.hs.get_datastore().get_app_services = Mock(return_value=services)
113+
114+
return interested_service, uninterested_service
115+
116+
def _make_application_service(
117+
self,
118+
namespaces: Optional[
119+
Dict[
120+
Union[
121+
ApplicationService.NS_USERS,
122+
ApplicationService.NS_ALIASES,
123+
ApplicationService.NS_ROOMS,
124+
],
125+
Iterable[Dict],
126+
]
127+
] = None,
128+
supports_ephemeral: Optional[bool] = True,
129+
) -> ApplicationService:
130+
return ApplicationService(
131+
token=None,
132+
hostname="example.com",
133+
id=random_string(10),
134+
sender="@as:example.com",
135+
rate_limited=False,
136+
namespaces=namespaces,
137+
supports_ephemeral=supports_ephemeral,
138+
)
139+
140+
# TODO: Test that ephemeral messages aren't sent to application services that have
141+
# ephemeral: false

tests/rest/client/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ def send(
230230
custom_headers: Optional[
231231
Iterable[Tuple[Union[bytes, str], Union[bytes, str]]]
232232
] = None,
233-
):
233+
) -> JsonDict:
234234
if body is None:
235235
body = "body_text_here"
236236

@@ -257,7 +257,7 @@ def send_event(
257257
custom_headers: Optional[
258258
Iterable[Tuple[Union[bytes, str], Union[bytes, str]]]
259259
] = None,
260-
):
260+
) -> JsonDict:
261261
if txn_id is None:
262262
txn_id = "m%s" % (str(time.time()))
263263

tests/unittest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def wait_on_thread(self, deferred, timeout=10):
320320
def wait_for_background_updates(self) -> None:
321321
"""Block until all background database updates have completed."""
322322
while not self.get_success(
323-
self.store.db_pool.updates.has_completed_background_updates()
323+
self.hs.get_datastore().db_pool.updates.has_completed_background_updates()
324324
):
325325
self.get_success(
326326
self.store.db_pool.updates.do_next_background_update(100), by=0.1

tests/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ def setup_test_homeserver(
236236
else:
237237
database_config = {
238238
"name": "sqlite3",
239-
"args": {"database": ":memory:", "cp_min": 1, "cp_max": 1},
239+
"args": {"database": "test.db", "cp_min": 1, "cp_max": 1},
240240
}
241241

242242
if "db_txn_limit" in kwargs:

0 commit comments

Comments
 (0)