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