Update intentional mentions (MSC3952) to depend on `exact_event_match` (MSC3758). (#15037)
This replaces the specific `is_room_mention` push rule condition used in MSC3952 with the generic `exact_event_match` push rule condition from MSC3758. No functionality changes due to this.pull/15083/head
							parent
							
								
									d1efc47925
								
							
						
					
					
						commit
						979f237b28
					
				|  | @ -0,0 +1 @@ | |||
| Update [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952) support based on changes to the MSC. | ||||
|  | @ -45,7 +45,6 @@ fn bench_match_exact(b: &mut Bencher) { | |||
|         flattened_keys, | ||||
|         false, | ||||
|         BTreeSet::new(), | ||||
|         false, | ||||
|         10, | ||||
|         Some(0), | ||||
|         Default::default(), | ||||
|  | @ -95,7 +94,6 @@ fn bench_match_word(b: &mut Bencher) { | |||
|         flattened_keys, | ||||
|         false, | ||||
|         BTreeSet::new(), | ||||
|         false, | ||||
|         10, | ||||
|         Some(0), | ||||
|         Default::default(), | ||||
|  | @ -145,7 +143,6 @@ fn bench_match_word_miss(b: &mut Bencher) { | |||
|         flattened_keys, | ||||
|         false, | ||||
|         BTreeSet::new(), | ||||
|         false, | ||||
|         10, | ||||
|         Some(0), | ||||
|         Default::default(), | ||||
|  | @ -195,7 +192,6 @@ fn bench_eval_message(b: &mut Bencher) { | |||
|         flattened_keys, | ||||
|         false, | ||||
|         BTreeSet::new(), | ||||
|         false, | ||||
|         10, | ||||
|         Some(0), | ||||
|         Default::default(), | ||||
|  |  | |||
|  | @ -21,13 +21,13 @@ use lazy_static::lazy_static; | |||
| use serde_json::Value; | ||||
| 
 | ||||
| use super::KnownCondition; | ||||
| use crate::push::Action; | ||||
| use crate::push::Condition; | ||||
| use crate::push::EventMatchCondition; | ||||
| use crate::push::PushRule; | ||||
| use crate::push::RelatedEventMatchCondition; | ||||
| use crate::push::SetTweak; | ||||
| use crate::push::TweakValue; | ||||
| use crate::push::{Action, ExactEventMatchCondition, SimpleJsonValue}; | ||||
| 
 | ||||
| const HIGHLIGHT_ACTION: Action = Action::SetTweak(SetTweak { | ||||
|     set_tweak: Cow::Borrowed("highlight"), | ||||
|  | @ -168,7 +168,10 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[ | |||
|         rule_id: Cow::Borrowed(".org.matrix.msc3952.is_room_mention"), | ||||
|         priority_class: 5, | ||||
|         conditions: Cow::Borrowed(&[ | ||||
|             Condition::Known(KnownCondition::IsRoomMention), | ||||
|             Condition::Known(KnownCondition::ExactEventMatch(ExactEventMatchCondition { | ||||
|                 key: Cow::Borrowed("content.org.matrix.msc3952.mentions.room"), | ||||
|                 value: Cow::Borrowed(&SimpleJsonValue::Bool(true)), | ||||
|             })), | ||||
|             Condition::Known(KnownCondition::SenderNotificationPermission { | ||||
|                 key: Cow::Borrowed("room"), | ||||
|             }), | ||||
|  |  | |||
|  | @ -73,8 +73,6 @@ pub struct PushRuleEvaluator { | |||
|     has_mentions: bool, | ||||
|     /// The user mentions that were part of the message.
 | ||||
|     user_mentions: BTreeSet<String>, | ||||
|     /// True if the message is a room message.
 | ||||
|     room_mention: bool, | ||||
| 
 | ||||
|     /// The number of users in the room.
 | ||||
|     room_member_count: u64, | ||||
|  | @ -116,7 +114,6 @@ impl PushRuleEvaluator { | |||
|         flattened_keys: BTreeMap<String, JsonValue>, | ||||
|         has_mentions: bool, | ||||
|         user_mentions: BTreeSet<String>, | ||||
|         room_mention: bool, | ||||
|         room_member_count: u64, | ||||
|         sender_power_level: Option<i64>, | ||||
|         notification_power_levels: BTreeMap<String, i64>, | ||||
|  | @ -137,7 +134,6 @@ impl PushRuleEvaluator { | |||
|             body, | ||||
|             has_mentions, | ||||
|             user_mentions, | ||||
|             room_mention, | ||||
|             room_member_count, | ||||
|             notification_power_levels, | ||||
|             sender_power_level, | ||||
|  | @ -279,7 +275,6 @@ impl PushRuleEvaluator { | |||
|                     false | ||||
|                 } | ||||
|             } | ||||
|             KnownCondition::IsRoomMention => self.room_mention, | ||||
|             KnownCondition::ContainsDisplayName => { | ||||
|                 if let Some(dn) = display_name { | ||||
|                     if !dn.is_empty() { | ||||
|  | @ -529,7 +524,6 @@ fn push_rule_evaluator() { | |||
|         flattened_keys, | ||||
|         false, | ||||
|         BTreeSet::new(), | ||||
|         false, | ||||
|         10, | ||||
|         Some(0), | ||||
|         BTreeMap::new(), | ||||
|  | @ -562,7 +556,6 @@ fn test_requires_room_version_supports_condition() { | |||
|         flattened_keys, | ||||
|         false, | ||||
|         BTreeSet::new(), | ||||
|         false, | ||||
|         10, | ||||
|         Some(0), | ||||
|         BTreeMap::new(), | ||||
|  |  | |||
|  | @ -336,8 +336,6 @@ pub enum KnownCondition { | |||
|     ExactEventPropertyContains(ExactEventMatchCondition), | ||||
|     #[serde(rename = "org.matrix.msc3952.is_user_mention")] | ||||
|     IsUserMention, | ||||
|     #[serde(rename = "org.matrix.msc3952.is_room_mention")] | ||||
|     IsRoomMention, | ||||
|     ContainsDisplayName, | ||||
|     RoomMemberCount { | ||||
|         #[serde(skip_serializing_if = "Option::is_none")] | ||||
|  | @ -667,17 +665,6 @@ fn test_deserialize_unstable_msc3952_user_condition() { | |||
|     )); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_deserialize_unstable_msc3952_room_condition() { | ||||
|     let json = r#"{"kind":"org.matrix.msc3952.is_room_mention"}"#; | ||||
| 
 | ||||
|     let condition: Condition = serde_json::from_str(json).unwrap(); | ||||
|     assert!(matches!( | ||||
|         condition, | ||||
|         Condition::Known(KnownCondition::IsRoomMention) | ||||
|     )); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_deserialize_custom_condition() { | ||||
|     let json = r#"{"kind":"custom_tag"}"#; | ||||
|  |  | |||
|  | @ -59,7 +59,6 @@ class PushRuleEvaluator: | |||
|         flattened_keys: Mapping[str, JsonValue], | ||||
|         has_mentions: bool, | ||||
|         user_mentions: Set[str], | ||||
|         room_mention: bool, | ||||
|         room_member_count: int, | ||||
|         sender_power_level: Optional[int], | ||||
|         notification_power_levels: Mapping[str, int], | ||||
|  |  | |||
|  | @ -179,9 +179,10 @@ class ExperimentalConfig(Config): | |||
|             "msc3783_escape_event_match_key", False | ||||
|         ) | ||||
| 
 | ||||
|         # MSC3952: Intentional mentions | ||||
|         self.msc3952_intentional_mentions = experimental.get( | ||||
|             "msc3952_intentional_mentions", False | ||||
|         # MSC3952: Intentional mentions, this depends on MSC3758. | ||||
|         self.msc3952_intentional_mentions = ( | ||||
|             experimental.get("msc3952_intentional_mentions", False) | ||||
|             and self.msc3758_exact_event_match | ||||
|         ) | ||||
| 
 | ||||
|         # MSC3959: Do not generate notifications for edits. | ||||
|  |  | |||
|  | @ -400,7 +400,6 @@ class BulkPushRuleEvaluator: | |||
|         mentions = event.content.get(EventContentFields.MSC3952_MENTIONS) | ||||
|         has_mentions = self._intentional_mentions_enabled and isinstance(mentions, dict) | ||||
|         user_mentions: Set[str] = set() | ||||
|         room_mention = False | ||||
|         if has_mentions: | ||||
|             # mypy seems to have lost the type even though it must be a dict here. | ||||
|             assert isinstance(mentions, dict) | ||||
|  | @ -410,8 +409,6 @@ class BulkPushRuleEvaluator: | |||
|                 user_mentions = set( | ||||
|                     filter(lambda item: isinstance(item, str), user_mentions_raw) | ||||
|                 ) | ||||
|             # Room mention is only true if the value is exactly true. | ||||
|             room_mention = mentions.get("room") is True | ||||
| 
 | ||||
|         evaluator = PushRuleEvaluator( | ||||
|             _flatten_dict( | ||||
|  | @ -420,7 +417,6 @@ class BulkPushRuleEvaluator: | |||
|             ), | ||||
|             has_mentions, | ||||
|             user_mentions, | ||||
|             room_mention, | ||||
|             room_member_count, | ||||
|             sender_power_level, | ||||
|             notification_levels, | ||||
|  |  | |||
|  | @ -227,7 +227,14 @@ class TestBulkPushRuleEvaluator(HomeserverTestCase): | |||
|         ) | ||||
|         return len(result) > 0 | ||||
| 
 | ||||
|     @override_config({"experimental_features": {"msc3952_intentional_mentions": True}}) | ||||
|     @override_config( | ||||
|         { | ||||
|             "experimental_features": { | ||||
|                 "msc3758_exact_event_match": True, | ||||
|                 "msc3952_intentional_mentions": True, | ||||
|             } | ||||
|         } | ||||
|     ) | ||||
|     def test_user_mentions(self) -> None: | ||||
|         """Test the behavior of an event which includes invalid user mentions.""" | ||||
|         bulk_evaluator = BulkPushRuleEvaluator(self.hs) | ||||
|  | @ -323,7 +330,14 @@ class TestBulkPushRuleEvaluator(HomeserverTestCase): | |||
|             ) | ||||
|         ) | ||||
| 
 | ||||
|     @override_config({"experimental_features": {"msc3952_intentional_mentions": True}}) | ||||
|     @override_config( | ||||
|         { | ||||
|             "experimental_features": { | ||||
|                 "msc3758_exact_event_match": True, | ||||
|                 "msc3952_intentional_mentions": True, | ||||
|             } | ||||
|         } | ||||
|     ) | ||||
|     def test_room_mentions(self) -> None: | ||||
|         """Test the behavior of an event which includes invalid room mentions.""" | ||||
|         bulk_evaluator = BulkPushRuleEvaluator(self.hs) | ||||
|  |  | |||
|  | @ -149,7 +149,6 @@ class PushRuleEvaluatorTestCase(unittest.TestCase): | |||
|         *, | ||||
|         has_mentions: bool = False, | ||||
|         user_mentions: Optional[Set[str]] = None, | ||||
|         room_mention: bool = False, | ||||
|         related_events: Optional[JsonDict] = None, | ||||
|     ) -> PushRuleEvaluator: | ||||
|         event = FrozenEvent( | ||||
|  | @ -170,7 +169,6 @@ class PushRuleEvaluatorTestCase(unittest.TestCase): | |||
|             _flatten_dict(event), | ||||
|             has_mentions, | ||||
|             user_mentions or set(), | ||||
|             room_mention, | ||||
|             room_member_count, | ||||
|             sender_power_level, | ||||
|             cast(Dict[str, int], power_levels.get("notifications", {})), | ||||
|  | @ -232,27 +230,6 @@ class PushRuleEvaluatorTestCase(unittest.TestCase): | |||
|         # Note that invalid data is tested at tests.push.test_bulk_push_rule_evaluator.TestBulkPushRuleEvaluator.test_mentions | ||||
|         # since the BulkPushRuleEvaluator is what handles data sanitisation. | ||||
| 
 | ||||
|     def test_room_mentions(self) -> None: | ||||
|         """Check for room mentions.""" | ||||
|         condition = {"kind": "org.matrix.msc3952.is_room_mention"} | ||||
| 
 | ||||
|         # No room mention shouldn't match. | ||||
|         evaluator = self._get_evaluator({}, has_mentions=True) | ||||
|         self.assertFalse(evaluator.matches(condition, None, None)) | ||||
| 
 | ||||
|         # Room mention should match. | ||||
|         evaluator = self._get_evaluator({}, has_mentions=True, room_mention=True) | ||||
|         self.assertTrue(evaluator.matches(condition, None, None)) | ||||
| 
 | ||||
|         # A room mention and user mention is valid. | ||||
|         evaluator = self._get_evaluator( | ||||
|             {}, has_mentions=True, user_mentions={"@another:test"}, room_mention=True | ||||
|         ) | ||||
|         self.assertTrue(evaluator.matches(condition, None, None)) | ||||
| 
 | ||||
|         # Note that invalid data is tested at tests.push.test_bulk_push_rule_evaluator.TestBulkPushRuleEvaluator.test_mentions | ||||
|         # since the BulkPushRuleEvaluator is what handles data sanitisation. | ||||
| 
 | ||||
|     def _assert_matches( | ||||
|         self, condition: JsonDict, content: JsonMapping, msg: Optional[str] = None | ||||
|     ) -> None: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Patrick Cloke
						Patrick Cloke