forwarding.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 xso::{AsXml, FromXml};
  8
  9use crate::delay::Delay;
 10use crate::message::Message;
 11use crate::ns;
 12
 13/// Contains a forwarded stanza, either standalone or part of another
 14/// extension (such as carbons).
 15#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
 16#[xml(namespace = ns::FORWARD, name = "forwarded")]
 17pub struct Forwarded {
 18    /// When the stanza originally got sent.
 19    #[xml(child(default))]
 20    pub delay: Option<Delay>,
 21
 22    /// The stanza being forwarded.
 23    // The schema says that we should allow either a Message, Presence or Iq, in either
 24    // jabber:client or jabber:server, but in the wild so far we’ve only seen Message being
 25    // transmitted, so let’s hardcode that for now.  The schema also makes it optional, but so far
 26    // it’s always present (or this wrapper is useless).
 27    #[xml(child)]
 28    pub message: Message,
 29}
 30
 31#[cfg(test)]
 32mod tests {
 33    use super::*;
 34    use minidom::Element;
 35    use xso::error::{Error, FromElementError};
 36
 37    #[cfg(target_pointer_width = "32")]
 38    #[test]
 39    fn test_size() {
 40        assert_size!(Forwarded, 152);
 41    }
 42
 43    #[cfg(target_pointer_width = "64")]
 44    #[test]
 45    fn test_size() {
 46        assert_size!(Forwarded, 288);
 47    }
 48
 49    #[test]
 50    fn test_simple() {
 51        let elem: Element =
 52            "<forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client'/></forwarded>"
 53                .parse()
 54                .unwrap();
 55        Forwarded::try_from(elem).unwrap();
 56    }
 57
 58    #[test]
 59    #[cfg_attr(feature = "disable-validation", should_panic = "Result::unwrap_err")]
 60    fn test_invalid_child() {
 61        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client'/><coucou/></forwarded>"
 62            .parse()
 63            .unwrap();
 64        let error = Forwarded::try_from(elem).unwrap_err();
 65        let message = match error {
 66            FromElementError::Invalid(Error::Other(string)) => string,
 67            _ => panic!(),
 68        };
 69        assert_eq!(message, "Unknown child in Forwarded element.");
 70    }
 71
 72    #[test]
 73    fn test_serialise() {
 74        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><message xmlns='jabber:client' type='chat'/></forwarded>".parse().unwrap();
 75        let forwarded = Forwarded {
 76            delay: None,
 77            message: Message::new(None),
 78        };
 79        let elem2 = forwarded.into();
 80        assert_eq!(elem, elem2);
 81    }
 82
 83    #[test]
 84    fn test_serialize_with_delay_and_stanza() {
 85        let reference: Element = "<forwarded xmlns='urn:xmpp:forward:0'><delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25+00:00'/><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded>"
 86        .parse()
 87        .unwrap();
 88
 89        let elem: Element = "<message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/>"
 90          .parse()
 91          .unwrap();
 92        let message = Message::try_from(elem).unwrap();
 93
 94        let elem: Element =
 95            "<delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25Z'/>"
 96                .parse()
 97                .unwrap();
 98        let delay = Delay::try_from(elem).unwrap();
 99
100        let forwarded = Forwarded {
101            delay: Some(delay),
102            message,
103        };
104
105        let serialized: Element = forwarded.into();
106        assert_eq!(serialized, reference);
107    }
108
109    #[test]
110    fn test_invalid_duplicate_delay() {
111        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25+00:00'/><delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25+00:00'/><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded>"
112            .parse()
113            .unwrap();
114        let error = Forwarded::try_from(elem).unwrap_err();
115        let message = match error {
116            FromElementError::Invalid(Error::Other(string)) => string,
117            _ => panic!(),
118        };
119        assert_eq!(
120            message,
121            "Forwarded element must not have more than one child in field 'delay'."
122        );
123    }
124
125    #[test]
126    fn test_invalid_duplicate_message() {
127        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25+00:00'/><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/><message xmlns='jabber:client' to='juliet@capulet.example/balcony' from='romeo@montague.example/home'/></forwarded>"
128            .parse()
129            .unwrap();
130        let error = Forwarded::try_from(elem).unwrap_err();
131        let message = match error {
132            FromElementError::Invalid(Error::Other(string)) => string,
133            _ => panic!(),
134        };
135        assert_eq!(
136            message,
137            "Forwarded element must not have more than one child in field 'message'."
138        );
139    }
140}