|
12 | 12 | # See the License for the specific language governing permissions and
|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
| 15 | +from typing import Any |
15 | 16 | from unittest.mock import patch
|
16 | 17 |
|
17 | 18 | from twisted.test.proto_helpers import MemoryReactor
|
18 | 19 |
|
| 20 | +from synapse.api.constants import EventContentFields |
19 | 21 | from synapse.api.room_versions import RoomVersions
|
20 | 22 | from synapse.push.bulk_push_rule_evaluator import BulkPushRuleEvaluator
|
21 | 23 | from synapse.rest import admin
|
@@ -126,3 +128,89 @@ def test_action_for_event_by_user_disabled_by_config(self) -> None:
|
126 | 128 | # Ensure no actions are generated!
|
127 | 129 | self.get_success(bulk_evaluator.action_for_events_by_user([(event, context)]))
|
128 | 130 | bulk_evaluator._action_for_event_by_user.assert_not_called()
|
| 131 | + |
| 132 | + @override_config({"experimental_features": {"msc3952_intentional_mentions": True}}) |
| 133 | + def test_mentions(self) -> None: |
| 134 | + """Test the behavior of an event which includes invalid mentions.""" |
| 135 | + bulk_evaluator = BulkPushRuleEvaluator(self.hs) |
| 136 | + |
| 137 | + sentinel = object() |
| 138 | + |
| 139 | + def create_and_process(mentions: Any = sentinel) -> bool: |
| 140 | + """Returns true iff the `mentions` trigger an event push action.""" |
| 141 | + content = {} |
| 142 | + if mentions is not sentinel: |
| 143 | + content[EventContentFields.MSC3952_MENTIONS] = mentions |
| 144 | + |
| 145 | + # Create a new message event which should cause a notification. |
| 146 | + event, context = self.get_success( |
| 147 | + self.event_creation_handler.create_event( |
| 148 | + self.requester, |
| 149 | + { |
| 150 | + "type": "test", |
| 151 | + "room_id": self.room_id, |
| 152 | + "content": content, |
| 153 | + "sender": f"@bob:{self.hs.hostname}", |
| 154 | + }, |
| 155 | + ) |
| 156 | + ) |
| 157 | + |
| 158 | + # Ensure no actions are generated! |
| 159 | + self.get_success( |
| 160 | + bulk_evaluator.action_for_events_by_user([(event, context)]) |
| 161 | + ) |
| 162 | + |
| 163 | + # If any actions are generated for this event, return true. |
| 164 | + result = self.get_success( |
| 165 | + self.hs.get_datastores().main.db_pool.simple_select_list( |
| 166 | + table="event_push_actions_staging", |
| 167 | + keyvalues={"event_id": event.event_id}, |
| 168 | + retcols=("*",), |
| 169 | + desc="get_event_push_actions_staging", |
| 170 | + ) |
| 171 | + ) |
| 172 | + return len(result) > 0 |
| 173 | + |
| 174 | + # Not including the mentions field should not notify. |
| 175 | + self.assertFalse(create_and_process()) |
| 176 | + # An empty mentions field should not notify. |
| 177 | + self.assertFalse(create_and_process({})) |
| 178 | + |
| 179 | + # Non-dict mentions should be ignored. |
| 180 | + mentions: Any |
| 181 | + for mentions in (None, True, False, 1, "foo", []): |
| 182 | + self.assertFalse(create_and_process(mentions)) |
| 183 | + |
| 184 | + # A non-list should be ignored. |
| 185 | + for mentions in (None, True, False, 1, "foo", {}): |
| 186 | + self.assertFalse(create_and_process({"user_ids": mentions})) |
| 187 | + |
| 188 | + # The Matrix ID appearing anywhere in the list should notify. |
| 189 | + self.assertTrue(create_and_process({"user_ids": [self.alice]})) |
| 190 | + self.assertTrue(create_and_process({"user_ids": ["@another:test", self.alice]})) |
| 191 | + |
| 192 | + # Duplicate user IDs should notify. |
| 193 | + self.assertTrue(create_and_process({"user_ids": [self.alice, self.alice]})) |
| 194 | + |
| 195 | + # Invalid entries in the list are ignored. |
| 196 | + self.assertFalse(create_and_process({"user_ids": [None, True, False, {}, []]})) |
| 197 | + self.assertTrue( |
| 198 | + create_and_process({"user_ids": [None, True, False, {}, [], self.alice]}) |
| 199 | + ) |
| 200 | + |
| 201 | + # Room mentions from those without power should not notify. |
| 202 | + self.assertFalse(create_and_process({"room": True})) |
| 203 | + |
| 204 | + # Room mentions from those with power should notify. |
| 205 | + self.helper.send_state( |
| 206 | + self.room_id, |
| 207 | + "m.room.power_levels", |
| 208 | + {"notifications": {"room": 0}}, |
| 209 | + self.token, |
| 210 | + state_key="", |
| 211 | + ) |
| 212 | + self.assertTrue(create_and_process({"room": True})) |
| 213 | + |
| 214 | + # Invalid data should not notify. |
| 215 | + for mentions in (None, False, 1, "foo", [], {}): |
| 216 | + self.assertFalse(create_and_process({"room": mentions})) |
0 commit comments