1919#
2020#
2121
22+ from http import HTTPStatus
2223from typing import Any , Optional
2324from unittest .mock import AsyncMock , patch
2425
3031from synapse .api .room_versions import RoomVersions
3132from synapse .push .bulk_push_rule_evaluator import BulkPushRuleEvaluator
3233from synapse .rest import admin
33- from synapse .rest .client import login , register , room
34+ from synapse .rest .client import login , push_rule , register , room
3435from synapse .server import HomeServer
3536from synapse .types import JsonDict , create_requester
3637from synapse .util import Clock
@@ -44,6 +45,7 @@ class TestBulkPushRuleEvaluator(HomeserverTestCase):
4445 room .register_servlets ,
4546 login .register_servlets ,
4647 register .register_servlets ,
48+ push_rule .register_servlets ,
4749 ]
4850
4951 def prepare (
@@ -494,6 +496,135 @@ def test_thread_subscriptions(self) -> None:
494496 )
495497 )
496498
499+ @override_config ({"experimental_features" : {"msc4306_enabled" : True }})
500+ def test_thread_subscriptions_suppression_after_keyword_mention_overrides (
501+ self ,
502+ ) -> None :
503+ """
504+ Tests one of the purposes of the `postcontent` push rule section:
505+ When a keyword mention is configured (in the `content` section),
506+ it does not get suppressed by the thread being unsubscribed.
507+ """
508+ # add a keyword mention to alice's push rules
509+ channel = self .make_request (
510+ "PUT" ,
511+ "/_matrix/client/v3/pushrules/global/content/biscuits" ,
512+ {"pattern" : "biscuits" , "actions" : ["notify" ]},
513+ access_token = self .token ,
514+ )
515+ self .assertEqual (channel .code , HTTPStatus .OK )
516+
517+ bulk_evaluator = BulkPushRuleEvaluator (self .hs )
518+ (thread_root_id ,) = self .helper .send_messages (self .room_id , 1 , tok = self .token )
519+
520+ self .assertFalse (
521+ self ._create_and_process (
522+ bulk_evaluator ,
523+ {
524+ "msgtype" : "m.text" ,
525+ "body" : "do you want some cookies?" ,
526+ "m.relates_to" : {
527+ "rel_type" : RelationTypes .THREAD ,
528+ "event_id" : thread_root_id ,
529+ },
530+ },
531+ type = "m.room.message" ,
532+ ),
533+ "alice is not subscribed to thread and does not have a mention on 'cookies' so should not be notified" ,
534+ )
535+
536+ self .assertTrue (
537+ self ._create_and_process (
538+ bulk_evaluator ,
539+ {
540+ "msgtype" : "m.text" ,
541+ "body" : "biscuits are available in the kitchen" ,
542+ "m.relates_to" : {
543+ "rel_type" : RelationTypes .THREAD ,
544+ "event_id" : thread_root_id ,
545+ },
546+ },
547+ type = "m.room.message" ,
548+ ),
549+ "alice is not subscribed to thread but DOES have a mention on 'biscuits' so should be notified" ,
550+ )
551+
552+ @override_config ({"experimental_features" : {"msc4306_enabled" : True }})
553+ def test_thread_subscriptions_notification_before_keywords_and_mentions (
554+ self ,
555+ ) -> None :
556+ """
557+ Tests one of the purposes of the `postcontent` push rule section:
558+ When a room is set to (what is commonly known as) 'keywords & mentions', we still receive notifications
559+ for messages in threads that we are subscribed to.
560+ Effectively making this 'keywords, mentions & subscriptions'
561+ """
562+ # add a 'keywords & mentions' setting to the room alice's push rules
563+ # In case this rule isn't clear: by adding a rule in the `room` section that does nothing,
564+ # it stops execution of the push rules before we fall through to the `underride` section,
565+ # where intuitively many kinds of messages will ambiently generate notifications.
566+ # Mentions and keywords are triggered before the `room` block, so this doesn't suppress those.
567+ channel = self .make_request (
568+ "PUT" ,
569+ f"/_matrix/client/v3/pushrules/global/room/{ self .room_id } " ,
570+ {"actions" : []},
571+ access_token = self .token ,
572+ )
573+ self .assertEqual (channel .code , HTTPStatus .OK )
574+
575+ bulk_evaluator = BulkPushRuleEvaluator (self .hs )
576+ (thread_root_id ,) = self .helper .send_messages (self .room_id , 1 , tok = self .token )
577+
578+ # sanity check that our mentions still work
579+ self .assertFalse (
580+ self ._create_and_process (
581+ bulk_evaluator ,
582+ {
583+ "msgtype" : "m.text" ,
584+ "body" : "this is a plain message with no mention" ,
585+ },
586+ type = "m.room.message" ,
587+ ),
588+ "alice should not be notified (mentions & keywords room setting)" ,
589+ )
590+ self .assertTrue (
591+ self ._create_and_process (
592+ bulk_evaluator ,
593+ {
594+ "msgtype" : "m.text" ,
595+ "body" : "this is a message that mentions alice" ,
596+ },
597+ type = "m.room.message" ,
598+ ),
599+ "alice should be notified (mentioned)" ,
600+ )
601+
602+ # let's have alice subscribe to the thread
603+ self .get_success (
604+ self .hs .get_datastores ().main .subscribe_user_to_thread (
605+ self .alice ,
606+ self .room_id ,
607+ thread_root_id ,
608+ automatic_event_orderings = None ,
609+ )
610+ )
611+
612+ self .assertTrue (
613+ self ._create_and_process (
614+ bulk_evaluator ,
615+ {
616+ "msgtype" : "m.text" ,
617+ "body" : "some message in the thread" ,
618+ "m.relates_to" : {
619+ "rel_type" : RelationTypes .THREAD ,
620+ "event_id" : thread_root_id ,
621+ },
622+ },
623+ type = "m.room.message" ,
624+ ),
625+ "alice is subscribed to thread so should be notified" ,
626+ )
627+
497628 def test_with_disabled_thread_subscriptions (self ) -> None :
498629 """
499630 Test what happens with threaded events when MSC4306 is disabled.
0 commit comments