diff options
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 2 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 6 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/RosterController.cpp | 16 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/RosterController.h | 44 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp | 34 | ||||
| -rw-r--r-- | Swift/Controllers/UnitTest/PresenceNotifierTest.cpp | 30 | ||||
| -rw-r--r-- | Swiften/Client/Client.cpp | 2 | ||||
| -rw-r--r-- | Swiften/Presence/PresenceOracle.cpp | 27 | ||||
| -rw-r--r-- | Swiften/Presence/PresenceOracle.h | 10 | ||||
| -rw-r--r-- | Swiften/Presence/UnitTest/PresenceOracleTest.cpp | 17 | ||||
| -rw-r--r-- | Swiften/Roster/XMPPRosterImpl.cpp | 7 | ||||
| -rw-r--r-- | Swiften/Roster/XMPPRosterImpl.h | 3 |
12 files changed, 132 insertions, 66 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index 487f0f9..f276e92 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -83,19 +83,19 @@ public: iqChannel_ = new DummyIQChannel(); iqRouter_ = new IQRouter(iqChannel_); // capsProvider_ = new DummyCapsProvider(); eventController_ = new EventController(); chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>(); xmppRoster_ = new XMPPRosterImpl(); mucRegistry_ = new MUCRegistry(); nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); - presenceOracle_ = new PresenceOracle(stanzaChannel_); + presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); serverDiscoInfo_ = boost::make_shared<DiscoInfo>(); presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_); uiEventStream_ = new UIEventStream(); // entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); entityCapsProvider_ = new DummyEntityCapsProvider(); chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>(); mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>(); diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index cc4045a..bc6ada2 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -21,18 +21,19 @@ #include <Swiften/Elements/MUCUserPayload.h> #include <Swiften/MUC/MUCBookmarkManager.h> #include <Swiften/MUC/UnitTest/MockMUC.h> #include <Swiften/Network/TimerFactory.h> #include <Swiften/Presence/DirectedPresenceSender.h> #include <Swiften/Presence/PresenceOracle.h> #include <Swiften/Presence/StanzaChannelPresenceSender.h> #include <Swiften/Queries/DummyIQChannel.h> #include <Swiften/Roster/XMPPRoster.h> +#include <Swiften/Roster/XMPPRosterImpl.h> #include <Swiften/VCards/VCardManager.h> #include <Swiften/VCards/VCardMemoryStorage.h> #include <Swift/Controllers/Chat/ChatMessageParser.h> #include <Swift/Controllers/Chat/MUCController.h> #include <Swift/Controllers/Chat/UserSearchController.h> #include <Swift/Controllers/Roster/GroupRosterItem.h> #include <Swift/Controllers/Roster/Roster.h> #include <Swift/Controllers/Settings/DummySettingsProvider.h> @@ -66,19 +67,20 @@ public: nick_ = "aLiCe"; mucJID_ = JID("teaparty@rooms.wonderland.lit"); mocks_ = new MockRepository(); stanzaChannel_ = new DummyStanzaChannel(); iqChannel_ = new DummyIQChannel(); iqRouter_ = new IQRouter(iqChannel_); eventController_ = new EventController(); chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>(); - presenceOracle_ = new PresenceOracle(stanzaChannel_); + xmppRoster_ = new XMPPRosterImpl(); + presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); uiEventStream_ = new UIEventStream(); avatarManager_ = new NullAvatarManager(); TimerFactory* timerFactory = NULL; window_ = new MockChatWindow(); mucRegistry_ = new MUCRegistry(); entityCapsProvider_ = new DummyEntityCapsProvider(); settings_ = new DummySettingsProvider(); @@ -98,18 +100,19 @@ public: delete mucBookmarkManager_; delete clientBlockListManager_; delete vcardManager_; delete vcardStorage_; delete highlightManager_; delete settings_; delete entityCapsProvider_; delete eventController_; delete presenceOracle_; + delete xmppRoster_; delete mocks_; delete uiEventStream_; delete stanzaChannel_; delete presenceSender_; delete directedPresenceSender_; delete iqRouter_; delete iqChannel_; delete mucRegistry_; delete avatarManager_; @@ -436,13 +439,14 @@ private: DummyEntityCapsProvider* entityCapsProvider_; DummySettingsProvider* settings_; HighlightManager* highlightManager_; boost::shared_ptr<ChatMessageParser> chatMessageParser_; boost::shared_ptr<CryptoProvider> crypto_; VCardManager* vcardManager_; VCardMemoryStorage* vcardStorage_; ClientBlockListManager* clientBlockListManager_; MUCBookmarkManager* mucBookmarkManager_; + XMPPRoster* xmppRoster_; }; CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest); diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp index 2d35b6a..73efa43 100644 --- a/Swift/Controllers/Roster/RosterController.cpp +++ b/Swift/Controllers/Roster/RosterController.cpp @@ -1,51 +1,55 @@ /* - * Copyright (c) 2010-2014 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/Controllers/Roster/RosterController.h> #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> +#include <Swiften/Avatars/AvatarManager.h> +#include <Swiften/Base/Path.h> #include <Swiften/Base/foreach.h> #include <Swiften/Base/format.h> -#include <Swiften/Base/Path.h> #include <Swiften/Client/ClientBlockListManager.h> #include <Swiften/Client/NickManager.h> #include <Swiften/Client/NickResolver.h> #include <Swiften/Disco/EntityCapsManager.h> #include <Swiften/Elements/DiscoInfo.h> #include <Swiften/FileTransfer/FileTransferManager.h> #include <Swiften/JID/JID.h> #include <Swiften/Jingle/JingleSessionManager.h> #include <Swiften/Presence/PresenceOracle.h> #include <Swiften/Presence/SubscriptionManager.h> #include <Swiften/Queries/IQRouter.h> #include <Swiften/Roster/GetRosterRequest.h> #include <Swiften/Roster/SetRosterRequest.h> #include <Swiften/Roster/XMPPRoster.h> #include <Swiften/Roster/XMPPRosterItem.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swift/Controllers/FileTransfer/FileTransferOverview.h> #include <Swift/Controllers/Intl.h> #include <Swift/Controllers/Roster/GroupRosterItem.h> -#include <Swift/Controllers/Roster/OfflineRosterFilter.h> -#include <Swift/Controllers/Roster/Roster.h> -#include <Swift/Controllers/Roster/RosterVCardProvider.h> #include <Swift/Controllers/Roster/ItemOperations/AppearOffline.h> -#include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h> #include <Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h> +#include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h> #include <Swift/Controllers/Roster/ItemOperations/SetBlockingState.h> #include <Swift/Controllers/Roster/ItemOperations/SetName.h> #include <Swift/Controllers/Roster/ItemOperations/SetPresence.h> #include <Swift/Controllers/Roster/ItemOperations/SetVCard.h> +#include <Swift/Controllers/Roster/OfflineRosterFilter.h> +#include <Swift/Controllers/Roster/Roster.h> +#include <Swift/Controllers/Roster/RosterGroupExpandinessPersister.h> +#include <Swift/Controllers/Roster/RosterVCardProvider.h> #include <Swift/Controllers/SettingConstants.h> #include <Swift/Controllers/UIEvents/AddContactUIEvent.h> #include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h> #include <Swift/Controllers/UIEvents/RenameGroupUIEvent.h> #include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> #include <Swift/Controllers/UIInterfaces/MainWindow.h> #include <Swift/Controllers/UIInterfaces/MainWindowFactory.h> #include <Swift/Controllers/XMPPEvents/ErrorEvent.h> diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h index f4ae581..545abfc 100644 --- a/Swift/Controllers/Roster/RosterController.h +++ b/Swift/Controllers/Roster/RosterController.h @@ -1,59 +1,61 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include <string> #include <set> +#include <string> #include <boost/shared_ptr.hpp> +#include <Swiften/Avatars/AvatarManager.h> #include <Swiften/Base/boost_bsignals.h> -#include <Swiften/JID/JID.h> -#include <Swiften/Elements/Presence.h> #include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Elements/Presence.h> #include <Swiften/Elements/RosterPayload.h> -#include <Swiften/Avatars/AvatarManager.h> -#include <Swiften/VCards/VCardManager.h> +#include <Swiften/Elements/VCard.h> +#include <Swiften/JID/JID.h> +#include <Swift/Controllers/Roster/ContactRosterItem.h> #include <Swift/Controllers/UIEvents/UIEvent.h> -#include <Swift/Controllers/FileTransfer/FileTransferOverview.h> -#include <Swift/Controllers/Roster/RosterGroupExpandinessPersister.h> namespace Swift { + class AvatarManager; + class ClientBlockListManager; + class EntityCapsProvider; + class EventController; + class FileTransferManager; + class FileTransferOverview; class IQRouter; - class Roster; - class XMPPRoster; - class XMPPRosterItem; class MainWindow; class MainWindowFactory; - class OfflineRosterFilter; + class NickManager; class NickResolver; + class OfflineRosterFilter; class PresenceOracle; + class Roster; + class RosterGroupExpandinessPersister; + class RosterVCardProvider; + class SettingsProvider; class SubscriptionManager; - class EventController; class SubscriptionRequestEvent; class UIEventStream; - class IQRouter; - class SettingsProvider; - class NickManager; - class EntityCapsProvider; - class FileTransferManager; - class ClientBlockListManager; - class RosterVCardProvider; + class VCardManager; + class XMPPRoster; + class XMPPRosterItem; class RosterController { public: - RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager); + RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager); ~RosterController(); void showRosterWindow(); void setJID(const JID& jid) { myJID_ = jid; } MainWindow* getWindow() {return mainWindow_;} boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest; boost::signal<void ()> onSignOutRequest; void handleOwnVCardChanged(VCard::ref vcard); void handleAvatarChanged(const JID& jid); void handlePresenceChanged(Presence::ref presence); diff --git a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp index c396e48..9320af1 100644 --- a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp +++ b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp @@ -1,12 +1,11 @@ - /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/Avatars/NullAvatarManager.h> #include <Swiften/Base/Algorithm.h> @@ -22,23 +21,22 @@ #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h> #include <Swiften/Jingle/JingleSessionManager.h> #include <Swiften/MUC/MUCRegistry.h> #include <Swiften/Presence/PresenceOracle.h> #include <Swiften/Presence/SubscriptionManager.h> #include <Swiften/Queries/DummyIQChannel.h> #include <Swiften/Queries/IQRouter.h> #include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/VCards/VCardManager.h> #include <Swiften/VCards/VCardMemoryStorage.h> -// #include <Swiften/Elements/Payload.h> -// #include <Swiften/Elements/RosterItemPayload.h> -// #include <Swiften/Elements/RosterPayload.h> +#include <Swift/Controllers/FileTransfer/FileTransferOverview.h> #include <Swift/Controllers/Roster/ContactRosterItem.h> #include <Swift/Controllers/Roster/GroupRosterItem.h> #include <Swift/Controllers/Roster/Roster.h> #include <Swift/Controllers/Roster/RosterController.h> #include <Swift/Controllers/Settings/DummySettingsProvider.h> #include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UnitTest/MockMainWindowFactory.h> #include <Swift/Controllers/XMPPEvents/EventController.h> @@ -56,32 +54,33 @@ class RosterControllerTest : public CppUnit::TestFixture { CPPUNIT_TEST(testAdd); CPPUNIT_TEST(testAddSubscription); CPPUNIT_TEST(testReceiveRename); CPPUNIT_TEST(testReceiveRegroup); CPPUNIT_TEST(testSendRename); CPPUNIT_TEST(testPresence); CPPUNIT_TEST(testHighestPresence); CPPUNIT_TEST(testNotHighestPresence); CPPUNIT_TEST(testUnavailablePresence); + CPPUNIT_TEST(testRemoveResultsInUnavailablePresence); CPPUNIT_TEST_SUITE_END(); public: void setUp() { jid_ = JID("testjid@swift.im/swift"); xmppRoster_ = new XMPPRosterImpl(); avatarManager_ = new NullAvatarManager(); mainWindowFactory_ = new MockMainWindowFactory(); mucRegistry_ = new MUCRegistry(); nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); channel_ = new DummyIQChannel(); router_ = new IQRouter(channel_); stanzaChannel_ = new DummyStanzaChannel(); - presenceOracle_ = new PresenceOracle(stanzaChannel_); + presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); subscriptionManager_ = new SubscriptionManager(stanzaChannel_); eventController_ = new EventController(); uiEventStream_ = new UIEventStream(); settings_ = new DummySettingsProvider(); nickManager_ = new DummyNickManager(); capsProvider_ = new DummyCapsProvider(); entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); jingleSessionManager_ = new JingleSessionManager(router_); @@ -313,18 +312,41 @@ class RosterControllerTest : public CppUnit::TestFixture { 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(std::string("Robert"), item.getName()); CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size()); assertVectorsEqual(groups, item.getGroups(), __LINE__); } + void testRemoveResultsInUnavailablePresence() { + std::vector<std::string> groups; + groups.push_back("testGroup1"); + JID from("test@testdomain.com"); + xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); + Presence::ref lowPresence(new Presence()); + lowPresence->setFrom(withResource(from, "bob")); + lowPresence->setPriority(2); + lowPresence->setStatus("Not here"); + Presence::ref highPresence(new Presence()); + highPresence->setFrom(withResource(from, "bert")); + highPresence->setPriority(10); + highPresence->setStatus("So totally here"); + stanzaChannel_->onPresenceReceived(highPresence); + stanzaChannel_->onPresenceReceived(lowPresence); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size()); + + xmppRoster_->onJIDRemoved(JID("test@testdomain.com")); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size()); + CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType()); + } + void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) { foreach (const std::string& entry, v1) { if (std::find(v2.begin(), v2.end(), entry) == v2.end()) { std::stringstream stream; stream << "Couldn't find " << entry << " in v2 (line " << line << ")"; CPPUNIT_FAIL(stream.str()); } } } diff --git a/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp b/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp index 681177a..40530dc 100644 --- a/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp +++ b/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp @@ -1,29 +1,33 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/extensions/TestFactoryRegistry.h> #include <vector> + #include <boost/bind.hpp> -#include "Swift/Controllers/PresenceNotifier.h" -#include "Swiften/Client/NickResolver.h" -#include "SwifTools/Notifier/LoggingNotifier.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Roster/XMPPRosterImpl.h" -#include "Swiften/Presence/PresenceOracle.h" -#include "Swiften/Avatars/DummyAvatarManager.h" -#include "Swiften/Network/DummyTimerFactory.h" +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Avatars/DummyAvatarManager.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Client/NickResolver.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Network/DummyTimerFactory.h> +#include <Swiften/Presence/PresenceOracle.h> +#include <Swiften/Roster/XMPPRosterImpl.h> + +#include <Swift/Controllers/PresenceNotifier.h> + +#include <SwifTools/Notifier/LoggingNotifier.h> using namespace Swift; class PresenceNotifierTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(PresenceNotifierTest); CPPUNIT_TEST(testReceiveFirstPresenceCreatesAvailableNotification); CPPUNIT_TEST(testReceiveSecondPresenceCreatesStatusChangeNotification); CPPUNIT_TEST(testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification); CPPUNIT_TEST(testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification); @@ -48,19 +52,19 @@ class PresenceNotifierTest : public CppUnit::TestFixture { void setUp() { stanzaChannel = new DummyStanzaChannel(); notifier = new LoggingNotifier(); mucRegistry = new MUCRegistry(); user1 = JID("user1@bar.com/bla"); user2 = JID("user2@foo.com/baz"); avatarManager = new DummyAvatarManager(); roster = new XMPPRosterImpl(); nickResolver = new NickResolver(JID("foo@bar.com"), roster, NULL, mucRegistry); - presenceOracle = new PresenceOracle(stanzaChannel); + presenceOracle = new PresenceOracle(stanzaChannel, roster); timerFactory = new DummyTimerFactory(); } void tearDown() { delete timerFactory; delete presenceOracle; delete nickResolver; delete roster; delete avatarManager; diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 3bfdd3f..f1266e9 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -43,19 +43,19 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net softwareVersionResponder = new SoftwareVersionResponder(getIQRouter()); softwareVersionResponder->start(); roster = new XMPPRosterImpl(); rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages()->getRosterStorage()); subscriptionManager = new SubscriptionManager(getStanzaChannel()); - presenceOracle = new PresenceOracle(getStanzaChannel()); + presenceOracle = new PresenceOracle(getStanzaChannel(), roster); presenceOracle->onPresenceChange.connect(boost::ref(onPresenceChange)); stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel()); directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender); discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories->getCryptoProvider()); mucRegistry = new MUCRegistry(); mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry); diff --git a/Swiften/Presence/PresenceOracle.cpp b/Swiften/Presence/PresenceOracle.cpp index 59dff41..e4129fb 100644 --- a/Swiften/Presence/PresenceOracle.cpp +++ b/Swiften/Presence/PresenceOracle.cpp @@ -1,72 +1,87 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include "PresenceOracle.h" +#include <Swiften/Presence/PresenceOracle.h> #include <boost/bind.hpp> #include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Roster/XMPPRoster.h> namespace Swift { -PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel) { - stanzaChannel_ = stanzaChannel; +PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster) : stanzaChannel_(stanzaChannel), xmppRoster_(roster) { stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1)); stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1)); + xmppRoster_->onJIDRemoved.connect(boost::bind(&PresenceOracle::handleJIDRemoved, this, _1)); } PresenceOracle::~PresenceOracle() { stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1)); stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1)); + xmppRoster_->onJIDRemoved.disconnect(boost::bind(&PresenceOracle::handleJIDRemoved, this, _1)); } void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) { if (available) { entries_.clear(); } } - void PresenceOracle::handleIncomingPresence(Presence::ref presence) { JID bareJID(presence->getFrom().toBare()); if (presence->getType() == Presence::Subscribe) { } else { Presence::ref passedPresence = presence; if (presence->getType() == Presence::Unsubscribe) { /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ passedPresence = Presence::ref(new Presence()); passedPresence->setType(Presence::Unavailable); passedPresence->setFrom(bareJID); passedPresence->setStatus(presence->getStatus()); } - std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID]; + PresenceMap jidMap = entries_[bareJID]; if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { /* Have a bare-JID only presence of offline */ jidMap.clear(); } else if (passedPresence->getType() == Presence::Available) { /* Don't have a bare-JID only offline presence once there are available presences */ jidMap.erase(bareJID); } if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) { jidMap.erase(passedPresence->getFrom()); } else { jidMap[passedPresence->getFrom()] = passedPresence; } entries_[bareJID] = jidMap; onPresenceChange(passedPresence); } } +void PresenceOracle::handleJIDRemoved(const JID& removedJID) { + /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ + Presence::ref unavailablePresence = Presence::ref(new Presence()); + unavailablePresence->setType(Presence::Unavailable); + unavailablePresence->setFrom(removedJID); + + if (entries_.find(removedJID) != entries_.end()) { + entries_[removedJID].clear(); + entries_[removedJID][removedJID] = unavailablePresence; + } + + onPresenceChange(unavailablePresence); +} + Presence::ref PresenceOracle::getLastPresence(const JID& jid) const { PresencesMap::const_iterator i = entries_.find(jid.toBare()); if (i == entries_.end()) { return Presence::ref(); } PresenceMap presenceMap = i->second; PresenceMap::const_iterator j = presenceMap.find(jid); if (j != presenceMap.end()) { return j->second; diff --git a/Swiften/Presence/PresenceOracle.h b/Swiften/Presence/PresenceOracle.h index 84d5b3c..f312506 100644 --- a/Swiften/Presence/PresenceOracle.h +++ b/Swiften/Presence/PresenceOracle.h @@ -1,43 +1,45 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <map> - #include <string> -#include <Swiften/Elements/Presence.h> #include <Swiften/Base/API.h> #include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Presence.h> namespace Swift { class StanzaChannel; + class XMPPRoster; class SWIFTEN_API PresenceOracle { public: - PresenceOracle(StanzaChannel* stanzaChannel); + PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster); ~PresenceOracle(); Presence::ref getLastPresence(const JID&) const; Presence::ref getHighestPriorityPresence(const JID& bareJID) const; std::vector<Presence::ref> getAllPresence(const JID& bareJID) const; public: boost::signal<void (Presence::ref)> onPresenceChange; private: void handleIncomingPresence(Presence::ref presence); void handleStanzaChannelAvailableChanged(bool); + void handleJIDRemoved(const JID& removedJID); private: typedef std::map<JID, Presence::ref> PresenceMap; typedef std::map<JID, PresenceMap> PresencesMap; PresencesMap entries_; StanzaChannel* stanzaChannel_; + XMPPRoster* xmppRoster_; }; } diff --git a/Swiften/Presence/UnitTest/PresenceOracleTest.cpp b/Swiften/Presence/UnitTest/PresenceOracleTest.cpp index 41857e1..85dcca9 100644 --- a/Swiften/Presence/UnitTest/PresenceOracleTest.cpp +++ b/Swiften/Presence/UnitTest/PresenceOracleTest.cpp @@ -1,53 +1,59 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> -#include <Swiften/Presence/PresenceOracle.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + #include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Presence/PresenceOracle.h> #include <Swiften/Presence/SubscriptionManager.h> +#include <Swiften/Roster/XMPPRoster.h> +#include <Swiften/Roster/XMPPRosterImpl.h> using namespace Swift; class PresenceOracleTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(PresenceOracleTest); CPPUNIT_TEST(testReceivePresence); CPPUNIT_TEST(testReceivePresenceFromDifferentResources); CPPUNIT_TEST(testSubscriptionRequest); CPPUNIT_TEST(testReconnectResetsPresences); CPPUNIT_TEST(testHighestPresenceSingle); CPPUNIT_TEST(testHighestPresenceMultiple); CPPUNIT_TEST(testHighestPresenceGlobal); CPPUNIT_TEST(testHighestPresenceChangePriority); CPPUNIT_TEST_SUITE_END(); public: void setUp() { stanzaChannel_ = new DummyStanzaChannel(); - oracle_ = new PresenceOracle(stanzaChannel_); + xmppRoster_ = new XMPPRosterImpl(); + + oracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); oracle_->onPresenceChange.connect(boost::bind(&PresenceOracleTest::handlePresenceChange, this, _1)); subscriptionManager_ = new SubscriptionManager(stanzaChannel_); subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&PresenceOracleTest::handlePresenceSubscriptionRequest, this, _1, _2)); user1 = JID("user1@foo.com/Foo"); user1alt = JID("user1@foo.com/Bar"); user2 = JID("user2@bar.com/Bar"); } void tearDown() { delete subscriptionManager_; delete oracle_; + delete xmppRoster_; delete stanzaChannel_; } void testHighestPresenceSingle() { JID bareJID("alice@wonderland.lit"); Presence::ref fiveOn = makeOnline("blah", 5); Presence::ref fiveOff = makeOffline("/blah"); CPPUNIT_ASSERT_EQUAL(Presence::ref(), oracle_->getHighestPriorityPresence(bareJID)); stanzaChannel_->onPresenceReceived(fiveOn); @@ -180,18 +186,19 @@ class PresenceOracleTest : public CppUnit::TestFixture { private: struct SubscriptionRequestInfo { JID jid; std::string reason; }; PresenceOracle* oracle_; SubscriptionManager* subscriptionManager_; DummyStanzaChannel* stanzaChannel_; + XMPPRoster* xmppRoster_; std::vector<Presence::ref> changes; std::vector<SubscriptionRequestInfo> subscriptionRequests; JID user1; JID user1alt; JID user2; }; CPPUNIT_TEST_SUITE_REGISTRATION(PresenceOracleTest); diff --git a/Swiften/Roster/XMPPRosterImpl.cpp b/Swiften/Roster/XMPPRosterImpl.cpp index d438f69..96b9949 100644 --- a/Swiften/Roster/XMPPRosterImpl.cpp +++ b/Swiften/Roster/XMPPRosterImpl.cpp @@ -1,23 +1,28 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Roster/XMPPRosterImpl.h> + #include <Swiften/Base/foreach.h> namespace Swift { XMPPRosterImpl::XMPPRosterImpl() { } +XMPPRosterImpl::~XMPPRosterImpl() { + +} + void XMPPRosterImpl::addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription) { JID bareJID(jid.toBare()); std::map<JID, XMPPRosterItem>::iterator i = entries_.find(bareJID); if (i != entries_.end()) { std::string oldName = i->second.getName(); std::vector<std::string> oldGroups = i->second.getGroups(); i->second = XMPPRosterItem(jid, name, groups, subscription); onJIDUpdated(bareJID, oldName, oldGroups); } diff --git a/Swiften/Roster/XMPPRosterImpl.h b/Swiften/Roster/XMPPRosterImpl.h index 6a11b36..284b18a 100644 --- a/Swiften/Roster/XMPPRosterImpl.h +++ b/Swiften/Roster/XMPPRosterImpl.h @@ -1,27 +1,28 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <map> #include <set> #include <Swiften/Base/API.h> #include <Swiften/Roster/XMPPRoster.h> namespace Swift { class SWIFTEN_API XMPPRosterImpl : public XMPPRoster { public: XMPPRosterImpl(); + virtual ~XMPPRosterImpl(); void addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription); void removeContact(const JID& jid); void clear(); bool containsJID(const JID& jid); RosterItemPayload::Subscription getSubscriptionStateForJID(const JID& jid); std::string getNameForJID(const JID& jid) const; std::vector<std::string> getGroupsForJID(const JID& jid); |
Swift