12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
-
15
+ from typing import Optional
16
16
from unittest .mock import Mock , call
17
17
18
18
from signedjson .key import generate_signing_key
@@ -339,67 +339,80 @@ def test_persisting_presence_updates(self):
339
339
340
340
341
341
class PresenceTimeoutTestCase (unittest .TestCase ):
342
+ """Tests different timers and that the timer does not change `status_msg` of user."""
343
+
342
344
def test_idle_timer (self ):
343
345
user_id = "@foo:bar"
346
+ status_msg = "I'm here!"
344
347
now = 5000000
345
348
346
349
state = UserPresenceState .default (user_id )
347
350
state = state .copy_and_replace (
348
351
state = PresenceState .ONLINE ,
349
352
last_active_ts = now - IDLE_TIMER - 1 ,
350
353
last_user_sync_ts = now ,
354
+ status_msg = status_msg ,
351
355
)
352
356
353
357
new_state = handle_timeout (state , is_mine = True , syncing_user_ids = set (), now = now )
354
358
355
359
self .assertIsNotNone (new_state )
356
360
self .assertEquals (new_state .state , PresenceState .UNAVAILABLE )
361
+ self .assertEquals (new_state .status_msg , status_msg )
357
362
358
363
def test_busy_no_idle (self ):
359
364
"""
360
365
Tests that a user setting their presence to busy but idling doesn't turn their
361
366
presence state into unavailable.
362
367
"""
363
368
user_id = "@foo:bar"
369
+ status_msg = "I'm here!"
364
370
now = 5000000
365
371
366
372
state = UserPresenceState .default (user_id )
367
373
state = state .copy_and_replace (
368
374
state = PresenceState .BUSY ,
369
375
last_active_ts = now - IDLE_TIMER - 1 ,
370
376
last_user_sync_ts = now ,
377
+ status_msg = status_msg ,
371
378
)
372
379
373
380
new_state = handle_timeout (state , is_mine = True , syncing_user_ids = set (), now = now )
374
381
375
382
self .assertIsNotNone (new_state )
376
383
self .assertEquals (new_state .state , PresenceState .BUSY )
384
+ self .assertEquals (new_state .status_msg , status_msg )
377
385
378
386
def test_sync_timeout (self ):
379
387
user_id = "@foo:bar"
388
+ status_msg = "I'm here!"
380
389
now = 5000000
381
390
382
391
state = UserPresenceState .default (user_id )
383
392
state = state .copy_and_replace (
384
393
state = PresenceState .ONLINE ,
385
394
last_active_ts = 0 ,
386
395
last_user_sync_ts = now - SYNC_ONLINE_TIMEOUT - 1 ,
396
+ status_msg = status_msg ,
387
397
)
388
398
389
399
new_state = handle_timeout (state , is_mine = True , syncing_user_ids = set (), now = now )
390
400
391
401
self .assertIsNotNone (new_state )
392
402
self .assertEquals (new_state .state , PresenceState .OFFLINE )
403
+ self .assertEquals (new_state .status_msg , status_msg )
393
404
394
405
def test_sync_online (self ):
395
406
user_id = "@foo:bar"
407
+ status_msg = "I'm here!"
396
408
now = 5000000
397
409
398
410
state = UserPresenceState .default (user_id )
399
411
state = state .copy_and_replace (
400
412
state = PresenceState .ONLINE ,
401
413
last_active_ts = now - SYNC_ONLINE_TIMEOUT - 1 ,
402
414
last_user_sync_ts = now - SYNC_ONLINE_TIMEOUT - 1 ,
415
+ status_msg = status_msg ,
403
416
)
404
417
405
418
new_state = handle_timeout (
@@ -408,9 +421,11 @@ def test_sync_online(self):
408
421
409
422
self .assertIsNotNone (new_state )
410
423
self .assertEquals (new_state .state , PresenceState .ONLINE )
424
+ self .assertEquals (new_state .status_msg , status_msg )
411
425
412
426
def test_federation_ping (self ):
413
427
user_id = "@foo:bar"
428
+ status_msg = "I'm here!"
414
429
now = 5000000
415
430
416
431
state = UserPresenceState .default (user_id )
@@ -419,12 +434,13 @@ def test_federation_ping(self):
419
434
last_active_ts = now ,
420
435
last_user_sync_ts = now ,
421
436
last_federation_update_ts = now - FEDERATION_PING_INTERVAL - 1 ,
437
+ status_msg = status_msg ,
422
438
)
423
439
424
440
new_state = handle_timeout (state , is_mine = True , syncing_user_ids = set (), now = now )
425
441
426
442
self .assertIsNotNone (new_state )
427
- self .assertEquals (new_state , new_state )
443
+ self .assertEquals (state , new_state )
428
444
429
445
def test_no_timeout (self ):
430
446
user_id = "@foo:bar"
@@ -444,6 +460,7 @@ def test_no_timeout(self):
444
460
445
461
def test_federation_timeout (self ):
446
462
user_id = "@foo:bar"
463
+ status_msg = "I'm here!"
447
464
now = 5000000
448
465
449
466
state = UserPresenceState .default (user_id )
@@ -452,6 +469,7 @@ def test_federation_timeout(self):
452
469
last_active_ts = now ,
453
470
last_user_sync_ts = now ,
454
471
last_federation_update_ts = now - FEDERATION_TIMEOUT - 1 ,
472
+ status_msg = status_msg ,
455
473
)
456
474
457
475
new_state = handle_timeout (
@@ -460,9 +478,11 @@ def test_federation_timeout(self):
460
478
461
479
self .assertIsNotNone (new_state )
462
480
self .assertEquals (new_state .state , PresenceState .OFFLINE )
481
+ self .assertEquals (new_state .status_msg , status_msg )
463
482
464
483
def test_last_active (self ):
465
484
user_id = "@foo:bar"
485
+ status_msg = "I'm here!"
466
486
now = 5000000
467
487
468
488
state = UserPresenceState .default (user_id )
@@ -471,6 +491,7 @@ def test_last_active(self):
471
491
last_active_ts = now - LAST_ACTIVE_GRANULARITY - 1 ,
472
492
last_user_sync_ts = now ,
473
493
last_federation_update_ts = now ,
494
+ status_msg = status_msg ,
474
495
)
475
496
476
497
new_state = handle_timeout (state , is_mine = True , syncing_user_ids = set (), now = now )
@@ -516,6 +537,144 @@ def test_external_process_timeout(self):
516
537
)
517
538
self .assertEqual (state .state , PresenceState .OFFLINE )
518
539
540
+ def test_user_goes_offline_by_timeout_status_msg_remain (self ):
541
+ """Test that if a user doesn't update the records for a while
542
+ users presence goes `OFFLINE` because of timeout and `status_msg` remains.
543
+ """
544
+ user_id = "@test:server"
545
+ status_msg = "I'm here!"
546
+
547
+ # Mark user as online
548
+ self ._set_presencestate_with_status_msg (
549
+ user_id , PresenceState .ONLINE , status_msg
550
+ )
551
+
552
+ # Check that if we wait a while without telling the handler the user has
553
+ # stopped syncing that their presence state doesn't get timed out.
554
+ self .reactor .advance (SYNC_ONLINE_TIMEOUT / 2 )
555
+
556
+ state = self .get_success (
557
+ self .presence_handler .get_state (UserID .from_string (user_id ))
558
+ )
559
+ self .assertEqual (state .state , PresenceState .ONLINE )
560
+ self .assertEqual (state .status_msg , status_msg )
561
+
562
+ # Check that if the timeout fires, then the syncing user gets timed out
563
+ self .reactor .advance (SYNC_ONLINE_TIMEOUT )
564
+
565
+ state = self .get_success (
566
+ self .presence_handler .get_state (UserID .from_string (user_id ))
567
+ )
568
+ # status_msg should remain even after going offline
569
+ self .assertEqual (state .state , PresenceState .OFFLINE )
570
+ self .assertEqual (state .status_msg , status_msg )
571
+
572
+ def test_user_goes_offline_manually_with_no_status_msg (self ):
573
+ """Test that if a user change presence manually to `OFFLINE`
574
+ and no status is set, that `status_msg` is `None`.
575
+ """
576
+ user_id = "@test:server"
577
+ status_msg = "I'm here!"
578
+
579
+ # Mark user as online
580
+ self ._set_presencestate_with_status_msg (
581
+ user_id , PresenceState .ONLINE , status_msg
582
+ )
583
+
584
+ # Mark user as offline
585
+ self .get_success (
586
+ self .presence_handler .set_state (
587
+ UserID .from_string (user_id ), {"presence" : PresenceState .OFFLINE }
588
+ )
589
+ )
590
+
591
+ state = self .get_success (
592
+ self .presence_handler .get_state (UserID .from_string (user_id ))
593
+ )
594
+ self .assertEqual (state .state , PresenceState .OFFLINE )
595
+ self .assertEqual (state .status_msg , None )
596
+
597
+ def test_user_goes_offline_manually_with_status_msg (self ):
598
+ """Test that if a user change presence manually to `OFFLINE`
599
+ and a status is set, that `status_msg` appears.
600
+ """
601
+ user_id = "@test:server"
602
+ status_msg = "I'm here!"
603
+
604
+ # Mark user as online
605
+ self ._set_presencestate_with_status_msg (
606
+ user_id , PresenceState .ONLINE , status_msg
607
+ )
608
+
609
+ # Mark user as offline
610
+ self ._set_presencestate_with_status_msg (
611
+ user_id , PresenceState .OFFLINE , "And now here."
612
+ )
613
+
614
+ def test_user_reset_online_with_no_status (self ):
615
+ """Test that if a user set again the presence manually
616
+ and no status is set, that `status_msg` is `None`.
617
+ """
618
+ user_id = "@test:server"
619
+ status_msg = "I'm here!"
620
+
621
+ # Mark user as online
622
+ self ._set_presencestate_with_status_msg (
623
+ user_id , PresenceState .ONLINE , status_msg
624
+ )
625
+
626
+ # Mark user as online again
627
+ self .get_success (
628
+ self .presence_handler .set_state (
629
+ UserID .from_string (user_id ), {"presence" : PresenceState .ONLINE }
630
+ )
631
+ )
632
+
633
+ state = self .get_success (
634
+ self .presence_handler .get_state (UserID .from_string (user_id ))
635
+ )
636
+ # status_msg should remain even after going offline
637
+ self .assertEqual (state .state , PresenceState .ONLINE )
638
+ self .assertEqual (state .status_msg , None )
639
+
640
+ def test_set_presence_with_status_msg_none (self ):
641
+ """Test that if a user set again the presence manually
642
+ and status is `None`, that `status_msg` is `None`.
643
+ """
644
+ user_id = "@test:server"
645
+ status_msg = "I'm here!"
646
+
647
+ # Mark user as online
648
+ self ._set_presencestate_with_status_msg (
649
+ user_id , PresenceState .ONLINE , status_msg
650
+ )
651
+
652
+ # Mark user as online and `status_msg = None`
653
+ self ._set_presencestate_with_status_msg (user_id , PresenceState .ONLINE , None )
654
+
655
+ def _set_presencestate_with_status_msg (
656
+ self , user_id : str , state : PresenceState , status_msg : Optional [str ]
657
+ ):
658
+ """Set a PresenceState and status_msg and check the result.
659
+
660
+ Args:
661
+ user_id: User for that the status is to be set.
662
+ PresenceState: The new PresenceState.
663
+ status_msg: Status message that is to be set.
664
+ """
665
+ self .get_success (
666
+ self .presence_handler .set_state (
667
+ UserID .from_string (user_id ),
668
+ {"presence" : state , "status_msg" : status_msg },
669
+ )
670
+ )
671
+
672
+ new_state = self .get_success (
673
+ self .presence_handler .get_state (UserID .from_string (user_id ))
674
+ )
675
+ self .assertEqual (new_state .state , state )
676
+ self .assertEqual (new_state .status_msg , status_msg )
677
+
519
678
520
679
class PresenceFederationQueueTestCase (unittest .HomeserverTestCase ):
521
680
def prepare (self , reactor , clock , hs ):
0 commit comments