media_element.rs

  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_with_children!(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}