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 helpers::TrimmedPlainText;
8
9generate_element_with_text!(URI, "uri", MEDIA_ELEMENT,
10 [
11 type_: String = "type" => required
12 ],
13 uri: TrimmedPlainText<String>
14);
15
16generate_element!(MediaElement, "media", MEDIA_ELEMENT,
17 attributes: [
18 width: Option<usize> = "width" => optional,
19 height: Option<usize> = "height" => optional
20 ],
21 children: [
22 uris: Vec<URI> = ("uri", MEDIA_ELEMENT) => URI
23 ]
24);
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29 use try_from::TryFrom;
30 use minidom::Element;
31 use error::Error;
32 use data_forms::DataForm;
33 use std::error::Error as StdError;
34
35 #[test]
36 fn test_simple() {
37 let elem: Element = "<media xmlns='urn:xmpp:media-element'/>".parse().unwrap();
38 let media = MediaElement::try_from(elem).unwrap();
39 assert!(media.width.is_none());
40 assert!(media.height.is_none());
41 assert!(media.uris.is_empty());
42 }
43
44 #[test]
45 fn test_width_height() {
46 let elem: Element = "<media xmlns='urn:xmpp:media-element' width='32' height='32'/>".parse().unwrap();
47 let media = MediaElement::try_from(elem).unwrap();
48 assert_eq!(media.width.unwrap(), 32);
49 assert_eq!(media.height.unwrap(), 32);
50 }
51
52 #[test]
53 fn test_uri() {
54 let elem: Element = "<media xmlns='urn:xmpp:media-element'><uri type='text/html'>https://example.org/</uri></media>".parse().unwrap();
55 let media = MediaElement::try_from(elem).unwrap();
56 assert_eq!(media.uris.len(), 1);
57 assert_eq!(media.uris[0].type_, "text/html");
58 assert_eq!(media.uris[0].uri, "https://example.org/");
59 }
60
61 #[test]
62 fn test_invalid_width_height() {
63 let elem: Element = "<media xmlns='urn:xmpp:media-element' width=''/>".parse().unwrap();
64 let error = MediaElement::try_from(elem).unwrap_err();
65 let error = match error {
66 Error::ParseIntError(error) => error,
67 _ => panic!(),
68 };
69 assert_eq!(error.description(), "cannot parse integer from empty string");
70
71 let elem: Element = "<media xmlns='urn:xmpp:media-element' width='coucou'/>".parse().unwrap();
72 let error = MediaElement::try_from(elem).unwrap_err();
73 let error = match error {
74 Error::ParseIntError(error) => error,
75 _ => panic!(),
76 };
77 assert_eq!(error.description(), "invalid digit found in string");
78
79 let elem: Element = "<media xmlns='urn:xmpp:media-element' height=''/>".parse().unwrap();
80 let error = MediaElement::try_from(elem).unwrap_err();
81 let error = match error {
82 Error::ParseIntError(error) => error,
83 _ => panic!(),
84 };
85 assert_eq!(error.description(), "cannot parse integer from empty string");
86
87 let elem: Element = "<media xmlns='urn:xmpp:media-element' height='-10'/>".parse().unwrap();
88 let error = MediaElement::try_from(elem).unwrap_err();
89 let error = match error {
90 Error::ParseIntError(error) => error,
91 _ => panic!(),
92 };
93 assert_eq!(error.description(), "invalid digit found in string");
94 }
95
96 #[test]
97 fn test_unknown_child() {
98 let elem: Element = "<media xmlns='urn:xmpp:media-element'><coucou/></media>".parse().unwrap();
99 let error = MediaElement::try_from(elem).unwrap_err();
100 let message = match error {
101 Error::ParseError(string) => string,
102 _ => panic!(),
103 };
104 assert_eq!(message, "Unknown child in media element.");
105 }
106
107 #[test]
108 fn test_bad_uri() {
109 let elem: Element = "<media xmlns='urn:xmpp:media-element'><uri>https://example.org/</uri></media>".parse().unwrap();
110 let error = MediaElement::try_from(elem).unwrap_err();
111 let message = match error {
112 Error::ParseError(string) => string,
113 _ => panic!(),
114 };
115 assert_eq!(message, "Required attribute 'type' missing.");
116
117 let elem: Element = "<media xmlns='urn:xmpp:media-element'><uri type='text/html'/></media>".parse().unwrap();
118 let error = MediaElement::try_from(elem).unwrap_err();
119 let message = match error {
120 Error::ParseError(string) => string,
121 _ => panic!(),
122 };
123 assert_eq!(message, "URI missing in uri.");
124 }
125
126 #[test]
127 fn test_xep_ex1() {
128 let elem: Element = r#"
129<media xmlns='urn:xmpp:media-element'>
130 <uri type='audio/x-wav'>
131 http://victim.example.com/challenges/speech.wav?F3A6292C
132 </uri>
133 <uri type='audio/ogg; codecs=speex'>
134 cid:sha1+a15a505e360702b79c75a5f67773072ed392f52a@bob.xmpp.org
135 </uri>
136 <uri type='audio/mpeg'>
137 http://victim.example.com/challenges/speech.mp3?F3A6292C
138 </uri>
139</media>"#.parse().unwrap();
140 let media = MediaElement::try_from(elem).unwrap();
141 assert!(media.width.is_none());
142 assert!(media.height.is_none());
143 assert_eq!(media.uris.len(), 3);
144 assert_eq!(media.uris[0].type_, "audio/x-wav");
145 assert_eq!(media.uris[0].uri, "http://victim.example.com/challenges/speech.wav?F3A6292C");
146 assert_eq!(media.uris[1].type_, "audio/ogg; codecs=speex");
147 assert_eq!(media.uris[1].uri, "cid:sha1+a15a505e360702b79c75a5f67773072ed392f52a@bob.xmpp.org");
148 assert_eq!(media.uris[2].type_, "audio/mpeg");
149 assert_eq!(media.uris[2].uri, "http://victim.example.com/challenges/speech.mp3?F3A6292C");
150 }
151
152 #[test]
153 fn test_xep_ex2() {
154 let elem: Element = r#"
155<x xmlns='jabber:x:data' type='form'>
156 [ ... ]
157 <field var='ocr'>
158 <media xmlns='urn:xmpp:media-element'
159 height='80'
160 width='290'>
161 <uri type='image/jpeg'>
162 http://www.victim.com/challenges/ocr.jpeg?F3A6292C
163 </uri>
164 <uri type='image/jpeg'>
165 cid:sha1+f24030b8d91d233bac14777be5ab531ca3b9f102@bob.xmpp.org
166 </uri>
167 </media>
168 </field>
169 [ ... ]
170</x>"#.parse().unwrap();
171 let form = DataForm::try_from(elem).unwrap();
172 assert_eq!(form.fields.len(), 1);
173 assert_eq!(form.fields[0].var, "ocr");
174 assert_eq!(form.fields[0].media[0].width, Some(290));
175 assert_eq!(form.fields[0].media[0].height, Some(80));
176 assert_eq!(form.fields[0].media[0].uris[0].type_, "image/jpeg");
177 assert_eq!(form.fields[0].media[0].uris[0].uri, "http://www.victim.com/challenges/ocr.jpeg?F3A6292C");
178 assert_eq!(form.fields[0].media[0].uris[1].type_, "image/jpeg");
179 assert_eq!(form.fields[0].media[0].uris[1].uri, "cid:sha1+f24030b8d91d233bac14777be5ab531ca3b9f102@bob.xmpp.org");
180 }
181}