diff options
Diffstat (limited to 'Swift/Controllers')
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 6 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 72 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/ContactRosterItem.cpp | 40 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/ContactRosterItem.h | 11 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/ItemOperations/SetMUC.h | 39 | ||||
| -rw-r--r-- | Swift/Controllers/UnitTest/MockChatWindow.h | 4 | 
6 files changed, 166 insertions, 6 deletions
| diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index afcb782..14d1767 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -32,6 +32,7 @@  #include <Swift/Controllers/Roster/GroupRosterItem.h>  #include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h>  #include <Swift/Controllers/Roster/ItemOperations/SetPresence.h> +#include <Swift/Controllers/Roster/ItemOperations/SetMUC.h>  #include <Swift/Controllers/Roster/Roster.h>  #include <Swift/Controllers/Roster/RosterVCardProvider.h>  #include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h> @@ -385,6 +386,7 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {  	appendToJoinParts(joinParts_, event);  	std::string groupName(roleToGroupName(occupant.getRole()));  	roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid)); +	roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation()));  	roster_->getGroup(groupName)->setManualSort(roleToSortName(occupant.getRole()));  	if (joined_) {  		std::string joinString; @@ -537,6 +539,7 @@ void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUC  	std::string group(roleToGroupName(occupant.getRole()));  	roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid));  	roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole())); +	roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation()));  	chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole()))), ChatWindow::DefaultDirection);  	if (nick == nick_) {  		setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); @@ -548,6 +551,9 @@ void MUCController::handleOccupantAffiliationChanged(const std::string& nick, co  	if (nick == nick_) {  		setAvailableRoomActions(affiliation, muc_->getOccupant(nick_).getRole());  	} +	JID jid(nickToJID(nick)); +	MUCOccupant occupant = muc_->getOccupant(nick); +	roster_->applyOnItems(SetMUC(jid, occupant.getRole(), affiliation));  }  std::string MUCController::roleToGroupName(MUCOccupant::Role role) { diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index 291fb22..3652e86 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -9,6 +9,7 @@  #include <boost/algorithm/string.hpp>  #include <hippomocks.h> +#include "Swiften/Base/foreach.h"  #include "Swift/Controllers/XMPPEvents/EventController.h"  #include "Swiften/Presence/DirectedPresenceSender.h"  #include "Swiften/Presence/StanzaChannelPresenceSender.h" @@ -20,6 +21,7 @@  #include "Swiften/Roster/XMPPRoster.h"  #include "Swift/Controllers/UIEvents/UIEventStream.h"  #include "Swift/Controllers/UnitTest/MockChatWindow.h" +#include "Swiften/MUC/UnitTest/MockMUC.h"  #include "Swiften/Client/DummyStanzaChannel.h"  #include "Swiften/Queries/DummyIQChannel.h"  #include "Swiften/Presence/PresenceOracle.h" @@ -33,6 +35,8 @@  #include <Swift/Controllers/Chat/ChatMessageParser.h>  #include <Swift/Controllers/Chat/UserSearchController.h>  #include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h> +#include <Swift/Controllers/Roster/Roster.h> +#include <Swift/Controllers/Roster/GroupRosterItem.h>  #include <Swiften/Crypto/CryptoProvider.h>  using namespace Swift; @@ -48,6 +52,7 @@ class MUCControllerTest : public CppUnit::TestFixture {  	CPPUNIT_TEST(testMessageWithEmptyLabelItem);  	CPPUNIT_TEST(testMessageWithLabelItem);  	CPPUNIT_TEST(testCorrectMessageWithLabelItem); +	CPPUNIT_TEST(testRoleAffiliationStates);  	CPPUNIT_TEST_SUITE_END();  public: @@ -74,7 +79,7 @@ public:  		entityCapsProvider_ = new DummyEntityCapsProvider();  		settings_ = new DummySettingsProvider();  		highlightManager_ = new HighlightManager(settings_); -		muc_ = boost::make_shared<MUC>(stanzaChannel_, iqRouter_, directedPresenceSender_, mucJID_, mucRegistry_); +		muc_ = boost::make_shared<MockMUC>(mucJID_);  		mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);  		chatMessageParser_ = new ChatMessageParser(std::map<std::string, std::string>());  		vcardStorage_ = new VCardMemoryStorage(crypto_.get()); @@ -337,10 +342,73 @@ public:  		CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));  	} +	JID jidFromOccupant(const MUCOccupant& occupant) { +		return JID(mucJID_.toString()+"/"+occupant.getNick()); +	} + +	void testRoleAffiliationStates() { + +		typedef std::map<std::string, MUCOccupant> occupant_map; +		occupant_map occupants; +		occupants.insert(occupant_map::value_type("Kev", MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Owner))); +		occupants.insert(occupant_map::value_type("Remko", MUCOccupant("Remko", MUCOccupant::Participant, MUCOccupant::Owner))); +		occupants.insert(occupant_map::value_type("Bert", MUCOccupant("Bert", MUCOccupant::Participant, MUCOccupant::Owner))); +		occupants.insert(occupant_map::value_type("Ernie", MUCOccupant("Ernie", MUCOccupant::Participant, MUCOccupant::Owner))); + +		/* populate the MUC with fake users */ +		typedef const std::pair<std::string,MUCOccupant> occupantIterator; +		foreach(occupantIterator &occupant, occupants) { +			muc_->insertOccupant(occupant.second); +		} + +		std::vector<MUCOccupant> alterations; +		alterations.push_back(MUCOccupant("Kev", MUCOccupant::Visitor, MUCOccupant::Admin)); +		alterations.push_back(MUCOccupant("Remko", MUCOccupant::Moderator, MUCOccupant::Member)); +		alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::Outcast)); +		alterations.push_back(MUCOccupant("Ernie", MUCOccupant::NoRole, MUCOccupant::Member)); +		alterations.push_back(MUCOccupant("Bert", MUCOccupant::Moderator, MUCOccupant::Owner)); +		alterations.push_back(MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Outcast)); +		alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::NoAffiliation)); +		alterations.push_back(MUCOccupant("Remko", MUCOccupant::NoRole, MUCOccupant::NoAffiliation)); +		alterations.push_back(MUCOccupant("Ernie", MUCOccupant::Visitor, MUCOccupant::Outcast)); + +		foreach(const MUCOccupant& alteration, alterations) { +			/* perform an alteration to a user's role and affiliation */ +			occupant_map::iterator occupant = occupants.find(alteration.getNick()); +			CPPUNIT_ASSERT(occupant != occupants.end()); +			const JID jid = jidFromOccupant(occupant->second); +			/* change the affiliation, leave the role in place */ +			muc_->changeAffiliation(jid, alteration.getAffiliation()); +			occupant->second = MUCOccupant(occupant->first, occupant->second.getRole(), alteration.getAffiliation()); +			testRoleAffiliationStatesVerify(occupants); +			/* change the role, leave the affiliation in place */ +			muc_->changeOccupantRole(jid, alteration.getRole()); +			occupant->second = MUCOccupant(occupant->first, alteration.getRole(), occupant->second.getAffiliation()); +			testRoleAffiliationStatesVerify(occupants); +		} +	} + +	void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) { +		/* verify that the roster is in sync */ +		GroupRosterItem* group = window_->getRosterModel()->getRoot(); +		foreach(RosterItem* rosterItem, group->getChildren()) { +			GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem); +			CPPUNIT_ASSERT(child); +			foreach(RosterItem* childItem, child->getChildren()) { +				ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(childItem); +				CPPUNIT_ASSERT(item); +				std::map<std::string, MUCOccupant>::const_iterator occupant = occupants.find(item->getJID().getResource()); +				CPPUNIT_ASSERT(occupant != occupants.end()); +				CPPUNIT_ASSERT(item->getMUCRole() == occupant->second.getRole()); +				CPPUNIT_ASSERT(item->getMUCAffiliation() == occupant->second.getAffiliation()); +			} +		} +	} +  private:  	JID self_;  	JID mucJID_; -	MUC::ref muc_; +	MockMUC::ref muc_;  	std::string nick_;  	DummyStanzaChannel* stanzaChannel_;  	DummyIQChannel* iqChannel_; diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp index 622b6ae..fde4c97 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.cpp +++ b/Swift/Controllers/Roster/ContactRosterItem.cpp @@ -11,13 +11,15 @@  #include <Swiften/Base/foreach.h>  #include <Swiften/Base/DateTime.h>  #include <Swiften/Elements/Idle.h> - +#include <Swift/Controllers/Intl.h>  #include <Swift/Controllers/Roster/GroupRosterItem.h>  namespace Swift { -ContactRosterItem::ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent) : RosterItem(name, parent), jid_(jid), displayJID_(displayJID), blockState_(BlockingNotSupported) { +ContactRosterItem::ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent) +: RosterItem(name, parent), jid_(jid), displayJID_(displayJID), mucRole_(MUCOccupant::NoRole), mucAffiliation_(MUCOccupant::NoAffiliation), blockState_(BlockingNotSupported) +{  }  ContactRosterItem::~ContactRosterItem() { @@ -137,6 +139,40 @@ void ContactRosterItem::removeGroup(const std::string& group) {  	groups_.erase(std::remove(groups_.begin(), groups_.end(), group), groups_.end());  } +MUCOccupant::Role ContactRosterItem::getMUCRole() const +{ +	return mucRole_; +} + +void ContactRosterItem::setMUCRole(const MUCOccupant::Role& role) +{ +	mucRole_ = role; +} + +MUCOccupant::Affiliation ContactRosterItem::getMUCAffiliation() const +{ +	return mucAffiliation_; +} + +void ContactRosterItem::setMUCAffiliation(const MUCOccupant::Affiliation& affiliation) +{ +	mucAffiliation_ = affiliation; +} + +std::string ContactRosterItem::getMUCAffiliationText() const +{ +	std::string affiliationString; +	switch (mucAffiliation_) { +		case MUCOccupant::Owner: affiliationString = QT_TRANSLATE_NOOP("", "Owner"); break; +		case MUCOccupant::Admin: affiliationString = QT_TRANSLATE_NOOP("", "Admin"); break; +		case MUCOccupant::Member: affiliationString = QT_TRANSLATE_NOOP("", "Member"); break; +		case MUCOccupant::Outcast: affiliationString = QT_TRANSLATE_NOOP("", "Outcast"); break; +		case MUCOccupant::NoAffiliation: affiliationString = ""; break; +	} + +	return affiliationString; +} +  void ContactRosterItem::setSupportedFeatures(const std::set<Feature>& features) {  	features_ = features;  	onDataChanged(); diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h index 6de7909..ab10c66 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.h +++ b/Swift/Controllers/Roster/ContactRosterItem.h @@ -18,6 +18,7 @@  #include <Swiften/Base/boost_bsignals.h>  #include <Swiften/Elements/Presence.h>  #include <Swiften/Elements/StatusShow.h> +#include <Swiften/Elements/MUCOccupant.h>  #include <Swiften/Elements/VCard.h>  #include <Swiften/JID/JID.h> @@ -61,7 +62,13 @@ class ContactRosterItem : public RosterItem {  		/** Only used so a contact can know about the groups it's in*/  		void addGroup(const std::string& group);  		void removeGroup(const std::string& group); -		 + +		MUCOccupant::Role getMUCRole() const; +		void setMUCRole(const MUCOccupant::Role& role); +		MUCOccupant::Affiliation getMUCAffiliation() const; +		void setMUCAffiliation(const MUCOccupant::Affiliation& affiliation); +		std::string getMUCAffiliationText() const; +  		void setSupportedFeatures(const std::set<Feature>& features);  		bool supportsFeature(Feature feature) const; @@ -82,6 +89,8 @@ class ContactRosterItem : public RosterItem {  		boost::shared_ptr<Presence> offlinePresence_;  		boost::shared_ptr<Presence> shownPresence_;  		std::vector<std::string> groups_; +		MUCOccupant::Role mucRole_; +		MUCOccupant::Affiliation mucAffiliation_;  		std::set<Feature> features_;  		BlockState blockState_;  		VCard::ref vcard_; diff --git a/Swift/Controllers/Roster/ItemOperations/SetMUC.h b/Swift/Controllers/Roster/ItemOperations/SetMUC.h new file mode 100644 index 0000000..de40e04 --- /dev/null +++ b/Swift/Controllers/Roster/ItemOperations/SetMUC.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/JID/JID.h> + +#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h> +#include <Swift/Controllers/Roster/ContactRosterItem.h> + +namespace Swift { + +class RosterItem; + +class SetMUC : public RosterItemOperation { +	public: +		SetMUC(const JID& jid, const MUCOccupant::Role& role, const MUCOccupant::Affiliation& affiliation) +		: RosterItemOperation(true, jid), jid_(jid), mucRole_(role), mucAffiliation_(affiliation) { +		} + +		virtual void operator() (RosterItem* item) const { +			ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); +			if (contact && contact->getJID().equals(jid_, JID::WithResource)) { +				contact->setMUCRole(mucRole_); +				contact->setMUCAffiliation(mucAffiliation_); +			} +		} + +	private: +		JID jid_; +		bool mucParticipant_; +		MUCOccupant::Role mucRole_; +		MUCOccupant::Affiliation mucAffiliation_; +}; + +} diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 43779c5..59ed0f1 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -49,7 +49,8 @@ namespace Swift {  			virtual void setSecurityLabelsError() {}  			virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;}  			virtual void setInputEnabled(bool /*enabled*/) {} -			virtual void setRosterModel(Roster* /*roster*/) {} +			virtual void setRosterModel(Roster* roster) { roster_ = roster; } +			Roster* getRosterModel() { return roster_; }  			virtual void setTabComplete(TabComplete*) {}  			void setAckState(const std::string& /*id*/, AckState /*state*/) {} @@ -86,6 +87,7 @@ namespace Swift {  			std::vector<SecurityLabelsCatalog::Item> labels_;  			bool labelsEnabled_;  			SecurityLabelsCatalog::Item label_; +			Roster* roster_;  	};  } | 
 Swift
 Swift