|
16 | 16 | import json
|
17 | 17 |
|
18 | 18 | import synapse.rest.admin
|
19 |
| -from synapse.api.constants import EventContentFields, EventTypes |
| 19 | +from synapse.api.constants import EventContentFields, EventTypes, RelationTypes |
20 | 20 | from synapse.rest.client.v1 import login, room
|
21 |
| -from synapse.rest.client.v2_alpha import sync |
| 21 | +from synapse.rest.client.v2_alpha import read_marker, sync |
22 | 22 |
|
23 | 23 | from tests import unittest
|
24 | 24 | from tests.server import TimedOutException
|
@@ -324,3 +324,163 @@ def test_sync_backwards_typing(self):
|
324 | 324 | "GET", sync_url % (access_token, next_batch)
|
325 | 325 | )
|
326 | 326 | self.assertRaises(TimedOutException, self.render, request)
|
| 327 | + |
| 328 | + |
| 329 | +class UnreadMessagesTestCase(unittest.HomeserverTestCase): |
| 330 | + servlets = [ |
| 331 | + synapse.rest.admin.register_servlets, |
| 332 | + login.register_servlets, |
| 333 | + read_marker.register_servlets, |
| 334 | + room.register_servlets, |
| 335 | + sync.register_servlets, |
| 336 | + ] |
| 337 | + |
| 338 | + def prepare(self, reactor, clock, hs): |
| 339 | + self.url = "/sync?since=%s" |
| 340 | + self.next_batch = "s0" |
| 341 | + |
| 342 | + # Register the first user (used to check the unread counts). |
| 343 | + self.user_id = self.register_user("kermit", "monkey") |
| 344 | + self.tok = self.login("kermit", "monkey") |
| 345 | + |
| 346 | + # Create the room we'll check unread counts for. |
| 347 | + self.room_id = self.helper.create_room_as(self.user_id, tok=self.tok) |
| 348 | + |
| 349 | + # Register the second user (used to send events to the room). |
| 350 | + self.user2 = self.register_user("kermit2", "monkey") |
| 351 | + self.tok2 = self.login("kermit2", "monkey") |
| 352 | + |
| 353 | + # Change the power levels of the room so that the second user can send state |
| 354 | + # events. |
| 355 | + self.power_levels = { |
| 356 | + "users": { |
| 357 | + self.user_id: 100, |
| 358 | + self.user2: 100, |
| 359 | + }, |
| 360 | + "users_default": 0, |
| 361 | + "events": { |
| 362 | + "m.room.name": 50, |
| 363 | + "m.room.power_levels": 100, |
| 364 | + "m.room.history_visibility": 100, |
| 365 | + "m.room.canonical_alias": 50, |
| 366 | + "m.room.avatar": 50, |
| 367 | + "m.room.tombstone": 100, |
| 368 | + "m.room.server_acl": 100, |
| 369 | + "m.room.encryption": 100 |
| 370 | + }, |
| 371 | + "events_default": 0, |
| 372 | + "state_default": 50, |
| 373 | + "ban": 50, |
| 374 | + "kick": 50, |
| 375 | + "redact": 50, |
| 376 | + "invite": 0 |
| 377 | + } |
| 378 | + self.helper.send_state( |
| 379 | + self.room_id, EventTypes.PowerLevels, self.power_levels, tok=self.tok, |
| 380 | + ) |
| 381 | + |
| 382 | + def test_unread_counts(self): |
| 383 | + """Tests that /sync returns the right value for the unread count (MSC2654).""" |
| 384 | + |
| 385 | + # Check that our own messages don't increase the unread count. |
| 386 | + self.helper.send(self.room_id, "hello", tok=self.tok) |
| 387 | + self._check_unread_count(0) |
| 388 | + |
| 389 | + # Join the new user and check that this doesn't increase the unread count. |
| 390 | + self.helper.join(room=self.room_id, user=self.user2, tok=self.tok2) |
| 391 | + self._check_unread_count(0) |
| 392 | + |
| 393 | + # Check that the new user sending a message increases our unread count. |
| 394 | + res = self.helper.send(self.room_id, "hello", tok=self.tok2) |
| 395 | + self._check_unread_count(1) |
| 396 | + |
| 397 | + # Check that redacting that message decreases our unread count. |
| 398 | + self.helper.redact(self.room_id, res["event_id"], tok=self.tok2) |
| 399 | + self._check_unread_count(0) |
| 400 | + |
| 401 | + # Re-send a message to prepare for the next check. |
| 402 | + res = self.helper.send(self.room_id, "hello", tok=self.tok2) |
| 403 | + self._check_unread_count(1) |
| 404 | + |
| 405 | + # Send a read receipt to tell the server we've read the latest event. |
| 406 | + body = json.dumps({"m.read": res["event_id"]}).encode("utf8") |
| 407 | + request, channel = self.make_request( |
| 408 | + "POST", "/rooms/%s/read_markers" % self.room_id, body, access_token=self.tok, |
| 409 | + ) |
| 410 | + self.render(request) |
| 411 | + self.assertEqual(channel.code, 200, channel.json_body) |
| 412 | + |
| 413 | + # Check that the unread counter is back to 0. |
| 414 | + self._check_unread_count(0) |
| 415 | + |
| 416 | + # Check that room name changes increase the unread counter. |
| 417 | + self.helper.send_state( |
| 418 | + self.room_id, "m.room.name", {"name": "my super room"}, tok=self.tok2, |
| 419 | + ) |
| 420 | + self._check_unread_count(1) |
| 421 | + |
| 422 | + # Check that room topic changes increase the unread counter. |
| 423 | + self.helper.send_state( |
| 424 | + self.room_id, "m.room.topic", {"topic": "welcome!!!"}, tok=self.tok2, |
| 425 | + ) |
| 426 | + self._check_unread_count(2) |
| 427 | + |
| 428 | + # Check that encrypted messages increase the unread counter. |
| 429 | + self.helper.send_event(self.room_id, EventTypes.Encrypted, {}, tok=self.tok2) |
| 430 | + self._check_unread_count(3) |
| 431 | + |
| 432 | + # Check that custom events with a body increase the unread counter. |
| 433 | + self.helper.send_event( |
| 434 | + self.room_id, "org.matrix.custom_type", {"body": "hello"}, tok=self.tok2, |
| 435 | + ) |
| 436 | + self._check_unread_count(4) |
| 437 | + |
| 438 | + # Check that power level changes increase the unread counter. |
| 439 | + self.power_levels["invite"] = 50 |
| 440 | + self.helper.send_state( |
| 441 | + self.room_id, EventTypes.PowerLevels, self.power_levels, tok=self.tok2, |
| 442 | + ) |
| 443 | + self._check_unread_count(5) |
| 444 | + |
| 445 | + # Check that edits don't increase the unread counter. |
| 446 | + self.helper.send_event( |
| 447 | + room_id=self.room_id, |
| 448 | + type=EventTypes.Message, |
| 449 | + content={ |
| 450 | + "body": "hello", |
| 451 | + "msgtype": "m.text", |
| 452 | + "m.relates_to": {"rel_type": RelationTypes.REPLACE} |
| 453 | + }, |
| 454 | + tok=self.tok2, |
| 455 | + ) |
| 456 | + self._check_unread_count(5) |
| 457 | + |
| 458 | + # Check that notices don't increase the unread counter. |
| 459 | + self.helper.send_event( |
| 460 | + room_id=self.room_id, |
| 461 | + type=EventTypes.Message, |
| 462 | + content={ |
| 463 | + "body": "hello", |
| 464 | + "msgtype": "m.notice", |
| 465 | + }, |
| 466 | + tok=self.tok2, |
| 467 | + ) |
| 468 | + self._check_unread_count(5) |
| 469 | + |
| 470 | + def _check_unread_count(self, expected_count: True): |
| 471 | + """Syncs and compares the unread count with the expected value.""" |
| 472 | + |
| 473 | + request, channel = self.make_request( |
| 474 | + "GET", self.url % self.next_batch, access_token=self.tok, |
| 475 | + ) |
| 476 | + self.render(request) |
| 477 | + |
| 478 | + self.assertEqual(channel.code, 200, channel.json_body) |
| 479 | + |
| 480 | + room_entry = channel.json_body["rooms"]["join"][self.room_id] |
| 481 | + self.assertEqual( |
| 482 | + room_entry["org.matrix.msc2654.unread_count"], expected_count, room_entry, |
| 483 | + ) |
| 484 | + |
| 485 | + # Store the next batch for the next request. |
| 486 | + self.next_batch = channel.json_body["next_batch"] |
0 commit comments