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