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
@@ -87,11 +87,11 @@ public:
87 chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); 87 chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
88 joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>(); 88 joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>();
89 xmppRoster_ = new XMPPRosterImpl(); 89 xmppRoster_ = new XMPPRosterImpl();
90 mucRegistry_ = new MUCRegistry(); 90 mucRegistry_ = new MUCRegistry();
91 nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); 91 nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
92 presenceOracle_ = new PresenceOracle(stanzaChannel_); 92 presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
93 serverDiscoInfo_ = boost::make_shared<DiscoInfo>(); 93 serverDiscoInfo_ = boost::make_shared<DiscoInfo>();
94 presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); 94 presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
95 directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); 95 directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
96 mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_); 96 mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_);
97 uiEventStream_ = new UIEventStream(); 97 uiEventStream_ = new UIEventStream();
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
@@ -25,10 +25,11 @@
25#include <Swiften/Presence/DirectedPresenceSender.h> 25#include <Swiften/Presence/DirectedPresenceSender.h>
26#include <Swiften/Presence/PresenceOracle.h> 26#include <Swiften/Presence/PresenceOracle.h>
27#include <Swiften/Presence/StanzaChannelPresenceSender.h> 27#include <Swiften/Presence/StanzaChannelPresenceSender.h>
28#include <Swiften/Queries/DummyIQChannel.h> 28#include <Swiften/Queries/DummyIQChannel.h>
29#include <Swiften/Roster/XMPPRoster.h> 29#include <Swiften/Roster/XMPPRoster.h>
30#include <Swiften/Roster/XMPPRosterImpl.h>
30#include <Swiften/VCards/VCardManager.h> 31#include <Swiften/VCards/VCardManager.h>
31#include <Swiften/VCards/VCardMemoryStorage.h> 32#include <Swiften/VCards/VCardMemoryStorage.h>
32 33
33#include <Swift/Controllers/Chat/ChatMessageParser.h> 34#include <Swift/Controllers/Chat/ChatMessageParser.h>
34#include <Swift/Controllers/Chat/MUCController.h> 35#include <Swift/Controllers/Chat/MUCController.h>
@@ -70,11 +71,12 @@ public:
70 iqChannel_ = new DummyIQChannel(); 71 iqChannel_ = new DummyIQChannel();
71 iqRouter_ = new IQRouter(iqChannel_); 72 iqRouter_ = new IQRouter(iqChannel_);
72 eventController_ = new EventController(); 73 eventController_ = new EventController();
73 chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); 74 chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
74 userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>(); 75 userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>();
75 presenceOracle_ = new PresenceOracle(stanzaChannel_); 76 xmppRoster_ = new XMPPRosterImpl();
77 presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
76 presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); 78 presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
77 directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); 79 directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
78 uiEventStream_ = new UIEventStream(); 80 uiEventStream_ = new UIEventStream();
79 avatarManager_ = new NullAvatarManager(); 81 avatarManager_ = new NullAvatarManager();
80 TimerFactory* timerFactory = NULL; 82 TimerFactory* timerFactory = NULL;
@@ -102,10 +104,11 @@ public:
102 delete highlightManager_; 104 delete highlightManager_;
103 delete settings_; 105 delete settings_;
104 delete entityCapsProvider_; 106 delete entityCapsProvider_;
105 delete eventController_; 107 delete eventController_;
106 delete presenceOracle_; 108 delete presenceOracle_;
109 delete xmppRoster_;
107 delete mocks_; 110 delete mocks_;
108 delete uiEventStream_; 111 delete uiEventStream_;
109 delete stanzaChannel_; 112 delete stanzaChannel_;
110 delete presenceSender_; 113 delete presenceSender_;
111 delete directedPresenceSender_; 114 delete directedPresenceSender_;
@@ -440,9 +443,10 @@ private:
440 boost::shared_ptr<CryptoProvider> crypto_; 443 boost::shared_ptr<CryptoProvider> crypto_;
441 VCardManager* vcardManager_; 444 VCardManager* vcardManager_;
442 VCardMemoryStorage* vcardStorage_; 445 VCardMemoryStorage* vcardStorage_;
443 ClientBlockListManager* clientBlockListManager_; 446 ClientBlockListManager* clientBlockListManager_;
444 MUCBookmarkManager* mucBookmarkManager_; 447 MUCBookmarkManager* mucBookmarkManager_;
448 XMPPRoster* xmppRoster_;
445}; 449};
446 450
447CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest); 451CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest);
448 452
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,19 +1,20 @@
1/* 1/*
2 * Copyright (c) 2010-2014 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#include <Swift/Controllers/Roster/RosterController.h> 7#include <Swift/Controllers/Roster/RosterController.h>
8 8
9#include <boost/bind.hpp> 9#include <boost/bind.hpp>
10#include <boost/smart_ptr/make_shared.hpp> 10#include <boost/smart_ptr/make_shared.hpp>
11 11
12#include <Swiften/Avatars/AvatarManager.h>
13#include <Swiften/Base/Path.h>
12#include <Swiften/Base/foreach.h> 14#include <Swiften/Base/foreach.h>
13#include <Swiften/Base/format.h> 15#include <Swiften/Base/format.h>
14#include <Swiften/Base/Path.h>
15#include <Swiften/Client/ClientBlockListManager.h> 16#include <Swiften/Client/ClientBlockListManager.h>
16#include <Swiften/Client/NickManager.h> 17#include <Swiften/Client/NickManager.h>
17#include <Swiften/Client/NickResolver.h> 18#include <Swiften/Client/NickResolver.h>
18#include <Swiften/Disco/EntityCapsManager.h> 19#include <Swiften/Disco/EntityCapsManager.h>
19#include <Swiften/Elements/DiscoInfo.h> 20#include <Swiften/Elements/DiscoInfo.h>
@@ -25,23 +26,26 @@
25#include <Swiften/Queries/IQRouter.h> 26#include <Swiften/Queries/IQRouter.h>
26#include <Swiften/Roster/GetRosterRequest.h> 27#include <Swiften/Roster/GetRosterRequest.h>
27#include <Swiften/Roster/SetRosterRequest.h> 28#include <Swiften/Roster/SetRosterRequest.h>
28#include <Swiften/Roster/XMPPRoster.h> 29#include <Swiften/Roster/XMPPRoster.h>
29#include <Swiften/Roster/XMPPRosterItem.h> 30#include <Swiften/Roster/XMPPRosterItem.h>
31#include <Swiften/VCards/VCardManager.h>
30 32
33#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
31#include <Swift/Controllers/Intl.h> 34#include <Swift/Controllers/Intl.h>
32#include <Swift/Controllers/Roster/GroupRosterItem.h> 35#include <Swift/Controllers/Roster/GroupRosterItem.h>
33#include <Swift/Controllers/Roster/OfflineRosterFilter.h>
34#include <Swift/Controllers/Roster/Roster.h>
35#include <Swift/Controllers/Roster/RosterVCardProvider.h>
36#include <Swift/Controllers/Roster/ItemOperations/AppearOffline.h> 36#include <Swift/Controllers/Roster/ItemOperations/AppearOffline.h>
37#include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h>
38#include <Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h> 37#include <Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h>
38#include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h>
39#include <Swift/Controllers/Roster/ItemOperations/SetBlockingState.h> 39#include <Swift/Controllers/Roster/ItemOperations/SetBlockingState.h>
40#include <Swift/Controllers/Roster/ItemOperations/SetName.h> 40#include <Swift/Controllers/Roster/ItemOperations/SetName.h>
41#include <Swift/Controllers/Roster/ItemOperations/SetPresence.h> 41#include <Swift/Controllers/Roster/ItemOperations/SetPresence.h>
42#include <Swift/Controllers/Roster/ItemOperations/SetVCard.h> 42#include <Swift/Controllers/Roster/ItemOperations/SetVCard.h>
43#include <Swift/Controllers/Roster/OfflineRosterFilter.h>
44#include <Swift/Controllers/Roster/Roster.h>
45#include <Swift/Controllers/Roster/RosterGroupExpandinessPersister.h>
46#include <Swift/Controllers/Roster/RosterVCardProvider.h>
43#include <Swift/Controllers/SettingConstants.h> 47#include <Swift/Controllers/SettingConstants.h>
44#include <Swift/Controllers/UIEvents/AddContactUIEvent.h> 48#include <Swift/Controllers/UIEvents/AddContactUIEvent.h>
45#include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h> 49#include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h>
46#include <Swift/Controllers/UIEvents/RenameGroupUIEvent.h> 50#include <Swift/Controllers/UIEvents/RenameGroupUIEvent.h>
47#include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h> 51#include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.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,55 +1,57 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#pragma once 7#pragma once
8 8
9#include <string>
10#include <set> 9#include <set>
10#include <string>
11 11
12#include <boost/shared_ptr.hpp> 12#include <boost/shared_ptr.hpp>
13 13
14#include <Swiften/Avatars/AvatarManager.h>
14#include <Swiften/Base/boost_bsignals.h> 15#include <Swiften/Base/boost_bsignals.h>
15#include <Swiften/JID/JID.h>
16#include <Swiften/Elements/Presence.h>
17#include <Swiften/Elements/ErrorPayload.h> 16#include <Swiften/Elements/ErrorPayload.h>
17#include <Swiften/Elements/Presence.h>
18#include <Swiften/Elements/RosterPayload.h> 18#include <Swiften/Elements/RosterPayload.h>
19#include <Swiften/Avatars/AvatarManager.h> 19#include <Swiften/Elements/VCard.h>
20#include <Swiften/VCards/VCardManager.h> 20#include <Swiften/JID/JID.h>
21 21
22#include <Swift/Controllers/Roster/ContactRosterItem.h>
22#include <Swift/Controllers/UIEvents/UIEvent.h> 23#include <Swift/Controllers/UIEvents/UIEvent.h>
23#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
24#include <Swift/Controllers/Roster/RosterGroupExpandinessPersister.h>
25 24
26namespace Swift { 25namespace Swift {
26 class AvatarManager;
27 class ClientBlockListManager;
28 class EntityCapsProvider;
29 class EventController;
30 class FileTransferManager;
31 class FileTransferOverview;
27 class IQRouter; 32 class IQRouter;
28 class Roster;
29 class XMPPRoster;
30 class XMPPRosterItem;
31 class MainWindow; 33 class MainWindow;
32 class MainWindowFactory; 34 class MainWindowFactory;
33 class OfflineRosterFilter; 35 class NickManager;
34 class NickResolver; 36 class NickResolver;
37 class OfflineRosterFilter;
35 class PresenceOracle; 38 class PresenceOracle;
39 class Roster;
40 class RosterGroupExpandinessPersister;
41 class RosterVCardProvider;
42 class SettingsProvider;
36 class SubscriptionManager; 43 class SubscriptionManager;
37 class EventController;
38 class SubscriptionRequestEvent; 44 class SubscriptionRequestEvent;
39 class UIEventStream; 45 class UIEventStream;
40 class IQRouter; 46 class VCardManager;
41 class SettingsProvider; 47 class XMPPRoster;
42 class NickManager; 48 class XMPPRosterItem;
43 class EntityCapsProvider;
44 class FileTransferManager;
45 class ClientBlockListManager;
46 class RosterVCardProvider;
47 49
48 class RosterController { 50 class RosterController {
49 public: 51 public:
50 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); 52 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);
51 ~RosterController(); 53 ~RosterController();
52 void showRosterWindow(); 54 void showRosterWindow();
53 void setJID(const JID& jid) { myJID_ = jid; } 55 void setJID(const JID& jid) { myJID_ = jid; }
54 MainWindow* getWindow() {return mainWindow_;} 56 MainWindow* getWindow() {return mainWindow_;}
55 boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest; 57 boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;
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,8 +1,7 @@
1
2/* 1/*
3 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
4 * All rights reserved. 3 * All rights reserved.
5 * See the COPYING file for more information. 4 * See the COPYING file for more information.
6 */ 5 */
7 6
8#include <cppunit/extensions/HelperMacros.h> 7#include <cppunit/extensions/HelperMacros.h>
@@ -26,15 +25,14 @@
26#include <Swiften/Presence/PresenceOracle.h> 25#include <Swiften/Presence/PresenceOracle.h>
27#include <Swiften/Presence/SubscriptionManager.h> 26#include <Swiften/Presence/SubscriptionManager.h>
28#include <Swiften/Queries/DummyIQChannel.h> 27#include <Swiften/Queries/DummyIQChannel.h>
29#include <Swiften/Queries/IQRouter.h> 28#include <Swiften/Queries/IQRouter.h>
30#include <Swiften/Roster/XMPPRosterImpl.h> 29#include <Swiften/Roster/XMPPRosterImpl.h>
30#include <Swiften/VCards/VCardManager.h>
31#include <Swiften/VCards/VCardMemoryStorage.h> 31#include <Swiften/VCards/VCardMemoryStorage.h>
32// #include <Swiften/Elements/Payload.h>
33// #include <Swiften/Elements/RosterItemPayload.h>
34// #include <Swiften/Elements/RosterPayload.h>
35 32
33#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
36#include <Swift/Controllers/Roster/ContactRosterItem.h> 34#include <Swift/Controllers/Roster/ContactRosterItem.h>
37#include <Swift/Controllers/Roster/GroupRosterItem.h> 35#include <Swift/Controllers/Roster/GroupRosterItem.h>
38#include <Swift/Controllers/Roster/Roster.h> 36#include <Swift/Controllers/Roster/Roster.h>
39#include <Swift/Controllers/Roster/RosterController.h> 37#include <Swift/Controllers/Roster/RosterController.h>
40#include <Swift/Controllers/Settings/DummySettingsProvider.h> 38#include <Swift/Controllers/Settings/DummySettingsProvider.h>
@@ -60,10 +58,11 @@ class RosterControllerTest : public CppUnit::TestFixture {
60 CPPUNIT_TEST(testSendRename); 58 CPPUNIT_TEST(testSendRename);
61 CPPUNIT_TEST(testPresence); 59 CPPUNIT_TEST(testPresence);
62 CPPUNIT_TEST(testHighestPresence); 60 CPPUNIT_TEST(testHighestPresence);
63 CPPUNIT_TEST(testNotHighestPresence); 61 CPPUNIT_TEST(testNotHighestPresence);
64 CPPUNIT_TEST(testUnavailablePresence); 62 CPPUNIT_TEST(testUnavailablePresence);
63 CPPUNIT_TEST(testRemoveResultsInUnavailablePresence);
65 CPPUNIT_TEST_SUITE_END(); 64 CPPUNIT_TEST_SUITE_END();
66 65
67 public: 66 public:
68 void setUp() { 67 void setUp() {
69 jid_ = JID("testjid@swift.im/swift"); 68 jid_ = JID("testjid@swift.im/swift");
@@ -73,11 +72,11 @@ class RosterControllerTest : public CppUnit::TestFixture {
73 mucRegistry_ = new MUCRegistry(); 72 mucRegistry_ = new MUCRegistry();
74 nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); 73 nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
75 channel_ = new DummyIQChannel(); 74 channel_ = new DummyIQChannel();
76 router_ = new IQRouter(channel_); 75 router_ = new IQRouter(channel_);
77 stanzaChannel_ = new DummyStanzaChannel(); 76 stanzaChannel_ = new DummyStanzaChannel();
78 presenceOracle_ = new PresenceOracle(stanzaChannel_); 77 presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
79 subscriptionManager_ = new SubscriptionManager(stanzaChannel_); 78 subscriptionManager_ = new SubscriptionManager(stanzaChannel_);
80 eventController_ = new EventController(); 79 eventController_ = new EventController();
81 uiEventStream_ = new UIEventStream(); 80 uiEventStream_ = new UIEventStream();
82 settings_ = new DummySettingsProvider(); 81 settings_ = new DummySettingsProvider();
83 nickManager_ = new DummyNickManager(); 82 nickManager_ = new DummyNickManager();
@@ -317,10 +316,33 @@ class RosterControllerTest : public CppUnit::TestFixture {
317 316
318 CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size()); 317 CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size());
319 assertVectorsEqual(groups, item.getGroups(), __LINE__); 318 assertVectorsEqual(groups, item.getGroups(), __LINE__);
320 } 319 }
321 320
321 void testRemoveResultsInUnavailablePresence() {
322 std::vector<std::string> groups;
323 groups.push_back("testGroup1");
324 JID from("test@testdomain.com");
325 xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
326 Presence::ref lowPresence(new Presence());
327 lowPresence->setFrom(withResource(from, "bob"));
328 lowPresence->setPriority(2);
329 lowPresence->setStatus("Not here");
330 Presence::ref highPresence(new Presence());
331 highPresence->setFrom(withResource(from, "bert"));
332 highPresence->setPriority(10);
333 highPresence->setStatus("So totally here");
334 stanzaChannel_->onPresenceReceived(highPresence);
335 stanzaChannel_->onPresenceReceived(lowPresence);
336
337 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size());
338
339 xmppRoster_->onJIDRemoved(JID("test@testdomain.com"));
340 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size());
341 CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType());
342 }
343
322 void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) { 344 void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) {
323 foreach (const std::string& entry, v1) { 345 foreach (const std::string& entry, v1) {
324 if (std::find(v2.begin(), v2.end(), entry) == v2.end()) { 346 if (std::find(v2.begin(), v2.end(), entry) == v2.end()) {
325 std::stringstream stream; 347 std::stringstream stream;
326 stream << "Couldn't find " << entry << " in v2 (line " << line << ")"; 348 stream << "Couldn't find " << entry << " in v2 (line " << line << ")";
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,25 +1,29 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#include <cppunit/extensions/HelperMacros.h>
8#include <cppunit/extensions/TestFactoryRegistry.h>
9#include <vector> 7#include <vector>
8
10#include <boost/bind.hpp> 9#include <boost/bind.hpp>
11 10
12#include "Swift/Controllers/PresenceNotifier.h" 11#include <cppunit/extensions/HelperMacros.h>
13#include "Swiften/Client/NickResolver.h" 12#include <cppunit/extensions/TestFactoryRegistry.h>
14#include "SwifTools/Notifier/LoggingNotifier.h" 13
15#include "Swiften/Client/DummyStanzaChannel.h" 14#include <Swiften/Avatars/DummyAvatarManager.h>
16#include "Swiften/MUC/MUCRegistry.h" 15#include <Swiften/Client/DummyStanzaChannel.h>
17#include "Swiften/Roster/XMPPRosterImpl.h" 16#include <Swiften/Client/NickResolver.h>
18#include "Swiften/Presence/PresenceOracle.h" 17#include <Swiften/MUC/MUCRegistry.h>
19#include "Swiften/Avatars/DummyAvatarManager.h" 18#include <Swiften/Network/DummyTimerFactory.h>
20#include "Swiften/Network/DummyTimerFactory.h" 19#include <Swiften/Presence/PresenceOracle.h>
20#include <Swiften/Roster/XMPPRosterImpl.h>
21
22#include <Swift/Controllers/PresenceNotifier.h>
23
24#include <SwifTools/Notifier/LoggingNotifier.h>
21 25
22using namespace Swift; 26using namespace Swift;
23 27
24class PresenceNotifierTest : public CppUnit::TestFixture { 28class PresenceNotifierTest : public CppUnit::TestFixture {
25 CPPUNIT_TEST_SUITE(PresenceNotifierTest); 29 CPPUNIT_TEST_SUITE(PresenceNotifierTest);
@@ -52,11 +56,11 @@ class PresenceNotifierTest : public CppUnit::TestFixture {
52 user1 = JID("user1@bar.com/bla"); 56 user1 = JID("user1@bar.com/bla");
53 user2 = JID("user2@foo.com/baz"); 57 user2 = JID("user2@foo.com/baz");
54 avatarManager = new DummyAvatarManager(); 58 avatarManager = new DummyAvatarManager();
55 roster = new XMPPRosterImpl(); 59 roster = new XMPPRosterImpl();
56 nickResolver = new NickResolver(JID("foo@bar.com"), roster, NULL, mucRegistry); 60 nickResolver = new NickResolver(JID("foo@bar.com"), roster, NULL, mucRegistry);
57 presenceOracle = new PresenceOracle(stanzaChannel); 61 presenceOracle = new PresenceOracle(stanzaChannel, roster);
58 timerFactory = new DummyTimerFactory(); 62 timerFactory = new DummyTimerFactory();
59 } 63 }
60 64
61 void tearDown() { 65 void tearDown() {
62 delete timerFactory; 66 delete timerFactory;
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
@@ -47,11 +47,11 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
47 roster = new XMPPRosterImpl(); 47 roster = new XMPPRosterImpl();
48 rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages()->getRosterStorage()); 48 rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages()->getRosterStorage());
49 49
50 subscriptionManager = new SubscriptionManager(getStanzaChannel()); 50 subscriptionManager = new SubscriptionManager(getStanzaChannel());
51 51
52 presenceOracle = new PresenceOracle(getStanzaChannel()); 52 presenceOracle = new PresenceOracle(getStanzaChannel(), roster);
53 presenceOracle->onPresenceChange.connect(boost::ref(onPresenceChange)); 53 presenceOracle->onPresenceChange.connect(boost::ref(onPresenceChange));
54 54
55 stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel()); 55 stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel());
56 directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender); 56 directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender);
57 discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories->getCryptoProvider()); 57 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,37 +1,38 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#include "PresenceOracle.h" 7#include <Swiften/Presence/PresenceOracle.h>
8 8
9#include <boost/bind.hpp> 9#include <boost/bind.hpp>
10 10
11#include <Swiften/Client/StanzaChannel.h> 11#include <Swiften/Client/StanzaChannel.h>
12#include <Swiften/Roster/XMPPRoster.h>
12 13
13namespace Swift { 14namespace Swift {
14 15
15PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel) { 16PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster) : stanzaChannel_(stanzaChannel), xmppRoster_(roster) {
16 stanzaChannel_ = stanzaChannel;
17 stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1)); 17 stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
18 stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1)); 18 stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
19 xmppRoster_->onJIDRemoved.connect(boost::bind(&PresenceOracle::handleJIDRemoved, this, _1));
19} 20}
20 21
21PresenceOracle::~PresenceOracle() { 22PresenceOracle::~PresenceOracle() {
22 stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1)); 23 stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
23 stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1)); 24 stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
25 xmppRoster_->onJIDRemoved.disconnect(boost::bind(&PresenceOracle::handleJIDRemoved, this, _1));
24} 26}
25 27
26void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) { 28void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) {
27 if (available) { 29 if (available) {
28 entries_.clear(); 30 entries_.clear();
29 } 31 }
30} 32}
31 33
32
33void PresenceOracle::handleIncomingPresence(Presence::ref presence) { 34void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
34 JID bareJID(presence->getFrom().toBare()); 35 JID bareJID(presence->getFrom().toBare());
35 if (presence->getType() == Presence::Subscribe) { 36 if (presence->getType() == Presence::Subscribe) {
36 } 37 }
37 else { 38 else {
@@ -41,11 +42,11 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
41 passedPresence = Presence::ref(new Presence()); 42 passedPresence = Presence::ref(new Presence());
42 passedPresence->setType(Presence::Unavailable); 43 passedPresence->setType(Presence::Unavailable);
43 passedPresence->setFrom(bareJID); 44 passedPresence->setFrom(bareJID);
44 passedPresence->setStatus(presence->getStatus()); 45 passedPresence->setStatus(presence->getStatus());
45 } 46 }
46 std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID]; 47 PresenceMap jidMap = entries_[bareJID];
47 if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { 48 if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) {
48 /* Have a bare-JID only presence of offline */ 49 /* Have a bare-JID only presence of offline */
49 jidMap.clear(); 50 jidMap.clear();
50 } else if (passedPresence->getType() == Presence::Available) { 51 } else if (passedPresence->getType() == Presence::Available) {
51 /* Don't have a bare-JID only offline presence once there are available presences */ 52 /* Don't have a bare-JID only offline presence once there are available presences */
@@ -59,10 +60,24 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
59 entries_[bareJID] = jidMap; 60 entries_[bareJID] = jidMap;
60 onPresenceChange(passedPresence); 61 onPresenceChange(passedPresence);
61 } 62 }
62} 63}
63 64
65void PresenceOracle::handleJIDRemoved(const JID& removedJID) {
66 /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
67 Presence::ref unavailablePresence = Presence::ref(new Presence());
68 unavailablePresence->setType(Presence::Unavailable);
69 unavailablePresence->setFrom(removedJID);
70
71 if (entries_.find(removedJID) != entries_.end()) {
72 entries_[removedJID].clear();
73 entries_[removedJID][removedJID] = unavailablePresence;
74 }
75
76 onPresenceChange(unavailablePresence);
77}
78
64Presence::ref PresenceOracle::getLastPresence(const JID& jid) const { 79Presence::ref PresenceOracle::getLastPresence(const JID& jid) const {
65 PresencesMap::const_iterator i = entries_.find(jid.toBare()); 80 PresencesMap::const_iterator i = entries_.find(jid.toBare());
66 if (i == entries_.end()) { 81 if (i == entries_.end()) {
67 return Presence::ref(); 82 return Presence::ref();
68 } 83 }
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,27 +1,27 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#pragma once 7#pragma once
8 8
9#include <map> 9#include <map>
10
11#include <string> 10#include <string>
12#include <Swiften/Elements/Presence.h>
13 11
14#include <Swiften/Base/API.h> 12#include <Swiften/Base/API.h>
15#include <Swiften/Base/boost_bsignals.h> 13#include <Swiften/Base/boost_bsignals.h>
14#include <Swiften/Elements/Presence.h>
16 15
17namespace Swift { 16namespace Swift {
18 class StanzaChannel; 17 class StanzaChannel;
18 class XMPPRoster;
19 19
20 class SWIFTEN_API PresenceOracle { 20 class SWIFTEN_API PresenceOracle {
21 public: 21 public:
22 PresenceOracle(StanzaChannel* stanzaChannel); 22 PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster);
23 ~PresenceOracle(); 23 ~PresenceOracle();
24 24
25 Presence::ref getLastPresence(const JID&) const; 25 Presence::ref getLastPresence(const JID&) const;
26 Presence::ref getHighestPriorityPresence(const JID& bareJID) const; 26 Presence::ref getHighestPriorityPresence(const JID& bareJID) const;
27 std::vector<Presence::ref> getAllPresence(const JID& bareJID) const; 27 std::vector<Presence::ref> getAllPresence(const JID& bareJID) const;
@@ -30,14 +30,16 @@ namespace Swift {
30 boost::signal<void (Presence::ref)> onPresenceChange; 30 boost::signal<void (Presence::ref)> onPresenceChange;
31 31
32 private: 32 private:
33 void handleIncomingPresence(Presence::ref presence); 33 void handleIncomingPresence(Presence::ref presence);
34 void handleStanzaChannelAvailableChanged(bool); 34 void handleStanzaChannelAvailableChanged(bool);
35 void handleJIDRemoved(const JID& removedJID);
35 36
36 private: 37 private:
37 typedef std::map<JID, Presence::ref> PresenceMap; 38 typedef std::map<JID, Presence::ref> PresenceMap;
38 typedef std::map<JID, PresenceMap> PresencesMap; 39 typedef std::map<JID, PresenceMap> PresencesMap;
39 PresencesMap entries_; 40 PresencesMap entries_;
40 StanzaChannel* stanzaChannel_; 41 StanzaChannel* stanzaChannel_;
42 XMPPRoster* xmppRoster_;
41 }; 43 };
42} 44}
43 45
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,19 +1,22 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#include <cppunit/extensions/HelperMacros.h>
8#include <cppunit/extensions/TestFactoryRegistry.h>
9#include <boost/bind.hpp> 7#include <boost/bind.hpp>
10#include <boost/shared_ptr.hpp> 8#include <boost/shared_ptr.hpp>
11 9
12#include <Swiften/Presence/PresenceOracle.h> 10#include <cppunit/extensions/HelperMacros.h>
11#include <cppunit/extensions/TestFactoryRegistry.h>
12
13#include <Swiften/Client/DummyStanzaChannel.h> 13#include <Swiften/Client/DummyStanzaChannel.h>
14#include <Swiften/Presence/PresenceOracle.h>
14#include <Swiften/Presence/SubscriptionManager.h> 15#include <Swiften/Presence/SubscriptionManager.h>
16#include <Swiften/Roster/XMPPRoster.h>
17#include <Swiften/Roster/XMPPRosterImpl.h>
15 18
16using namespace Swift; 19using namespace Swift;
17 20
18class PresenceOracleTest : public CppUnit::TestFixture { 21class PresenceOracleTest : public CppUnit::TestFixture {
19 CPPUNIT_TEST_SUITE(PresenceOracleTest); 22 CPPUNIT_TEST_SUITE(PresenceOracleTest);
@@ -28,11 +31,13 @@ class PresenceOracleTest : public CppUnit::TestFixture {
28 CPPUNIT_TEST_SUITE_END(); 31 CPPUNIT_TEST_SUITE_END();
29 32
30 public: 33 public:
31 void setUp() { 34 void setUp() {
32 stanzaChannel_ = new DummyStanzaChannel(); 35 stanzaChannel_ = new DummyStanzaChannel();
33 oracle_ = new PresenceOracle(stanzaChannel_); 36 xmppRoster_ = new XMPPRosterImpl();
37
38 oracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
34 oracle_->onPresenceChange.connect(boost::bind(&PresenceOracleTest::handlePresenceChange, this, _1)); 39 oracle_->onPresenceChange.connect(boost::bind(&PresenceOracleTest::handlePresenceChange, this, _1));
35 subscriptionManager_ = new SubscriptionManager(stanzaChannel_); 40 subscriptionManager_ = new SubscriptionManager(stanzaChannel_);
36 subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&PresenceOracleTest::handlePresenceSubscriptionRequest, this, _1, _2)); 41 subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&PresenceOracleTest::handlePresenceSubscriptionRequest, this, _1, _2));
37 user1 = JID("user1@foo.com/Foo"); 42 user1 = JID("user1@foo.com/Foo");
38 user1alt = JID("user1@foo.com/Bar"); 43 user1alt = JID("user1@foo.com/Bar");
@@ -40,10 +45,11 @@ class PresenceOracleTest : public CppUnit::TestFixture {
40 } 45 }
41 46
42 void tearDown() { 47 void tearDown() {
43 delete subscriptionManager_; 48 delete subscriptionManager_;
44 delete oracle_; 49 delete oracle_;
50 delete xmppRoster_;
45 delete stanzaChannel_; 51 delete stanzaChannel_;
46 } 52 }
47 53
48 void testHighestPresenceSingle() { 54 void testHighestPresenceSingle() {
49 JID bareJID("alice@wonderland.lit"); 55 JID bareJID("alice@wonderland.lit");
@@ -184,10 +190,11 @@ class PresenceOracleTest : public CppUnit::TestFixture {
184 std::string reason; 190 std::string reason;
185 }; 191 };
186 PresenceOracle* oracle_; 192 PresenceOracle* oracle_;
187 SubscriptionManager* subscriptionManager_; 193 SubscriptionManager* subscriptionManager_;
188 DummyStanzaChannel* stanzaChannel_; 194 DummyStanzaChannel* stanzaChannel_;
195 XMPPRoster* xmppRoster_;
189 std::vector<Presence::ref> changes; 196 std::vector<Presence::ref> changes;
190 std::vector<SubscriptionRequestInfo> subscriptionRequests; 197 std::vector<SubscriptionRequestInfo> subscriptionRequests;
191 JID user1; 198 JID user1;
192 JID user1alt; 199 JID user1alt;
193 JID user2; 200 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,19 +1,24 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#include <Swiften/Roster/XMPPRosterImpl.h> 7#include <Swiften/Roster/XMPPRosterImpl.h>
8
8#include <Swiften/Base/foreach.h> 9#include <Swiften/Base/foreach.h>
9 10
10namespace Swift { 11namespace Swift {
11 12
12XMPPRosterImpl::XMPPRosterImpl() { 13XMPPRosterImpl::XMPPRosterImpl() {
13} 14}
14 15
16XMPPRosterImpl::~XMPPRosterImpl() {
17
18}
19
15void XMPPRosterImpl::addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription) { 20void XMPPRosterImpl::addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription) {
16 JID bareJID(jid.toBare()); 21 JID bareJID(jid.toBare());
17 std::map<JID, XMPPRosterItem>::iterator i = entries_.find(bareJID); 22 std::map<JID, XMPPRosterItem>::iterator i = entries_.find(bareJID);
18 if (i != entries_.end()) { 23 if (i != entries_.end()) {
19 std::string oldName = i->second.getName(); 24 std::string oldName = i->second.getName();
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,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#pragma once 7#pragma once
@@ -14,10 +14,11 @@
14 14
15namespace Swift { 15namespace Swift {
16 class SWIFTEN_API XMPPRosterImpl : public XMPPRoster { 16 class SWIFTEN_API XMPPRosterImpl : public XMPPRoster {
17 public: 17 public:
18 XMPPRosterImpl(); 18 XMPPRosterImpl();
19 virtual ~XMPPRosterImpl();
19 20
20 void addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription); 21 void addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription);
21 void removeContact(const JID& jid); 22 void removeContact(const JID& jid);
22 void clear(); 23 void clear();
23 24