diff options
-rw-r--r-- | Swift/Controllers/RosterController.cpp | 40 | ||||
-rw-r--r-- | Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h | 34 | ||||
-rw-r--r-- | Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h | 26 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/MainWindow.h | 1 | ||||
-rw-r--r-- | Swift/Controllers/UnitTest/RosterControllerTest.cpp | 73 |
5 files changed, 169 insertions, 5 deletions
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<UIEvent> event) { return; } - + boost::shared_ptr<RenameRosterItemUIEvent> renameEvent = boost::dynamic_pointer_cast<RenameRosterItemUIEvent>(event); + if (renameEvent) { + JID contact(renameEvent->getJID()); + RosterItemPayload item(contact, renameEvent->getNewName(), xmppRoster_->getSubscriptionStateForJID(contact)); + item.setGroups(xmppRoster_->getGroupsForJID(contact)); + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->addItem(item); + boost::shared_ptr<SetRosterRequest> request(new SetRosterRequest(roster, iqRouter_)); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + return; + } + boost::shared_ptr<RegroupRosterItemUIEvent> regroupEvent = boost::dynamic_pointer_cast<RegroupRosterItemUIEvent>(event); + if (regroupEvent) { + JID contact(regroupEvent->getJID()); + RosterItemPayload item(contact, xmppRoster_->getNameForJID(contact), xmppRoster_->getSubscriptionStateForJID(contact)); + std::vector<String> newGroups; + const std::vector<String> addedGroups = regroupEvent->getAddedGroups(); + const std::vector<String> 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<RosterPayload> roster(new RosterPayload()); + roster->addItem(item); + boost::shared_ptr<SetRosterRequest> request(new SetRosterRequest(roster, iqRouter_)); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + return; + } } void RosterController::handleRosterSetError(boost::optional<ErrorPayload> error, boost::shared_ptr<RosterPayload> 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 <boost/shared_ptr.hpp> +#include <vector> + +#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<String>& addedGroups, const std::vector<String>& removedGroups) : jid_(jid), addedGroups_(addedGroups), removedGroups_(removedGroups) {} + + const JID& getJID() const {return jid_;} + const std::vector<String>& getAddedGroups() const {return addedGroups_;} + const std::vector<String>& getRemovedGroups() const {return removedGroups_;} + + private: + JID jid_; + std::vector<String> addedGroups_; + std::vector<String> 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 <boost/shared_ptr.hpp> + +#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<void (const JID&)> onStartChatRequest; boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest; boost::signal<void (bool)> onShowOfflineToggled; boost::signal<void ()> 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<String> 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<String> 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<UIEvent>(new RenameRosterItemUIEvent(jid, "Robert"))); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), channel_->iqs_.size()); + CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType()); + boost::shared_ptr<RosterPayload> payload = channel_->iqs_[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(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<String> oldGroups; + oldGroups.push_back(friends); + oldGroups.push_back(enemies); + std::vector<String> newGroups; + newGroups.push_back(friends); + newGroups.push_back(people); + newGroups.push_back(contacts); + std::vector<String> addedGroups; + addedGroups.push_back(people); + addedGroups.push_back(contacts); + std::vector<String> 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<UIEvent>(new RegroupRosterItemUIEvent(jid, addedGroups, removedGroups))); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), channel_->iqs_.size()); + CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType()); + boost::shared_ptr<RosterPayload> payload = channel_->iqs_[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(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<String>& v1, const std::vector<String>& 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_; |