|
20 | 20 | import json
|
21 | 21 | from http import HTTPStatus
|
22 | 22 | from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
|
23 |
| -from unittest.mock import Mock, call |
| 23 | +from unittest.mock import Mock, call, patch |
24 | 24 | from urllib import parse as urlparse
|
25 | 25 |
|
26 | 26 | from parameterized import param, parameterized
|
|
39 | 39 | RoomTypes,
|
40 | 40 | )
|
41 | 41 | from synapse.api.errors import Codes, HttpResponseException
|
| 42 | +from synapse.appservice import ApplicationService |
42 | 43 | from synapse.handlers.pagination import PurgeStatus
|
43 | 44 | from synapse.rest import admin
|
44 |
| -from synapse.rest.client import account, directory, login, profile, room, sync |
| 45 | +from synapse.rest.client import account, directory, login, profile, register, room, sync |
45 | 46 | from synapse.server import HomeServer
|
46 | 47 | from synapse.types import JsonDict, RoomAlias, UserID, create_requester
|
47 | 48 | from synapse.util import Clock
|
@@ -1252,6 +1253,120 @@ async def user_may_join_room(
|
1252 | 1253 | )
|
1253 | 1254 |
|
1254 | 1255 |
|
| 1256 | +class RoomAppserviceTsParamTestCase(unittest.HomeserverTestCase): |
| 1257 | + servlets = [ |
| 1258 | + room.register_servlets, |
| 1259 | + synapse.rest.admin.register_servlets, |
| 1260 | + register.register_servlets, |
| 1261 | + ] |
| 1262 | + |
| 1263 | + def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None: |
| 1264 | + self.appservice_user, _ = self.register_appservice_user( |
| 1265 | + "as_user_potato", self.appservice.token |
| 1266 | + ) |
| 1267 | + |
| 1268 | + # Create a room as the appservice user. |
| 1269 | + args = { |
| 1270 | + "access_token": self.appservice.token, |
| 1271 | + "user_id": self.appservice_user, |
| 1272 | + } |
| 1273 | + channel = self.make_request( |
| 1274 | + "POST", |
| 1275 | + f"/_matrix/client/r0/createRoom?{urlparse.urlencode(args)}", |
| 1276 | + content={"visibility": "public"}, |
| 1277 | + ) |
| 1278 | + |
| 1279 | + assert channel.code == 200 |
| 1280 | + self.room = channel.json_body["room_id"] |
| 1281 | + |
| 1282 | + self.main_store = self.hs.get_datastores().main |
| 1283 | + |
| 1284 | + def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer: |
| 1285 | + config = self.default_config() |
| 1286 | + |
| 1287 | + self.appservice = ApplicationService( |
| 1288 | + token="i_am_an_app_service", |
| 1289 | + id="1234", |
| 1290 | + namespaces={"users": [{"regex": r"@as_user.*", "exclusive": True}]}, |
| 1291 | + # Note: this user does not have to match the regex above |
| 1292 | + sender="@as_main:test", |
| 1293 | + ) |
| 1294 | + |
| 1295 | + mock_load_appservices = Mock(return_value=[self.appservice]) |
| 1296 | + with patch( |
| 1297 | + "synapse.storage.databases.main.appservice.load_appservices", |
| 1298 | + mock_load_appservices, |
| 1299 | + ): |
| 1300 | + hs = self.setup_test_homeserver(config=config) |
| 1301 | + return hs |
| 1302 | + |
| 1303 | + def test_send_event_ts(self) -> None: |
| 1304 | + """Test sending a non-state event with a custom timestamp.""" |
| 1305 | + ts = 1 |
| 1306 | + |
| 1307 | + url_params = { |
| 1308 | + "user_id": self.appservice_user, |
| 1309 | + "ts": ts, |
| 1310 | + } |
| 1311 | + channel = self.make_request( |
| 1312 | + "PUT", |
| 1313 | + path=f"/_matrix/client/r0/rooms/{self.room}/send/m.room.message/1234?" |
| 1314 | + + urlparse.urlencode(url_params), |
| 1315 | + content={"body": "test", "msgtype": "m.text"}, |
| 1316 | + access_token=self.appservice.token, |
| 1317 | + ) |
| 1318 | + self.assertEqual(channel.code, 200, channel.json_body) |
| 1319 | + event_id = channel.json_body["event_id"] |
| 1320 | + |
| 1321 | + # Ensure the event was persisted with the correct timestamp. |
| 1322 | + res = self.get_success(self.main_store.get_event(event_id)) |
| 1323 | + self.assertEquals(ts, res.origin_server_ts) |
| 1324 | + |
| 1325 | + def test_send_state_event_ts(self) -> None: |
| 1326 | + """Test sending a state event with a custom timestamp.""" |
| 1327 | + ts = 1 |
| 1328 | + |
| 1329 | + url_params = { |
| 1330 | + "user_id": self.appservice_user, |
| 1331 | + "ts": ts, |
| 1332 | + } |
| 1333 | + channel = self.make_request( |
| 1334 | + "PUT", |
| 1335 | + path=f"/_matrix/client/r0/rooms/{self.room}/state/m.room.name?" |
| 1336 | + + urlparse.urlencode(url_params), |
| 1337 | + content={"name": "test"}, |
| 1338 | + access_token=self.appservice.token, |
| 1339 | + ) |
| 1340 | + self.assertEqual(channel.code, 200, channel.json_body) |
| 1341 | + event_id = channel.json_body["event_id"] |
| 1342 | + |
| 1343 | + # Ensure the event was persisted with the correct timestamp. |
| 1344 | + res = self.get_success(self.main_store.get_event(event_id)) |
| 1345 | + self.assertEquals(ts, res.origin_server_ts) |
| 1346 | + |
| 1347 | + def test_send_membership_event_ts(self) -> None: |
| 1348 | + """Test sending a membership event with a custom timestamp.""" |
| 1349 | + ts = 1 |
| 1350 | + |
| 1351 | + url_params = { |
| 1352 | + "user_id": self.appservice_user, |
| 1353 | + "ts": ts, |
| 1354 | + } |
| 1355 | + channel = self.make_request( |
| 1356 | + "PUT", |
| 1357 | + path=f"/_matrix/client/r0/rooms/{self.room}/state/m.room.member/{self.appservice_user}?" |
| 1358 | + + urlparse.urlencode(url_params), |
| 1359 | + content={"membership": "join", "display_name": "test"}, |
| 1360 | + access_token=self.appservice.token, |
| 1361 | + ) |
| 1362 | + self.assertEqual(channel.code, 200, channel.json_body) |
| 1363 | + event_id = channel.json_body["event_id"] |
| 1364 | + |
| 1365 | + # Ensure the event was persisted with the correct timestamp. |
| 1366 | + res = self.get_success(self.main_store.get_event(event_id)) |
| 1367 | + self.assertEquals(ts, res.origin_server_ts) |
| 1368 | + |
| 1369 | + |
1255 | 1370 | class RoomJoinRatelimitTestCase(RoomBase):
|
1256 | 1371 | user_id = "@sid1:red"
|
1257 | 1372 |
|
|
0 commit comments