xmpp_parsers/
bookmarks2.rs1use xso::{AsXml, FromXml};
16
17use crate::jid::ResourcePart;
18use crate::ns;
19use minidom::Element;
20
21#[derive(FromXml, AsXml, Debug, Clone, Default)]
23#[xml(namespace = ns::BOOKMARKS2, name = "extensions")]
24pub struct Extensions {
25 #[xml(element(n = ..))]
27 pub payloads: Vec<Element>,
28}
29
30#[derive(FromXml, AsXml, Debug, Clone, Default)]
32#[xml(namespace = ns::BOOKMARKS2, name = "conference")]
33pub struct Conference {
34 #[xml(attribute(default))]
36 pub autojoin: bool,
37
38 #[xml(attribute(default))]
40 pub name: Option<String>,
41
42 #[xml(extract(default, fields(text(type_ = ResourcePart))))]
44 pub nick: Option<ResourcePart>,
45
46 #[xml(extract(default, fields(text(type_ = String))))]
48 pub password: Option<String>,
49
50 #[xml(child(default))]
52 pub extensions: Option<Extensions>,
53}
54
55impl Conference {
56 pub fn new() -> Conference {
58 Conference::default()
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use crate::pubsub::{self, pubsub::Item as PubSubItem};
66
67 #[cfg(target_pointer_width = "32")]
68 #[test]
69 fn test_size() {
70 assert_size!(Conference, 52);
71 }
72
73 #[cfg(target_pointer_width = "64")]
74 #[test]
75 fn test_size() {
76 assert_size!(Conference, 104);
77 }
78
79 #[test]
80 fn simple() {
81 let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:1' autojoin='false'/>"
82 .parse()
83 .unwrap();
84 let elem1 = elem.clone();
85 let conference = Conference::try_from(elem).unwrap();
86 assert_eq!(conference.autojoin, false);
87 assert_eq!(conference.name, None);
88 assert_eq!(conference.nick, None);
89 assert_eq!(conference.password, None);
90
91 let elem2 = Element::from(Conference::new());
92 assert_eq!(elem1, elem2);
93 }
94
95 #[test]
96 fn wrong_resource() {
97 let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:1' autojoin='true'><nick>Whatever\u{1F469}\u{1F3FE}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F469}\u{1F3FC}</nick></conference>".parse().unwrap();
99 let res = Conference::try_from(elem);
100 assert!(res.is_err());
101 assert_eq!(
102 res.unwrap_err().to_string().as_str(),
103 "text parse error: resource doesn’t pass resourceprep validation"
104 );
105 }
106
107 #[test]
108 fn complete() {
109 let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password><extensions><test xmlns='urn:xmpp:unknown' /></extensions></conference>".parse().unwrap();
110 let conference = Conference::try_from(elem).unwrap();
111 assert_eq!(conference.autojoin, true);
112 assert_eq!(conference.name, Some(String::from("Test MUC")));
113 assert_eq!(conference.clone().nick.unwrap().as_str(), "Coucou");
114 assert_eq!(conference.clone().password.unwrap(), "secret");
115 let payloads = conference.clone().extensions.unwrap().payloads;
116 assert_eq!(payloads.len(), 1);
117 assert!(payloads[0].is("test", "urn:xmpp:unknown"));
118 }
119
120 #[test]
121 fn wrapped() {
122 let elem: Element = "<item xmlns='http://jabber.org/protocol/pubsub' id='test-muc@muc.localhost'><conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password></conference></item>".parse().unwrap();
123 let item = PubSubItem::try_from(elem).unwrap();
124 let payload = item.payload.clone().unwrap();
125 println!("FOO: payload: {:?}", payload);
126 let conference = Conference::try_from(payload).unwrap();
128 println!("FOO: conference: {:?}", conference);
129 assert_eq!(conference.autojoin, true);
130 assert_eq!(conference.name, Some(String::from("Test MUC")));
131 assert_eq!(conference.clone().nick.unwrap().as_str(), "Coucou");
132 assert_eq!(conference.clone().password.unwrap(), "secret");
133
134 let elem: Element = "<event xmlns='http://jabber.org/protocol/pubsub#event'><items node='urn:xmpp:bookmarks:1'><item xmlns='http://jabber.org/protocol/pubsub#event' id='test-muc@muc.localhost'><conference xmlns='urn:xmpp:bookmarks:1' autojoin='true' name='Test MUC'><nick>Coucou</nick><password>secret</password></conference></item></items></event>".parse().unwrap();
135 let event = pubsub::Event::try_from(elem).unwrap();
136 let mut items = match event.payload {
137 pubsub::event::Payload::Items {
138 node,
139 published,
140 retracted,
141 } => {
142 assert_eq!(&node.0, ns::BOOKMARKS2);
143 assert_eq!(retracted.len(), 0);
144 published
145 }
146 _ => panic!(),
147 };
148 assert_eq!(items.len(), 1);
149 let item = items.pop().unwrap();
150 let payload = item.payload.clone().unwrap();
151 let conference = Conference::try_from(payload).unwrap();
152 assert_eq!(conference.autojoin, true);
153 assert_eq!(conference.name, Some(String::from("Test MUC")));
154 assert_eq!(conference.clone().nick.unwrap().as_str(), "Coucou");
155 assert_eq!(conference.clone().password.unwrap(), "secret");
156 }
157}