diff options
Diffstat (limited to 'Swiften/Presence')
-rw-r--r-- | Swiften/Presence/PayloadAddingPresenceSender.cpp | 44 | ||||
-rw-r--r-- | Swiften/Presence/PayloadAddingPresenceSender.h | 34 | ||||
-rw-r--r-- | Swiften/Presence/SConscript | 11 | ||||
-rw-r--r-- | Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp | 131 |
4 files changed, 220 insertions, 0 deletions
diff --git a/Swiften/Presence/PayloadAddingPresenceSender.cpp b/Swiften/Presence/PayloadAddingPresenceSender.cpp new file mode 100644 index 0000000..c3d1638 --- /dev/null +++ b/Swiften/Presence/PayloadAddingPresenceSender.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Presence/PayloadAddingPresenceSender.h" + +namespace Swift { + +PayloadAddingPresenceSender::PayloadAddingPresenceSender(PresenceSender* sender) : sender(sender) { +} + +void PayloadAddingPresenceSender::sendPresence(Presence::ref presence) { + if (presence->isAvailable()) { + if (!presence->getTo().isValid()) { + lastSentPresence = presence; + } + } + else { + lastSentPresence.reset(); + } + if (payload) { + Presence::ref sentPresence = Presence::create(presence); + sentPresence->updatePayload(payload); + sender->sendPresence(sentPresence); + } + else { + sender->sendPresence(presence); + } +} + +bool PayloadAddingPresenceSender::isAvailable() const { + return sender->isAvailable(); +} + +void PayloadAddingPresenceSender::setPayload(Payload::ref payload) { + this->payload = payload; + if (lastSentPresence) { + sendPresence(lastSentPresence); + } +} + +} diff --git a/Swiften/Presence/PayloadAddingPresenceSender.h b/Swiften/Presence/PayloadAddingPresenceSender.h new file mode 100644 index 0000000..5602ebe --- /dev/null +++ b/Swiften/Presence/PayloadAddingPresenceSender.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include "Swiften/Presence/PresenceSender.h" +#include "Swiften/Elements/Payload.h" + +namespace Swift { + class StanzaChannel; + + /** + * This presence sender adds payloads to outgoing presences. + * + * + */ + class PayloadAddingPresenceSender : public PresenceSender { + public: + PayloadAddingPresenceSender(PresenceSender*); + + void sendPresence(Presence::ref); + bool isAvailable() const; + + void setPayload(Payload::ref); + + private: + Presence::ref lastSentPresence; + PresenceSender* sender; + Payload::ref payload; + }; +} diff --git a/Swiften/Presence/SConscript b/Swiften/Presence/SConscript new file mode 100644 index 0000000..6911d45 --- /dev/null +++ b/Swiften/Presence/SConscript @@ -0,0 +1,11 @@ +Import("swiften_env") + +objects = swiften_env.StaticObject([ + "PresenceOracle.cpp", + "PresenceSender.cpp", + "DirectedPresenceSender.cpp", + "PayloadAddingPresenceSender.cpp", + "StanzaChannelPresenceSender.cpp", + "SubscriptionManager.cpp", + ]) +swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp b/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp new file mode 100644 index 0000000..3a6487a --- /dev/null +++ b/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <vector> +#include <boost/bind.hpp> + +#include "Swiften/Presence/PayloadAddingPresenceSender.h" +#include "Swiften/Presence/StanzaChannelPresenceSender.h" +#include "Swiften/Elements/Body.h" +#include "Swiften/Client/DummyStanzaChannel.h" + +using namespace Swift; + +class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(PayloadAddingPresenceSenderTest); + CPPUNIT_TEST(testSetPayloadAddsPayloadOnPresenceSend); + CPPUNIT_TEST(testSetNullPayloadDoesNotAddPayloadOnPresenceSend); + CPPUNIT_TEST(testSendPresenceDoesNotAlterOriginalPayload); + CPPUNIT_TEST(testSetPayloadAfterInitialPresenceResendsPresence); + CPPUNIT_TEST(testSetPayloadAfterUnavailablePresenceDoesNotResendPresence); + CPPUNIT_TEST(testSendDirectedPresenceIsNotResent); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + presenceSender = new StanzaChannelPresenceSender(stanzaChannel); + } + + void tearDown() { + delete presenceSender; + delete stanzaChannel; + } + + void testSetPayloadAddsPayloadOnPresenceSend() { + std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + + testling->setPayload(MyPayload::create("foo")); + testling->sendPresence(Presence::create("bar")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex<Presence>(0)->getStatus()); + CPPUNIT_ASSERT(stanzaChannel->getStanzaAtIndex<Presence>(0)->getPayload<MyPayload>()); + } + + void testSetNullPayloadDoesNotAddPayloadOnPresenceSend() { + std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + + testling->setPayload(MyPayload::ref()); + testling->sendPresence(Presence::create("bar")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex<Presence>(0)->getStatus()); + CPPUNIT_ASSERT(!stanzaChannel->getStanzaAtIndex<Presence>(0)->getPayload<MyPayload>()); + } + + void testSendPresenceDoesNotAlterOriginalPayload() { + std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + + testling->setPayload(MyPayload::create("foo")); + Presence::ref presence(Presence::create("bar")); + testling->sendPresence(presence); + + CPPUNIT_ASSERT(!presence->getPayload<MyPayload>()); + } + + void testSetPayloadAfterInitialPresenceResendsPresence() { + std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + + testling->sendPresence(Presence::create("bar")); + testling->setPayload(MyPayload::create("foo")); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex<Presence>(1)->getStatus()); + CPPUNIT_ASSERT(stanzaChannel->getStanzaAtIndex<Presence>(1)->getPayload<MyPayload>()); + } + + void testSetPayloadAfterUnavailablePresenceDoesNotResendPresence() { + std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + + Presence::ref presence = Presence::create("bar"); + presence->setType(Presence::Unavailable); + testling->sendPresence(presence); + + testling->setPayload(MyPayload::create("foo")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(stanzaChannel->sentStanzas.size())); + } + + void testSendDirectedPresenceIsNotResent() { + std::auto_ptr<PayloadAddingPresenceSender> testling(createSender()); + + testling->sendPresence(Presence::create("bar")); + Presence::ref directedPresence = Presence::create("baz"); + directedPresence->setTo(JID("foo@bar.com")); + testling->sendPresence(directedPresence); + testling->setPayload(MyPayload::create("foo")); + + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex<Presence>(2)->getStatus()); + } + + private: + std::auto_ptr<PayloadAddingPresenceSender> createSender() { + std::auto_ptr<PayloadAddingPresenceSender> sender(new PayloadAddingPresenceSender(presenceSender)); + return sender; + } + + struct MyPayload : public Payload { + typedef boost::shared_ptr<MyPayload> ref; + + MyPayload(const String& body) : body(body) {} + + static ref create(const String& body) { + return ref(new MyPayload(body)); + } + + String body; + }; + + private: + DummyStanzaChannel* stanzaChannel; + StanzaChannelPresenceSender* presenceSender; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(PayloadAddingPresenceSenderTest); |