diff options
| author | Kevin Smith <git@kismith.co.uk> | 2012-02-17 16:57:01 (GMT) |
|---|---|---|
| committer | Kevin Smith <git@kismith.co.uk> | 2012-02-21 14:34:55 (GMT) |
| commit | 3605b6622bc8b4abb810fac6b53f7f71be0fa7de (patch) | |
| tree | 638a8fd6449dd235931fe307e50119adf9c9fe22 /Swift/Controllers/Chat | |
| parent | b05f8fcb285d2d13d2be50a3eb1062048fbe30f5 (diff) | |
| download | swift-contrib-3605b6622bc8b4abb810fac6b53f7f71be0fa7de.zip swift-contrib-3605b6622bc8b4abb810fac6b53f7f71be0fa7de.tar.bz2 | |
Introduce system settings policies.
Release-Notes: It is now possible for sysadmins to deploy files with policies for configuration options, such as making it impossible for users to save passwords or to force sound notifications off, or to set defaults.
Also allow changing an option so that Swift disconnects on idle timeout, instead of going away.
Diffstat (limited to 'Swift/Controllers/Chat')
| -rw-r--r-- | Swift/Controllers/Chat/ChatController.cpp | 19 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatController.h | 11 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 34 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.h | 5 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 14 |
5 files changed, 49 insertions, 34 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 9a56300..ea0e8ea 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -1,121 +1,122 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2012 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "Swift/Controllers/Chat/ChatController.h" #include <boost/bind.hpp> #include <stdio.h> #include <Swift/Controllers/Intl.h> #include <Swiften/Base/format.h> #include <Swiften/Base/Algorithm.h> #include <Swiften/Avatars/AvatarManager.h> #include <Swiften/Chat/ChatStateNotifier.h> #include <Swiften/Chat/ChatStateTracker.h> #include <Swiften/Client/StanzaChannel.h> #include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> #include <Swiften/Client/NickResolver.h> #include <Swift/Controllers/XMPPEvents/EventController.h> #include <Swift/Controllers/FileTransfer/FileTransferController.h> #include <Swift/Controllers/StatusUtil.h> #include <Swiften/Disco/EntityCapsProvider.h> #include <Swiften/Base/foreach.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> #include <Swiften/Elements/DeliveryReceipt.h> #include <Swiften/Elements/DeliveryReceiptRequest.h> -#include <Swift/Controllers/UIEvents/ToggleRequestDeliveryReceiptsUIEvent.h> +#include <Swift/Controllers/SettingConstants.h> #include <Swiften/Base/Log.h> namespace Swift { /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ -ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts) - : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts) { +ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings) + : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings) { isInMUC_ = isInMUC; lastWasPresence_ = false; chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider); chatStateTracker_ = new ChatStateTracker(); nickResolver_ = nickResolver; presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1)); chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1)); stanzaChannel_->onStanzaAcked.connect(boost::bind(&ChatController::handleStanzaAcked, this, _1)); nickResolver_->onNickChanged.connect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2)); std::string nick = nickResolver_->jidToNick(toJID_); chatWindow_->setName(nick); std::string startMessage; Presence::ref theirPresence; if (isInMUC) { startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% in chatroom %2%")) % nick % contact.toBare().toString()); theirPresence = presenceOracle->getLastPresence(contact); } else { startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% - %2%")) % nick % contact.toBare().toString()); theirPresence = contact.isBare() ? presenceOracle->getHighestPriorityPresence(contact.toBare()) : presenceOracle->getLastPresence(contact); } startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None); if (theirPresence && !theirPresence->getStatus().empty()) { startMessage += " (" + theirPresence->getStatus() + ")"; } lastShownStatus_ = theirPresence ? theirPresence->getShow() : StatusShow::None; chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available); startMessage += "."; chatWindow_->addSystemMessage(startMessage); chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2)); chatWindow_->onFileTransferAccept.connect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2)); chatWindow_->onFileTransferCancel.connect(boost::bind(&ChatController::handleFileTransferCancel, this, _1)); chatWindow_->onSendFileRequest.connect(boost::bind(&ChatController::handleSendFileRequest, this, _1)); handleBareJIDCapsChanged(toJID_); - eventStream_->onUIEvent.connect(boost::bind(&ChatController::handleUIEvent, this, _1)); + + settings_->onSettingChanged.connect(boost::bind(&ChatController::handleSettingChanged, this, _1)); } void ChatController::handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/) { if (jid.toBare() == toJID_.toBare()) { chatWindow_->setName(nickResolver_->jidToNick(jid)); } } ChatController::~ChatController() { - eventStream_->onUIEvent.disconnect(boost::bind(&ChatController::handleUIEvent, this, _1)); + settings_->onSettingChanged.disconnect(boost::bind(&ChatController::handleSettingChanged, this, _1)); nickResolver_->onNickChanged.disconnect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2)); delete chatStateNotifier_; delete chatStateTracker_; } void ChatController::handleBareJIDCapsChanged(const JID& /*jid*/) { DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_); if (disco) { if (disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) { chatWindow_->setCorrectionEnabled(ChatWindow::Yes); } else { chatWindow_->setCorrectionEnabled(ChatWindow::No); } if (disco->hasFeature(DiscoInfo::MessageDeliveryReceiptsFeature)) { contactSupportsReceipts_ = ChatWindow::Yes; } else { contactSupportsReceipts_ = ChatWindow::No; } } else { SWIFT_LOG(debug) << "No disco info :(" << std::endl; chatWindow_->setCorrectionEnabled(ChatWindow::Maybe); contactSupportsReceipts_ = ChatWindow::Maybe; } checkForDisplayingDisplayReceiptsAlert(); } void ChatController::setToJID(const JID& jid) { chatStateNotifier_->setContact(jid); ChatControllerBase::setToJID(jid); Presence::ref presence; if (isInMUC_) { presence = presenceOracle_->getLastPresence(jid); } else { presence = jid.isBare() ? presenceOracle_->getHighestPriorityPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid); } @@ -142,73 +143,73 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me chatStateTracker_->handleMessageReceived(message); chatStateNotifier_->receivedMessageFromContact(message->getPayload<ChatState>()); if (boost::shared_ptr<DeliveryReceipt> receipt = message->getPayload<DeliveryReceipt>()) { SWIFT_LOG(debug) << "received receipt for id: " << receipt->getReceivedID() << std::endl; if (requestedReceipts_.find(receipt->getReceivedID()) != requestedReceipts_.end()) { chatWindow_->setMessageReceiptState(requestedReceipts_[receipt->getReceivedID()], ChatWindow::ReceiptReceived); requestedReceipts_.erase(receipt->getReceivedID()); } } else if (message->getPayload<DeliveryReceiptRequest>()) { if (receivingPresenceFromUs_) { boost::shared_ptr<Message> receiptMessage = boost::make_shared<Message>(); receiptMessage->setTo(toJID_); receiptMessage->addPayload(boost::make_shared<DeliveryReceipt>(message->getID())); stanzaChannel_->sendMessage(receiptMessage); } } } void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { eventController_->handleIncomingEvent(messageEvent); } void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) { chatStateNotifier_->addChatStateRequest(message); if (userWantsReceipts_ && (contactSupportsReceipts_ != ChatWindow::No) && message) { message->addPayload(boost::make_shared<DeliveryReceiptRequest>()); } } void ChatController::setContactIsReceivingPresence(bool isReceivingPresence) { receivingPresenceFromUs_ = isReceivingPresence; } -void ChatController::handleUIEvent(boost::shared_ptr<UIEvent> event) { - if (boost::shared_ptr<ToggleRequestDeliveryReceiptsUIEvent> toggleAllowReceipts = boost::dynamic_pointer_cast<ToggleRequestDeliveryReceiptsUIEvent>(event)) { - userWantsReceipts_ = toggleAllowReceipts->getEnabled(); +void ChatController::handleSettingChanged(const std::string& settingPath) { + if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { + userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); checkForDisplayingDisplayReceiptsAlert(); } } void ChatController::checkForDisplayingDisplayReceiptsAlert() { if (userWantsReceipts_ && (contactSupportsReceipts_ == ChatWindow::No)) { chatWindow_->setAlert("This chat doesn't support delivery receipts."); } else if (userWantsReceipts_ && (contactSupportsReceipts_ == ChatWindow::Maybe)) { chatWindow_->setAlert("This chat may not support delivery receipts. You might not receive delivery receipts for the messages you sent."); } else { chatWindow_->cancelAlert(); } } void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) { boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>(); if (replace) { eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_)); chatWindow_->replaceMessage(body, myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time()); } else { myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time()); } if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) { chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending); unackedStanzas_[sentStanza] = myLastMessageUIID_; } if (sentStanza->getPayload<DeliveryReceiptRequest>()) { requestedReceipts_[sentStanza->getID()] = myLastMessageUIID_; chatWindow_->setMessageReceiptState(myLastMessageUIID_, ChatWindow::ReceiptRequested); } lastWasPresence_ = false; chatStateNotifier_->userSentMessage(); diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h index 9c01923..2a66772 100644 --- a/Swift/Controllers/Chat/ChatController.h +++ b/Swift/Controllers/Chat/ChatController.h @@ -1,76 +1,77 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2012 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once -#include "Swift/Controllers/Chat/ChatControllerBase.h" +#include <Swift/Controllers/Chat/ChatControllerBase.h> #include <map> #include <string> #include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { class AvatarManager; class ChatStateNotifier; class ChatStateTracker; class NickResolver; class EntityCapsProvider; class FileTransferController; - class UIEvent; + class SettingsProvider; class ChatController : public ChatControllerBase { public: - ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts); + ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings); virtual ~ChatController(); virtual void setToJID(const JID& jid); virtual void setOnline(bool online); virtual void handleNewFileTransferController(FileTransferController* ftc); virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/); private: void handlePresenceChange(boost::shared_ptr<Presence> newPresence); std::string getStatusChangeString(boost::shared_ptr<Presence> presence); bool isIncomingMessageFromMe(boost::shared_ptr<Message> message); void postSendMessage(const std::string &body, boost::shared_ptr<Stanza> sentStanza); void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent); void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent); void preSendMessageRequest(boost::shared_ptr<Message>); std::string senderDisplayNameFromMessage(const JID& from); virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const; void handleStanzaAcked(boost::shared_ptr<Stanza> stanza); void dayTicked() {lastWasPresence_ = false;} void handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/); void handleBareJIDCapsChanged(const JID& jid); void handleFileTransferCancel(std::string /* id */); void handleFileTransferStart(std::string /* id */, std::string /* description */); void handleFileTransferAccept(std::string /* id */, std::string /* filename */); void handleSendFileRequest(std::string filename); - void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleSettingChanged(const std::string& settingPath); void checkForDisplayingDisplayReceiptsAlert(); private: NickResolver* nickResolver_; ChatStateNotifier* chatStateNotifier_; ChatStateTracker* chatStateTracker_; std::string myLastMessageUIID_; bool isInMUC_; bool lastWasPresence_; std::string lastStatusChangeString_; std::map<boost::shared_ptr<Stanza>, std::string> unackedStanzas_; std::map<std::string, std::string> requestedReceipts_; StatusShow::Type lastShownStatus_; UIEventStream* eventStream_; ChatWindow::Tristate contactSupportsReceipts_; bool receivingPresenceFromUs_; bool userWantsReceipts_; std::map<std::string, FileTransferController*> ftControllers; + SettingsProvider* settings_; }; } diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index c19c524..a2b286f 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -1,148 +1,155 @@ /* * Copyright (c) 2010-2011 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "Swift/Controllers/Chat/ChatsManager.h" #include <boost/bind.hpp> #include <boost/algorithm/string.hpp> #include <Swiften/Base/foreach.h> #include <Swift/Controllers/Chat/ChatController.h> #include <Swift/Controllers/Chat/ChatControllerBase.h> #include <Swift/Controllers/Chat/MUCSearchController.h> #include <Swift/Controllers/XMPPEvents/EventController.h> #include <Swift/Controllers/Chat/MUCController.h> #include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> #include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h> #include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h> -#include <Swift/Controllers/UIEvents/ToggleRequestDeliveryReceiptsUIEvent.h> #include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h> #include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h> #include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h> #include <Swiften/Presence/PresenceSender.h> #include <Swiften/Client/NickResolver.h> #include <Swiften/MUC/MUCManager.h> #include <Swiften/Elements/ChatState.h> #include <Swiften/Elements/MUCUserPayload.h> #include <Swiften/Elements/DeliveryReceipt.h> #include <Swiften/Elements/DeliveryReceiptRequest.h> #include <Swiften/MUC/MUCBookmarkManager.h> #include <Swift/Controllers/FileTransfer/FileTransferController.h> #include <Swift/Controllers/FileTransfer/FileTransferOverview.h> #include <Swift/Controllers/ProfileSettingsProvider.h> #include <Swiften/Avatars/AvatarManager.h> #include <Swiften/Elements/MUCInvitationPayload.h> #include <Swiften/Roster/XMPPRoster.h> +#include <Swift/Controllers/Settings/SettingsProvider.h> +#include <Swift/Controllers/SettingConstants.h> namespace Swift { typedef std::pair<JID, ChatController*> JIDChatControllerPair; typedef std::pair<JID, MUCController*> JIDMUCControllerPair; #define RECENT_CHATS "recent_chats" ChatsManager::ChatsManager( 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* settings, + ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, - bool eagleMode) : + bool eagleMode, + SettingsProvider* settings) : jid_(jid), joinMUCWindowFactory_(joinMUCWindowFactory), useDelayForLatency_(useDelayForLatency), mucRegistry_(mucRegistry), entityCapsProvider_(entityCapsProvider), mucManager(mucManager), ftOverview_(ftOverview), roster_(roster), - eagleMode_(eagleMode) { + eagleMode_(eagleMode), + settings_(settings) { timerFactory_ = timerFactory; eventController_ = eventController; stanzaChannel_ = stanzaChannel; iqRouter_ = iqRouter; chatWindowFactory_ = chatWindowFactory; nickResolver_ = nickResolver; presenceOracle_ = presenceOracle; avatarManager_ = NULL; serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo()); presenceSender_ = presenceSender; uiEventStream_ = uiEventStream; mucBookmarkManager_ = NULL; - profileSettings_ = settings; + profileSettings_ = profileSettings; presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1)); uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1)); chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_); chatListWindow_->onMUCBookmarkActivated.connect(boost::bind(&ChatsManager::handleMUCBookmarkActivated, this, _1)); chatListWindow_->onRecentActivated.connect(boost::bind(&ChatsManager::handleRecentActivated, this, _1)); chatListWindow_->onClearRecentsRequested.connect(boost::bind(&ChatsManager::handleClearRecentsRequested, this)); joinMUCWindow_ = NULL; - mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, settings); + mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_); mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1)); ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1)); roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); roster_->onRosterCleared.connect(boost::bind(&ChatsManager::handleRosterCleared, this)); + + settings_->onSettingChanged.connect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); + setupBookmarks(); loadRecents(); } ChatsManager::~ChatsManager() { + settings_->onSettingChanged.disconnect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); roster_->onJIDAdded.disconnect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); roster_->onJIDRemoved.disconnect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); roster_->onJIDUpdated.disconnect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); roster_->onRosterCleared.disconnect(boost::bind(&ChatsManager::handleRosterCleared, this)); delete joinMUCWindow_; foreach (JIDChatControllerPair controllerPair, chatControllers_) { delete controllerPair.second; } foreach (JIDMUCControllerPair controllerPair, mucControllers_) { delete controllerPair.second; } delete mucBookmarkManager_; delete mucSearchController_; } void ChatsManager::saveRecents() { std::string recents; int i = 1; foreach (ChatListWindow::Chat chat, recentChats_) { std::vector<std::string> activity; boost::split(activity, chat.activity, boost::is_any_of("\t\n")); if (activity.empty()) { /* Work around Boost bug https://svn.boost.org/trac/boost/ticket/4751 */ activity.push_back(""); } std::string recent = chat.jid.toString() + "\t" + (eagleMode_ ? "" : activity[0]) + "\t" + (chat.isMUC ? "true" : "false") + "\t" + chat.nick; recents += recent + "\n"; if (i++ > 25) { break; } } profileSettings_->storeString(RECENT_CHATS, recents); } void ChatsManager::handleClearRecentsRequested() { @@ -316,91 +323,94 @@ void ChatsManager::handleUnreadCountChanged(ChatControllerBase* controller) { } unreadTotal += chatItem.unreadCount; } chatListWindow_->setRecents(recentChats_); chatListWindow_->setUnreadCount(unreadTotal); } void ChatsManager::appendRecent(const ChatListWindow::Chat& chat) { recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end()); recentChats_.push_front(chat); } void ChatsManager::prependRecent(const ChatListWindow::Chat& chat) { recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end()); recentChats_.push_back(chat); } void ChatsManager::handleUserLeftMUC(MUCController* mucController) { std::map<JID, MUCController*>::iterator it; for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) { if ((*it).second == mucController) { foreach (ChatListWindow::Chat& chat, recentChats_) { if (chat.isMUC && chat.jid == (*it).first) { chat.statusType = StatusShow::None; chatListWindow_->setRecents(recentChats_); break; } } mucControllers_.erase(it); delete mucController; return; } } } +void ChatsManager::handleSettingChanged(const std::string& settingPath) { + if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { + userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); + return; + } +} + void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> event) { boost::shared_ptr<RequestChatUIEvent> chatEvent = boost::dynamic_pointer_cast<RequestChatUIEvent>(event); if (chatEvent) { handleChatRequest(chatEvent->getContact()); return; } boost::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = boost::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event); if (removeMUCBookmarkEvent) { mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark()); return; } boost::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = boost::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event); if (addMUCBookmarkEvent) { mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark()); return; } - boost::shared_ptr<ToggleRequestDeliveryReceiptsUIEvent> toggleRequestDeliveryReceiptsEvent = boost::dynamic_pointer_cast<ToggleRequestDeliveryReceiptsUIEvent>(event); - if (toggleRequestDeliveryReceiptsEvent) { - userWantsReceipts_ = toggleRequestDeliveryReceiptsEvent->getEnabled(); - return; - } + boost::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = boost::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event); if (editMUCBookmarkEvent) { mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark()); } else if (JoinMUCUIEvent::ref joinEvent = boost::dynamic_pointer_cast<JoinMUCUIEvent>(event)) { handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew()); mucControllers_[joinEvent->getJID()]->activateChatWindow(); } else if (boost::shared_ptr<RequestJoinMUCUIEvent> joinEvent = boost::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) { if (!joinMUCWindow_) { joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow(uiEventStream_); joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this)); } joinMUCWindow_->setMUC(joinEvent->getRoom()); joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_)); joinMUCWindow_->show(); } } /** * If a resource goes offline, release bound chatdialog to that resource. */ void ChatsManager::handlePresenceChange(boost::shared_ptr<Presence> newPresence) { if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return; foreach (ChatListWindow::Chat& chat, recentChats_) { if (newPresence->getFrom().toBare() == chat.jid.toBare() && !chat.isMUC) { Presence::ref presence = presenceOracle_->getHighestPriorityPresence(chat.jid.toBare()); chat.setStatusType(presence ? presence->getShow() : StatusShow::None); chatListWindow_->setRecents(recentChats_); break; } } @@ -457,71 +467,71 @@ void ChatsManager::setOnline(bool enabled) { controllerPair.second->setOnline(enabled); if (enabled) { controllerPair.second->rejoin(); } } if (!enabled) { delete mucBookmarkManager_; mucBookmarkManager_ = NULL; chatListWindow_->setBookmarksEnabled(false); } else { setupBookmarks(); } } void ChatsManager::handleChatRequest(const std::string &contact) { ChatController* controller = getChatControllerOrFindAnother(JID(contact)); controller->activateChatWindow(); } ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) { ChatController* controller = getChatControllerIfExists(contact); if (!controller && !mucRegistry_->isMUC(contact.toBare())) { foreach (JIDChatControllerPair pair, chatControllers_) { if (pair.first.toBare() == contact.toBare()) { controller = pair.second; break; } } } return controller ? controller : createNewChatController(contact); } ChatController* ChatsManager::createNewChatController(const JID& contact) { assert(chatControllers_.find(contact) == chatControllers_.end()); - ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_); + ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_); chatControllers_[contact] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); updatePresenceReceivingStateOnChatController(contact); return controller; } ChatController* ChatsManager::getChatControllerOrCreate(const JID &contact) { ChatController* controller = getChatControllerIfExists(contact); return controller ? controller : createNewChatController(contact); } ChatController* ChatsManager::getChatControllerIfExists(const JID &contact, bool rebindIfNeeded) { if (chatControllers_.find(contact) == chatControllers_.end()) { if (mucRegistry_->isMUC(contact.toBare())) { return NULL; } //Need to look for an unbound window to bind first JID bare(contact.toBare()); if (chatControllers_.find(bare) != chatControllers_.end()) { rebindControllerJID(bare, contact); } else { foreach (JIDChatControllerPair pair, chatControllers_) { if (pair.first.toBare() == contact.toBare()) { if (rebindIfNeeded) { rebindControllerJID(pair.first, contact); return chatControllers_[contact]; } else { return pair.second; } } } return NULL; diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 0c7f492..4d1fc14 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -14,116 +14,119 @@ #include <Swiften/Elements/DiscoInfo.h> #include <Swiften/Elements/Message.h> #include <Swiften/Elements/Presence.h> #include <Swiften/JID/JID.h> #include <Swiften/MUC/MUCRegistry.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIInterfaces/ChatListWindow.h> #include <Swiften/MUC/MUCBookmark.h> namespace Swift { class EventController; class ChatController; class ChatControllerBase; class MUCController; class MUCManager; class ChatWindowFactory; class JoinMUCWindow; class JoinMUCWindowFactory; class NickResolver; class PresenceOracle; class AvatarManager; class StanzaChannel; class IQRouter; class PresenceSender; class MUCBookmarkManager; class ChatListWindowFactory; class TimerFactory; class EntityCapsProvider; class DirectedPresenceSender; class MUCSearchWindowFactory; class ProfileSettingsProvider; class MUCSearchController; class FileTransferOverview; class FileTransferController; class XMPPRoster; + class SettingsProvider; class ChatsManager { public: - ChatsManager(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* settings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode); + ChatsManager(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* settings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings); virtual ~ChatsManager(); void setAvatarManager(AvatarManager* avatarManager); void setOnline(bool enabled); void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<Message> message); private: ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity); void handleChatRequest(const std::string& contact); void handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool addAutoJoin, bool createAsReservedIfNew); void handleSearchMUCRequest(); void handleMUCSelectedAfterSearch(const JID&); void rebindControllerJID(const JID& from, const JID& to); void handlePresenceChange(boost::shared_ptr<Presence> newPresence); void handleUIEvent(boost::shared_ptr<UIEvent> event); void handleMUCBookmarkAdded(const MUCBookmark& bookmark); void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); void handleUserLeftMUC(MUCController* mucController); void handleBookmarksReady(); void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC); void handleNewFileTransferController(FileTransferController*); void appendRecent(const ChatListWindow::Chat& chat); void prependRecent(const ChatListWindow::Chat& chat); void setupBookmarks(); void loadRecents(); void saveRecents(); void handleChatMadeRecent(); void handleMUCBookmarkActivated(const MUCBookmark&); void handleRecentActivated(const ChatListWindow::Chat&); void handleUnreadCountChanged(ChatControllerBase* controller); void handleAvatarChanged(const JID& jid); void handleClearRecentsRequested(); void handleJIDAddedToRoster(const JID&); void handleJIDRemovedFromRoster(const JID&); void handleJIDUpdatedInRoster(const JID&); void handleRosterCleared(); + void handleSettingChanged(const std::string& settingPath); void updatePresenceReceivingStateOnChatController(const JID&); ChatController* getChatControllerOrFindAnother(const JID &contact); ChatController* createNewChatController(const JID &contact); ChatController* getChatControllerOrCreate(const JID &contact); ChatController* getChatControllerIfExists(const JID &contact, bool rebindIfNeeded = true); private: std::map<JID, MUCController*> mucControllers_; std::map<JID, ChatController*> chatControllers_; EventController* eventController_; JID jid_; StanzaChannel* stanzaChannel_; IQRouter* iqRouter_; ChatWindowFactory* chatWindowFactory_; JoinMUCWindowFactory* joinMUCWindowFactory_; NickResolver* nickResolver_; PresenceOracle* presenceOracle_; AvatarManager* avatarManager_; PresenceSender* presenceSender_; UIEventStream* uiEventStream_; MUCBookmarkManager* mucBookmarkManager_; boost::shared_ptr<DiscoInfo> serverDiscoInfo_; ChatListWindow* chatListWindow_; JoinMUCWindow* joinMUCWindow_; boost::bsignals::scoped_connection uiEventConnection_; bool useDelayForLatency_; TimerFactory* timerFactory_; MUCRegistry* mucRegistry_; EntityCapsProvider* entityCapsProvider_; MUCManager* mucManager; MUCSearchController* mucSearchController_; std::list<ChatListWindow::Chat> recentChats_; ProfileSettingsProvider* profileSettings_; FileTransferOverview* ftOverview_; XMPPRoster* roster_; bool eagleMode_; bool userWantsReceipts_; + SettingsProvider* settings_; }; } diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index 8162bec..cd868e6 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -1,169 +1,169 @@ /* - * Copyright (c) 2010-2011 Kevin Smith + * Copyright (c) 2010-2012 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include "3rdParty/hippomocks.h" #include <boost/bind.hpp> #include "Swift/Controllers/Chat/ChatsManager.h" #include "Swift/Controllers/Chat/UnitTest/MockChatListWindow.h" #include "Swift/Controllers/UIInterfaces/ChatWindow.h" #include "Swift/Controllers/Settings/DummySettingsProvider.h" #include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" #include "Swift/Controllers/UIInterfaces/ChatListWindowFactory.h" #include "Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h" #include "Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h" #include "Swiften/Client/Client.h" #include "Swiften/Disco/EntityCapsManager.h" #include "Swiften/Disco/CapsProvider.h" #include "Swiften/MUC/MUCManager.h" #include "Swift/Controllers/Chat/ChatController.h" #include "Swift/Controllers/XMPPEvents/EventController.h" #include "Swift/Controllers/Chat/MUCController.h" #include "Swiften/Presence/StanzaChannelPresenceSender.h" #include "Swiften/Avatars/NullAvatarManager.h" #include "Swiften/Avatars/AvatarMemoryStorage.h" #include "Swiften/VCards/VCardManager.h" #include "Swiften/VCards/VCardMemoryStorage.h" #include "Swiften/Client/NickResolver.h" #include "Swiften/Presence/DirectedPresenceSender.h" #include "Swiften/Roster/XMPPRosterImpl.h" #include "Swift/Controllers/UnitTest/MockChatWindow.h" #include "Swiften/Client/DummyStanzaChannel.h" #include "Swiften/Queries/DummyIQChannel.h" #include "Swiften/Presence/PresenceOracle.h" #include "Swiften/Jingle/JingleSessionManager.h" #include "Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h" #include "Swift/Controllers/UIEvents/RequestChatUIEvent.h" #include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h" #include "Swift/Controllers/UIEvents/UIEventStream.h" -#include "Swift/Controllers/UIEvents/ToggleRequestDeliveryReceiptsUIEvent.h" #include <Swift/Controllers/ProfileSettingsProvider.h> #include "Swift/Controllers/FileTransfer/FileTransferOverview.h" #include "Swiften/Elements/DeliveryReceiptRequest.h" #include "Swiften/Elements/DeliveryReceipt.h" #include <Swiften/Base/Algorithm.h> +#include <Swift/Controllers/SettingConstants.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); CPPUNIT_TEST(testSecondOpenWindowIncoming); CPPUNIT_TEST(testFirstOpenWindowOutgoing); CPPUNIT_TEST(testFirstOpenWindowBareToFull); CPPUNIT_TEST(testSecondWindow); CPPUNIT_TEST(testUnbindRebind); CPPUNIT_TEST(testNoDuplicateUnbind); CPPUNIT_TEST(testThreeMUCWindows); CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnRemoveFromRoster); CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster); CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth); CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom); CPPUNIT_TEST_SUITE_END(); public: void setUp() { mocks_ = new MockRepository(); jid_ = JID("test@test.com/resource"); stanzaChannel_ = new DummyStanzaChannel(); iqChannel_ = new DummyIQChannel(); iqRouter_ = new IQRouter(iqChannel_); capsProvider_ = new DummyCapsProvider(); eventController_ = new EventController(); chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>(); xmppRoster_ = new XMPPRosterImpl(); mucRegistry_ = new MUCRegistry(); nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); presenceOracle_ = new PresenceOracle(stanzaChannel_); serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo()); presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_); uiEventStream_ = new UIEventStream(); entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>(); mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>(); settings_ = new DummySettingsProvider(); profileSettings_ = new ProfileSettingsProvider("a", settings_); chatListWindow_ = new MockChatListWindow(); ftManager_ = new DummyFileTransferManager(); ftOverview_ = new FileTransferOverview(ftManager_); mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_); - manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false); + 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_); avatarManager_ = new NullAvatarManager(); manager_->setAvatarManager(avatarManager_); }; void tearDown() { //delete chatListWindowFactory - delete settings_; delete profileSettings_; delete avatarManager_; delete manager_; delete ftOverview_; delete ftManager_; delete directedPresenceSender_; delete presenceSender_; delete presenceOracle_; delete nickResolver_; delete mucRegistry_; delete stanzaChannel_; delete eventController_; delete iqRouter_; delete iqChannel_; delete uiEventStream_; delete mucManager_; delete xmppRoster_; delete entityCapsManager_; delete capsProvider_; delete chatListWindow_; delete mocks_; + delete settings_; } void testFirstOpenWindowIncoming() { JID messageJID("testling@test.com/resource1"); MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); boost::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, window->lastMessageBody_); } void testSecondOpenWindowIncoming() { JID messageJID1("testling@test.com/resource1"); MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1); boost::shared_ptr<Message> message1(new Message()); message1->setFrom(messageJID1); std::string body1("This is a legible message. >HEH@)oeueu"); message1->setBody(body1); manager_->handleIncomingMessage(message1); CPPUNIT_ASSERT_EQUAL(body1, window1->lastMessageBody_); JID messageJID2("testling@test.com/resource2"); //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2); boost::shared_ptr<Message> message2(new Message()); @@ -321,130 +321,130 @@ public: presenceOracle_->onPresenceChange(jid1Offline); boost::shared_ptr<Presence> jid2Online(new Presence()); jid2Online->setFrom(JID(messageJID2)); boost::shared_ptr<Presence> jid2Offline(new Presence()); jid2Offline->setFrom(JID(messageJID2)); jid2Offline->setType(Presence::Unavailable); presenceOracle_->onPresenceChange(jid2Offline); JID messageJID3("testling@test.com/resource3"); boost::shared_ptr<Message> message3(new Message()); message3->setFrom(messageJID3); std::string body3("This is a legible message3."); message3->setBody(body3); manager_->handleIncomingMessage(message3); CPPUNIT_ASSERT_EQUAL(body3, window1->lastMessageBody_); boost::shared_ptr<Message> message2b(new Message()); message2b->setFrom(messageJID2); std::string body2b("This is a legible message2b."); message2b->setBody(body2b); manager_->handleIncomingMessage(message2b); CPPUNIT_ASSERT_EQUAL(body2b, window1->lastMessageBody_); } /** * Test that ChatController doesn't send receipts anymore after removal of the contact from the roster. */ void testChatControllerPresenceAccessUpdatedOnRemoveFromRoster() { JID messageJID("testling@test.com/resource1"); xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both); MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new ToggleRequestDeliveryReceiptsUIEvent(true))); + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); manager_->handleIncomingMessage(message); Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); xmppRoster_->removeContact(messageJID); message->setID("2"); manager_->handleIncomingMessage(message); CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); } /** * Test that ChatController sends receipts after the contact has been added to the roster. */ void testChatControllerPresenceAccessUpdatedOnAddToRoster() { JID messageJID("testling@test.com/resource1"); MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new ToggleRequestDeliveryReceiptsUIEvent(true))); + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); manager_->handleIncomingMessage(message); CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size()); xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both); message->setID("2"); manager_->handleIncomingMessage(message); CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); } /** * Test that ChatController sends receipts if requested after change from subscription state To to subscription state Both. */ void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth() { testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::Both); } /** * Test that ChatController sends receipts if requested after change from subscription state To to subscription state From. */ void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom() { testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From); } void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) { JID messageJID("testling@test.com/resource1"); xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from); MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new ToggleRequestDeliveryReceiptsUIEvent(true))); + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); manager_->handleIncomingMessage(message); CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size()); xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), to); message->setID("2"); manager_->handleIncomingMessage(message); CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); } private: boost::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) { boost::shared_ptr<Message> message = boost::make_shared<Message>(); message->setFrom(from); message->setID(id); message->addPayload(boost::make_shared<DeliveryReceiptRequest>()); return message; } size_t st(int i) { return static_cast<size_t>(i); } private: JID jid_; ChatsManager* manager_; DummyStanzaChannel* stanzaChannel_; IQChannel* iqChannel_; IQRouter* iqRouter_; EventController* eventController_; |
Swift