blocking.rs

  1// Copyright (c) 2017 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  2//
  3// This Source Code Form is subject to the terms of the Mozilla Public
  4// License, v. 2.0. If a copy of the MPL was not distributed with this
  5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6
  7use try_from::TryFrom;
  8
  9use jid::Jid;
 10use minidom::Element;
 11
 12use error::Error;
 13
 14use ns;
 15
 16generate_empty_element!(BlocklistRequest, "blocklist", BLOCKING);
 17
 18macro_rules! generate_blocking_element {
 19    ($elem:ident, $name:tt) => (
 20        #[derive(Debug, Clone)]
 21        pub struct $elem {
 22            pub items: Vec<Jid>,
 23        }
 24
 25        impl TryFrom<Element> for $elem {
 26            type Err = Error;
 27
 28            fn try_from(elem: Element) -> Result<$elem, Error> {
 29                check_self!(elem, $name, BLOCKING);
 30                check_no_attributes!(elem, $name);
 31                let mut items = vec!();
 32                for child in elem.children() {
 33                    check_self!(child, "item", BLOCKING);
 34                    check_no_unknown_attributes!(child, "item", ["jid"]);
 35                    check_no_children!(child, "item");
 36                    items.push(get_attr!(child, "jid", required));
 37                }
 38                Ok($elem { items })
 39            }
 40        }
 41
 42        impl From<$elem> for Element {
 43            fn from(elem: $elem) -> Element {
 44                Element::builder($name)
 45                        .ns(ns::BLOCKING)
 46                        .append(elem.items.into_iter().map(|jid| {
 47                             Element::builder("item")
 48                                     .ns(ns::BLOCKING)
 49                                     .attr("jid", jid)
 50                                     .build()
 51                         }).collect::<Vec<_>>())
 52                        .build()
 53            }
 54        }
 55    );
 56}
 57
 58generate_blocking_element!(BlocklistResult, "blocklist");
 59generate_blocking_element!(Block, "block");
 60generate_blocking_element!(Unblock, "unblock");
 61
 62generate_empty_element!(Blocked, "blocked", BLOCKING_ERRORS);
 63
 64#[cfg(test)]
 65mod tests {
 66    use super::*;
 67
 68    #[test]
 69    fn test_simple() {
 70        let elem: Element = "<blocklist xmlns='urn:xmpp:blocking'/>".parse().unwrap();
 71        let request_elem = elem.clone();
 72        BlocklistRequest::try_from(request_elem).unwrap();
 73
 74        let result_elem = elem.clone();
 75        let result = BlocklistResult::try_from(result_elem).unwrap();
 76        assert_eq!(result.items, vec!());
 77
 78        let elem: Element = "<block xmlns='urn:xmpp:blocking'/>".parse().unwrap();
 79        let block = Block::try_from(elem).unwrap();
 80        assert_eq!(block.items, vec!());
 81
 82        let elem: Element = "<unblock xmlns='urn:xmpp:blocking'/>".parse().unwrap();
 83        let unblock = Unblock::try_from(elem).unwrap();
 84        assert_eq!(unblock.items, vec!());
 85    }
 86
 87    #[test]
 88    fn test_items() {
 89        let elem: Element = "<blocklist xmlns='urn:xmpp:blocking'><item jid='coucou@coucou'/><item jid='domain'/></blocklist>".parse().unwrap();
 90        let two_items = vec!(
 91            Jid {
 92                node: Some(String::from("coucou")),
 93                domain: String::from("coucou"),
 94                resource: None,
 95            },
 96            Jid {
 97                node: None,
 98                domain: String::from("domain"),
 99                resource: None,
100            },
101        );
102
103        let request_elem = elem.clone();
104        let error = BlocklistRequest::try_from(request_elem).unwrap_err();
105        let message = match error {
106            Error::ParseError(string) => string,
107            _ => panic!(),
108        };
109        assert_eq!(message, "Unknown child in blocklist element.");
110
111        let result_elem = elem.clone();
112        let result = BlocklistResult::try_from(result_elem).unwrap();
113        assert_eq!(result.items, two_items);
114
115        let elem: Element = "<block xmlns='urn:xmpp:blocking'><item jid='coucou@coucou'/><item jid='domain'/></block>".parse().unwrap();
116        let block = Block::try_from(elem).unwrap();
117        assert_eq!(block.items, two_items);
118
119        let elem: Element = "<unblock xmlns='urn:xmpp:blocking'><item jid='coucou@coucou'/><item jid='domain'/></unblock>".parse().unwrap();
120        let unblock = Unblock::try_from(elem).unwrap();
121        assert_eq!(unblock.items, two_items);
122    }
123
124    #[test]
125    fn test_invalid() {
126        let elem: Element = "<blocklist xmlns='urn:xmpp:blocking' coucou=''/>".parse().unwrap();
127        let request_elem = elem.clone();
128        let error = BlocklistRequest::try_from(request_elem).unwrap_err();
129        let message = match error {
130            Error::ParseError(string) => string,
131            _ => panic!(),
132        };
133        assert_eq!(message, "Unknown attribute in blocklist element.");
134
135        let result_elem = elem.clone();
136        let error = BlocklistResult::try_from(result_elem).unwrap_err();
137        let message = match error {
138            Error::ParseError(string) => string,
139            _ => panic!(),
140        };
141        assert_eq!(message, "Unknown attribute in blocklist element.");
142
143        let elem: Element = "<block xmlns='urn:xmpp:blocking' coucou=''/>".parse().unwrap();
144        let error = Block::try_from(elem).unwrap_err();
145        let message = match error {
146            Error::ParseError(string) => string,
147            _ => panic!(),
148        };
149        assert_eq!(message, "Unknown attribute in block element.");
150
151        let elem: Element = "<unblock xmlns='urn:xmpp:blocking' coucou=''/>".parse().unwrap();
152        let error = Unblock::try_from(elem).unwrap_err();
153        let message = match error {
154            Error::ParseError(string) => string,
155            _ => panic!(),
156        };
157        assert_eq!(message, "Unknown attribute in unblock element.");
158    }
159}