ruwuma/ruma-common/src/push/condition.rs
2020-09-03 20:55:11 +02:00

155 lines
4.7 KiB
Rust

use serde::{Deserialize, Serialize};
mod room_member_count_is;
pub use room_member_count_is::{ComparisonOperator, RoomMemberCountIs};
/// A condition that must apply for an associated push rule's action to be taken.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum PushCondition {
/// This is a glob pattern match on a field of the event.
EventMatch {
/// The dot-separated field of the event to match.
key: String,
/// The glob-style pattern to match against.
///
/// Patterns with no special glob characters should be treated as having asterisks prepended
/// and appended when testing the condition.
pattern: String,
},
/// This matches unencrypted messages where `content.body` contains the owner's display name in
/// that room.
ContainsDisplayName,
/// This matches the current number of members in the room.
RoomMemberCount {
/// The condition on the current number of members in the room.
is: RoomMemberCountIs,
},
/// This takes into account the current power levels in the room, ensuring the sender of the
/// event has high enough power to trigger the notification.
SenderNotificationPermission {
/// The field in the power level event the user needs a minimum power level for.
///
/// Fields must be specified under the `notifications` property in the power level event's
/// `content`.
key: String,
},
}
#[cfg(test)]
mod tests {
use js_int::uint;
use matches::assert_matches;
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
use super::{PushCondition, RoomMemberCountIs};
#[test]
fn serialize_event_match_condition() {
let json_data = json!({
"key": "content.msgtype",
"kind": "event_match",
"pattern": "m.notice"
});
assert_eq!(
to_json_value(&PushCondition::EventMatch {
key: "content.msgtype".into(),
pattern: "m.notice".into(),
})
.unwrap(),
json_data
);
}
#[test]
fn serialize_contains_display_name_condition() {
assert_eq!(
to_json_value(&PushCondition::ContainsDisplayName).unwrap(),
json!({ "kind": "contains_display_name" })
);
}
#[test]
fn serialize_room_member_count_condition() {
let json_data = json!({
"is": "2",
"kind": "room_member_count"
});
assert_eq!(
to_json_value(&PushCondition::RoomMemberCount {
is: RoomMemberCountIs::from(uint!(2))
})
.unwrap(),
json_data
);
}
#[test]
fn serialize_sender_notification_permission_condition() {
let json_data = json!({
"key": "room",
"kind": "sender_notification_permission"
});
assert_eq!(
json_data,
to_json_value(&PushCondition::SenderNotificationPermission { key: "room".into() })
.unwrap()
);
}
#[test]
fn deserialize_event_match_condition() {
let json_data = json!({
"key": "content.msgtype",
"kind": "event_match",
"pattern": "m.notice"
});
assert_matches!(
from_json_value::<PushCondition>(json_data).unwrap(),
PushCondition::EventMatch { key, pattern }
if key == "content.msgtype" && pattern == "m.notice"
);
}
#[test]
fn deserialize_contains_display_name_condition() {
assert_matches!(
from_json_value::<PushCondition>(json!({ "kind": "contains_display_name" })).unwrap(),
PushCondition::ContainsDisplayName
);
}
#[test]
fn deserialize_room_member_count_condition() {
let json_data = json!({
"is": "2",
"kind": "room_member_count"
});
assert_matches!(
from_json_value::<PushCondition>(json_data).unwrap(),
PushCondition::RoomMemberCount { is }
if is == RoomMemberCountIs::from(uint!(2))
);
}
#[test]
fn deserialize_sender_notification_permission_condition() {
let json_data = json!({
"key": "room",
"kind": "sender_notification_permission"
});
assert_matches!(
from_json_value::<PushCondition>(json_data).unwrap(),
PushCondition::SenderNotificationPermission {
key
} if key == "room"
);
}
}