mirror of https://github.com/poljar/matrix-nio.git
635 lines
23 KiB
Python
635 lines
23 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import json
|
|
import pdb
|
|
|
|
from nio.api import PushRuleKind
|
|
from nio.events import (
|
|
AccountDataEvent,
|
|
BadEvent,
|
|
CallAnswerEvent,
|
|
CallCandidatesEvent,
|
|
CallEvent,
|
|
CallHangupEvent,
|
|
CallInviteEvent,
|
|
DummyEvent,
|
|
EphemeralEvent,
|
|
Event,
|
|
ForwardedRoomKeyEvent,
|
|
FullyReadEvent,
|
|
InviteAliasEvent,
|
|
InviteEvent,
|
|
InviteMemberEvent,
|
|
InviteNameEvent,
|
|
KeyVerificationAccept,
|
|
KeyVerificationCancel,
|
|
KeyVerificationKey,
|
|
KeyVerificationMac,
|
|
KeyVerificationStart,
|
|
MegolmEvent,
|
|
OlmEvent,
|
|
PowerLevelsEvent,
|
|
PushContainsDisplayName,
|
|
PushEventMatch,
|
|
PushRoomMemberCount,
|
|
PushRule,
|
|
PushRuleset,
|
|
PushRulesEvent,
|
|
PushSenderNotificationPermission,
|
|
PushUnknownCondition,
|
|
Receipt,
|
|
ReceiptEvent,
|
|
RedactedEvent,
|
|
RedactionEvent,
|
|
RoomAliasEvent,
|
|
RoomAvatarEvent,
|
|
RoomCreateEvent,
|
|
RoomEncryptedImage,
|
|
RoomEncryptionEvent,
|
|
RoomGuestAccessEvent,
|
|
RoomHistoryVisibilityEvent,
|
|
RoomJoinRulesEvent,
|
|
RoomKeyEvent,
|
|
RoomKeyRequest,
|
|
RoomKeyRequestCancellation,
|
|
RoomMemberEvent,
|
|
RoomMessageEmote,
|
|
RoomMessageNotice,
|
|
RoomMessageText,
|
|
RoomNameEvent,
|
|
RoomTopicEvent,
|
|
StickerEvent,
|
|
TagEvent,
|
|
ToDeviceEvent,
|
|
TypingNoticeEvent,
|
|
UnknownAccountDataEvent,
|
|
UnknownBadEvent,
|
|
UnknownEncryptedEvent,
|
|
)
|
|
from nio.responses import RoomSummary
|
|
from nio.rooms import MatrixRoom
|
|
|
|
|
|
class TestClass:
|
|
@staticmethod
|
|
def _load_response(filename):
|
|
with open(filename) as f:
|
|
return json.loads(f.read())
|
|
|
|
def test_redacted_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/redacted.json")
|
|
response = RedactedEvent.from_dict(parsed_dict)
|
|
assert isinstance(response, RedactedEvent)
|
|
|
|
def test_malformed_event(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/redacted_invalid.json"
|
|
)
|
|
response = RedactedEvent.from_dict(parsed_dict)
|
|
assert isinstance(response, BadEvent)
|
|
|
|
def test_create_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/create.json")
|
|
event = RoomCreateEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomCreateEvent)
|
|
|
|
def test_guest_access_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/guest_access.json")
|
|
event = RoomGuestAccessEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomGuestAccessEvent)
|
|
|
|
def test_join_rules_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/join_rules.json")
|
|
event = RoomJoinRulesEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomJoinRulesEvent)
|
|
|
|
def test_history_visibility_event(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/history_visibility.json"
|
|
)
|
|
event = RoomHistoryVisibilityEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomHistoryVisibilityEvent)
|
|
|
|
def test_topic_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/topic.json")
|
|
event = RoomTopicEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomTopicEvent)
|
|
|
|
def test_room_avatar_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/room_avatar.json")
|
|
event = RoomAvatarEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomAvatarEvent)
|
|
|
|
def test_room_avatar_event_no_url(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/room_avatar.json")
|
|
parsed_dict["content"].pop("url")
|
|
event = RoomAvatarEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, BadEvent)
|
|
|
|
def test_tag_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/tag.json")
|
|
event = AccountDataEvent.parse_event(parsed_dict)
|
|
assert isinstance(event, TagEvent)
|
|
|
|
def test_name_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/name.json")
|
|
event = RoomNameEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomNameEvent)
|
|
|
|
def test_alias_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/alias.json")
|
|
event = RoomAliasEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomAliasEvent)
|
|
|
|
def test_message_text(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/message_text.json")
|
|
event = RoomMessageText.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomMessageText)
|
|
|
|
def test_message_emote(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/message_emote.json")
|
|
event = RoomMessageEmote.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomMessageEmote)
|
|
|
|
def test_message_notice(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/message_notice.json")
|
|
event = RoomMessageNotice.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomMessageNotice)
|
|
|
|
def test_power_levels(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/power_levels.json")
|
|
event = PowerLevelsEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, PowerLevelsEvent)
|
|
|
|
levels = event.power_levels
|
|
admin = "@example:localhost"
|
|
mod = "@alice:localhost"
|
|
higher_user = "@carol:localhost"
|
|
user = "@bob:localhost"
|
|
|
|
assert levels.get_state_event_required_level("m.room.name") == 50
|
|
assert levels.get_state_event_required_level("m.room.undefined") == 50
|
|
assert levels.get_message_event_required_level("m.room.message") == 25
|
|
assert levels.get_message_event_required_level("m.room.undefined") == 0
|
|
assert levels.get_notification_required_level("room") == 60
|
|
assert levels.get_notification_required_level("non_existant") == 50
|
|
|
|
assert levels.get_user_level(admin) == 100
|
|
assert levels.get_user_level(user) == 0
|
|
|
|
assert levels.can_user_send_state(admin, "m.room.name") is True
|
|
assert levels.can_user_send_state(user, "m.room.name") is False
|
|
assert levels.can_user_send_message(admin) is True
|
|
assert levels.can_user_send_message(user, "m.room.message") is False
|
|
|
|
assert levels.can_user_invite(admin) is True
|
|
assert levels.can_user_invite(user) is True
|
|
|
|
assert levels.can_user_kick(admin) is True
|
|
assert levels.can_user_kick(user) is False
|
|
assert levels.can_user_kick(admin, admin) is False
|
|
assert levels.can_user_kick(admin, mod) is True
|
|
assert levels.can_user_kick(mod, admin) is False
|
|
assert levels.can_user_kick(mod, higher_user) is True
|
|
assert levels.can_user_kick(higher_user, user) is False
|
|
|
|
assert levels.can_user_ban(admin) is True
|
|
assert levels.can_user_ban(user) is False
|
|
assert levels.can_user_ban(admin, admin) is False
|
|
assert levels.can_user_ban(admin, mod) is True
|
|
assert levels.can_user_ban(mod, admin) is False
|
|
assert levels.can_user_ban(mod, higher_user) is True
|
|
assert levels.can_user_ban(higher_user, user) is False
|
|
|
|
assert levels.can_user_redact(admin) is True
|
|
assert levels.can_user_redact(user) is False
|
|
|
|
assert levels.can_user_notify(admin, "room") is True
|
|
assert levels.can_user_notify(mod, "room") is False
|
|
|
|
def test_membership(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/member.json")
|
|
event = RoomMemberEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RoomMemberEvent)
|
|
|
|
def test_redaction(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/redaction.json")
|
|
event = RedactionEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, RedactionEvent)
|
|
|
|
def test_sticker(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/sticker.json")
|
|
event = StickerEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, StickerEvent)
|
|
|
|
def test_empty_event(self):
|
|
parsed_dict = {}
|
|
response = RedactedEvent.from_dict(parsed_dict)
|
|
assert isinstance(response, UnknownBadEvent)
|
|
|
|
def test_room_encryption(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/room_encryption.json")
|
|
event = Event.parse_event(parsed_dict)
|
|
assert isinstance(event, RoomEncryptionEvent)
|
|
|
|
def test_room_key(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/room_key.json")
|
|
event = RoomKeyEvent.from_dict(parsed_dict, "@alice:example.org", "alice_key")
|
|
assert isinstance(event, RoomKeyEvent)
|
|
|
|
def test_forwarded_room_key(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/forwarded_room_key.json"
|
|
)
|
|
event = ForwardedRoomKeyEvent.from_dict(
|
|
parsed_dict, "@alice:example.org", "alice_key"
|
|
)
|
|
assert isinstance(event, ForwardedRoomKeyEvent)
|
|
|
|
def test_invalid_state_event(self):
|
|
for event_type, event_file in [
|
|
("m.room.create", "create.json"),
|
|
("m.room.guest_access", "guest_access.json"),
|
|
("m.room.join_rules", "join_rules.json"),
|
|
("m.room.history_visibility", "history_visibility.json"),
|
|
("m.room.member", "member.json"),
|
|
("m.room.canonical_alias", "alias.json"),
|
|
("m.room.name", "name.json"),
|
|
("m.room.topic", "topic.json"),
|
|
("m.room.avatar", "room_avatar.json"),
|
|
("m.room.power_levels", "power_levels.json"),
|
|
("m.room.encryption", "room_encryption.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
parsed_dict.pop("state_key")
|
|
|
|
event = Event.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, BadEvent)
|
|
assert event.source["type"] == event_type
|
|
|
|
def test_invalid_invite_state_events(self):
|
|
for event_type, event_file in [
|
|
("m.room.member", "member.json"),
|
|
("m.room.canonical_alias", "alias.json"),
|
|
("m.room.name", "name.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
parsed_dict.pop("state_key")
|
|
|
|
event = InviteEvent.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, BadEvent)
|
|
assert event.source["type"] == event_type
|
|
|
|
for event_type, event_file in [
|
|
("m.room.member", "member.json"),
|
|
("m.room.canonical_alias", "alias.json"),
|
|
("m.room.name", "name.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
parsed_dict.pop("type")
|
|
|
|
event = InviteEvent.parse_event(parsed_dict)
|
|
assert not event
|
|
|
|
def test_invite_events(self):
|
|
for event_type, event_file in [
|
|
(InviteMemberEvent, "member.json"),
|
|
(InviteAliasEvent, "alias.json"),
|
|
(InviteNameEvent, "name.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
event = InviteEvent.parse_event(parsed_dict)
|
|
assert isinstance(event, event_type)
|
|
|
|
def test_megolm_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/megolm.json")
|
|
event = Event.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, MegolmEvent)
|
|
|
|
parsed_dict["content"]["algorithm"] = "m.megolm.unknown"
|
|
event = Event.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, UnknownEncryptedEvent)
|
|
|
|
def test_olm_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/olm.json")
|
|
event = ToDeviceEvent.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, OlmEvent)
|
|
|
|
parsed_dict["content"]["algorithm"] = "m.megolm.unknown"
|
|
event = ToDeviceEvent.parse_event(parsed_dict)
|
|
|
|
assert not event
|
|
|
|
def test_ephemeral_event(self):
|
|
event = EphemeralEvent.parse_event({})
|
|
|
|
assert not event
|
|
|
|
event = EphemeralEvent.parse_event({"type": "m.unknown", "content": {}})
|
|
|
|
assert not event
|
|
|
|
def test_typing_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/typing.json")
|
|
event = EphemeralEvent.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, TypingNoticeEvent)
|
|
|
|
assert "@bob:example.com" in event.users
|
|
|
|
def test_read_receipt_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/receipt.json")
|
|
event = EphemeralEvent.parse_event(parsed_dict)
|
|
|
|
# Warning: this is directly tied to the above file; any changes below
|
|
# need to be reflected there too.
|
|
receipt = Receipt(
|
|
"$152037280074GZeOm:localhost", "m.read", "@bob:example.com", 1520372804619
|
|
)
|
|
|
|
assert isinstance(event, ReceiptEvent)
|
|
assert receipt in event.receipts
|
|
|
|
def test_read_receipt_event_bad_ts(self):
|
|
"""Test reading an m_receipt event that has malformed data for one user.
|
|
|
|
@alice:example.com is a user using Synapse pre 0.99.3 with a
|
|
timestamp bug. We want to ignore her malformed value without losing
|
|
the receipt data from @bob:example.com
|
|
"""
|
|
parsed_dict = TestClass._load_response("tests/data/events/receipt_invalid.json")
|
|
event = EphemeralEvent.parse_event(parsed_dict)
|
|
|
|
# Warning: this is directly tied to the above file; any changes below
|
|
# need to be reflected there too.
|
|
receipt = Receipt(
|
|
"$152037280074GZeOm:localhost", "m.read", "@bob:example.com", 1520372804619
|
|
)
|
|
|
|
assert isinstance(event, ReceiptEvent)
|
|
assert receipt in event.receipts
|
|
|
|
def test_account_data_event(self):
|
|
event = AccountDataEvent.parse_event({})
|
|
|
|
assert isinstance(event, UnknownBadEvent)
|
|
|
|
event = AccountDataEvent.parse_event({"type": "m.unknown", "content": {}})
|
|
|
|
assert isinstance(event, UnknownAccountDataEvent)
|
|
|
|
def test_fully_read_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/fully_read.json")
|
|
event = AccountDataEvent.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, FullyReadEvent)
|
|
|
|
def test_invalid_call_events(self):
|
|
for _, event_file in [
|
|
(CallInviteEvent, "call_invite.json"),
|
|
(CallAnswerEvent, "call_answer.json"),
|
|
(CallCandidatesEvent, "call_candidates.json"),
|
|
(CallHangupEvent, "call_hangup.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
parsed_dict["content"].pop("call_id")
|
|
event = CallEvent.parse_event(parsed_dict)
|
|
assert isinstance(event, BadEvent)
|
|
|
|
def test_call_events(self):
|
|
for event_type, event_file in [
|
|
(CallInviteEvent, "call_invite.json"),
|
|
(CallAnswerEvent, "call_answer.json"),
|
|
(CallCandidatesEvent, "call_candidates.json"),
|
|
(CallHangupEvent, "call_hangup.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
event = CallEvent.parse_event(parsed_dict)
|
|
assert isinstance(event, event_type)
|
|
|
|
def test_key_verification_events(self):
|
|
for event_type, event_file in [
|
|
(KeyVerificationStart, "key_start.json"),
|
|
(KeyVerificationAccept, "key_accept.json"),
|
|
(KeyVerificationKey, "key_key.json"),
|
|
(KeyVerificationMac, "key_mac.json"),
|
|
(KeyVerificationCancel, "key_cancel.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
event = ToDeviceEvent.parse_event(parsed_dict)
|
|
assert isinstance(event, event_type)
|
|
|
|
def test_invalid_key_verification(self):
|
|
for _, event_file in [
|
|
(KeyVerificationStart, "key_start.json"),
|
|
(KeyVerificationAccept, "key_accept.json"),
|
|
(KeyVerificationKey, "key_key.json"),
|
|
(KeyVerificationMac, "key_mac.json"),
|
|
(KeyVerificationCancel, "key_cancel.json"),
|
|
]:
|
|
parsed_dict = TestClass._load_response(f"tests/data/events/{event_file}")
|
|
parsed_dict["content"].pop("transaction_id")
|
|
event = ToDeviceEvent.parse_event(parsed_dict)
|
|
assert isinstance(event, UnknownBadEvent)
|
|
|
|
def test_invalid_room_event(self):
|
|
event = Event.parse_event({"type": "m.unknown"})
|
|
|
|
assert isinstance(event, UnknownBadEvent)
|
|
|
|
def test_redacted_state_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/redacted_state.json")
|
|
event = Event.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, RedactedEvent)
|
|
|
|
def test_dummy_event(self):
|
|
parsed_dict = TestClass._load_response("tests/data/events/dummy.json")
|
|
event = DummyEvent.from_dict(parsed_dict, "@alice:example.org", "alice_key")
|
|
|
|
assert isinstance(event, DummyEvent)
|
|
|
|
def test_room_key_request(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/room_key_request.json"
|
|
)
|
|
event = ToDeviceEvent.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, RoomKeyRequest)
|
|
assert event.room_id is not None
|
|
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/room_key_request_cancel.json"
|
|
)
|
|
event = ToDeviceEvent.parse_event(parsed_dict)
|
|
|
|
assert isinstance(event, RoomKeyRequestCancellation)
|
|
|
|
def test_encrypted_media_thumbnails(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/room_encrypted_image.json"
|
|
)
|
|
|
|
event = Event.parse_decrypted_event(parsed_dict)
|
|
|
|
assert isinstance(event, RoomEncryptedImage)
|
|
assert event.thumbnail_url
|
|
assert event.thumbnail_key
|
|
assert event.thumbnail_hashes
|
|
assert event.thumbnail_iv
|
|
assert event.mimetype
|
|
|
|
def test_event_flattening(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/to_flatten.json",
|
|
)
|
|
|
|
event = Event.from_dict(parsed_dict)
|
|
assert event.flattened() == {
|
|
"content.body": "foo",
|
|
"content.m.dotted.key": "bar",
|
|
"event_id": "!test:example.org",
|
|
"origin_server_ts": 0,
|
|
"sender": "@alice:example.org",
|
|
"type": "m.flatten_test",
|
|
}
|
|
|
|
def test_pushrules_parsing(self):
|
|
parsed_dict = TestClass._load_response(
|
|
"tests/data/events/push_rules.json",
|
|
)
|
|
parsed_rule = parsed_dict["content"]["global"]["override"][0]
|
|
|
|
event = PushRulesEvent.from_dict(parsed_dict)
|
|
assert isinstance(event, PushRulesEvent)
|
|
assert bool(event) is True
|
|
rule = event.global_rules.override[0]
|
|
|
|
for i, action in enumerate(rule.actions):
|
|
assert action.as_value == parsed_rule["actions"][i]
|
|
|
|
for i, condition in enumerate(rule.conditions):
|
|
assert condition.as_value == parsed_rule["conditions"][i]
|
|
|
|
def test_pushrules_matching(self):
|
|
room = MatrixRoom("!test:example.org", "@alice:example.com")
|
|
name = "Alice"
|
|
|
|
event = Event.from_dict(
|
|
{
|
|
"event_id": "!test:example.org",
|
|
"room_id": room.room_id,
|
|
"origin_server_ts": 0,
|
|
"sender": "@alice:example.org",
|
|
"type": "m.test",
|
|
"words": "foo bar",
|
|
"int": 0,
|
|
"content": {"body": "a,here c"},
|
|
}
|
|
)
|
|
|
|
args = (event, room, name)
|
|
|
|
# PushEventMatch
|
|
|
|
must_succeed = [
|
|
("type", "m.test"),
|
|
("type", "M*T"), # glob + ignoring case
|
|
("content.body", "heRe"), # word boundaries + ignoring case
|
|
("content.body", "a"), # word at the start of the string
|
|
("content.body", "c"), # word at the end of the string
|
|
("content.body", "[a-z]*c"), # more glob patterns
|
|
]
|
|
|
|
must_fail = [
|
|
("int", "0"), # only match string values
|
|
("words", "foo"), # match words only for content.body
|
|
("content.body", "her"), # not a full word match
|
|
]
|
|
|
|
for key, pattern in must_succeed:
|
|
assert PushEventMatch(key, pattern).matches(*args)
|
|
|
|
for key, pattern in must_fail:
|
|
assert not PushEventMatch(key, pattern).matches(*args)
|
|
|
|
# PushContainsDisplayName
|
|
|
|
assert not PushContainsDisplayName().matches(*args)
|
|
|
|
del event.source["content"]["body"]
|
|
assert not PushContainsDisplayName().matches(*args)
|
|
|
|
event.source["content"]["body"] = "alice!"
|
|
assert PushContainsDisplayName().matches(*args)
|
|
|
|
# PushRoomMemberCount
|
|
|
|
room.summary = RoomSummary(100, 5) # invited members don't matter
|
|
tests = [(5, "=="), (6, "<"), (4, ">"), (5, "<="), (4, ">=")]
|
|
|
|
for count, operator in tests:
|
|
assert PushRoomMemberCount(count, operator).matches(*args)
|
|
|
|
# PushSenderNotificationPermission
|
|
|
|
assert not PushSenderNotificationPermission("room").matches(*args)
|
|
|
|
room.power_levels.users[event.sender] = 50
|
|
assert PushSenderNotificationPermission("room").matches(*args)
|
|
|
|
# PushUnknownCondition
|
|
|
|
assert not PushUnknownCondition({}).matches(*args)
|
|
|
|
# PushRule
|
|
|
|
rule = PushRule(PushRuleKind.override, "all", False)
|
|
assert rule.matches(*args)
|
|
rule.enabled = False
|
|
assert not rule.matches(*args)
|
|
|
|
cnds = [PushEventMatch("type", "m.test")]
|
|
rule = PushRule(PushRuleKind.override, "test", False, conditions=cnds)
|
|
assert rule.matches(*args)
|
|
cnds.append(PushUnknownCondition({}))
|
|
assert not rule.matches(*args)
|
|
|
|
rule = PushRule(PushRuleKind.room, room.room_id, False)
|
|
assert rule.matches(*args)
|
|
rule.id += "blah"
|
|
assert not rule.matches(*args)
|
|
|
|
rule = PushRule(PushRuleKind.sender, event.sender, False)
|
|
assert rule.matches(*args)
|
|
rule.id += "blah"
|
|
assert not rule.matches(*args)
|
|
|
|
event.source["content"]["body"] = "a here! b c"
|
|
rule = PushRule(PushRuleKind.content, "here", False, pattern="here")
|
|
assert rule.matches(*args)
|
|
rule.pattern = "her"
|
|
assert not rule.matches(*args)
|
|
|
|
# PushRuleset
|
|
|
|
ruleset = PushRuleset(
|
|
room=[
|
|
PushRule(PushRuleKind.room, "blah", False),
|
|
PushRule(PushRuleKind.room, room.room_id, False),
|
|
],
|
|
sender=[PushRule(PushRuleKind.sender, event.sender, False)],
|
|
)
|
|
assert ruleset.matching_rule(*args) is ruleset.room[1]
|
|
|
|
del ruleset.room[1]
|
|
del ruleset.sender[0]
|
|
assert ruleset.matching_rule(*args) is None
|