diff options
Diffstat (limited to 'Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp')
-rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 269 |
1 files changed, 253 insertions, 16 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index 8fc26b5..954dd2f 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -32,9 +32,13 @@ #include <Swiften/Elements/Forwarded.h> #include <Swiften/Elements/MUCInvitationPayload.h> #include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/Elements/PrivateStorage.h> +#include <Swiften/Elements/Storage.h> #include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h> #include <Swiften/Jingle/JingleSessionManager.h> #include <Swiften/MUC/MUCManager.h> +#include <Swiften/MUC/UnitTest/MockMUC.h> +#include <Swiften/MUC/MUCBookmarkManager.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/Presence/DirectedPresenceSender.h> #include <Swiften/Presence/PresenceOracle.h> @@ -47,6 +51,7 @@ #include <Swift/Controllers/Chat/ChatController.h> #include <Swift/Controllers/Chat/ChatsManager.h> +#include <Swift/Controllers/Chat/Chattables.h> #include <Swift/Controllers/Chat/MUCController.h> #include <Swift/Controllers/Chat/UnitTest/MockChatListWindow.h> #include <Swift/Controllers/EventNotifier.h> @@ -54,6 +59,7 @@ #include <Swift/Controllers/ProfileSettingsProvider.h> #include <Swift/Controllers/SettingConstants.h> #include <Swift/Controllers/Settings/DummySettingsProvider.h> +#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> #include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> @@ -71,7 +77,6 @@ #include <SwifTools/Notifier/Notifier.h> #include <Swift/QtUI/QtSwiftUtil.h> -#include <Swiften/MUC/UnitTest/MockMUC.h> using namespace Swift; @@ -104,6 +109,16 @@ class DummyNotifier : public Notifier { std::vector<Notification> notifications; }; +class ExtendedChatsManager : public ChatsManager { +public: + ExtendedChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, const std::map<std::string, std::string>& emoticons, VCardManager* vcardManager, Chattables& chattables) : + ChatsManager(jid, stanzaChannel, iqRouter, eventController, chatWindowFactory, joinMUCWindowFactory, nickResolver, presenceOracle, presenceSender, uiEventStream, chatListWindowFactory, useDelayForLatency, timerFactory, mucRegistry, entityCapsProvider, mucManager, mucSearchWindowFactory, profileSettings, ftOverview, roster, eagleMode, settings, historyController_, whiteboardManager, highlightManager, clientBlockListManager, emoticons, vcardManager, chattables) { + } + MUCBookmarkManager* getBookmarkManager() { + return mucBookmarkManager_; + } +}; + class ChatsManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ChatsManagerTest); @@ -155,12 +170,23 @@ class ChatsManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST(testImpromptuChatWindowTitle); CPPUNIT_TEST(testStandardMUCChatWindowTitle); + // Bookmark tests + CPPUNIT_TEST(testReceivingBookmarksWithDomainJID); + CPPUNIT_TEST(testReceivingBookmarksWithBareJID); + CPPUNIT_TEST(testReceivingBookmarksWithFullJID); + CPPUNIT_TEST(testAutoJoinBookmarksAndChattables); + CPPUNIT_TEST(testJoinNoAutojoinBookmark); + CPPUNIT_TEST(testJoinAndBookmarkMUC); + CPPUNIT_TEST(testReceivingNoBookmarks); + CPPUNIT_TEST(testReceivingNullBookmarks); + CPPUNIT_TEST(testReceivingBookmarksError); + CPPUNIT_TEST_SUITE_END(); public: void setUp() { mocks_ = new MockRepository(); - notifier_ = std::unique_ptr<DummyNotifier>(new DummyNotifier()); + notifier_ = std::make_unique<DummyNotifier>(); jid_ = JID("test@test.com/resource"); stanzaChannel_ = new DummyStanzaChannel(); iqRouter_ = new IQRouter(stanzaChannel_); @@ -200,7 +226,8 @@ public: mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_); clientBlockListManager_ = new ClientBlockListManager(iqRouter_); timerFactory_ = new DummyTimerFactory(); - manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, timerFactory_, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, nullptr, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, vcardManager_); + chattables_ = std::make_unique<Chattables>(); + manager_ = new ExtendedChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, timerFactory_, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, nullptr, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, vcardManager_, *chattables_); manager_->setAvatarManager(avatarManager_); } @@ -776,7 +803,7 @@ public: // send message to participantA auto messageBody = std::string("message body to send"); window->onSendMessageRequest(messageBody, false); - auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(2); + auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(3); CPPUNIT_ASSERT_EQUAL(messageBody, *sendMessageStanza->getBody()); // receive reply with error @@ -1228,6 +1255,11 @@ public: CPPUNIT_ASSERT_EQUAL(forwardedBody, MockChatWindow::bodyFromMessage(window->lastAddedMessage_)); CPPUNIT_ASSERT_EQUAL(false, window->lastAddedMessageSenderIsSelf_); + + auto recentChats = manager_->getRecentChats(); + CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1)); + CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, originalMessage->getFrom().toBare()); + CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some further text.")); } } @@ -1264,6 +1296,11 @@ public: CPPUNIT_ASSERT_EQUAL(true, window->lastAddedMessageSenderIsSelf_); CPPUNIT_ASSERT_EQUAL(size_t(1), window->receiptChanges_.size()); CPPUNIT_ASSERT_EQUAL(ChatWindow::ReceiptRequested, window->receiptChanges_[0].second); + + auto recentChats = manager_->getRecentChats(); + CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1)); + CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, originalMessage->getTo().toBare()); + CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some text my other resource sent.")); } // incoming carbons message for the received delivery receipt to the other resource @@ -1280,23 +1317,29 @@ public: CPPUNIT_ASSERT_EQUAL(size_t(2), window->receiptChanges_.size()); CPPUNIT_ASSERT_EQUAL(ChatWindow::ReceiptReceived, window->receiptChanges_[1].second); + + //Delivery receipt should not change the latest recent entry. Checking for the original message. + auto recentChats = manager_->getRecentChats(); + CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1)); + CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, messageJID.toBare()); + CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some text my other resource sent.")); } } - + void testCarbonsForwardedIncomingDuplicates() { JID messageJID("testling@test.com/resource1"); JID jid2 = jid_.toBare().withResource("someOtherResource"); - + MockChatWindow* window = new MockChatWindow(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - + std::shared_ptr<Message> message(new Message()); message->setFrom(messageJID); std::string body("This is a legible message. >HEH@)oeueu"); message->setBody(body); manager_->handleIncomingMessage(message); CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_)); - + // incoming carbons message from another resource and duplicate of it { auto originalMessage = std::make_shared<Message>(); @@ -1306,19 +1349,24 @@ public: originalMessage->setType(Message::Chat); std::string forwardedBody = "Some further text."; originalMessage->setBody(forwardedBody); - + auto messageWrapper = createCarbonsMessage(std::make_shared<CarbonsReceived>(), originalMessage); - + manager_->handleIncomingMessage(messageWrapper); - + CPPUNIT_ASSERT_EQUAL(forwardedBody, MockChatWindow::bodyFromMessage(window->lastAddedMessage_)); CPPUNIT_ASSERT_EQUAL(false, window->lastAddedMessageSenderIsSelf_); window->resetLastMessages(); - + messageWrapper = createCarbonsMessage(std::make_shared<CarbonsReceived>(), originalMessage); manager_->handleIncomingMessage(messageWrapper); CPPUNIT_ASSERT_EQUAL(std::string(), MockChatWindow::bodyFromMessage(window->lastAddedMessage_)); CPPUNIT_ASSERT_EQUAL(false, window->lastAddedMessageSenderIsSelf_); + + auto recentChats = manager_->getRecentChats(); + CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1)); + CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, originalMessage->getFrom().toBare()); + CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some further text.")); } } @@ -1537,7 +1585,11 @@ public: uiEventStream_->send(std::make_shared<CreateImpromptuMUCUIEvent>(jids, mucJID, "")); CPPUNIT_ASSERT_EQUAL(std::string("bar@test.com, foo@test.com"), manager_->getRecentChats()[0].getTitle()); - auto mucJoinPresence = std::dynamic_pointer_cast<Presence>(stanzaChannel_->sentStanzas[2]); + // Check the MUC security marking request + auto mucInfoRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[2]); + CPPUNIT_ASSERT(mucInfoRequest); + + auto mucJoinPresence = std::dynamic_pointer_cast<Presence>(stanzaChannel_->sentStanzas[3]); CPPUNIT_ASSERT(mucJoinPresence); // MUC presence reply @@ -1598,6 +1650,191 @@ public: CPPUNIT_ASSERT_EQUAL(std::string("mucroom"), window->name_); } + std::shared_ptr<Storage> createBookmarkStorageWithJID(std::shared_ptr<IQ> bookmarkRequest, const JID& jid, const bool autojoin) { + CPPUNIT_ASSERT(bookmarkRequest); + CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType()); + + auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>(); + CPPUNIT_ASSERT(privateStorage); + + auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload()); + CPPUNIT_ASSERT(storage); + + auto roomsStorage = std::make_shared<Storage>(); + if (jid.isValid()) { + auto room = Storage::Room(); + room.jid = jid; + room.autoJoin = autojoin; + roomsStorage->addRoom(room); + } + return roomsStorage; + } + + void testReceivingBookmarksWithDomainJID() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(createBookmarkStorageWithJID(bookmarkRequest, "montague.lit", true)) + ); + stanzaChannel_->onIQReceived(response); + } + + void testReceivingBookmarksWithBareJID() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID("example@montague.lit"), uiEventStream_).Return(window); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(createBookmarkStorageWithJID(bookmarkRequest, "example@montague.lit", true)) + ); + stanzaChannel_->onIQReceived(response); + } + + void testReceivingNoBookmarks() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>() + ); + stanzaChannel_->onIQReceived(response); + } + + void testReceivingNullBookmarks() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + nullptr + ); + stanzaChannel_->onIQReceived(response); + } + + void testReceivingBookmarksError() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto response = IQ::createError( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + ErrorPayload::Condition::ServiceUnavailable, + ErrorPayload::Type::Cancel, + nullptr + ); + stanzaChannel_->onIQReceived(response); + } + + void testReceivingBookmarksWithFullJID() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(createBookmarkStorageWithJID(bookmarkRequest, "example@montague.lit/someresource", true)) + ); + stanzaChannel_->onIQReceived(response); + } + + void testAutoJoinBookmarksAndChattables() { + + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto roomsStorage = createBookmarkStorageWithJID(bookmarkRequest, "autojoin@bookmark.lit", true); + auto room = Storage::Room(); + room.jid = "noAutojoin@bookmark.lit"; + roomsStorage->addRoom(room); + + //Only autojoin@bookmark.lit window should open. + MockChatWindow* autojoinBookmarkWindow = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID("autojoin@bookmark.lit"), uiEventStream_).Return(autojoinBookmarkWindow); + + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(roomsStorage) + ); + stanzaChannel_->onIQReceived(response); + //Both bookmarks should be added to the chattables. + CPPUNIT_ASSERT_EQUAL(size_t(2), chattables_->get().size()); + auto autoJoinState = chattables_->getState("autojoin@bookmark.lit"); + CPPUNIT_ASSERT(autoJoinState.type == Chattables::State::Type::Room); + CPPUNIT_ASSERT_EQUAL(autoJoinState.status, StatusShow::Online); + auto noAutoJoinState = chattables_->getState("noAutojoin@bookmark.lit"); + CPPUNIT_ASSERT(noAutoJoinState.type == Chattables::State::Type::Room); + CPPUNIT_ASSERT_EQUAL(noAutoJoinState.status, StatusShow::None); + } + + void testJoinNoAutojoinBookmark() { + + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto roomsStorage = createBookmarkStorageWithJID(bookmarkRequest, "example@montague.lit", false); + + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(roomsStorage) + ); + stanzaChannel_->onIQReceived(response); + + //Join previous bookmarked room, expecting no increase in chattables and change of autojoin in bookmark to true + MockChatWindow* newExampleChatWindow = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID("example@montague.lit"), uiEventStream_).Return(newExampleChatWindow); + uiEventStream_->send(std::make_shared<JoinMUCUIEvent>("example@montague.lit", boost::optional<std::string>(), boost::optional<std::string>())); + CPPUNIT_ASSERT_EQUAL(size_t(1), chattables_->get().size()); + auto state = chattables_->getState("example@montague.lit"); + CPPUNIT_ASSERT(state.type == Chattables::State::Type::Room); + CPPUNIT_ASSERT_EQUAL(state.status, StatusShow::Online); + + auto bookmarks = manager_->getBookmarkManager()->getBookmarks(); + CPPUNIT_ASSERT_EQUAL(bookmarks.size(), size_t(1)); + CPPUNIT_ASSERT(bookmarks[0].getRoom() == JID("example@montague.lit")); + CPPUNIT_ASSERT(bookmarks[0].getAutojoin()); + } + + void testJoinAndBookmarkMUC() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + auto roomsStorage = createBookmarkStorageWithJID(bookmarkRequest, "", true); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(roomsStorage) + ); + stanzaChannel_->onIQReceived(response); + + //Join non-bookmarked room expecting for the room to get bookmarked with autojoin to true + MockChatWindow* exampleChatWindow = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With("example@montague.lit", uiEventStream_).Return(exampleChatWindow); + uiEventStream_->send(std::make_shared<JoinMUCUIEvent>("example@montague.lit", boost::optional<std::string>(), boost::optional<std::string>())); + { + CPPUNIT_ASSERT_EQUAL(size_t(1), chattables_->get().size()); + auto state = chattables_->getState("example@montague.lit"); + CPPUNIT_ASSERT(state.type == Chattables::State::Type::Room); + CPPUNIT_ASSERT_EQUAL(state.status, StatusShow::Online); + + auto bookmarks = manager_->getBookmarkManager()->getBookmarks(); + CPPUNIT_ASSERT_EQUAL(bookmarks.size(), size_t(1)); + CPPUNIT_ASSERT(bookmarks[0].getRoom() == JID("example@montague.lit")); + CPPUNIT_ASSERT(bookmarks[0].getAutojoin()); + + } + //Exiting room that is bookmarked, expecting chattable to stay but bookmark autojoin change to false. + exampleChatWindow->onClosed(); + { + CPPUNIT_ASSERT_EQUAL(size_t(1), chattables_->get().size()); + auto bookmarks = manager_->getBookmarkManager()->getBookmarks(); + CPPUNIT_ASSERT_EQUAL(bookmarks.size(), size_t(1)); + CPPUNIT_ASSERT(bookmarks[0].getRoom() == JID("example@montague.lit")); + CPPUNIT_ASSERT(!bookmarks[0].getAutojoin()); + } + } + private: std::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) { std::shared_ptr<Message> message = std::make_shared<Message>(); @@ -1622,7 +1859,7 @@ private: private: JID jid_; std::unique_ptr<DummyNotifier> notifier_; - ChatsManager* manager_; + ExtendedChatsManager* manager_; DummyStanzaChannel* stanzaChannel_; IQRouter* iqRouter_; EventController* eventController_; @@ -1660,8 +1897,8 @@ private: int handledHighlightActions_; std::set<std::string> soundsPlayed_; DummyTimerFactory* timerFactory_; + std::unique_ptr<Chattables> chattables_; }; CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest); - |