123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- # 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.api.constants import EduTypes
- from synapse.rest import admin
- from synapse.rest.client import login, sendtodevice, sync
- from tests.unittest import HomeserverTestCase, override_config
- class SendToDeviceTestCase(HomeserverTestCase):
- servlets = [
- admin.register_servlets,
- login.register_servlets,
- sendtodevice.register_servlets,
- sync.register_servlets,
- ]
- def test_user_to_user(self) -> None:
- """A to-device message from one user to another should get delivered"""
- user1 = self.register_user("u1", "pass")
- user1_tok = self.login("u1", "pass", "d1")
- user2 = self.register_user("u2", "pass")
- user2_tok = self.login("u2", "pass", "d2")
- # send the message
- test_msg = {"foo": "bar"}
- chan = self.make_request(
- "PUT",
- "/_matrix/client/r0/sendToDevice/m.test/1234",
- content={"messages": {user2: {"d2": test_msg}}},
- access_token=user1_tok,
- )
- self.assertEqual(chan.code, 200, chan.result)
- # check it appears
- channel = self.make_request("GET", "/sync", access_token=user2_tok)
- self.assertEqual(channel.code, 200, channel.result)
- expected_result = {
- "events": [
- {
- "sender": user1,
- "type": "m.test",
- "content": test_msg,
- }
- ]
- }
- self.assertEqual(channel.json_body["to_device"], expected_result)
- # it should re-appear if we do another sync
- channel = self.make_request("GET", "/sync", access_token=user2_tok)
- self.assertEqual(channel.code, 200, channel.result)
- self.assertEqual(channel.json_body["to_device"], expected_result)
- # it should *not* appear if we do an incremental sync
- sync_token = channel.json_body["next_batch"]
- channel = self.make_request(
- "GET", f"/sync?since={sync_token}", access_token=user2_tok
- )
- self.assertEqual(channel.code, 200, channel.result)
- self.assertEqual(channel.json_body.get("to_device", {}).get("events", []), [])
- @override_config({"rc_key_requests": {"per_second": 10, "burst_count": 2}})
- def test_local_room_key_request(self) -> None:
- """m.room_key_request has special-casing; test from local user"""
- user1 = self.register_user("u1", "pass")
- user1_tok = self.login("u1", "pass", "d1")
- user2 = self.register_user("u2", "pass")
- user2_tok = self.login("u2", "pass", "d2")
- # send three messages
- for i in range(3):
- chan = self.make_request(
- "PUT",
- f"/_matrix/client/r0/sendToDevice/m.room_key_request/{i}",
- content={"messages": {user2: {"d2": {"idx": i}}}},
- access_token=user1_tok,
- )
- self.assertEqual(chan.code, 200, chan.result)
- # now sync: we should get two of the three
- channel = self.make_request("GET", "/sync", access_token=user2_tok)
- self.assertEqual(channel.code, 200, channel.result)
- msgs = channel.json_body["to_device"]["events"]
- self.assertEqual(len(msgs), 2)
- for i in range(2):
- self.assertEqual(
- msgs[i],
- {"sender": user1, "type": "m.room_key_request", "content": {"idx": i}},
- )
- sync_token = channel.json_body["next_batch"]
- # ... time passes
- self.reactor.advance(1)
- # and we can send more messages
- chan = self.make_request(
- "PUT",
- "/_matrix/client/r0/sendToDevice/m.room_key_request/3",
- content={"messages": {user2: {"d2": {"idx": 3}}}},
- access_token=user1_tok,
- )
- self.assertEqual(chan.code, 200, chan.result)
- # ... which should arrive
- channel = self.make_request(
- "GET", f"/sync?since={sync_token}", access_token=user2_tok
- )
- self.assertEqual(channel.code, 200, channel.result)
- msgs = channel.json_body["to_device"]["events"]
- self.assertEqual(len(msgs), 1)
- self.assertEqual(
- msgs[0],
- {"sender": user1, "type": "m.room_key_request", "content": {"idx": 3}},
- )
- @override_config({"rc_key_requests": {"per_second": 10, "burst_count": 2}})
- def test_remote_room_key_request(self) -> None:
- """m.room_key_request has special-casing; test from remote user"""
- user2 = self.register_user("u2", "pass")
- user2_tok = self.login("u2", "pass", "d2")
- federation_registry = self.hs.get_federation_registry()
- # send three messages
- for i in range(3):
- self.get_success(
- federation_registry.on_edu(
- EduTypes.DIRECT_TO_DEVICE,
- "remote_server",
- {
- "sender": "@user:remote_server",
- "type": "m.room_key_request",
- "messages": {user2: {"d2": {"idx": i}}},
- "message_id": f"{i}",
- },
- )
- )
- # now sync: we should get two of the three
- channel = self.make_request("GET", "/sync", access_token=user2_tok)
- self.assertEqual(channel.code, 200, channel.result)
- msgs = channel.json_body["to_device"]["events"]
- self.assertEqual(len(msgs), 2)
- for i in range(2):
- self.assertEqual(
- msgs[i],
- {
- "sender": "@user:remote_server",
- "type": "m.room_key_request",
- "content": {"idx": i},
- },
- )
- sync_token = channel.json_body["next_batch"]
- # ... time passes
- self.reactor.advance(1)
- # and we can send more messages
- self.get_success(
- federation_registry.on_edu(
- EduTypes.DIRECT_TO_DEVICE,
- "remote_server",
- {
- "sender": "@user:remote_server",
- "type": "m.room_key_request",
- "messages": {user2: {"d2": {"idx": 3}}},
- "message_id": "3",
- },
- )
- )
- # ... which should arrive
- channel = self.make_request(
- "GET", f"/sync?since={sync_token}", access_token=user2_tok
- )
- self.assertEqual(channel.code, 200, channel.result)
- msgs = channel.json_body["to_device"]["events"]
- self.assertEqual(len(msgs), 1)
- self.assertEqual(
- msgs[0],
- {
- "sender": "@user:remote_server",
- "type": "m.room_key_request",
- "content": {"idx": 3},
- },
- )
- def test_limited_sync(self) -> None:
- """If a limited sync for to-devices happens the next /sync should respond immediately."""
- self.register_user("u1", "pass")
- user1_tok = self.login("u1", "pass", "d1")
- user2 = self.register_user("u2", "pass")
- user2_tok = self.login("u2", "pass", "d2")
- # Do an initial sync
- channel = self.make_request("GET", "/sync", access_token=user2_tok)
- self.assertEqual(channel.code, 200, channel.result)
- sync_token = channel.json_body["next_batch"]
- # Send 150 to-device messages. We limit to 100 in `/sync`
- for i in range(150):
- test_msg = {"foo": "bar"}
- chan = self.make_request(
- "PUT",
- f"/_matrix/client/r0/sendToDevice/m.test/1234-{i}",
- content={"messages": {user2: {"d2": test_msg}}},
- access_token=user1_tok,
- )
- self.assertEqual(chan.code, 200, chan.result)
- channel = self.make_request(
- "GET", f"/sync?since={sync_token}&timeout=300000", access_token=user2_tok
- )
- self.assertEqual(channel.code, 200, channel.result)
- messages = channel.json_body.get("to_device", {}).get("events", [])
- self.assertEqual(len(messages), 100)
- sync_token = channel.json_body["next_batch"]
- channel = self.make_request(
- "GET", f"/sync?since={sync_token}&timeout=300000", access_token=user2_tok
- )
- self.assertEqual(channel.code, 200, channel.result)
- messages = channel.json_body.get("to_device", {}).get("events", [])
- self.assertEqual(len(messages), 50)
|