xmpp-rs/src/media_element.rs

257 lines
8.2 KiB
Rust
Raw Normal View History

2017-04-29 21:14:34 +00:00
// Copyright (c) 2017 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use crate::util::helpers::TrimmedPlainText;
generate_element!(
2018-08-02 16:47:06 +00:00
/// Represents an URI used in a media element.
URI, "uri", MEDIA_ELEMENT,
attributes: [
2018-08-02 16:47:06 +00:00
/// The MIME type of the URI referenced.
///
/// See the [IANA MIME Media Types Registry][1] for a list of
/// registered types, but unregistered or yet-to-be-registered are
/// accepted too.
///
/// [1]: https://www.iana.org/assignments/media-types/media-types.xhtml
type_: Required<String> = "type"
],
text: (
/// The actual URI contained.
uri: TrimmedPlainText<String>
)
);
2018-08-02 16:47:06 +00:00
generate_element!(
/// References a media element, to be used in [data
/// forms](../data_forms/index.html).
MediaElement, "media", MEDIA_ELEMENT,
attributes: [
2018-08-02 16:47:06 +00:00
/// The recommended display width in pixels.
width: Option<usize> = "width",
2018-08-02 16:47:06 +00:00
/// The recommended display height in pixels.
height: Option<usize> = "height"
],
children: [
2018-08-02 16:47:06 +00:00
/// A list of URIs referencing this media.
2018-05-14 14:30:28 +00:00
uris: Vec<URI> = ("uri", MEDIA_ELEMENT) => URI
]
);
2017-04-18 19:44:36 +00:00
#[cfg(test)]
mod tests {
2017-05-06 19:48:41 +00:00
use super::*;
use crate::data_forms::DataForm;
use crate::util::error::Error;
2018-12-18 14:32:05 +00:00
use minidom::Element;
use std::error::Error as StdError;
use std::convert::TryFrom;
2017-04-18 19:44:36 +00:00
2018-10-28 12:10:48 +00:00
#[cfg(target_pointer_width = "32")]
#[test]
fn test_size() {
assert_size!(URI, 24);
assert_size!(MediaElement, 28);
}
#[cfg(target_pointer_width = "64")]
#[test]
fn test_size() {
assert_size!(URI, 48);
assert_size!(MediaElement, 56);
}
2017-04-18 19:44:36 +00:00
#[test]
fn test_simple() {
let elem: Element = "<media xmlns='urn:xmpp:media-element'/>".parse().unwrap();
let media = MediaElement::try_from(elem).unwrap();
2017-04-18 19:44:36 +00:00
assert!(media.width.is_none());
assert!(media.height.is_none());
assert!(media.uris.is_empty());
}
#[test]
fn test_width_height() {
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element' width='32' height='32'/>"
.parse()
.unwrap();
let media = MediaElement::try_from(elem).unwrap();
2017-04-18 19:44:36 +00:00
assert_eq!(media.width.unwrap(), 32);
assert_eq!(media.height.unwrap(), 32);
}
#[test]
fn test_uri() {
let elem: Element = "<media xmlns='urn:xmpp:media-element'><uri type='text/html'>https://example.org/</uri></media>".parse().unwrap();
let media = MediaElement::try_from(elem).unwrap();
2017-04-18 19:44:36 +00:00
assert_eq!(media.uris.len(), 1);
assert_eq!(media.uris[0].type_, "text/html");
assert_eq!(media.uris[0].uri, "https://example.org/");
}
#[test]
fn test_invalid_width_height() {
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element' width=''/>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
let error = match error {
Error::ParseIntError(error) => error,
_ => panic!(),
};
2018-12-18 14:32:05 +00:00
assert_eq!(
error.description(),
"cannot parse integer from empty string"
);
2017-04-18 19:44:36 +00:00
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element' width='coucou'/>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
let error = match error {
Error::ParseIntError(error) => error,
_ => panic!(),
};
assert_eq!(error.description(), "invalid digit found in string");
2017-04-18 19:44:36 +00:00
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element' height=''/>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
let error = match error {
Error::ParseIntError(error) => error,
_ => panic!(),
};
2018-12-18 14:32:05 +00:00
assert_eq!(
error.description(),
"cannot parse integer from empty string"
);
2017-04-18 19:44:36 +00:00
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element' height='-10'/>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
let error = match error {
Error::ParseIntError(error) => error,
_ => panic!(),
};
assert_eq!(error.description(), "invalid digit found in string");
2017-04-18 19:44:36 +00:00
}
#[test]
fn test_unknown_child() {
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element'><coucou/></media>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
2017-04-18 19:44:36 +00:00
let message = match error {
Error::ParseError(string) => string,
_ => panic!(),
};
assert_eq!(message, "Unknown child in media element.");
}
#[test]
fn test_bad_uri() {
2018-12-18 14:32:05 +00:00
let elem: Element =
"<media xmlns='urn:xmpp:media-element'><uri>https://example.org/</uri></media>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
2017-04-18 19:44:36 +00:00
let message = match error {
Error::ParseError(string) => string,
_ => panic!(),
};
assert_eq!(message, "Required attribute 'type' missing.");
2017-04-18 19:44:36 +00:00
2018-12-18 14:32:05 +00:00
let elem: Element = "<media xmlns='urn:xmpp:media-element'><uri type='text/html'/></media>"
.parse()
.unwrap();
let error = MediaElement::try_from(elem).unwrap_err();
2017-04-18 19:44:36 +00:00
let message = match error {
Error::ParseError(string) => string,
_ => panic!(),
};
assert_eq!(message, "URI missing in uri.");
}
#[test]
fn test_xep_ex1() {
let elem: Element = r#"
<media xmlns='urn:xmpp:media-element'>
<uri type='audio/x-wav'>
http://victim.example.com/challenges/speech.wav?F3A6292C
</uri>
<uri type='audio/ogg; codecs=speex'>
cid:sha1+a15a505e360702b79c75a5f67773072ed392f52a@bob.xmpp.org
</uri>
<uri type='audio/mpeg'>
http://victim.example.com/challenges/speech.mp3?F3A6292C
</uri>
2018-12-18 14:32:05 +00:00
</media>"#
.parse()
.unwrap();
let media = MediaElement::try_from(elem).unwrap();
2017-04-18 19:44:36 +00:00
assert!(media.width.is_none());
assert!(media.height.is_none());
assert_eq!(media.uris.len(), 3);
assert_eq!(media.uris[0].type_, "audio/x-wav");
2018-12-18 14:32:05 +00:00
assert_eq!(
media.uris[0].uri,
"http://victim.example.com/challenges/speech.wav?F3A6292C"
);
2017-04-18 19:44:36 +00:00
assert_eq!(media.uris[1].type_, "audio/ogg; codecs=speex");
2018-12-18 14:32:05 +00:00
assert_eq!(
media.uris[1].uri,
"cid:sha1+a15a505e360702b79c75a5f67773072ed392f52a@bob.xmpp.org"
);
2017-04-18 19:44:36 +00:00
assert_eq!(media.uris[2].type_, "audio/mpeg");
2018-12-18 14:32:05 +00:00
assert_eq!(
media.uris[2].uri,
"http://victim.example.com/challenges/speech.mp3?F3A6292C"
);
2017-04-18 19:44:36 +00:00
}
#[test]
fn test_xep_ex2() {
let elem: Element = r#"
<x xmlns='jabber:x:data' type='form'>
[ ... ]
<field var='ocr'>
<media xmlns='urn:xmpp:media-element'
height='80'
width='290'>
<uri type='image/jpeg'>
http://www.victim.com/challenges/ocr.jpeg?F3A6292C
</uri>
<uri type='image/jpeg'>
cid:sha1+f24030b8d91d233bac14777be5ab531ca3b9f102@bob.xmpp.org
</uri>
</media>
</field>
[ ... ]
2018-12-18 14:32:05 +00:00
</x>"#
.parse()
.unwrap();
let form = DataForm::try_from(elem).unwrap();
2017-04-18 19:44:36 +00:00
assert_eq!(form.fields.len(), 1);
assert_eq!(form.fields[0].var, "ocr");
assert_eq!(form.fields[0].media[0].width, Some(290));
assert_eq!(form.fields[0].media[0].height, Some(80));
assert_eq!(form.fields[0].media[0].uris[0].type_, "image/jpeg");
2018-12-18 14:32:05 +00:00
assert_eq!(
form.fields[0].media[0].uris[0].uri,
"http://www.victim.com/challenges/ocr.jpeg?F3A6292C"
);
2017-04-18 19:44:36 +00:00
assert_eq!(form.fields[0].media[0].uris[1].type_, "image/jpeg");
2018-12-18 14:32:05 +00:00
assert_eq!(
form.fields[0].media[0].uris[1].uri,
"cid:sha1+f24030b8d91d233bac14777be5ab531ca3b9f102@bob.xmpp.org"
);
2017-04-18 19:44:36 +00:00
}
}