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