diff --git a/tests/module_api/test_account_data_manager.py b/tests/module_api/test_account_data_manager.py
index bec018d9e7..89009bea8c 100644
--- a/tests/module_api/test_account_data_manager.py
+++ b/tests/module_api/test_account_data_manager.py
@@ -11,8 +11,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from twisted.test.proto_helpers import MemoryReactor
+
from synapse.api.errors import SynapseError
from synapse.rest import admin
+from synapse.server import HomeServer
+from synapse.util import Clock
from tests.unittest import HomeserverTestCase
@@ -22,7 +26,9 @@ class ModuleApiTestCase(HomeserverTestCase):
admin.register_servlets,
]
- def prepare(self, reactor, clock, homeserver) -> None:
+ def prepare(
+ self, reactor: MemoryReactor, clock: Clock, homeserver: HomeServer
+ ) -> None:
self._store = homeserver.get_datastores().main
self._module_api = homeserver.get_module_api()
self._account_data_mgr = self._module_api.account_data_manager
@@ -91,7 +97,7 @@ class ModuleApiTestCase(HomeserverTestCase):
)
with self.assertRaises(TypeError):
# This throws an exception because it's a frozen dict.
- the_data["wombat"] = False
+ the_data["wombat"] = False # type: ignore[index]
def test_put_global(self) -> None:
"""
@@ -143,15 +149,14 @@ class ModuleApiTestCase(HomeserverTestCase):
with self.assertRaises(TypeError):
# The account data type must be a string.
self.get_success_or_raise(
- self._module_api.account_data_manager.put_global(
- self.user_id, 42, {} # type: ignore
- )
+ self._module_api.account_data_manager.put_global(self.user_id, 42, {}) # type: ignore[arg-type]
)
with self.assertRaises(TypeError):
# The account data dict must be a dict.
+ # noinspection PyTypeChecker
self.get_success_or_raise(
self._module_api.account_data_manager.put_global(
- self.user_id, "test.data", 42 # type: ignore
+ self.user_id, "test.data", 42 # type: ignore[arg-type]
)
)
diff --git a/tests/module_api/test_api.py b/tests/module_api/test_api.py
index 9fd5d59c55..8bc84aaaca 100644
--- a/tests/module_api/test_api.py
+++ b/tests/module_api/test_api.py
@@ -19,8 +19,9 @@ from synapse.api.constants import EduTypes, EventTypes
from synapse.events import EventBase
from synapse.federation.units import Transaction
from synapse.handlers.presence import UserPresenceState
+from synapse.handlers.push_rules import InvalidRuleException
from synapse.rest import admin
-from synapse.rest.client import login, presence, profile, room
+from synapse.rest.client import login, notifications, presence, profile, room
from synapse.types import create_requester
from tests.events.test_presence_router import send_presence_update, sync_presence
@@ -38,6 +39,7 @@ class ModuleApiTestCase(HomeserverTestCase):
room.register_servlets,
presence.register_servlets,
profile.register_servlets,
+ notifications.register_servlets,
]
def prepare(self, reactor, clock, homeserver):
@@ -553,6 +555,86 @@ class ModuleApiTestCase(HomeserverTestCase):
self.assertEqual(state[("org.matrix.test", "")].state_key, "")
self.assertEqual(state[("org.matrix.test", "")].content, {})
+ def test_set_push_rules_action(self) -> None:
+ """Test that a module can change the actions of an existing push rule for a user."""
+
+ # Create a room with 2 users in it. Push rules must not match if the user is the
+ # event's sender, so we need one user to send messages and one user to receive
+ # notifications.
+ user_id = self.register_user("user", "password")
+ tok = self.login("user", "password")
+
+ room_id = self.helper.create_room_as(user_id, is_public=True, tok=tok)
+
+ user_id2 = self.register_user("user2", "password")
+ tok2 = self.login("user2", "password")
+ self.helper.join(room_id, user_id2, tok=tok2)
+
+ # Register a 3rd user and join them to the room, so that we don't accidentally
+ # trigger 1:1 push rules.
+ user_id3 = self.register_user("user3", "password")
+ tok3 = self.login("user3", "password")
+ self.helper.join(room_id, user_id3, tok=tok3)
+
+ # Send a message as the second user and check that it notifies.
+ res = self.helper.send(room_id=room_id, body="here's a message", tok=tok2)
+ event_id = res["event_id"]
+
+ channel = self.make_request(
+ "GET",
+ "/notifications",
+ access_token=tok,
+ )
+ self.assertEqual(channel.code, 200, channel.result)
+
+ self.assertEqual(len(channel.json_body["notifications"]), 1, channel.json_body)
+ self.assertEqual(
+ channel.json_body["notifications"][0]["event"]["event_id"],
+ event_id,
+ channel.json_body,
+ )
+
+ # Change the .m.rule.message actions to not notify on new messages.
+ self.get_success(
+ defer.ensureDeferred(
+ self.module_api.set_push_rule_action(
+ user_id=user_id,
+ scope="global",
+ kind="underride",
+ rule_id=".m.rule.message",
+ actions=["dont_notify"],
+ )
+ )
+ )
+
+ # Send another message as the second user and check that the number of
+ # notifications didn't change.
+ self.helper.send(room_id=room_id, body="here's another message", tok=tok2)
+
+ channel = self.make_request(
+ "GET",
+ "/notifications?from=",
+ access_token=tok,
+ )
+ self.assertEqual(channel.code, 200, channel.result)
+ self.assertEqual(len(channel.json_body["notifications"]), 1, channel.json_body)
+
+ def test_check_push_rules_actions(self) -> None:
+ """Test that modules can check whether a list of push rules actions are spec
+ compliant.
+ """
+ with self.assertRaises(InvalidRuleException):
+ self.module_api.check_push_rule_actions(["foo"])
+
+ with self.assertRaises(InvalidRuleException):
+ self.module_api.check_push_rule_actions({"foo": "bar"})
+
+ self.module_api.check_push_rule_actions(["notify"])
+
+ self.module_api.check_push_rule_actions(
+ [{"set_tweak": "sound", "value": "default"}]
+ )
+
class ModuleApiWorkerTestCase(BaseMultiWorkerStreamTestCase):
"""For testing ModuleApi functionality in a multi-worker setup"""
|