diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-02-05 17:04:44 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-02-05 17:04:44 (GMT) | 
| commit | 0468ee852e54f81043ff9589951c1d9f88a1848e (patch) | |
| tree | d4d7369c470bc4269c309fa84724ae5939365a4d | |
| parent | 374ebf0f8c32c4fd8758af4b8381ac5cff0d151c (diff) | |
| download | swift-0468ee852e54f81043ff9589951c1d9f88a1848e.zip swift-0468ee852e54f81043ff9589951c1d9f88a1848e.tar.bz2 | |
Fixed some bugs with MUC joining.
| -rw-r--r-- | Swiften/Elements/MUCOwnerPayload.h | 2 | ||||
| -rw-r--r-- | Swiften/Elements/MUCPayload.h | 2 | ||||
| -rw-r--r-- | Swiften/MUC/MUC.cpp | 73 | ||||
| -rw-r--r-- | Swiften/MUC/MUC.h | 11 | ||||
| -rw-r--r-- | Swiften/MUC/UnitTest/MUCTest.cpp | 26 | 
5 files changed, 75 insertions, 39 deletions
| diff --git a/Swiften/Elements/MUCOwnerPayload.h b/Swiften/Elements/MUCOwnerPayload.h index c418cc6..6c3e5f0 100644 --- a/Swiften/Elements/MUCOwnerPayload.h +++ b/Swiften/Elements/MUCOwnerPayload.h @@ -13,6 +13,8 @@  namespace Swift {  	class MUCOwnerPayload : public Payload {  		public: +			typedef boost::shared_ptr<MUCOwnerPayload> ref; +  			MUCOwnerPayload() {  			} diff --git a/Swiften/Elements/MUCPayload.h b/Swiften/Elements/MUCPayload.h index 5d7c4f5..b8210e1 100644 --- a/Swiften/Elements/MUCPayload.h +++ b/Swiften/Elements/MUCPayload.h @@ -16,6 +16,8 @@  namespace Swift {  	class MUCPayload : public Payload {  		public: +			typedef boost::shared_ptr<MUCPayload> ref; +  			MUCPayload() {  				maxChars_ = -1;  				maxStanzas_ = -1; diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp index 15a9a4f..486ba27 100644 --- a/Swiften/MUC/MUC.cpp +++ b/Swiften/MUC/MUC.cpp @@ -8,6 +8,7 @@  #include <boost/bind.hpp>  #include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp>  #include "Swiften/Presence/DirectedPresenceSender.h"  #include "Swiften/Client/StanzaChannel.h" @@ -37,30 +38,34 @@ void MUC::joinAs(const String &nick) {  	internalJoin(nick);  } +/** + * Join the MUC with context since date. + */ +void MUC::joinWithContextSince(const String &nick, const boost::posix_time::ptime& since) { +	joinSince_ = since; +	internalJoin(nick); +} +  void MUC::internalJoin(const String &nick) {  	//TODO: password  	//TODO: history request -	mucRegistry->addMUC(getJID());  	joinComplete_ = false; +	joinSucceeded_ = false; + +	mucRegistry->addMUC(getJID()); +  	ownMUCJID = JID(ownMUCJID.getNode(), ownMUCJID.getDomain(), nick); -	presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); -	boost::shared_ptr<Presence> joinPresence(presenceSender->getLastSentUndirectedPresence()); + +	Presence::ref joinPresence = boost::make_shared<Presence>(*presenceSender->getLastSentUndirectedPresence());  	assert(joinPresence->getType() == Presence::Available);  	joinPresence->setTo(ownMUCJID); -	boost::shared_ptr<MUCPayload> mucPayload(new MUCPayload()); +	MUCPayload::ref mucPayload = boost::make_shared<MUCPayload>();  	if (joinSince_ != boost::posix_time::not_a_date_time) {  		mucPayload->setSince(joinSince_);  	}  	joinPresence->addPayload(mucPayload); -	presenceSender->sendPresence(joinPresence); -} -/** - * Join the MUC with context since date. - */ -void MUC::joinWithContextSince(const String &nick, const boost::posix_time::ptime& since) { -	joinSince_ = since; -	internalJoin(nick); +	presenceSender->sendPresence(joinPresence);  }  void MUC::part() { @@ -77,27 +82,34 @@ void MUC::handleUserLeft(LeavingType type) {  	}  	occupants.clear();  	joinComplete_ = false; +	joinSucceeded_ = false;  	presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence);  } -void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) { +void MUC::handleIncomingPresence(Presence::ref presence) {  	if (!isFromMUC(presence->getFrom())) {  		return;  	} -	boost::shared_ptr<MUCUserPayload> mucPayload; -	foreach (boost::shared_ptr<MUCUserPayload> payload, presence->getPayloads<MUCUserPayload>()) { + +	MUCUserPayload::ref mucPayload; +	foreach (MUCUserPayload::ref payload, presence->getPayloads<MUCUserPayload>()) {  		if (payload->getItems().size() > 0 || payload->getStatusCodes().size() > 0) {  			mucPayload = payload;  		}  	} -	if (!joinComplete_) { +	// On the first incoming presence, check if our join has succeeded  +	// (i.e. we start getting non-error presence from the MUC) or not +	if (!joinSucceeded_) {  		if (presence->getType() == Presence::Error) {  			String reason; -			presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence);  			onJoinFailed(presence->getPayload<ErrorPayload>());  			return;  		} +		else { +			joinSucceeded_ = true; +			presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence); +		}  	}  	String nick = presence->getFrom().getResource(); @@ -121,7 +133,8 @@ void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) {  		if (presence->getFrom() == ownMUCJID) {  			handleUserLeft(Part);  			return; -		} else { +		}  +		else {  			std::map<String,MUCOccupant>::iterator i = occupants.find(nick);  			if (i != occupants.end()) {  				//TODO: part type @@ -129,7 +142,8 @@ void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) {  				occupants.erase(i);  			}  		} -	} else if (presence->getType() == Presence::Available) { +	}  +	else if (presence->getType() == Presence::Available) {  		std::map<String, MUCOccupant>::iterator it = occupants.find(nick);  		MUCOccupant occupant(nick, role, affiliation);  		bool isJoin = true; @@ -158,19 +172,24 @@ void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) {  			if (status.code == 110) {  				/* Simply knowing this is your presence is enough, 210 doesn't seem to be necessary. */  				joinComplete_ = true; -				presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); -				ownMUCJID = presence->getFrom(); -				presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); +				if (ownMUCJID != presence->getFrom()) { +					presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); +					ownMUCJID = presence->getFrom(); +					presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence); +				}  				onJoinComplete(getOwnNick());  			}  			if (status.code == 201) {  				/* Room is created and locked */  				/* Currently deal with this by making an instant room */ -				presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); -				ownMUCJID = presence->getFrom(); -				boost::shared_ptr<MUCOwnerPayload> mucPayload(new MUCOwnerPayload()); +				if (ownMUCJID != presence->getFrom()) { +					presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); +					ownMUCJID = presence->getFrom(); +					presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence); +				} +				MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload());  				presenceSender->addDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::DontSendPresence); -				mucPayload->setPayload(boost::shared_ptr<Payload>(new Form(Form::SubmitType))); +				mucPayload->setPayload(boost::make_shared<Form>(Form::SubmitType));  				GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_);  				request->onResponse.connect(boost::bind(&MUC::handleCreationConfigResponse, this, _1, _2));  				request->send(); @@ -180,7 +199,7 @@ void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) {  } -void MUC::handleCreationConfigResponse(boost::shared_ptr<MUCOwnerPayload> /*unused*/, ErrorPayload::ref error) { +void MUC::handleCreationConfigResponse(MUCOwnerPayload::ref /*unused*/, ErrorPayload::ref error) {  	if (error) {  		presenceSender->removeDirectedPresenceReceiver(ownMUCJID, DirectedPresenceSender::AndSendPresence);  		onJoinFailed(error); diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h index 44759d5..cdef292 100644 --- a/Swiften/MUC/MUC.h +++ b/Swiften/MUC/MUC.h @@ -48,14 +48,14 @@ namespace Swift {  			/*void queryRoomItems(); */  			String getCurrentNick();  			void part(); -			void handleIncomingMessage(boost::shared_ptr<Message> message); +			void handleIncomingMessage(Message::ref message);  			/** Expose public so it can be called when e.g. user goes offline */  			void handleUserLeft(LeavingType);  		public:  			boost::signal<void (const String& /*nick*/)> onJoinComplete; -			boost::signal<void (boost::shared_ptr<ErrorPayload>)> onJoinFailed; -			boost::signal<void (boost::shared_ptr<Presence>)> onOccupantPresenceChange; +			boost::signal<void (ErrorPayload::ref)> onJoinFailed; +			boost::signal<void (Presence::ref)> onOccupantPresenceChange;  			boost::signal<void (const String&, const MUCOccupant& /*now*/, const MUCOccupant::Role& /*old*/)> onOccupantRoleChanged;  			boost::signal<void (const String&, const MUCOccupant::Affiliation& /*new*/, const MUCOccupant::Affiliation& /*old*/)> onOccupantAffiliationChanged;  			boost::signal<void (const MUCOccupant&)> onOccupantJoined; @@ -74,9 +74,9 @@ namespace Swift {  			}  		private: -			void handleIncomingPresence(boost::shared_ptr<Presence> presence); +			void handleIncomingPresence(Presence::ref presence);  			void internalJoin(const String& nick); -			void handleCreationConfigResponse(boost::shared_ptr<MUCOwnerPayload>, ErrorPayload::ref); +			void handleCreationConfigResponse(MUCOwnerPayload::ref, ErrorPayload::ref);  		private:  			JID ownMUCJID; @@ -85,6 +85,7 @@ namespace Swift {  			DirectedPresenceSender* presenceSender;  			MUCRegistry* mucRegistry;  			std::map<String, MUCOccupant> occupants; +			bool joinSucceeded_;  			bool joinComplete_;  			boost::bsignals::scoped_connection scopedConnection_;  			boost::posix_time::ptime joinSince_; diff --git a/Swiften/MUC/UnitTest/MUCTest.cpp b/Swiften/MUC/UnitTest/MUCTest.cpp index 1e3582b..fd07711 100644 --- a/Swiften/MUC/UnitTest/MUCTest.cpp +++ b/Swiften/MUC/UnitTest/MUCTest.cpp @@ -21,7 +21,8 @@ using namespace Swift;  class MUCTest : public CppUnit::TestFixture {  		CPPUNIT_TEST_SUITE(MUCTest);  		CPPUNIT_TEST(testJoin); -		CPPUNIT_TEST(testJoin_ChangePresenceDuringJoin); +		CPPUNIT_TEST(testJoin_ChangePresenceDuringJoinDoesNotSendPresenceBeforeJoinSuccess); +		CPPUNIT_TEST(testJoin_ChangePresenceDuringJoinResendsPresenceAfterJoinSuccess);  		/*CPPUNIT_TEST(testJoin_Success);  		CPPUNIT_TEST(testJoin_Fail);*/  		CPPUNIT_TEST_SUITE_END(); @@ -53,15 +54,26 @@ class MUCTest : public CppUnit::TestFixture {  			CPPUNIT_ASSERT_EQUAL(JID("foo@bar.com/Alice"), p->getTo());  		} -		void testJoin_ChangePresenceDuringJoin() { +		void testJoin_ChangePresenceDuringJoinDoesNotSendPresenceBeforeJoinSuccess() {  			MUC::ref testling = createMUC(JID("foo@bar.com"));  			testling->joinAs("Alice");  			presenceSender->sendPresence(Presence::create("Test")); +			CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(channel->sentStanzas.size())); +		} + +		void testJoin_ChangePresenceDuringJoinResendsPresenceAfterJoinSuccess() { +			MUC::ref testling = createMUC(JID("foo@bar.com")); +			testling->joinAs("Alice"); + +			presenceSender->sendPresence(Presence::create("Test")); +			receivePresence(JID("foo@bar.com/Rabbit"), "Here"); +  			CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(channel->sentStanzas.size()));  			Presence::ref p = channel->getStanzaAtIndex<Presence>(2);  			CPPUNIT_ASSERT(p);  			CPPUNIT_ASSERT_EQUAL(JID("foo@bar.com/Alice"), p->getTo()); +			CPPUNIT_ASSERT_EQUAL(String("Test"), p->getStatus());  		}  		/*void testJoin_Success() { @@ -91,14 +103,14 @@ class MUCTest : public CppUnit::TestFixture {  			joinResults.push_back(r);  		} -		/*void receivePresence(const JID& jid, const String& status, const MUCUserPayload::Item& item) { +		void receivePresence(const JID& jid, const String& status) {  			Presence::ref p = Presence::create(status);  			p->setFrom(jid); -			MUCUserPayload::ref mucUserPayload = boost::make_shared<MUCUserPayload>(); -			mucUserPayload->addItem(item); -			p->addPayload(mucUserPayload); +			//MUCUserPayload::ref mucUserPayload = boost::make_shared<MUCUserPayload>(); +			//mucUserPayload->addItem(item); +			//p->addPayload(mucUserPayload);  			channel->onPresenceReceived(p); -		}*/ +		}  	private:  		DummyStanzaChannel* channel; | 
 Swift
 Swift