From 0fa21303c2ea99ff8b89507889de82f768978f23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 12 Jun 2009 10:40:31 +0200
Subject: Do not handle IQs directly in XMPPRosterController.

XMPPRosterController now uses a RosterPushResponder to handle roster
pushes.

diff --git a/Swift/Controllers/UnitTest/XMPPRosterControllerTest.cpp b/Swift/Controllers/UnitTest/XMPPRosterControllerTest.cpp
index c1d53c6..0b7fd6c 100644
--- a/Swift/Controllers/UnitTest/XMPPRosterControllerTest.cpp
+++ b/Swift/Controllers/UnitTest/XMPPRosterControllerTest.cpp
@@ -19,14 +19,13 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture
 		CPPUNIT_TEST(testRemove);
 		CPPUNIT_TEST_SUITE_END();
 
-		DummyIQChannel* channel_;
-		IQRouter* router_;
 	public:
 		XMPPRosterControllerTest() {}
 
 		void setUp() {
 			channel_ = new DummyIQChannel();
 			router_ = new IQRouter(channel_);
+			xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
 		}
 
 		void tearDown() {
@@ -35,52 +34,45 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture
 		}
 
 		void testAdd() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			XMPPRosterController controller(router_, xmppRoster);
-			JID testling("foo@bar");
-			CPPUNIT_ASSERT(!xmppRoster->containsJID(testling));
-			boost::shared_ptr<Payload> payload(new RosterPayload());
-			RosterItemPayload item(testling, "Bob", RosterItemPayload::Both);
-			dynamic_cast<RosterPayload*>(payload.get())->addItem(item);
-			controller.handleIQ(IQ::createRequest(IQ::Set, JID(), "eou", payload));
-			CPPUNIT_ASSERT(xmppRoster->containsJID(testling));
+			XMPPRosterController controller(router_, xmppRoster_);
+
+			boost::shared_ptr<RosterPayload> payload(new RosterPayload());
+			payload->addItem(RosterItemPayload(JID("foo@bar.com"), "Bob", RosterItemPayload::Both));
+			channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "eou", payload));
+
+			CPPUNIT_ASSERT(xmppRoster_->containsJID(JID("foo@bar.com")));
+			CPPUNIT_ASSERT_EQUAL(String("Bob"), xmppRoster_->getNameForJID(JID("foo@bar.com")));
 		}
 
 		void testModify() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			XMPPRosterController controller(router_, xmppRoster);
-			JID testling("foo@bar");
-			CPPUNIT_ASSERT(!xmppRoster->containsJID(testling));
-			boost::shared_ptr<Payload> payload1(new RosterPayload());
-			RosterItemPayload item1(testling, "Bob", RosterItemPayload::Both);
-			dynamic_cast<RosterPayload*>(payload1.get())->addItem(item1);
-			controller.handleIQ(IQ::createRequest(IQ::Set, JID(), "eou", payload1));
-			CPPUNIT_ASSERT(xmppRoster->containsJID(testling));
-			CPPUNIT_ASSERT_EQUAL(String("Bob"), xmppRoster->getNameForJID(testling));
-			boost::shared_ptr<Payload> payload2(new RosterPayload());
-			RosterItemPayload item2(testling, "Bob2", RosterItemPayload::Both);
-			dynamic_cast<RosterPayload*>(payload2.get())->addItem(item2);
-			controller.handleIQ(IQ::createRequest(IQ::Set, JID(), "eou", payload2));
-			CPPUNIT_ASSERT_EQUAL(String("Bob2"), xmppRoster->getNameForJID(testling));
+			XMPPRosterController controller(router_, xmppRoster_);
+			boost::shared_ptr<RosterPayload> payload1(new RosterPayload());
+			payload1->addItem(RosterItemPayload(JID("foo@bar"), "Bob", RosterItemPayload::Both));
+			channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id1", payload1));
+
+			boost::shared_ptr<RosterPayload> payload2(new RosterPayload());
+			payload2->addItem(RosterItemPayload(JID("foo@bar"), "Bob2", RosterItemPayload::Both));
+			channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id2", payload2));
+
+			CPPUNIT_ASSERT_EQUAL(String("Bob2"), xmppRoster_->getNameForJID(JID("foo@bar")));
 		}
 
 		void testRemove() {
-			boost::shared_ptr<XMPPRoster> xmppRoster(new XMPPRoster());
-			XMPPRosterController controller(router_, xmppRoster);
-			JID testling("foo@bar");
-			CPPUNIT_ASSERT(!xmppRoster->containsJID(testling));
-			boost::shared_ptr<Payload> payload1(new RosterPayload());
-			RosterItemPayload item1(testling, "Bob", RosterItemPayload::Both);
-			dynamic_cast<RosterPayload*>(payload1.get())->addItem(item1);
-			controller.handleIQ(IQ::createRequest(IQ::Set, JID(), "eou", payload1));
-			CPPUNIT_ASSERT(xmppRoster->containsJID(testling));
-			boost::shared_ptr<Payload> payload2(new RosterPayload());
-			RosterItemPayload item2(testling, "Bob", RosterItemPayload::Remove);
-			dynamic_cast<RosterPayload*>(payload2.get())->addItem(item2);
-			controller.handleIQ(IQ::createRequest(IQ::Set, JID(), "eou", payload2));
-			CPPUNIT_ASSERT(!xmppRoster->containsJID(testling));
+			XMPPRosterController controller(router_, xmppRoster_);
+			boost::shared_ptr<RosterPayload> payload1(new RosterPayload());
+			payload1->addItem(RosterItemPayload(JID("foo@bar"), "Bob", RosterItemPayload::Both));
+			channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id1", payload1));
+
+			boost::shared_ptr<RosterPayload> payload2(new RosterPayload());
+			payload2->addItem(RosterItemPayload(JID("foo@bar"), "Bob", RosterItemPayload::Remove));
+			channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id2", payload2));
+			CPPUNIT_ASSERT(!xmppRoster_->containsJID(JID("foo@bar")));
 		}
 
+	private:
+		DummyIQChannel* channel_;
+		IQRouter* router_;
+		boost::shared_ptr<XMPPRoster> xmppRoster_;
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(XMPPRosterControllerTest);
diff --git a/Swift/Controllers/XMPPRosterController.cpp b/Swift/Controllers/XMPPRosterController.cpp
index 8385f65..46fb40c 100644
--- a/Swift/Controllers/XMPPRosterController.cpp
+++ b/Swift/Controllers/XMPPRosterController.cpp
@@ -21,13 +21,8 @@ namespace Swift {
 /**
  * The controller does not gain ownership of these parameters.
  */
-XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, boost::shared_ptr<XMPPRoster> xmppRoster)
- : iqRouter_(iqRouter), xmppRoster_(xmppRoster) {
-	iqRouter_->addHandler(this);
-}
-
-XMPPRosterController::~XMPPRosterController() {
-	iqRouter_->removeHandler(this);
+XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, boost::shared_ptr<XMPPRoster> xmppRoster) : iqRouter_(iqRouter), rosterPushResponder_(iqRouter), xmppRoster_(xmppRoster) {
+	rosterPushResponder_.onRosterReceived.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1));
 }
 
 void XMPPRosterController::requestRoster() {
@@ -46,13 +41,4 @@ void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload>
 	}
 }
 
-bool XMPPRosterController::handleIQ(boost::shared_ptr<IQ> iq) {
-	if (iq->getType() != IQ::Set || iq->getPayload<RosterPayload>().get() == NULL || iq->getFrom().isValid()) {
-		return false;
-	}
-	handleRosterReceived(iq->getPayload<RosterPayload>());
-	return true;
-}
-
 }
-
diff --git a/Swift/Controllers/XMPPRosterController.h b/Swift/Controllers/XMPPRosterController.h
index 7695ff5..c3c4625 100644
--- a/Swift/Controllers/XMPPRosterController.h
+++ b/Swift/Controllers/XMPPRosterController.h
@@ -4,7 +4,7 @@
 #include "Swiften/Base/String.h"
 #include "Swiften/Elements/IQ.h"
 #include "Swiften/Elements/RosterPayload.h"
-#include "Swiften/Queries/IQHandler.h"
+#include "Swiften/Queries/Responders/RosterPushResponder.h"
 
 #include <boost/signals.hpp>
 #include <boost/shared_ptr.hpp>
@@ -13,19 +13,19 @@ namespace Swift {
 	class IQRouter;
 	class XMPPRoster;
 
-	class XMPPRosterController : public IQHandler {
+	class XMPPRosterController {
 		public:
 			XMPPRosterController(IQRouter *iqRouter, boost::shared_ptr<XMPPRoster> xmppRoster);
-			~XMPPRosterController();
 
 			void requestRoster();
 
 			boost::shared_ptr<XMPPRoster> getXMPPRoster() {return xmppRoster_;};
-			bool handleIQ(boost::shared_ptr<IQ>);
+
+			void handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload);
 
 		private:
 			IQRouter* iqRouter_;
-			void handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload);
+			RosterPushResponder rosterPushResponder_;
 			boost::shared_ptr<XMPPRoster> xmppRoster_;
 	};
 }
diff --git a/Swiften/Queries/Responders/RosterPushResponder.h b/Swiften/Queries/Responders/RosterPushResponder.h
new file mode 100644
index 0000000..69185c8
--- /dev/null
+++ b/Swiften/Queries/Responders/RosterPushResponder.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <boost/signal.hpp>
+
+#include "Swiften/Queries/SetResponder.h"
+#include "Swiften/Elements/RosterPayload.h"
+
+namespace Swift {
+	class RosterPushResponder : public SetResponder<RosterPayload> {
+		public:
+			RosterPushResponder(IQRouter* router) : SetResponder<RosterPayload>(router) {}
+
+		public:
+			boost::signal<void (boost::shared_ptr<RosterPayload>)> onRosterReceived;
+
+		private:
+			virtual bool handleSetRequest(const JID& from, const String& id, boost::shared_ptr<RosterPayload> payload) {
+				onRosterReceived(payload);
+				sendResponse(from, id, boost::shared_ptr<Payload>());
+				return true;
+			}
+	};
+}
-- 
cgit v0.10.2-6-g49f6