summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2015-10-16 10:10:09 (GMT)
committerTobias Markmann <tm@ayena.de>2015-10-16 12:33:11 (GMT)
commit907fdbdab74b72cc4fde2425dc9b2d4d461daf66 (patch)
tree1dc977342eee505c60fcd88f7a67ed5b801b317b /Swift/Controllers/Chat
parentf5b5f35868b3f1fd93906d6458cca965f12c6a5f (diff)
downloadswift-907fdbdab74b72cc4fde2425dc9b2d4d461daf66.zip
swift-907fdbdab74b72cc4fde2425dc9b2d4d461daf66.tar.bz2
Add additional unit tests for Chat <-> JID binding
The recent commit 582ca91 changed the behavior the binding between chat sessions and the full JID of a chat contact. This commit adds additional unit tests verifying the behavior of implemented in 582ca91. This means a chat session binds to the full JID of an incoming message only if the message has a non-empty body text or is a 'typing' chat state notification. It also tests the rebind to another resource if a 'typing'-CSN or a body message is received from that resource. Test-Information: All unit tests pass on OS X 10.10.5. Change-Id: Id3f25d8a3ff78c407ed4b2a97bd421dc4aa58688
Diffstat (limited to 'Swift/Controllers/Chat')
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp254
1 files changed, 233 insertions, 21 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index cf3253a..487f0f9 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -1,16 +1,15 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <boost/bind.hpp>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-
#include <hippomocks.h>
-#include <boost/bind.hpp>
-
#include <Swiften/Avatars/AvatarMemoryStorage.h>
#include <Swiften/Avatars/NullAvatarManager.h>
#include <Swiften/Base/Algorithm.h>
@@ -20,8 +19,7 @@
#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/Disco/DummyEntityCapsProvider.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
@@ -33,12 +31,11 @@
#include <Swiften/Queries/DummyIQChannel.h>
#include <Swiften/Roster/XMPPRosterImpl.h>
#include <Swiften/VCards/VCardManager.h>
-#include <Swiften/VCards/VCardManager.h>
#include <Swiften/VCards/VCardMemoryStorage.h>
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
-#include <Swift/Controllers/Chat/ChatsManager.h>
#include <Swift/Controllers/Chat/ChatController.h>
+#include <Swift/Controllers/Chat/ChatsManager.h>
#include <Swift/Controllers/Chat/MUCController.h>
#include <Swift/Controllers/Chat/UnitTest/MockChatListWindow.h>
#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
@@ -58,13 +55,8 @@
#include <Swift/Controllers/WhiteboardManager.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
-
using namespace Swift;
-class DummyCapsProvider : public CapsProvider {
- DiscoInfo::ref getCaps(const std::string&) const {return DiscoInfo::ref(new DiscoInfo());}
-};
-
class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ChatsManagerTest);
CPPUNIT_TEST(testFirstOpenWindowIncoming);
@@ -79,6 +71,8 @@ class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster);
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth);
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom);
+ CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt);
+ CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
CPPUNIT_TEST_SUITE_END();
public:
@@ -88,7 +82,7 @@ public:
stanzaChannel_ = new DummyStanzaChannel();
iqChannel_ = new DummyIQChannel();
iqRouter_ = new IQRouter(iqChannel_);
- capsProvider_ = new DummyCapsProvider();
+// capsProvider_ = new DummyCapsProvider();
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>();
@@ -101,7 +95,8 @@ public:
directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_);
uiEventStream_ = new UIEventStream();
- entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
+// entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
+ entityCapsProvider_ = new DummyEntityCapsProvider();
chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>();
settings_ = new DummySettingsProvider();
@@ -110,7 +105,7 @@ public:
ftManager_ = new DummyFileTransferManager();
ftOverview_ = new FileTransferOverview(ftManager_);
avatarManager_ = new NullAvatarManager();
- wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsManager_);
+ wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsProvider_);
wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_);
highlightManager_ = new HighlightManager(settings_);
@@ -119,7 +114,7 @@ public:
vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_);
mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_);
clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
- manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, NULL, vcardManager_);
+ manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, NULL, vcardManager_);
manager_->setAvatarManager(avatarManager_);
}
@@ -150,8 +145,7 @@ public:
delete uiEventStream_;
delete mucManager_;
delete xmppRoster_;
- delete entityCapsManager_;
- delete capsProvider_;
+ delete entityCapsProvider_;
delete chatListWindow_;
delete mocks_;
delete settings_;
@@ -429,6 +423,225 @@ public:
testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From);
}
+ void testChatControllerFullJIDBindingOnMessageAndNotReceipt() {
+ JID ownJID("test@test.com/resource");
+ JID sender("foo@test.com");
+ std::vector<JID> senderResource;
+ senderResource.push_back(sender.withResource("resourceA"));
+ senderResource.push_back(sender.withResource("resourceB"));
+
+ // We support delivery receipts.
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ // Open chat window to a sender.
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
+
+ uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender));
+
+ foreach(const JID& senderJID, senderResource) {
+ // The sender supports delivery receipts.
+ DiscoInfo::ref disco = boost::make_shared<DiscoInfo>();
+ disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
+ entityCapsProvider_->caps[senderJID] = disco;
+
+ // The sender is online.
+ Presence::ref senderPresence = boost::make_shared<Presence>();
+ senderPresence->setFrom(senderJID);
+ senderPresence->setTo(ownJID);
+ stanzaChannel_->onPresenceReceived(senderPresence);
+
+ entityCapsProvider_->onCapsChanged(senderJID);
+ }
+
+ // Send first message.
+ window->onSendMessageRequest("hello there", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ foreach(const JID& senderJID, senderResource) {
+ Message::ref receiptReply = boost::make_shared<Message>();
+ receiptReply->setFrom(senderJID);
+ receiptReply->setTo(ownJID);
+
+ boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(0)->getID());
+ receiptReply->addPayload(receipt);
+ manager_->handleIncomingMessage(receiptReply);
+ }
+
+ // Send second message.
+ window->onSendMessageRequest("how are you?", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ foreach(const JID& senderJID, senderResource) {
+ Message::ref receiptReply = boost::make_shared<Message>();
+ receiptReply->setFrom(senderJID);
+ receiptReply->setTo(ownJID);
+
+ boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
+ receiptReply->addPayload(receipt);
+ manager_->handleIncomingMessage(receiptReply);
+ }
+
+ // Reply with a message including a body text.
+ Message::ref reply = boost::make_shared<Message>();
+ reply->setFrom(senderResource[0]);
+ reply->setTo(ownJID);
+ reply->setBody("fine.");
+ manager_->handleIncomingMessage(reply);
+
+ // Send third message.
+ window->onSendMessageRequest("great to hear.", false);
+
+ // The chat session is bound to the full JID of the first resource.
+ CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>());
+
+ // Receive random receipt from second sender resource.
+ reply = boost::make_shared<Message>();
+ reply->setFrom(senderResource[1]);
+ reply->setTo(ownJID);
+
+ boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(2)->getID());
+ reply->addPayload(receipt);
+ manager_->handleIncomingMessage(reply);
+
+ // Send forth message.
+ window->onSendMessageRequest("what else is new?", false);
+
+ // The chat session is bound to the full JID of the first resource.
+ CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
+
+ // Reply with a message including a body text from second resource.
+ reply = boost::make_shared<Message>();
+ reply->setFrom(senderResource[1]);
+ reply->setTo(ownJID);
+ reply->setBody("nothing.");
+ manager_->handleIncomingMessage(reply);
+
+ // Send fifth message.
+ window->onSendMessageRequest("okay", false);
+
+ // The chat session is now bound to the full JID of the second resource.
+ CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(4)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(4)->getPayload<DeliveryReceiptRequest>());
+ }
+
+ void testChatControllerFullJIDBindingOnTypingAndNotActive() {
+ JID ownJID("test@test.com/resource");
+ JID sender("foo@test.com");
+ std::vector<JID> senderResource;
+ senderResource.push_back(sender.withResource("resourceA"));
+ senderResource.push_back(sender.withResource("resourceB"));
+
+ // We support delivery receipts.
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ // Open chat window to a sender.
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
+
+ uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender));
+
+ foreach(const JID& senderJID, senderResource) {
+ // The sender supports delivery receipts.
+ DiscoInfo::ref disco = boost::make_shared<DiscoInfo>();
+ disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
+ entityCapsProvider_->caps[senderJID] = disco;
+
+ // The sender is online.
+ Presence::ref senderPresence = boost::make_shared<Presence>();
+ senderPresence->setFrom(senderJID);
+ senderPresence->setTo(ownJID);
+ stanzaChannel_->onPresenceReceived(senderPresence);
+
+ entityCapsProvider_->onCapsChanged(senderJID);
+ }
+
+ // Send first message.
+ window->onSendMessageRequest("hello there", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ foreach(const JID& senderJID, senderResource) {
+ Message::ref reply = boost::make_shared<Message>();
+ reply->setFrom(senderJID);
+ reply->setTo(ownJID);
+
+ boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>();
+ csn->setChatState(ChatState::Active);
+ reply->addPayload(csn);
+ manager_->handleIncomingMessage(reply);
+ }
+
+ // Send second message.
+ window->onSendMessageRequest("how are you?", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ foreach(const JID& senderJID, senderResource) {
+ Message::ref receiptReply = boost::make_shared<Message>();
+ receiptReply->setFrom(senderJID);
+ receiptReply->setTo(ownJID);
+
+ boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
+ receiptReply->addPayload(receipt);
+ manager_->handleIncomingMessage(receiptReply);
+ }
+
+ // Reply with a message including a CSN.
+ Message::ref reply = boost::make_shared<Message>();
+ reply->setFrom(senderResource[0]);
+ reply->setTo(ownJID);
+
+ boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>();
+ csn->setChatState(ChatState::Composing);
+ reply->addPayload(csn);
+ manager_->handleIncomingMessage(reply);
+
+ // Send third message.
+ window->onSendMessageRequest("great to hear.", false);
+
+ // The chat session is now bound to the full JID of the first resource due to its recent composing message.
+ CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>());
+
+ // Reply with a message including a CSN from the other resource.
+ reply = boost::make_shared<Message>();
+ reply->setFrom(senderResource[1]);
+ reply->setTo(ownJID);
+
+ csn = boost::make_shared<ChatState>();
+ csn->setChatState(ChatState::Composing);
+ reply->addPayload(csn);
+ manager_->handleIncomingMessage(reply);
+
+ // Send third message.
+ window->onSendMessageRequest("ping.", false);
+
+ // The chat session is now bound to the full JID of the second resource due to its recent composing message.
+ CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
+ }
+
void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) {
JID messageJID("testling@test.com/resource1");
xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from);
@@ -487,8 +700,7 @@ private:
MUCSearchWindowFactory* mucSearchWindowFactory_;
MUCRegistry* mucRegistry_;
DirectedPresenceSender* directedPresenceSender_;
- EntityCapsManager* entityCapsManager_;
- CapsProvider* capsProvider_;
+ DummyEntityCapsProvider* entityCapsProvider_;
MUCManager* mucManager_;
DummySettingsProvider* settings_;
ProfileSettingsProvider* profileSettings_;