Experimental support for MSC3772 (#12740)

Implements the following behind an experimental configuration flag:

* A new push rule kind for mutually related events.
* A new default push rule (`.m.rule.thread_reply`) under an unstable prefix.

This is missing part of MSC3772:

* The `.m.rule.thread_reply_to_me` push rule, this depends on MSC3664 / #11804.
This commit is contained in:
Patrick Cloke 2022-05-24 09:23:23 -04:00 committed by GitHub
parent 0b3423fd51
commit 88ce3080d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 287 additions and 6 deletions

View file

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Dict, Optional, Union
from typing import Dict, Optional, Set, Tuple, Union
import frozendict
@ -26,7 +26,12 @@ from tests import unittest
class PushRuleEvaluatorTestCase(unittest.TestCase):
def _get_evaluator(self, content: JsonDict) -> PushRuleEvaluatorForEvent:
def _get_evaluator(
self,
content: JsonDict,
relations: Optional[Dict[str, Set[Tuple[str, str]]]] = None,
relations_match_enabled: bool = False,
) -> PushRuleEvaluatorForEvent:
event = FrozenEvent(
{
"event_id": "$event_id",
@ -42,7 +47,12 @@ class PushRuleEvaluatorTestCase(unittest.TestCase):
sender_power_level = 0
power_levels: Dict[str, Union[int, Dict[str, int]]] = {}
return PushRuleEvaluatorForEvent(
event, room_member_count, sender_power_level, power_levels
event,
room_member_count,
sender_power_level,
power_levels,
relations or set(),
relations_match_enabled,
)
def test_display_name(self) -> None:
@ -276,3 +286,71 @@ class PushRuleEvaluatorTestCase(unittest.TestCase):
push_rule_evaluator.tweaks_for_actions(actions),
{"sound": "default", "highlight": True},
)
def test_relation_match(self) -> None:
"""Test the relation_match push rule kind."""
# Check if the experimental feature is disabled.
evaluator = self._get_evaluator(
{}, {"m.annotation": {("@user:test", "m.reaction")}}
)
condition = {"kind": "relation_match"}
# Oddly, an unknown condition always matches.
self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
# A push rule evaluator with the experimental rule enabled.
evaluator = self._get_evaluator(
{}, {"m.annotation": {("@user:test", "m.reaction")}}, True
)
# Check just relation type.
condition = {
"kind": "org.matrix.msc3772.relation_match",
"rel_type": "m.annotation",
}
self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
# Check relation type and sender.
condition = {
"kind": "org.matrix.msc3772.relation_match",
"rel_type": "m.annotation",
"sender": "@user:test",
}
self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
condition = {
"kind": "org.matrix.msc3772.relation_match",
"rel_type": "m.annotation",
"sender": "@other:test",
}
self.assertFalse(evaluator.matches(condition, "@user:test", "foo"))
# Check relation type and event type.
condition = {
"kind": "org.matrix.msc3772.relation_match",
"rel_type": "m.annotation",
"type": "m.reaction",
}
self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
# Check just sender, this fails since rel_type is required.
condition = {
"kind": "org.matrix.msc3772.relation_match",
"sender": "@user:test",
}
self.assertFalse(evaluator.matches(condition, "@user:test", "foo"))
# Check sender glob.
condition = {
"kind": "org.matrix.msc3772.relation_match",
"rel_type": "m.annotation",
"sender": "@*:test",
}
self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))
# Check event type glob.
condition = {
"kind": "org.matrix.msc3772.relation_match",
"rel_type": "m.annotation",
"event_type": "*.reaction",
}
self.assertTrue(evaluator.matches(condition, "@user:test", "foo"))