summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Presence')
-rw-r--r--Swiften/Presence/PayloadAddingPresenceSender.cpp44
-rw-r--r--Swiften/Presence/PayloadAddingPresenceSender.h34
-rw-r--r--Swiften/Presence/SConscript11
-rw-r--r--Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp131
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);