diff options
Diffstat (limited to 'Swift/Controllers')
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.cpp | 2 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 66 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.h | 6 | ||||
-rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 22 | ||||
-rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 155 | ||||
-rw-r--r-- | Swift/Controllers/UIEvents/JoinMUCUIEvent.h | 2 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindow.h | 2 |
7 files changed, 178 insertions, 77 deletions
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index 4d4ca86..8a26a56 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -378,7 +378,7 @@ void ChatControllerBase::handleMUCInvitation(Message::ref message) { MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>(); if (autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) { - eventStream_->send(std::make_shared<JoinMUCUIEvent>(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true)); + eventStream_->send(std::make_shared<JoinMUCUIEvent>(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, true)); } else { MUCInviteEvent::ref inviteEvent = std::make_shared<MUCInviteEvent>(toJID_, invite->getJID(), invite->getReason(), invite->getPassword(), true, invite->getIsImpromptu()); handleGeneralMUCInvitation(inviteEvent); diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 63fd677..532b925 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -353,9 +353,11 @@ void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { if (bookmark.getRoom().isBare() && !bookmark.getRoom().getNode().empty()) { std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom()); if (it == mucControllers_.end() && bookmark.getAutojoin()) { - handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false ); + handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false); } #ifndef NOT_YET + //Only one entry of the bookmark should exist + chatListWindow_->removeMUCBookmark(bookmark); chatListWindow_->addMUCBookmark(bookmark); #endif chattables_.addJID(bookmark.getRoom(), Chattables::State::Type::Room); @@ -534,6 +536,12 @@ void ChatsManager::handleUserLeftMUC(MUCController* mucController) { auto state = chattables_.getState(jid); state.status = StatusShow::None; chattables_.setState(jid, state); + //If user deletes bookmark from chatListWindow_ and then decides to leave the room, or if the server doesn't support bookmarks, the bookmark will not exist. + if (auto bookmarkFound = mucBookmarkManager_->lookupBookmark(jid)) { + MUCBookmark newBookmark(bookmarkFound.get()); + newBookmark.setAutojoin(false); + mucBookmarkManager_->replaceBookmark(bookmarkFound.get(), newBookmark); + } mucControllers_.erase(it); delete mucController; break; @@ -619,7 +627,7 @@ void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) { invitees_[roomJID].insert(jid); } // join muc - MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true); + MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), true, true); mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, createImpromptuMUCEvent->getJIDs(), createImpromptuMUCEvent->getReason(), boost::optional<JID>())); mucControllers_[roomJID]->activateChatWindow(); } @@ -629,7 +637,7 @@ void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) { mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark()); } else if (JoinMUCUIEvent::ref joinEvent = std::dynamic_pointer_cast<JoinMUCUIEvent>(event)) { - handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu()); + handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu()); mucControllers_[joinEvent->getJID()]->activateChatWindow(); } else if (std::shared_ptr<RequestJoinMUCUIEvent> joinEvent = std::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) { @@ -665,7 +673,7 @@ void ChatsManager::handleTransformChatToMUC(ChatController* chatController, Chat JID roomJID = JID(idGenerator_.generateID(), localMUCServiceJID_); // join muc - MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true, chatWindow); + MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), true, true, chatWindow); mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, jidsToInvite, reason, boost::optional<JID>(reuseChatInvite))); } @@ -839,20 +847,8 @@ void ChatsManager::rebindControllerJID(const JID& from, const JID& to) { chatControllers_[to]->setToJID(to); } -MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<std::string>& password, const boost::optional<std::string>& nickMaybe, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow) { +MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<std::string>& password, const boost::optional<std::string>& nickMaybe, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow) { MUC::ref muc; - if (addAutoJoin) { - MUCBookmark bookmark(mucJID, mucJID.getNode()); - bookmark.setAutojoin(true); - if (nickMaybe) { - bookmark.setNick(*nickMaybe); - } - if (password) { - bookmark.setPassword(*password); - } - mucBookmarkManager_->addBookmark(bookmark); - } - std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID); if (it != mucControllers_.end()) { if (stanzaChannel_->isAvailable()) { @@ -875,6 +871,10 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti } std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getConfiguration(), ChatMessageParser::Mode::GroupChat); /* a message parser that knows this is a room/MUC (not a chat) */ controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, nickResolver_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_, settings_, chattables_); + chattables_.addJID(muc->getJID(), Chattables::State::Type::Room); + auto state = chattables_.getState(muc->getJID()); + state.status = StatusShow::Online; + chattables_.setState(muc->getJID(), state); if (chatWindowFactoryAdapter) { /* The adapters are only passed to chat windows, which are deleted in their * controllers' dtor, which are deleted in ChatManager's dtor. The adapters @@ -906,6 +906,24 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti mucControllers_[mucJID]->setChatWindowTitle(chatListWindowIter->getTitle()); } #endif + if (auto existingBookmark = mucBookmarkManager_->lookupBookmark(mucJID)) { + if (!existingBookmark->getAutojoin()) { + MUCBookmark newbookmark(existingBookmark.get()); + newbookmark.setAutojoin(true); + mucBookmarkManager_->replaceBookmark(*existingBookmark, newbookmark); + } + } + else { + MUCBookmark bookmark(mucJID, mucJID.getNode()); + bookmark.setAutojoin(true); + if (nickMaybe) { + bookmark.setNick(*nickMaybe); + } + if (password) { + bookmark.setPassword(*password); + } + mucBookmarkManager_->addBookmark(bookmark); + } mucControllers_[mucJID]->showChatWindow(); return muc; } @@ -1015,11 +1033,11 @@ void ChatsManager::handleIncomingMessage(std::shared_ptr<Message> incomingMessag ChatWindow* window = controller->detachChatWindow(); chatControllers_.erase(fromJID); delete controller; - handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true, window); + handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, true, window); return; } } else { - handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true); + handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, true); return; } } @@ -1091,7 +1109,7 @@ void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) { else if (chat.isMUC) { bool isImpromptu = (!chat.inviteesNames.empty() || !chat.impromptuJIDs.empty()); /* FIXME: This means that recents requiring passwords will just flat-out not work */ - uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick, false, false, isImpromptu)); + uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick, false, isImpromptu)); } else { uiEventStream_->send(std::make_shared<RequestChatUIEvent>(chat.jid)); @@ -1106,8 +1124,12 @@ void ChatsManager::handleChattableActivated(const JID& jid) { uiEventStream_->send(std::make_shared<RequestChatUIEvent>(jid)); } else if (state.type == Chattables::State::Type::Room) { - //FIXME: Find bookmarks and do handleMUCBookmarkActivated things - uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(jid, boost::optional<std::string>(), boost::optional<std::string>())); // Just a quick hack to reuse already open MUCs + if (auto foundBookmark = mucBookmarkManager_->lookupBookmark(jid)) { + handleMUCBookmarkActivated(foundBookmark.get()); + } + else { + uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(jid, boost::optional<std::string>(), boost::optional<std::string>())); // Just a quick hack to reuse already open MUCs + } } } diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 0b85840..e120831 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -94,7 +94,7 @@ namespace Swift { #endif void handleChatRequest(const std::string& contact); void finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID = boost::optional<JID>()); - MUC::ref handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow = nullptr); + MUC::ref handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow = nullptr); void handleSearchMUCRequest(); void handleMUCSelectedAfterSearch(const JID&); void rebindControllerJID(const JID& from, const JID& to); @@ -152,6 +152,9 @@ namespace Swift { ChatController* getChatControllerOrCreate(const JID &contact); ChatController* getChatControllerIfExists(const JID &contact, bool rebindIfNeeded = true); + protected: + MUCBookmarkManager* mucBookmarkManager_; + private: std::map<JID, MUCController*> mucControllers_; std::map<JID, ChatController*> chatControllers_; @@ -167,7 +170,6 @@ namespace Swift { AvatarManager* avatarManager_; PresenceSender* presenceSender_; UIEventStream* uiEventStream_; - MUCBookmarkManager* mucBookmarkManager_; std::shared_ptr<DiscoInfo> serverDiscoInfo_; #ifndef NOT_YET ChatListWindow* chatListWindow_; diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 071b919..30d4933 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -36,6 +36,7 @@ #include <SwifTools/TabComplete.h> #include <Swift/Controllers/Chat/ChatMessageParser.h> +#include <Swift/Controllers/Chat/Chattables.h> #include <Swift/Controllers/Highlighting/Highlighter.h> #include <Swift/Controllers/Intl.h> #include <Swift/Controllers/Roster/ContactRosterItem.h> @@ -60,17 +61,6 @@ namespace Swift { -class MUCBookmarkPredicate { - public: - MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { } - bool operator()(const MUCBookmark& operand) { - return operand.getRoom() == roomJID_; - } - - private: - JID roomJID_; -}; - /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ @@ -174,14 +164,7 @@ MUCController::MUCController ( mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1))); mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1))); - std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks(); - std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID())); - if (bookmarkIterator != mucBookmarks.end()) { - updateChatWindowBookmarkStatus(*bookmarkIterator); - } - else { - updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>()); - } + updateChatWindowBookmarkStatus(mucBookmarkManager_->lookupBookmark(muc->getJID())); } MUCController::~MUCController() { @@ -498,6 +481,7 @@ void MUCController::setAvailableRoomActions(const MUCOccupant::Affiliation& affi if (role <= MUCOccupant::Visitor) { actions.push_back(ChatWindow::Invite); } + actions.push_back(ChatWindow::Leave); chatWindow_->setAvailableRoomActions(actions); } diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index e0a7fe3..7469d64 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -38,6 +38,7 @@ #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> @@ -58,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> @@ -107,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); @@ -162,6 +174,9 @@ class ChatsManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST(testReceivingBookmarksWithDomainJID); CPPUNIT_TEST(testReceivingBookmarksWithBareJID); CPPUNIT_TEST(testReceivingBookmarksWithFullJID); + CPPUNIT_TEST(testAutoJoinBookmarksAndChattables); + CPPUNIT_TEST(testJoinNoAutojoinBookmark); + CPPUNIT_TEST(testJoinAndBookmarkMUC); CPPUNIT_TEST_SUITE_END(); @@ -209,7 +224,7 @@ public: clientBlockListManager_ = new ClientBlockListManager(iqRouter_); timerFactory_ = new DummyTimerFactory(); chattables_ = std::make_unique<Chattables>(); - 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_); + 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_); } @@ -1632,17 +1647,7 @@ public: CPPUNIT_ASSERT_EQUAL(std::string("mucroom"), window->name_); } - static std::shared_ptr<Storage> createBookmarkStorageWithJID(const JID& jid) { - auto storage = std::make_shared<Storage>(); - auto room = Storage::Room(); - room.jid = jid; - room.autoJoin = true; - storage->addRoom(room); - return storage; - } - - void testReceivingBookmarksWithDomainJID() { - auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); + 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()); @@ -1652,56 +1657,144 @@ public: 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("montague.lit")) + std::make_shared<PrivateStorage>(createBookmarkStorageWithJID(bookmarkRequest, "montague.lit", true)) ); stanzaChannel_->onIQReceived(response); } void testReceivingBookmarksWithBareJID() { auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); - CPPUNIT_ASSERT(bookmarkRequest); - CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType()); + 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); + } - auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>(); - CPPUNIT_ASSERT(privateStorage); + 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); + } - auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload()); - CPPUNIT_ASSERT(storage); + void testAutoJoinBookmarksAndChattables() { - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID("example@montague.lit"), uiEventStream_).Return(window); + 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>(createBookmarkStorageWithJID("example@montague.lit")) + 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 testReceivingBookmarksWithFullJID() { + void testJoinNoAutojoinBookmark() { + auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]); - CPPUNIT_ASSERT(bookmarkRequest); - CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType()); + auto roomsStorage = createBookmarkStorageWithJID(bookmarkRequest, "example@montague.lit", false); - auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>(); - CPPUNIT_ASSERT(privateStorage); + auto response = IQ::createResult( + bookmarkRequest->getFrom(), + bookmarkRequest->getTo(), + bookmarkRequest->getID(), + std::make_shared<PrivateStorage>(roomsStorage) + ); + stanzaChannel_->onIQReceived(response); - auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload()); - CPPUNIT_ASSERT(storage); + //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>(createBookmarkStorageWithJID("example@montague.lit/someresource")) + 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: @@ -1728,7 +1821,7 @@ private: private: JID jid_; std::unique_ptr<DummyNotifier> notifier_; - ChatsManager* manager_; + ExtendedChatsManager* manager_; DummyStanzaChannel* stanzaChannel_; IQRouter* iqRouter_; EventController* eventController_; diff --git a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h index 5d6df55..78103a8 100644 --- a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h @@ -19,7 +19,7 @@ namespace Swift { class JoinMUCUIEvent : public UIEvent { public: typedef std::shared_ptr<JoinMUCUIEvent> ref; - JoinMUCUIEvent(const JID& jid, const boost::optional<std::string>& password = boost::optional<std::string>(), const boost::optional<std::string>& nick = boost::optional<std::string>(), bool joinAutomaticallyInFuture = false, bool createAsReservedRoomIfNew = false, bool isImpromptu = false, bool isContinuation = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password), isImpromptuMUC_(isImpromptu), isContinuation_(isContinuation) {} + JoinMUCUIEvent(const JID& jid, const boost::optional<std::string>& password = boost::optional<std::string>(), const boost::optional<std::string>& nick = boost::optional<std::string>(), bool createAsReservedRoomIfNew = false, bool isImpromptu = false, bool isContinuation = false) : jid_(jid), nick_(nick), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password), isImpromptuMUC_(isImpromptu), isContinuation_(isContinuation) {} const boost::optional<std::string>& getNick() const {return nick_;} const JID& getJID() const {return jid_;} bool getShouldJoinAutomatically() const {return joinAutomatically_;} diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 507269f..daece0e 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -141,7 +141,7 @@ namespace Swift { enum AckState {Pending, Received, Failed}; enum ReceiptState {ReceiptRequested, ReceiptReceived, ReceiptFailed}; enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile}; - enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite}; + enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite, Leave}; enum FileTransferState { Initialisation, ///< Collecting information required for sending the request out. WaitingForAccept, ///< The file transfer request was send out. |