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