summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp20
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp31
2 files changed, 47 insertions, 4 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 503a050..e2751f7 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -466,10 +466,22 @@ std::string ChatController::getStatusChangeString(boost::shared_ptr<Presence> pr
void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresence) {
bool relevantPresence = false;
- if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) {
- // Presence matches ChatController JID.
- newPresence = presenceOracle_->getAccountPresence(toJID_);
- relevantPresence = true;
+ if (isInMUC_) {
+ // For MUC participants we only have a single presence to choose one and
+ // even for multi-session nicknames multiple resources are not distinguishable
+ // to other participants.
+ if (toJID_.equals(newPresence->getFrom(), JID::WithResource)) {
+ relevantPresence = true;
+ }
+ }
+ else {
+ // For standard chats we retrieve the account presence from the PresenceOracle,
+ // as there can be multiple presences to choose from.
+ if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) {
+ // Presence matches ChatController JID.
+ newPresence = presenceOracle_->getAccountPresence(toJID_);
+ relevantPresence = true;
+ }
}
if (!relevantPresence) {
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 281783e..5f89f62 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -73,6 +73,7 @@ class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom);
CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt);
CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
+ CPPUNIT_TEST(testChatControllerPMPresenceHandling);
CPPUNIT_TEST_SUITE_END();
public:
@@ -642,6 +643,36 @@ public:
CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
}
+ void testChatControllerPMPresenceHandling() {
+ JID participantA = JID("test@rooms.test.com/participantA");
+ JID participantB = JID("test@rooms.test.com/participantB");
+
+ mucRegistry_->addMUC("test@rooms.test.com");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window);
+
+ uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(participantA))));
+
+ Presence::ref presence = Presence::create();
+ presence->setFrom(participantA);
+ presence->setShow(StatusShow::Online);
+ stanzaChannel_->onPresenceReceived(presence);
+ CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_));
+
+ presence = Presence::create();
+ presence->setFrom(participantB);
+ presence->setShow(StatusShow::Away);
+ stanzaChannel_->onPresenceReceived(presence);
+
+ presence = Presence::create();
+ presence->setFrom(participantA);
+ presence->setShow(StatusShow::None);
+ presence->setType(Presence::Unavailable);
+ stanzaChannel_->onPresenceReceived(presence);
+ CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_));
+ }
+
void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) {
JID messageJID("testling@test.com/resource1");
xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from);