diff options
Diffstat (limited to 'Swiften/Parser/PayloadParsers')
15 files changed, 399 insertions, 88 deletions
diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp b/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp index 405c593..71bce54 100644 --- a/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp +++ b/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -7,6 +7,7 @@ #include <Swiften/Parser/PayloadParsers/BytestreamsParser.h> #include <boost/lexical_cast.hpp> +#include <boost/numeric/conversion/cast.hpp> namespace Swift { @@ -23,7 +24,9 @@ void BytestreamsParser::handleStartElement(const std::string& element, const std else if (level == PayloadLevel) { if (element == "streamhost") { try { - getPayloadInternal()->addStreamHost(Bytestreams::StreamHost(attributes.getAttribute("host"), JID(attributes.getAttribute("jid")), boost::lexical_cast<int>(attributes.getAttribute("port")))); + getPayloadInternal()->addStreamHost(Bytestreams::StreamHost(attributes.getAttribute("host"), JID(attributes.getAttribute("jid")), boost::numeric_cast<unsigned short>(boost::lexical_cast<int>(attributes.getAttribute("port"))))); + } + catch (boost::numeric::bad_numeric_cast&) { } catch (boost::bad_lexical_cast&) { } diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index 8f57704..9e56b63 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -56,6 +56,7 @@ #include <Swiften/Parser/PayloadParsers/MIXRegisterNickParserFactory.h> #include <Swiften/Parser/PayloadParsers/MIXSetNickParserFactory.h> #include <Swiften/Parser/PayloadParsers/MIXDestroyParser.h> +#include <Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.h> #include <Swiften/Parser/PayloadParsers/MIXJoinParserFactory.h> #include <Swiften/Parser/PayloadParsers/MIXPayloadParserFactory.h> #include <Swiften/Parser/PayloadParsers/MIXUserPreferenceParser.h> @@ -74,6 +75,7 @@ #include <Swiften/Parser/PayloadParsers/PubSubOwnerPubSubParser.h> #include <Swiften/Parser/PayloadParsers/PubSubParser.h> #include <Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/ReferencePayloadParser.h> #include <Swiften/Parser/PayloadParsers/ReplaceParser.h> #include <Swiften/Parser/PayloadParsers/ResourceBindParser.h> #include <Swiften/Parser/PayloadParsers/ResultSetParser.h> @@ -143,6 +145,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(std::make_shared<MIXRegisterNickParserFactory>()); factories_.push_back(std::make_shared<MIXSetNickParserFactory>()); factories_.push_back(std::make_shared<GenericPayloadParserFactory<MIXCreateParser> >("create", "urn:xmpp:mix:0")); + factories_.push_back(std::make_shared<GenericPayloadParserFactory<MIXUpdateSubscriptionParser> >("update-subscription", "urn:xmpp:mix:0")); factories_.push_back(std::make_shared<GenericPayloadParserFactory<MIXUserPreferenceParser> >("user-preference", "urn:xmpp:mix:0")); factories_.push_back(std::make_shared<MIXPayloadParserFactory>()); factories_.push_back(std::make_shared<GenericPayloadParserFactory<MIXLeaveParser> >("leave", "urn:xmpp:mix:0")); @@ -185,6 +188,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(std::make_shared<GenericPayloadParserFactory2<CarbonsSentParser> >("sent", "urn:xmpp:carbons:2", this)); factories_.push_back(std::make_shared<GenericPayloadParserFactory<CarbonsPrivateParser> >("private", "urn:xmpp:carbons:2")); factories_.push_back(std::make_shared<MIXJoinParserFactory>()); + factories_.push_back(std::make_shared<GenericPayloadParserFactory2<ReferencePayloadParser> >("reference", "urn:xmpp:reference:0", this)); for (auto& factory : factories_) { addFactory(factory.get()); diff --git a/Swiften/Parser/PayloadParsers/IBBParser.cpp b/Swiften/Parser/PayloadParsers/IBBParser.cpp index 9b6babc..1ba44e1 100644 --- a/Swiften/Parser/PayloadParsers/IBBParser.cpp +++ b/Swiften/Parser/PayloadParsers/IBBParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -39,7 +39,7 @@ void IBBParser::handleStartElement(const std::string& element, const std::string getPayloadInternal()->setStanzaType(IBB::IQStanza); } try { - getPayloadInternal()->setBlockSize(boost::lexical_cast<int>(attributes.getAttribute("block-size"))); + getPayloadInternal()->setBlockSize(boost::lexical_cast<unsigned int>(attributes.getAttribute("block-size"))); } catch (boost::bad_lexical_cast&) { } diff --git a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp index e639e20..a405e0e 100644 --- a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014-2016 Isode Limited. + * Copyright (c) 2014-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -13,6 +13,7 @@ #include <Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h> #include <boost/lexical_cast.hpp> +#include <boost/numeric/conversion/cast.hpp> #include <boost/optional.hpp> #include <Swiften/Base/Log.h> @@ -40,10 +41,10 @@ namespace Swift { JingleS5BTransportPayload::Candidate candidate; candidate.cid = attributes.getAttributeValue("cid").get_value_or(""); - int port = -1; + unsigned short port = 0; try { - port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get_value_or("-1")); - } catch(boost::bad_lexical_cast &) { } + port = boost::numeric_cast<unsigned short>(boost::lexical_cast<int>(attributes.getAttributeValue("port").get_value_or("0"))); + } catch(...) { } candidate.hostPort = HostAddressPort(HostAddress::fromString(attributes.getAttributeValue("host").get_value_or("")).get_value_or(HostAddress()), port); candidate.jid = JID(attributes.getAttributeValue("jid").get_value_or("")); int priority = -1; diff --git a/Swiften/Parser/PayloadParsers/MIXJoinParser.cpp b/Swiften/Parser/PayloadParsers/MIXJoinParser.cpp index 0c09c44..6e72f90 100644 --- a/Swiften/Parser/PayloadParsers/MIXJoinParser.cpp +++ b/Swiften/Parser/PayloadParsers/MIXJoinParser.cpp @@ -9,7 +9,6 @@ #include <boost/optional.hpp> #include <Swiften/Parser/PayloadParserFactory.h> -#include <Swiften/Parser/PayloadParsers/MIXSubscribeParser.h> #include <Swiften/Parser/PayloadParsers/FormParser.h> using namespace Swift; @@ -36,7 +35,9 @@ void MIXJoinParser::handleStartElement(const std::string& element, const std::st if (level_ == 1) { if (element == "subscribe" && ns == "urn:xmpp:mix:0") { - currentPayloadParser_ = std::make_shared<MIXSubscribeParser>(); + if (boost::optional<std::string> attributeValue = attributes.getAttributeValue("node")) { + getPayloadInternal()->addSubscription(*attributeValue); + } } if (element == "x" && ns == "jabber:x:data") { currentPayloadParser_ = std::make_shared<FormParser>(); @@ -57,9 +58,6 @@ void MIXJoinParser::handleEndElement(const std::string& element, const std::stri } if (level_ == 1) { - if (element == "subscribe" && ns == "urn:xmpp:mix:0") { - getPayloadInternal()->addSubscription(std::dynamic_pointer_cast<MIXSubscribe>(currentPayloadParser_->getPayload())); - } if (element == "x" && ns == "jabber:x:data") { getPayloadInternal()->setForm(std::dynamic_pointer_cast<Form>(currentPayloadParser_->getPayload())); } diff --git a/Swiften/Parser/PayloadParsers/MIXSubscribeParser.cpp b/Swiften/Parser/PayloadParsers/MIXSubscribeParser.cpp deleted file mode 100644 index 1500716..0000000 --- a/Swiften/Parser/PayloadParsers/MIXSubscribeParser.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Tarun Gupta - * Licensed under the simplified BSD license. - * See Documentation/Licenses/BSD-simplified.txt for more information. - */ - -#include <Swiften/Parser/PayloadParsers/MIXSubscribeParser.h> - -#include <boost/optional.hpp> - -#include <Swiften/Parser/PayloadParserFactory.h> -#include <Swiften/Parser/PayloadParserFactoryCollection.h> - -using namespace Swift; - -MIXSubscribeParser::MIXSubscribeParser() : level_(0) { -} - -MIXSubscribeParser::~MIXSubscribeParser() { -} - -void MIXSubscribeParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) { - if (level_ == 0) { - if (boost::optional<std::string> attributeValue = attributes.getAttributeValue("node")) { - getPayloadInternal()->setNode(*attributeValue); - } - } - ++level_; -} - -void MIXSubscribeParser::handleEndElement(const std::string& , const std::string& ) { - --level_; -} - -void MIXSubscribeParser::handleCharacterData(const std::string& ) { -} diff --git a/Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.cpp b/Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.cpp new file mode 100644 index 0000000..d530e49 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 Tarun Gupta + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.h> + +#include <boost/optional.hpp> + +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParsers/FormParser.h> + +namespace Swift { + +MIXUpdateSubscriptionParser::MIXUpdateSubscriptionParser() : level_(0) { +} + +MIXUpdateSubscriptionParser::~MIXUpdateSubscriptionParser() { +} + +void MIXUpdateSubscriptionParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level_ == 0) { + if (boost::optional<std::string> attributeValue = attributes.getAttributeValue("jid")) { + if (boost::optional<JID> jid = JID::parse(*attributeValue)) { + getPayloadInternal()->setJID(*jid); + } + } + } + + if (level_ == 1) { + if (element == "subscribe" && ns == "urn:xmpp:mix:0") { + if (boost::optional<std::string> attributeValue = attributes.getAttributeValue("node")) { + getPayloadInternal()->addSubscription(*attributeValue); + } + } + } + + ++level_; +} + +void MIXUpdateSubscriptionParser::handleEndElement(const std::string&, const std::string&) { + --level_; +} + +void MIXUpdateSubscriptionParser::handleCharacterData(const std::string&) { +} + +} diff --git a/Swiften/Parser/PayloadParsers/MIXSubscribeParser.h b/Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.h index 95d6d74..47966ff 100644 --- a/Swiften/Parser/PayloadParsers/MIXSubscribeParser.h +++ b/Swiften/Parser/PayloadParsers/MIXUpdateSubscriptionParser.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2017 Isode Limited. + * Copyright (c) 2017-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -15,17 +15,16 @@ #include <memory> #include <Swiften/Base/API.h> -#include <Swiften/Elements/MIXSubscribe.h> +#include <Swiften/Elements/MIXUpdateSubscription.h> #include <Swiften/Parser/GenericPayloadParser.h> namespace Swift { - class PayloadParserFactoryCollection; class PayloadParser; - class SWIFTEN_API MIXSubscribeParser : public GenericPayloadParser<MIXSubscribe> { + class SWIFTEN_API MIXUpdateSubscriptionParser : public GenericPayloadParser<MIXUpdateSubscription> { public: - MIXSubscribeParser(); - virtual ~MIXSubscribeParser() override; + MIXUpdateSubscriptionParser(); + virtual ~MIXUpdateSubscriptionParser() override; virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) override; virtual void handleEndElement(const std::string& element, const std::string&) override; diff --git a/Swiften/Parser/PayloadParsers/ReferencePayloadParser.cpp b/Swiften/Parser/PayloadParsers/ReferencePayloadParser.cpp new file mode 100644 index 0000000..a337a29 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ReferencePayloadParser.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Parser/PayloadParsers/ReferencePayloadParser.h> + +#include <cassert> +#include <iostream> + +#include <Swiften/Parser/PayloadParserFactory.h> +#include <Swiften/Parser/PayloadParserFactoryCollection.h> + +namespace Swift { + +ReferencePayloadParser::ReferencePayloadParser(PayloadParserFactoryCollection* factories) : factories_(factories) { +} + +ReferencePayload::Type ReferencePayloadParser::getTypeFromString(const std::string& typeString) const { + if (typeString == "data") { + return ReferencePayload::Type::Data; + } + else if (typeString == "mention") { + return ReferencePayload::Type::Mention; + } + else if (typeString == "pubsub") { + return ReferencePayload::Type::PubSub; + } + else { + return ReferencePayload::Type::Unknown; + } +} + +void ReferencePayloadParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level_ == topLevel_) { + if (element == "reference") { + getPayloadInternal()->setType(getTypeFromString(attributes.getAttribute("type"))); + getPayloadInternal()->setUri(attributes.getAttributeValue("uri")); + getPayloadInternal()->setBegin(attributes.getAttributeValue("begin")); + getPayloadInternal()->setEnd(attributes.getAttributeValue("end")); + getPayloadInternal()->setAnchor(attributes.getAttributeValue("anchor")); + } + } + else if (level_ == payloadLevel_) { + PayloadParserFactory* payloadParserFactory = factories_->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser_.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (level_ >= payloadLevel_ && currentPayloadParser_) { + currentPayloadParser_->handleStartElement(element, ns, attributes); + } + + ++level_; +} + +void ReferencePayloadParser::handleEndElement(const std::string& element, const std::string& ns) { + --level_; + if (currentPayloadParser_) { + if (level_ >= payloadLevel_) { + currentPayloadParser_->handleEndElement(element, ns); + } + + if (level_ == payloadLevel_) { + getPayloadInternal()->addPayload(currentPayloadParser_->getPayload()); + currentPayloadParser_.reset(); + } + } +} + +void ReferencePayloadParser::handleCharacterData(const std::string& data) { + if (level_ > payloadLevel_ && currentPayloadParser_) { + currentPayloadParser_->handleCharacterData(data); + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/ReferencePayloadParser.h b/Swiften/Parser/PayloadParsers/ReferencePayloadParser.h new file mode 100644 index 0000000..3afd181 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/ReferencePayloadParser.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Base/API.h> +#include <Swiften/Elements/ReferencePayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + + class PayloadParserFactoryCollection; + + class SWIFTEN_API ReferencePayloadParser : public GenericPayloadParser<ReferencePayload> { + public: + + ReferencePayloadParser(PayloadParserFactoryCollection* factories); + + virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string& ns); + virtual void handleCharacterData(const std::string& data); + + private: + + ReferencePayload::Type getTypeFromString(const std::string& typeString) const; + int level_ = 0; + const int topLevel_ = 0; + const int payloadLevel_ = 1; + PayloadParserFactoryCollection* factories_; + std::shared_ptr<PayloadParser> currentPayloadParser_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp index 502f400..7a5a1fd 100644 --- a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp +++ b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2015-2016 Isode Limited. + * Copyright (c) 2015-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -13,6 +13,7 @@ #include <Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h> #include <boost/lexical_cast.hpp> +#include <boost/numeric/conversion/cast.hpp> #include <boost/optional.hpp> namespace Swift { @@ -27,15 +28,14 @@ void S5BProxyRequestParser::handleStartElement(const std::string& element, const if (element == "streamhost") { if (attributes.getAttributeValue("host") && attributes.getAttributeValue("jid") && attributes.getAttributeValue("port")) { std::string host = attributes.getAttributeValue("host").get_value_or(""); - int port = -1; + unsigned short port = 0; JID jid = attributes.getAttributeValue("jid").get_value_or(""); try { - port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get()); - } catch (boost::bad_lexical_cast &) { - port = -1; + port = boost::numeric_cast<unsigned short>(boost::lexical_cast<int>(attributes.getAttributeValue("port").get())); + } catch (...) { } - if (!host.empty() && port != -1 && jid.isValid()) { + if (!host.empty() && port != 0 && jid.isValid()) { S5BProxyRequest::StreamHost streamHost; streamHost.host = host; streamHost.port = port; diff --git a/Swiften/Parser/PayloadParsers/UnitTest/MIXJoinParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/MIXJoinParserTest.cpp index 88d8fc1..0ad4589 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/MIXJoinParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/MIXJoinParserTest.cpp @@ -30,12 +30,11 @@ TEST(MIXJoinParserTest, XEP0369_Example22) { ASSERT_FALSE(payload->getJID()); ASSERT_FALSE(payload->getForm()); - const std::vector<MIXSubscribe::ref> items = payload->getSubscriptions(); - ASSERT_EQ(static_cast<size_t>(4), items.size()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:messages"), items[0]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:presence"), items[1]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:participants"), items[2]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:config"), items[3]->getNode()); + ASSERT_EQ(static_cast<size_t>(4), payload->getSubscriptions().size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:presence"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:participants"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:config"))); } TEST(MIXJoinParserTest, XEP0369_Example23) { @@ -56,12 +55,11 @@ TEST(MIXJoinParserTest, XEP0369_Example23) { ASSERT_FALSE(payload->getJID()); ASSERT_FALSE(payload->getForm()); - const std::vector<MIXSubscribe::ref> items = payload->getSubscriptions(); - ASSERT_EQ(static_cast<size_t>(4), items.size()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:messages"), items[0]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:presence"), items[1]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:participants"), items[2]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:config"), items[3]->getNode()); + ASSERT_EQ(static_cast<size_t>(4), payload->getSubscriptions().size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:presence"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:participants"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:config"))); } TEST(MIXJoinParserTest, XEP0369_Example24) { @@ -83,12 +81,11 @@ TEST(MIXJoinParserTest, XEP0369_Example24) { ASSERT_EQ(JID("123456#coven@mix.shakespeare.example"), *payload->getJID()); ASSERT_FALSE(payload->getForm()); - const std::vector<MIXSubscribe::ref> items = payload->getSubscriptions(); - ASSERT_EQ(static_cast<size_t>(4), items.size()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:messages"), items[0]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:presence"), items[1]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:participants"), items[2]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:config"), items[3]->getNode()); + ASSERT_EQ(static_cast<size_t>(4), payload->getSubscriptions().size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:presence"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:participants"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:config"))); } TEST(MIXJoinParserTest, XEP0369_Example29) { @@ -112,10 +109,10 @@ TEST(MIXJoinParserTest, XEP0369_Example29) { ASSERT_FALSE(payload->getChannel()); ASSERT_FALSE(payload->getJID()); - const std::vector<MIXSubscribe::ref> items = payload->getSubscriptions(); - ASSERT_EQ(static_cast<size_t>(2), items.size()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:messages"), items[0]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:presence"), items[1]->getNode()); + + ASSERT_EQ(static_cast<size_t>(2), payload->getSubscriptions().size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:presence"))); ASSERT_TRUE(payload->getForm()); ASSERT_EQ(Form::Type::SubmitType, payload->getForm()->getType()); @@ -156,10 +153,9 @@ TEST(MIXJoinParserTest, XEP0369_Example30) { ASSERT_TRUE(payload->getJID()); ASSERT_EQ(JID("hag66@shakespeare.example"), *payload->getJID()); - const std::vector<MIXSubscribe::ref> items = payload->getSubscriptions(); - ASSERT_EQ(static_cast<size_t>(2), items.size()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:messages"), items[0]->getNode()); - ASSERT_EQ(std::string("urn:xmpp:mix:nodes:presence"), items[1]->getNode()); + ASSERT_EQ(static_cast<size_t>(2), payload->getSubscriptions().size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:presence"))); ASSERT_TRUE(payload->getForm()); ASSERT_EQ(Form::Type::ResultType, payload->getForm()->getType()); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/MIXUpdateSubscriptionParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/MIXUpdateSubscriptionParserTest.cpp new file mode 100644 index 0000000..985a34b --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/MIXUpdateSubscriptionParserTest.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 Tarun Gupta + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <gtest/gtest.h> + +#include <Swiften/Elements/MIXUpdateSubscription.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> + +using namespace Swift; + +TEST(MIXUpdateSubscriptionParserTest, XEP0369_Example28) { + PayloadsParserTester parser; + ASSERT_TRUE(parser.parse( + "<update-subscription xmlns=\"urn:xmpp:mix:0\">" + "<subscribe node=\"urn:xmpp:mix:nodes:messages\"/>" + "</update-subscription>" + )); + + auto payload = parser.getPayload<MIXUpdateSubscription>(); + ASSERT_TRUE(payload); + + ASSERT_FALSE(payload->getJID()); + + auto items = payload->getSubscriptions(); + ASSERT_EQ(static_cast<size_t>(1), items.size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); +} + +TEST(MIXUpdateSubscriptionParserTest, XEP0369_Example28_WithJID) { + PayloadsParserTester parser; + ASSERT_TRUE(parser.parse( + "<update-subscription xmlns=\"urn:xmpp:mix:0\" jid=\"hag66@shakespeare.example\">" + "<subscribe node=\"urn:xmpp:mix:nodes:messages\"/>" + "</update-subscription>" + )); + + auto payload = parser.getPayload<MIXUpdateSubscription>(); + ASSERT_TRUE(payload); + + ASSERT_TRUE(payload->getJID()); + ASSERT_EQ(JID("hag66@shakespeare.example"), *payload->getJID()); + + auto items = payload->getSubscriptions(); + ASSERT_EQ(static_cast<size_t>(1), items.size()); + ASSERT_TRUE(payload->hasSubscription(std::string("urn:xmpp:mix:nodes:messages"))); +} diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h index dcdbffa..8f9e0e1 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h +++ b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h @@ -19,7 +19,7 @@ namespace Swift { class PayloadsParserTester : public XMLParserClient { public: PayloadsParserTester() : level(0) { - xmlParser = PlatformXMLParserFactory().createXMLParser(this); + xmlParser = PlatformXMLParserFactory().createXMLParser(this, false); } bool parse(const std::string& data) { diff --git a/Swiften/Parser/PayloadParsers/UnitTest/ReferencePayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/ReferencePayloadParserTest.cpp new file mode 100644 index 0000000..ca7b280 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/ReferencePayloadParserTest.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <gtest/gtest.h> + +#include <Swiften/Elements/Body.h> +#include <Swiften/Elements/Delay.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Parser/PayloadParsers/ReferencePayloadParser.h> +#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> + +using namespace Swift; + +TEST(ReferencePayloadParserTest, testParse) { + PayloadsParserTester parser; + + ASSERT_TRUE(parser.parse( + "<reference xmlns='urn:xmpp:reference:0' " + "type='data' " + "uri='https://www.example.com/mindBlowingImage.jpeg' " + "begin='11' " + "end='22' " + "anchor='xmpp:data@localhost.example.test'>" + "</reference>")); + + auto payload = std::dynamic_pointer_cast<ReferencePayload>(parser.getPayload()); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(payload->getType())); + ASSERT_EQ(std::string("https://www.example.com/mindBlowingImage.jpeg"), *payload->getUri()); + ASSERT_EQ(std::string("11"), *payload->getBegin()); + ASSERT_EQ(std::string("22"), *payload->getEnd()); + ASSERT_EQ(std::string("xmpp:data@localhost.example.test"), *payload->getAnchor()); +} + +TEST(ReferencePayloadParserTest, testParseNoType) { + PayloadsParserTester parser; + + ASSERT_TRUE(parser.parse( + "<reference xmlns='urn:xmpp:reference:0' " + "uri='https://www.example.com/mindBlowingImage.jpeg' " + "begin='11' " + "end='22' " + "anchor='xmpp:data@localhost.example.test'>" + "</reference>")); + + auto payload = std::dynamic_pointer_cast<ReferencePayload>(parser.getPayload()); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Unknown), static_cast<int>(payload->getType())); + ASSERT_EQ(std::string("https://www.example.com/mindBlowingImage.jpeg"), *payload->getUri()); + ASSERT_EQ(std::string("11"), *payload->getBegin()); + ASSERT_EQ(std::string("22"), *payload->getEnd()); + ASSERT_EQ(std::string("xmpp:data@localhost.example.test"), *payload->getAnchor()); +} + +TEST(ReferencePayloadParserTest, testParseEmbeddedPayloads) { + PayloadsParserTester parser; + + ASSERT_TRUE(parser.parse( + "<reference xmlns='urn:xmpp:reference:0' type='data'> " + "<error type=\"modify\">" + "<bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>" + "<delay xmlns='urn:xmpp:delay' from='juliet@capulet.com/balcony' stamp='2002-09-10T23:41:07Z'/>" + "<text xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">boo</text>" + "</error>" + "</reference>")); + + auto payload = std::dynamic_pointer_cast<ReferencePayload>(parser.getPayload()); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(payload->getType())); + ASSERT_FALSE(payload->getUri()); + ASSERT_FALSE(payload->getBegin()); + ASSERT_FALSE(payload->getEnd()); + ASSERT_FALSE(payload->getAnchor()); + auto childPayloadList = payload->getPayloads(); + auto errorPayload = std::dynamic_pointer_cast<ErrorPayload>(childPayloadList[0]); + ASSERT_TRUE(errorPayload); + ASSERT_EQ("boo", errorPayload->getText()); + auto delayPayload = std::dynamic_pointer_cast<Delay>(errorPayload->getPayload()); + ASSERT_TRUE(delayPayload); +} + +TEST(ReferencePayloadParserTest, testParseEmbeddedPayloadWithText) { + PayloadsParserTester parser; + + ASSERT_TRUE(parser.parse( + "<reference xmlns='urn:xmpp:reference:0' type='data'> " + "<body>Example Text</body>" + "</reference>")); + + auto payload = std::dynamic_pointer_cast<ReferencePayload>(parser.getPayload()); + auto childPayloadList = payload->getPayloads(); + auto bodyPayload = std::dynamic_pointer_cast<Body>(childPayloadList[0]); + ASSERT_EQ("Example Text", bodyPayload->getText()); +} + +TEST(ReferencePayloadParserTest, testParseRecursive) { + PayloadsParserTester parser; + + ASSERT_TRUE(parser.parse( + "<reference xmlns='urn:xmpp:reference:0' type='data'> " + "<reference xmlns='urn:xmpp:reference:0' type='data' uri='https://download.montague.lit/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/summit.jpg' /> " + "<reference xmlns='urn:xmpp:reference:0' type='data' uri='xmpp:romeo@montague.lit/resource?jingle;id=9559976B-3FBF-4E7E-B457-2DAA225972BB' /> " + "<reference xmlns='urn:xmpp:reference:0' type='data'> " + "<reference xmlns='urn:xmpp:reference:0' type='data' uri='https://www.example.com/mindBlowingImage.jpeg' /> " + "</reference>" + "</reference>")); + + auto payload = std::dynamic_pointer_cast<ReferencePayload>(parser.getPayload()); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(payload->getType())); + auto childPayloadList = payload->getPayloads(); + auto childPayloadA = std::dynamic_pointer_cast<ReferencePayload>(childPayloadList[0]); + auto childPayloadB = std::dynamic_pointer_cast<ReferencePayload>(childPayloadList[1]); + auto childPayloadC = std::dynamic_pointer_cast<ReferencePayload>(childPayloadList[2]); + ASSERT_TRUE(childPayloadA); + ASSERT_TRUE(childPayloadB); + ASSERT_TRUE(childPayloadC); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(childPayloadA->getType())); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(childPayloadB->getType())); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(childPayloadC->getType())); + ASSERT_EQ(std::string("https://download.montague.lit/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/summit.jpg"), *childPayloadA->getUri()); + ASSERT_EQ(std::string("xmpp:romeo@montague.lit/resource?jingle;id=9559976B-3FBF-4E7E-B457-2DAA225972BB"), *childPayloadB->getUri()); + ASSERT_FALSE(childPayloadC->getUri()); + ASSERT_FALSE(childPayloadC->getBegin()); + ASSERT_FALSE(childPayloadC->getEnd()); + ASSERT_FALSE(childPayloadC->getAnchor()); + auto grandChildPayloadList = childPayloadC->getPayloads(); + auto grandChildPayload = std::dynamic_pointer_cast<ReferencePayload>(grandChildPayloadList[0]); + ASSERT_TRUE(grandChildPayload); + ASSERT_EQ(static_cast<int>(ReferencePayload::Type::Data), static_cast<int>(grandChildPayload->getType())); + ASSERT_EQ(std::string("https://www.example.com/mindBlowingImage.jpeg"), *grandChildPayload->getUri()); + ASSERT_FALSE(grandChildPayload->getBegin()); + ASSERT_FALSE(grandChildPayload->getEnd()); + ASSERT_FALSE(grandChildPayload->getAnchor()); +} |