From ecc4dc5633b6d3b46ff2ef24d7d976172b9c01ae Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 24 Sep 2010 16:38:29 +0100 Subject: Add logic and tests for modifying roster items. No UI Yet. (Partially) Resolves: #575 (Partially) Resolves: #272 diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp index c8f94f1..79cf3b8 100644 --- a/Swift/Controllers/RosterController.cpp +++ b/Swift/Controllers/RosterController.cpp @@ -29,7 +29,8 @@ #include "Swiften/Roster/XMPPRoster.h" #include "Swift/Controllers/UIEvents/AddContactUIEvent.h" #include "Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h" - +#include "Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h" +#include "Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h" namespace Swift { @@ -172,7 +173,42 @@ void RosterController::handleUIEvent(boost::shared_ptr event) { return; } - + boost::shared_ptr renameEvent = boost::dynamic_pointer_cast(event); + if (renameEvent) { + JID contact(renameEvent->getJID()); + RosterItemPayload item(contact, renameEvent->getNewName(), xmppRoster_->getSubscriptionStateForJID(contact)); + item.setGroups(xmppRoster_->getGroupsForJID(contact)); + boost::shared_ptr roster(new RosterPayload()); + roster->addItem(item); + boost::shared_ptr request(new SetRosterRequest(roster, iqRouter_)); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + return; + } + boost::shared_ptr regroupEvent = boost::dynamic_pointer_cast(event); + if (regroupEvent) { + JID contact(regroupEvent->getJID()); + RosterItemPayload item(contact, xmppRoster_->getNameForJID(contact), xmppRoster_->getSubscriptionStateForJID(contact)); + std::vector newGroups; + const std::vector addedGroups = regroupEvent->getAddedGroups(); + const std::vector removedGroups = regroupEvent->getRemovedGroups(); + foreach (const String& oldGroup, xmppRoster_->getGroupsForJID(contact)) { + if (std::find(removedGroups.begin(), removedGroups.end(), oldGroup) == removedGroups.end() + && std::find(addedGroups.begin(), addedGroups.end(), oldGroup) == addedGroups.end()) { + newGroups.push_back(oldGroup); + } + } + foreach (const String& newGroup, regroupEvent->getAddedGroups()) { + newGroups.push_back(newGroup); + } + item.setGroups(newGroups); + boost::shared_ptr roster(new RosterPayload()); + roster->addItem(item); + boost::shared_ptr request(new SetRosterRequest(roster, iqRouter_)); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + return; + } } void RosterController::handleRosterSetError(boost::optional error, boost::shared_ptr rosterPayload) { diff --git a/Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h new file mode 100644 index 0000000..b8552b3 --- /dev/null +++ b/Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include +#include + +#include "Swift/Controllers/UIEvents/UIEvent.h" +#include "Swiften/MUC/MUCBookmark.h" + +namespace Swift { + /** + * An event for regrouping a roster item. + * This doesn't need to cover all groups, so it's valid to have the + * contact in several groups that are neither removedGroups or addedGroups. + */ + class RegroupRosterItemUIEvent : public UIEvent { + public: + RegroupRosterItemUIEvent(const JID& jid, const std::vector& addedGroups, const std::vector& removedGroups) : jid_(jid), addedGroups_(addedGroups), removedGroups_(removedGroups) {} + + const JID& getJID() const {return jid_;} + const std::vector& getAddedGroups() const {return addedGroups_;} + const std::vector& getRemovedGroups() const {return removedGroups_;} + + private: + JID jid_; + std::vector addedGroups_; + std::vector removedGroups_; + }; +} diff --git a/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h new file mode 100644 index 0000000..4b550e6 --- /dev/null +++ b/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include + +#include "Swift/Controllers/UIEvents/UIEvent.h" +#include "Swiften/MUC/MUCBookmark.h" + +namespace Swift { + class RenameRosterItemUIEvent : public UIEvent { + public: + RenameRosterItemUIEvent(const JID& jid, const String& newName) : jid_(jid), newName_(newName) {} + + const JID& getJID() const {return jid_;} + const String& getNewName() const {return newName_;} + + private: + JID jid_; + String newName_; + }; +} diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h index 4709499..5d0c14e 100644 --- a/Swift/Controllers/UIInterfaces/MainWindow.h +++ b/Swift/Controllers/UIInterfaces/MainWindow.h @@ -26,7 +26,6 @@ namespace Swift { virtual void setMyStatusType(StatusShow::Type type) = 0; virtual void setRosterModel(Roster* roster) = 0; - boost::signal onStartChatRequest; boost::signal onChangeStatusRequest; boost::signal onShowOfflineToggled; boost::signal onSignOutRequest; diff --git a/Swift/Controllers/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/UnitTest/RosterControllerTest.cpp index de46588..4ecc4c8 100644 --- a/Swift/Controllers/UnitTest/RosterControllerTest.cpp +++ b/Swift/Controllers/UnitTest/RosterControllerTest.cpp @@ -26,6 +26,8 @@ #include "Swiften/Presence/PresenceSender.h" #include "Swift/Controllers/NickResolver.h" #include "Swift/Controllers/UIEvents/UIEventStream.h" +#include "Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h" +#include "Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h" #include "Swiften/MUC/MUCRegistry.h" using namespace Swift; @@ -37,7 +39,9 @@ class RosterControllerTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(RosterControllerTest); CPPUNIT_TEST(testAdd); CPPUNIT_TEST(testAddSubscription); - CPPUNIT_TEST(testRename); + CPPUNIT_TEST(testReceiveRename); + CPPUNIT_TEST(testSendRename); + CPPUNIT_TEST(testSendRegroup); CPPUNIT_TEST_SUITE_END(); public: @@ -107,7 +111,7 @@ class RosterControllerTest : public CppUnit::TestFixture }; - void testRename() { + void testReceiveRename() { std::vector groups; JID jid("test@testdomain.com"); xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both); @@ -121,6 +125,71 @@ class RosterControllerTest : public CppUnit::TestFixture CPPUNIT_ASSERT_EQUAL(String("NewName"), groupChild(0)->getChildren()[0]->getDisplayName()); }; + void testSendRename() { + JID jid("testling@wonderland.lit"); + std::vector groups; + groups.push_back("Friends"); + groups.push_back("Enemies"); + xmppRoster_->addContact(jid, "Bob", groups, RosterItemPayload::From); + CPPUNIT_ASSERT_EQUAL(groups.size(), xmppRoster_->getGroupsForJID(jid).size()); + uiEventStream_->send(boost::shared_ptr(new RenameRosterItemUIEvent(jid, "Robert"))); + CPPUNIT_ASSERT_EQUAL(static_cast(1), channel_->iqs_.size()); + CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType()); + boost::shared_ptr payload = channel_->iqs_[0]->getPayload(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), payload->getItems().size()); + RosterItemPayload item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(jid, item.getJID()); + CPPUNIT_ASSERT_EQUAL(String("Robert"), item.getName()); + + CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size()); + assertVectorsEqual(groups, item.getGroups(), __LINE__); + } + + void testSendRegroup() { + JID jid("testling@wonderland.lit"); + String friends("Friends"); + String enemies("Ememies"); + String people("People"); + String contacts("Contacts"); + std::vector oldGroups; + oldGroups.push_back(friends); + oldGroups.push_back(enemies); + std::vector newGroups; + newGroups.push_back(friends); + newGroups.push_back(people); + newGroups.push_back(contacts); + std::vector addedGroups; + addedGroups.push_back(people); + addedGroups.push_back(contacts); + std::vector removedGroups; + removedGroups.push_back(enemies); + + + xmppRoster_->addContact(jid, "Bob", oldGroups, RosterItemPayload::From); + CPPUNIT_ASSERT_EQUAL(oldGroups.size(), xmppRoster_->getGroupsForJID(jid).size()); + uiEventStream_->send(boost::shared_ptr(new RegroupRosterItemUIEvent(jid, addedGroups, removedGroups))); + CPPUNIT_ASSERT_EQUAL(static_cast(1), channel_->iqs_.size()); + CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType()); + boost::shared_ptr payload = channel_->iqs_[0]->getPayload(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), payload->getItems().size()); + RosterItemPayload item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(jid, item.getJID()); + CPPUNIT_ASSERT_EQUAL(String("Bob"), item.getName()); + + CPPUNIT_ASSERT_EQUAL(newGroups.size(), item.getGroups().size()); + assertVectorsEqual(newGroups, item.getGroups(), __LINE__); + } + + void assertVectorsEqual(const std::vector& v1, const std::vector& v2, int line) { + foreach (const String& entry, v1) { + if (std::find(v2.begin(), v2.end(), entry) == v2.end()) { + std::stringstream stream; + stream << "Couldn't find " << entry.getUTF8String() << " in v2 (line " << line << ")"; + CPPUNIT_FAIL(stream.str()); + } + } + } + private: JID jid_; XMPPRoster* xmppRoster_; -- cgit v0.10.2-6-g49f6