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