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}