summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp2
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp6
-rw-r--r--Swift/Controllers/Roster/RosterController.cpp16
-rw-r--r--Swift/Controllers/Roster/RosterController.h44
-rw-r--r--Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp34
-rw-r--r--Swift/Controllers/UnitTest/PresenceNotifierTest.cpp30
-rw-r--r--Swiften/Client/Client.cpp2
-rw-r--r--Swiften/Presence/PresenceOracle.cpp27
-rw-r--r--Swiften/Presence/PresenceOracle.h10
-rw-r--r--Swiften/Presence/UnitTest/PresenceOracleTest.cpp17
-rw-r--r--Swiften/Roster/XMPPRosterImpl.cpp7
-rw-r--r--Swiften/Roster/XMPPRosterImpl.h3
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
@@ -86,13 +86,13 @@ public:
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_);
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
@@ -24,12 +24,13 @@
#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>
@@ -69,13 +70,14 @@ public:
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();
@@ -101,12 +103,13 @@ public:
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_;
@@ -439,10 +442,11 @@ private:
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,20 +1,21 @@
/*
- * 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>
@@ -24,25 +25,28 @@
#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>
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,56 +1,58 @@
/*
- * 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;
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,9 +1,8 @@
-
/*
- * 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>
@@ -25,17 +24,16 @@
#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>
@@ -59,12 +57,13 @@ class RosterControllerTest : public CppUnit::TestFixture {
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();
@@ -72,13 +71,13 @@ class RosterControllerTest : public CppUnit::TestFixture {
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();
@@ -316,12 +315,35 @@ class RosterControllerTest : public CppUnit::TestFixture {
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,26 +1,30 @@
/*
- * 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);
@@ -51,13 +55,13 @@ class PresenceNotifierTest : public CppUnit::TestFixture {
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;
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
@@ -46,13 +46,13 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
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());
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,38 +1,39 @@
/*
- * 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;
@@ -40,13 +41,13 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
/* 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);
@@ -58,12 +59,26 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
}
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;
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,20 +1,23 @@
/*
- * 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);
@@ -27,24 +30,27 @@ class PresenceOracleTest : public CppUnit::TestFixture {
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);
@@ -183,12 +189,13 @@ class PresenceOracleTest : public CppUnit::TestFixture {
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;
};
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,20 +1,25 @@
/*
- * 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();
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,8 +1,8 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
@@ -13,12 +13,13 @@
#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);