idle.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 minidom::Element;
 10use date::DateTime;
 11
 12use error::Error;
 13
 14use ns;
 15
 16generate_element_with_only_attributes!(Idle, "idle", ns::IDLE, [
 17    since: DateTime = "since" => required,
 18]);
 19
 20#[cfg(test)]
 21mod tests {
 22    use super::*;
 23    use std::str::FromStr;
 24    use std::error::Error as StdError;
 25
 26    #[test]
 27    fn test_simple() {
 28        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-21T20:19:55+01:00'/>".parse().unwrap();
 29        Idle::try_from(elem).unwrap();
 30    }
 31
 32    #[test]
 33    fn test_invalid_child() {
 34        let elem: Element = "<idle xmlns='urn:xmpp:idle:1'><coucou/></idle>".parse().unwrap();
 35        let error = Idle::try_from(elem).unwrap_err();
 36        let message = match error {
 37            Error::ParseError(string) => string,
 38            _ => panic!(),
 39        };
 40        assert_eq!(message, "Unknown child in idle element.");
 41    }
 42
 43    #[test]
 44    fn test_invalid_id() {
 45        let elem: Element = "<idle xmlns='urn:xmpp:idle:1'/>".parse().unwrap();
 46        let error = Idle::try_from(elem).unwrap_err();
 47        let message = match error {
 48            Error::ParseError(string) => string,
 49            _ => panic!(),
 50        };
 51        assert_eq!(message, "Required attribute 'since' missing.");
 52    }
 53
 54    #[test]
 55    fn test_invalid_date() {
 56        // There is no thirteenth month.
 57        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-13-01T12:23:34Z'/>".parse().unwrap();
 58        let error = Idle::try_from(elem).unwrap_err();
 59        let message = match error {
 60            Error::ChronoParseError(string) => string,
 61            _ => panic!(),
 62        };
 63        assert_eq!(message.description(), "input is out of range");
 64
 65        // Timezone ≥24:00 aren’t allowed.
 66        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11:02+25:00'/>".parse().unwrap();
 67        let error = Idle::try_from(elem).unwrap_err();
 68        let message = match error {
 69            Error::ChronoParseError(string) => string,
 70            _ => panic!(),
 71        };
 72        assert_eq!(message.description(), "input is out of range");
 73
 74        // Timezone without the : separator aren’t allowed.
 75        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11:02+0100'/>".parse().unwrap();
 76        let error = Idle::try_from(elem).unwrap_err();
 77        let message = match error {
 78            Error::ChronoParseError(string) => string,
 79            _ => panic!(),
 80        };
 81        assert_eq!(message.description(), "input contains invalid characters");
 82
 83        // No seconds, error message could be improved.
 84        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11+01:00'/>".parse().unwrap();
 85        let error = Idle::try_from(elem).unwrap_err();
 86        let message = match error {
 87            Error::ChronoParseError(string) => string,
 88            _ => panic!(),
 89        };
 90        assert_eq!(message.description(), "input contains invalid characters");
 91
 92        // TODO: maybe we’ll want to support this one, as per XEP-0082 §4.
 93        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='20170527T12:11:02+01:00'/>".parse().unwrap();
 94        let error = Idle::try_from(elem).unwrap_err();
 95        let message = match error {
 96            Error::ChronoParseError(string) => string,
 97            _ => panic!(),
 98        };
 99        assert_eq!(message.description(), "input contains invalid characters");
100
101        // No timezone.
102        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-27T12:11:02'/>".parse().unwrap();
103        let error = Idle::try_from(elem).unwrap_err();
104        let message = match error {
105            Error::ChronoParseError(string) => string,
106            _ => panic!(),
107        };
108        assert_eq!(message.description(), "premature end of input");
109    }
110
111    #[test]
112    fn test_serialise() {
113        let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-21T20:19:55+01:00'/>".parse().unwrap();
114        let idle = Idle { since: DateTime::from_str("2017-05-21T20:19:55+01:00").unwrap() };
115        let elem2 = idle.into();
116        assert_eq!(elem, elem2);
117    }
118}