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