summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2016-09-16 09:47:40 (GMT)
committerKevin Smith <kevin.smith@isode.com>2016-10-19 19:28:47 (GMT)
commita0199d151c8c0286caa5185988b5604d7e1e2d52 (patch)
treebaff226cd1043bc375d9c5062a197602cdc372c7
parent08a340dbfc9208d1c0e6d574fed244a98e104f01 (diff)
downloadswift-a0199d151c8c0286caa5185988b5604d7e1e2d52.zip
swift-a0199d151c8c0286caa5185988b5604d7e1e2d52.tar.bz2
Fix presence handling of own contact in roster
Previously, presence from your own full JID was not applied to your own roster entry. With this commit all presence changes are applied. Test-Information: Added unit test verifying new behavior. All unit tests pass on OS X 10.11.6. Change-Id: Ib93f487329aa1eec0e876857541780ff44b8cac9
-rw-r--r--Swift/Controllers/Roster/RosterController.cpp4
-rw-r--r--Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp24
2 files changed, 22 insertions, 6 deletions
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index 1c750a3..116ef2e 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -357,58 +357,56 @@ void RosterController::handleSubscriptionRequestAccepted(SubscriptionRequestEven
subscriptionManager_->confirmSubscription(event->getJID());
if (!xmppRoster_->containsJID(event->getJID()) || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::None || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::From) {
subscriptionManager_->requestSubscription(event->getJID());
}
}
void RosterController::handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event) {
subscriptionManager_->cancelSubscription(event->getJID());
}
void RosterController::handleOwnVCardChanged(VCard::ref vcard) {
ownContact_->setVCard(vcard);
mainWindow_->setMyContactRosterItem(ownContact_);
}
void RosterController::handleAvatarChanged(const JID& jid) {
boost::filesystem::path path = avatarManager_->getAvatarPath(jid);
roster_->applyOnItems(SetAvatar(jid, path));
if (jid.equals(myJID_, JID::WithoutResource)) {
mainWindow_->setMyAvatarPath(pathToString(path));
ownContact_->setAvatarPath(pathToString(path));
mainWindow_->setMyContactRosterItem(ownContact_);
}
}
void RosterController::handlePresenceChanged(Presence::ref presence) {
if (presence->getFrom().equals(myJID_, JID::WithResource)) {
ownContact_->applyPresence(presence);
mainWindow_->setMyContactRosterItem(ownContact_);
}
- else {
- handleIncomingPresence(presence);
- }
+ handleIncomingPresence(presence);
}
boost::optional<XMPPRosterItem> RosterController::getItem(const JID& jid) const {
return xmppRoster_->getItem(jid);
}
std::set<std::string> RosterController::getGroups() const {
return xmppRoster_->getGroups();
}
void RosterController::handleOnCapsChanged(const JID& jid) {
DiscoInfo::ref info = entityCapsManager_->getCaps(jid);
if (info) {
std::set<ContactRosterItem::Feature> features;
if (FileTransferManager::isSupportedBy(info)) {
features.insert(ContactRosterItem::FileTransferFeature);
}
if (info->hasFeature(DiscoInfo::WhiteboardFeature)) {
features.insert(ContactRosterItem::WhiteboardFeature);
}
roster_->applyOnItems(SetAvailableFeatures(jid, features));
}
}
}
diff --git a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
index e01f78a..0cd4080 100644
--- a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
@@ -1,93 +1,93 @@
/*
* Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <Swiften/Avatars/NullAvatarManager.h>
#include <Swiften/Base/Algorithm.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/DummyNickManager.h>
#include <Swiften/Client/DummyStanzaChannel.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#include <Swiften/Disco/CapsProvider.h>
#include <Swiften/Disco/EntityCapsManager.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swiften/MUC/MUCRegistry.h>
#include <Swiften/Presence/PresenceOracle.h>
#include <Swiften/Presence/SubscriptionManager.h>
#include <Swiften/Queries/DummyIQChannel.h>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Roster/XMPPRosterImpl.h>
#include <Swiften/VCards/VCardManager.h>
#include <Swiften/VCards/VCardMemoryStorage.h>
#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/RosterController.h>
#include <Swift/Controllers/Settings/DummySettingsProvider.h>
#include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UnitTest/MockMainWindowFactory.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
using namespace Swift;
#define CHILDREN mainWindow_->roster->getRoot()->getChildren()
class DummyCapsProvider : public CapsProvider {
DiscoInfo::ref getCaps(const std::string&) const {return DiscoInfo::ref(new DiscoInfo());}
};
class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(RosterControllerTest);
CPPUNIT_TEST(testAdd);
CPPUNIT_TEST(testAddSubscription);
CPPUNIT_TEST(testReceiveRename);
CPPUNIT_TEST(testReceiveRegroup);
CPPUNIT_TEST(testSendRename);
CPPUNIT_TEST(testPresence);
CPPUNIT_TEST(testHighestPresence);
CPPUNIT_TEST(testNotHighestPresence);
CPPUNIT_TEST(testUnavailablePresence);
CPPUNIT_TEST(testRemoveResultsInUnavailablePresence);
+ CPPUNIT_TEST(testOwnContactInRosterPresence);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
jid_ = JID("testjid@swift.im/swift");
xmppRoster_ = new XMPPRosterImpl();
avatarManager_ = new NullAvatarManager();
mainWindowFactory_ = new MockMainWindowFactory();
mucRegistry_ = new MUCRegistry();
nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, nullptr, mucRegistry_);
channel_ = new DummyIQChannel();
router_ = new IQRouter(channel_);
stanzaChannel_ = new DummyStanzaChannel();
presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
subscriptionManager_ = new SubscriptionManager(stanzaChannel_);
eventController_ = new EventController();
uiEventStream_ = new UIEventStream();
settings_ = new DummySettingsProvider();
nickManager_ = new DummyNickManager();
capsProvider_ = new DummyCapsProvider();
entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
jingleSessionManager_ = new JingleSessionManager(router_);
ftManager_ = new DummyFileTransferManager();
ftOverview_ = new FileTransferOverview(ftManager_);
clientBlockListManager_ = new ClientBlockListManager(router_);
crypto_ = PlatformCryptoProvider::create();
vcardStorage_ = new VCardMemoryStorage(crypto_);
vcardManager_ = new VCardManager(jid_, router_, vcardStorage_);
rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_, clientBlockListManager_, vcardManager_);
@@ -119,61 +119,60 @@ class RosterControllerTest : public CppUnit::TestFixture {
delete uiEventStream_;
delete settings_;
delete xmppRoster_;
}
GroupRosterItem* groupChild(size_t i) {
return dynamic_cast<GroupRosterItem*>(CHILDREN[i]);
}
JID withResource(const JID& jid, const std::string& resource) {
return JID(jid.toBare().toString() + "/" + resource);
}
void testPresence() {
std::vector<std::string> groups;
groups.push_back("testGroup1");
groups.push_back("testGroup2");
JID from("test@testdomain.com");
xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
Presence::ref presence(new Presence());
presence->setFrom(withResource(from, "bob"));
presence->setPriority(2);
presence->setStatus("So totally here");
stanzaChannel_->onPresenceReceived(presence);
ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
CPPUNIT_ASSERT(item);
CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText());
ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[1])->getChildren()[0]);
CPPUNIT_ASSERT(item2);
CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText());
-
}
void testHighestPresence() {
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(lowPresence);
stanzaChannel_->onPresenceReceived(highPresence);
ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
CPPUNIT_ASSERT(item);
CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
}
void testNotHighestPresence() {
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);
@@ -327,62 +326,81 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(jid, item.getJID());
CPPUNIT_ASSERT_EQUAL(std::string("Robert"), item.getName());
CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size());
assertVectorsEqual(groups, item.getGroups(), __LINE__);
}
void testRemoveResultsInUnavailablePresence() {
std::vector<std::string> groups;
groups.push_back("testGroup1");
JID from("test@testdomain.com");
xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
Presence::ref lowPresence(new Presence());
lowPresence->setFrom(withResource(from, "bob"));
lowPresence->setPriority(2);
lowPresence->setStatus("Not here");
Presence::ref highPresence(new Presence());
highPresence->setFrom(withResource(from, "bert"));
highPresence->setPriority(10);
highPresence->setStatus("So totally here");
stanzaChannel_->onPresenceReceived(highPresence);
stanzaChannel_->onPresenceReceived(lowPresence);
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size());
xmppRoster_->onJIDRemoved(JID("test@testdomain.com"));
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size());
CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType());
}
+ void testOwnContactInRosterPresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ groups.push_back("testGroup2");
+ JID from = jid_;
+ xmppRoster_->addContact(from.toBare(), "name", groups, RosterItemPayload::Both);
+ Presence::ref presence(new Presence());
+ presence->setFrom(from);
+ presence->setPriority(2);
+ presence->setStatus("So totally here");
+ stanzaChannel_->onPresenceReceived(presence);
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText());
+ ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[1])->getChildren()[0]);
+ CPPUNIT_ASSERT(item2);
+ CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText());
+ }
+
void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) {
- foreach (const std::string& entry, v1) {
+ for (const auto& 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());
}
}
}
private:
JID jid_;
XMPPRosterImpl* xmppRoster_;
MUCRegistry* mucRegistry_;
AvatarManager* avatarManager_;
MockMainWindowFactory* mainWindowFactory_;
NickManager* nickManager_;
NickResolver* nickResolver_;
RosterController* rosterController_;
DummyIQChannel* channel_;
DummyStanzaChannel* stanzaChannel_;
IQRouter* router_;
PresenceOracle* presenceOracle_;
SubscriptionManager* subscriptionManager_;
EventController* eventController_;
UIEventStream* uiEventStream_;
MockMainWindow* mainWindow_;
DummySettingsProvider* settings_;
DummyCapsProvider* capsProvider_;
EntityCapsManager* entityCapsManager_;
JingleSessionManager* jingleSessionManager_;
FileTransferManager* ftManager_;