diff options
| author | Tobias Markmann <tm@ayena.de> | 2015-09-14 15:08:39 (GMT) |
|---|---|---|
| committer | Kevin Smith <kevin.smith@isode.com> | 2015-10-16 14:58:03 (GMT) |
| commit | 9e6ee0f262e7dc663f4c706b16a346a268f425aa (patch) | |
| tree | 5926fd9cc9dec1233f95239b259a7730f99a5a72 | |
| parent | 8da6e35afab55d7232d47575faea2bde7cd44ece (diff) | |
| download | swift-9e6ee0f262e7dc663f4c706b16a346a268f425aa.zip swift-9e6ee0f262e7dc663f4c706b16a346a268f425aa.tar.bz2 | |
Mark removed contacts as unavailable in Swift
When removing a contact, a XMPP client will not receive an explicit
unavailable presence stanza for the contact from the server. Because
of that Swift used to show removed contacts still with their old
presence in the Chats tab or the chat view.
With this patch, the PresenceOracle will flush all known presence
of a contact as soon as the JID is removed from the roster. An
unavailable presence will stored under the removed bare JID and
is emitted via the PresenceOracle::onPresenceChange signal.
Test-Information:
Added a unit test verifying this behavior. Tested the behavior with
two scenarios:
a) Account A and B adding each other and accepting the subscription
request. Starting a chat between A and B. After removing B in A's
account, B used to be shown as available in the chat view and the
Chats tab. With this patch B is shown as unavailable.
b) Account A and B adding each other and accepting the subscription
request. A removing B, and B removing A. After A adds B again,
B used to be shown with the old presence even before B accepted
the subscription request. This behavior is also fixed with this
patch, not showing B as online until B accepted the subscription
request.
Change-Id: Iba97d3bedd0ac962ea00b25a0d2ed6106ed55a55
| -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 | |||
| @@ -89,7 +89,7 @@ public: | |||
| 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_); |
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 | |||
| @@ -27,6 +27,7 @@ | |||
| 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 | ||
| @@ -72,7 +73,8 @@ public: | |||
| 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(); |
| @@ -104,6 +106,7 @@ public: | |||
| 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_; |
| @@ -442,6 +445,7 @@ private: | |||
| 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 | ||
| 447 | CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest); | 451 | 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,5 +1,5 @@ | |||
| 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 | */ |
| @@ -9,9 +9,10 @@ | |||
| 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> |
| @@ -27,19 +28,22 @@ | |||
| 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> |
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,53 +1,55 @@ | |||
| 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 | ||
| 26 | namespace Swift { | 25 | namespace 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; } |
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,6 +1,5 @@ | |||
| 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 | */ |
| @@ -28,11 +27,10 @@ | |||
| 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> |
| @@ -62,6 +60,7 @@ class RosterControllerTest : public CppUnit::TestFixture { | |||
| 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: |
| @@ -75,7 +74,7 @@ class RosterControllerTest : public CppUnit::TestFixture { | |||
| 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(); |
| @@ -319,6 +318,29 @@ class RosterControllerTest : public CppUnit::TestFixture { | |||
| 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()) { |
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,23 +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 | #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 | ||
| 22 | using namespace Swift; | 26 | using namespace Swift; |
| 23 | 27 | ||
| @@ -54,7 +58,7 @@ class PresenceNotifierTest : public CppUnit::TestFixture { | |||
| 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 | ||
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 | |||
| @@ -49,7 +49,7 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net | |||
| 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()); |
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,26 +1,28 @@ | |||
| 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 | ||
| 13 | namespace Swift { | 14 | namespace Swift { |
| 14 | 15 | ||
| 15 | PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel) { | 16 | PresenceOracle::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 | ||
| 21 | PresenceOracle::~PresenceOracle() { | 22 | PresenceOracle::~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 | ||
| 26 | void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) { | 28 | void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) { |
| @@ -29,7 +31,6 @@ void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) { | |||
| 29 | } | 31 | } |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | |||
| 33 | void PresenceOracle::handleIncomingPresence(Presence::ref presence) { | 34 | void 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) { |
| @@ -43,7 +44,7 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) { | |||
| 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(); |
| @@ -61,6 +62,20 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) { | |||
| 61 | } | 62 | } |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 65 | void 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 | |||
| 64 | Presence::ref PresenceOracle::getLastPresence(const JID& jid) const { | 79 | Presence::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()) { |
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,5 +1,5 @@ | |||
| 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 | */ |
| @@ -7,19 +7,19 @@ | |||
| 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 | ||
| 17 | namespace Swift { | 16 | namespace 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; |
| @@ -32,12 +32,14 @@ namespace Swift { | |||
| 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,17 +1,20 @@ | |||
| 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 | ||
| 16 | using namespace Swift; | 19 | using namespace Swift; |
| 17 | 20 | ||
| @@ -30,7 +33,9 @@ class PresenceOracleTest : public CppUnit::TestFixture { | |||
| 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)); |
| @@ -42,6 +47,7 @@ class PresenceOracleTest : public CppUnit::TestFixture { | |||
| 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 | ||
| @@ -186,6 +192,7 @@ class PresenceOracleTest : public CppUnit::TestFixture { | |||
| 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; |
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,10 +1,11 @@ | |||
| 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 | ||
| 10 | namespace Swift { | 11 | namespace Swift { |
| @@ -12,6 +13,10 @@ namespace Swift { | |||
| 12 | XMPPRosterImpl::XMPPRosterImpl() { | 13 | XMPPRosterImpl::XMPPRosterImpl() { |
| 13 | } | 14 | } |
| 14 | 15 | ||
| 16 | XMPPRosterImpl::~XMPPRosterImpl() { | ||
| 17 | |||
| 18 | } | ||
| 19 | |||
| 15 | void XMPPRosterImpl::addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription) { | 20 | void 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); |
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,5 +1,5 @@ | |||
| 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 | */ |
| @@ -16,6 +16,7 @@ namespace 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); |
Swift