summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp8
-rw-r--r--Swift/Controllers/Chat/ChatController.h4
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp72
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h13
-rw-r--r--Swift/Controllers/Chat/ChatMessageParser.cpp10
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp12
-rw-r--r--Swift/Controllers/Chat/MUCController.h6
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp47
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp90
9 files changed, 195 insertions, 67 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index a80eee5..7f62c36 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -208,10 +208,10 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me
}
}
-void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
+void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) {
eventController_->handleIncomingEvent(messageEvent);
if (!messageEvent->getConcluded()) {
- highlighter_->handleHighlightAction(highlight);
+ handleHighlightActions(chatMessage);
}
}
@@ -316,9 +316,9 @@ void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<
boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
if (replace) {
eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_));
- replaceMessage(body, myLastMessageUIID_, true, boost::posix_time::microsec_clock::universal_time(), HighlightAction());
+ replaceMessage(chatMessageParser_->parseMessageBody(body, "", true), 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>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time(), HighlightAction());
+ myLastMessageUIID_ = addMessage(chatMessageParser_->parseMessageBody(body, "", true), QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time());
}
if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) {
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index 9ee82eb..6ec19df 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -52,7 +52,7 @@ namespace Swift {
virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
virtual void postSendMessage(const std::string &body, boost::shared_ptr<Stanza> sentStanza) SWIFTEN_OVERRIDE;
virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) SWIFTEN_OVERRIDE;
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction&) SWIFTEN_OVERRIDE;
+ virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE;
virtual void preSendMessageRequest(boost::shared_ptr<Message>) SWIFTEN_OVERRIDE;
virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index fef3e7a..c790cce 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -208,19 +208,50 @@ bool ChatControllerBase::hasOpenWindow() const {
return chatWindow_ && chatWindow_->isVisible();
}
-std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
+ChatWindow::ChatMessage ChatControllerBase::buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction) {
+ ChatWindow::ChatMessage chatMessage;
if (boost::starts_with(message, "/me ")) {
- return chatWindow_->addAction(chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight);
- } else {
- return chatWindow_->addMessage(chatMessageParser_->parseMessageBody(message,highlighter_->getNick(),senderIsSelf), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight);
+ chatMessage = chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second);
+ }
+ else {
+ chatMessage = chatMessageParser_->parseMessageBody(message, highlighter_->getNick(), senderIsSelf);
}
+ chatMessage.setFullMessageHighlightAction(fullMessageHighlightAction);
+ return chatMessage;
}
-void ChatControllerBase::replaceMessage(const std::string& message, const std::string& id, bool senderIsSelf, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- if (boost::starts_with(message, "/me ")) {
- chatWindow_->replaceWithAction(chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second), id, time, highlight);
- } else {
- chatWindow_->replaceMessage(chatMessageParser_->parseMessageBody(message,highlighter_->getNick(),senderIsSelf), id, time, highlight);
+void ChatControllerBase::handleHighlightActions(const ChatWindow::ChatMessage& chatMessage) {
+ std::set<std::string> playedSounds;
+ if (chatMessage.getFullMessageHighlightAction().playSound()) {
+ highlighter_->handleHighlightAction(chatMessage.getFullMessageHighlightAction());
+ playedSounds.insert(chatMessage.getFullMessageHighlightAction().getSoundFile());
+ }
+ foreach(boost::shared_ptr<ChatWindow::ChatMessagePart> part, chatMessage.getParts()) {
+ boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightMessage = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part);
+ if (highlightMessage && highlightMessage->action.playSound()) {
+ if (playedSounds.find(highlightMessage->action.getSoundFile()) == playedSounds.end()) {
+ highlighter_->handleHighlightAction(highlightMessage->action);
+ playedSounds.insert(highlightMessage->action.getSoundFile());
+ }
+ }
+ }
+}
+
+std::string ChatControllerBase::addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time) {
+ if (chatMessage.isMeCommand()) {
+ return chatWindow_->addAction(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time);
+ }
+ else {
+ return chatWindow_->addMessage(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time);
+ }
+}
+
+void ChatControllerBase::replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time) {
+ if (chatMessage.isMeCommand()) {
+ chatWindow_->replaceWithAction(chatMessage, id, time);
+ }
+ else {
+ chatWindow_->replaceMessage(chatMessage, id, time);
}
}
@@ -236,9 +267,11 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
targetedUnreadMessages_.push_back(messageEvent);
}
}
+
boost::shared_ptr<Message> message = messageEvent->getStanza();
- std::string body = message->getBody().get_value_or("");
- HighlightAction highlight;
+ ChatWindow::ChatMessage chatMessage;
+ boost::optional<std::string> optionalBody = message->getBody();
+ std::string body = optionalBody.get_value_or("");
if (message->isError()) {
if (!message->getTo().getResource().empty()) {
std::string errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>()));
@@ -280,22 +313,25 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
onActivity(body);
// Highlight
+ HighlightAction fullMessageHighlight;
if (!isIncomingMessageFromMe(message)) {
- highlight = highlighter_->findAction(body, senderHighlightNameFromMessage(from));
+ fullMessageHighlight = highlighter_->findFirstFullMessageMatchAction(body, senderHighlightNameFromMessage(from));
}
boost::shared_ptr<Replace> replace = message->getPayload<Replace>();
+ bool senderIsSelf = isIncomingMessageFromMe(message);
if (replace) {
- std::string body = message->getBody().get_value_or("");
// Should check if the user has a previous message
std::map<JID, std::string>::iterator lastMessage;
lastMessage = lastMessagesUIID_.find(from);
if (lastMessage != lastMessagesUIID_.end()) {
- replaceMessage(body, lastMessagesUIID_[from], isIncomingMessageFromMe(message), timeStamp, highlight);
+ chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight);
+ replaceMessage(chatMessage, lastMessagesUIID_[from], timeStamp);
}
}
else {
- addMessageHandleIncomingMessage(from, body, isIncomingMessageFromMe(message), label, timeStamp, highlight);
+ chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight);
+ addMessageHandleIncomingMessage(from, chatMessage, senderIsSelf, label, timeStamp);
}
logMessage(body, from, selfJID_, timeStamp, true);
@@ -303,11 +339,11 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
chatWindow_->show();
chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size()));
onUnreadCountChanged();
- postHandleIncomingMessage(messageEvent, highlight);
+ postHandleIncomingMessage(messageEvent, chatMessage);
}
-void ChatControllerBase::addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& timeStamp, const HighlightAction& highlight) {
- lastMessagesUIID_[from] = addMessage(message, senderDisplayNameFromMessage(from), senderIsSelf, label, avatarManager_->getAvatarPath(from), timeStamp, highlight);
+void ChatControllerBase::addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& timeStamp) {
+ lastMessagesUIID_[from] = addMessage(message, senderDisplayNameFromMessage(from), senderIsSelf, label, avatarManager_->getAvatarPath(from), timeStamp);
}
std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) {
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index 4e68a2b..98f0ab0 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -55,8 +55,8 @@ namespace Swift {
bool hasOpenWindow() const;
virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<MessageEvent> message);
- std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- void replaceMessage(const std::string& message, const std::string& id, bool senderIsSelf, const boost::posix_time::ptime& time, const HighlightAction& highlight);
+ std::string addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time);
+ void replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time);
virtual void setOnline(bool online);
void setEnabled(bool enabled);
virtual void setToJID(const JID& jid) {toJID_ = jid;}
@@ -82,8 +82,8 @@ namespace Swift {
virtual std::string senderHighlightNameFromMessage(const JID& from) = 0;
virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0;
virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {}
- virtual void addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&) {}
+ virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time);
+ virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage&) {}
virtual void preSendMessageRequest(boost::shared_ptr<Message>) {}
virtual bool isFromContact(const JID& from);
virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const = 0;
@@ -95,11 +95,14 @@ namespace Swift {
/** JID any iq for account should go to - bare except for PMs */
virtual JID getBaseJID();
virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) = 0;
+ ChatWindow::ChatMessage buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction);
+ void handleHighlightActions(const ChatWindow::ChatMessage& chatMessage);
private:
IDGenerator idGenerator_;
std::string lastSentMessageStanzaID_;
void createDayChangeTimer();
+
void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage);
void handleAllMessagesRead();
void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error);
diff --git a/Swift/Controllers/Chat/ChatMessageParser.cpp b/Swift/Controllers/Chat/ChatMessageParser.cpp
index 666ec2f..53c7588 100644
--- a/Swift/Controllers/Chat/ChatMessageParser.cpp
+++ b/Swift/Controllers/Chat/ChatMessageParser.cpp
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/ChatMessageParser.h>
-#include <vector>
#include <utility>
+#include <vector>
-#include <boost/smart_ptr/make_shared.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Base/Regex.h>
#include <Swiften/Base/foreach.h>
#include <SwifTools/Linkify.h>
-
namespace Swift {
ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode)
@@ -170,8 +169,7 @@ namespace Swift {
}
boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart = boost::make_shared<ChatWindow::ChatHighlightingMessagePart>();
highlightPart->text = match.str();
- highlightPart->foregroundColor = rule.getAction().getTextColor();
- highlightPart->backgroundColor = rule.getAction().getTextBackground();
+ highlightPart->action = rule.getAction();
newMessage.append(highlightPart);
start = matchEnd;
}
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 409fe1f..0bb670d 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -576,23 +576,23 @@ void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> mes
}
}
-void MUCController::addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
+void MUCController::addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) {
if (from.isBare()) {
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1%")) % message)), ChatWindow::DefaultDirection);
+ chatWindow_->addSystemMessage(message, ChatWindow::DefaultDirection);
}
else {
- ChatControllerBase::addMessageHandleIncomingMessage(from, message, senderIsSelf, label, time, highlight);
+ ChatControllerBase::addMessageHandleIncomingMessage(from, message, senderIsSelf, label, time);
}
}
-void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
+void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) {
boost::shared_ptr<Message> message = messageEvent->getStanza();
if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && !message->getPayload<Delay>()) {
if (messageTargetsMe(message) || isImpromptu_) {
eventController_->handleIncomingEvent(messageEvent);
}
if (!messageEvent->getConcluded()) {
- highlighter_->handleHighlightAction(highlight);
+ handleHighlightActions(chatMessage);
}
}
}
@@ -1074,7 +1074,7 @@ void MUCController::addRecentLogs() {
bool senderIsSelf = nick_ == message.getFromJID().getResource();
// the chatWindow uses utc timestamps
- addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset()), HighlightAction());
+ addMessage(chatMessageParser_->parseMessageBody(message.getMessage()), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset()));
}
}
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index a08d541..0fb739a 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -81,8 +81,8 @@ namespace Swift {
virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const SWIFTEN_OVERRIDE;
virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) SWIFTEN_OVERRIDE;
- virtual void addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time, const HighlightAction& highlight) SWIFTEN_OVERRIDE;
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&) SWIFTEN_OVERRIDE;
+ virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE;
+ virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE;
virtual void cancelReplaces() SWIFTEN_OVERRIDE;
virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE;
diff --git a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
index 1b92bb6..6748b9e 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -49,9 +49,11 @@ public:
CPPUNIT_ASSERT_EQUAL(path, part->imagePath);
}
- void assertHighlight(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
- boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(result.getParts()[index]);
- CPPUNIT_ASSERT_EQUAL(text, part->text);
+#define assertHighlight(RESULT, INDEX, TEXT, EXPECTED_HIGHLIGHT) \
+ { \
+ boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(RESULT.getParts()[INDEX]); \
+ CPPUNIT_ASSERT_EQUAL(std::string(TEXT), part->text); \
+ CPPUNIT_ASSERT(EXPECTED_HIGHLIGHT == part->action); \
}
void assertURL(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
@@ -108,13 +110,14 @@ public:
ChatWindow::ChatMessage result = testling.parseMessageBody(no_special_message);
assertText(result, 0, no_special_message);
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ HighlightRulesListPtr highlightRuleList = ruleListFromKeyword("trigger", false, false);
+ testling = ChatMessageParser(emoticons_, highlightRuleList);
result = testling.parseMessageBody(":) shiny :( trigger :) http://wonderland.lit/blah http://denmark.lit boom boom");
assertEmoticon(result, 0, smile1_, smile1Path_);
assertText(result, 1, " shiny ");
assertEmoticon(result, 2, smile2_, smile2Path_);
assertText(result, 3, " ");
- assertHighlight(result, 4, "trigger");
+ assertHighlight(result, 4, "trigger", highlightRuleList->getRule(0).getAction());
assertText(result, 5, " ");
assertEmoticon(result, 6, smile1_, smile1Path_);
assertText(result, 7, " ");
@@ -126,7 +129,7 @@ public:
testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
result = testling.parseMessageBody("testtriggermessage");
assertText(result, 0, "test");
- assertHighlight(result, 1, "trigger");
+ assertHighlight(result, 1, "trigger", highlightRuleList->getRule(0).getAction());
assertText(result, 2, "message");
testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, true));
@@ -139,32 +142,32 @@ public:
testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
result = testling.parseMessageBody("TrIgGeR");
- assertHighlight(result, 0, "TrIgGeR");
+ assertHighlight(result, 0, "TrIgGeR", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
result = testling.parseMessageBody("partialTrIgGeRmatch");
assertText(result, 0, "partial");
- assertHighlight(result, 1, "TrIgGeR");
+ assertHighlight(result, 1, "TrIgGeR", highlightRuleList->getRule(0).getAction());
assertText(result, 2, "match");
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
result = testling.parseMessageBody("zero one two three");
assertText(result, 0, "zero ");
- assertHighlight(result, 1, "one");
+ assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction());
assertText(result, 2, " two ");
- assertHighlight(result, 3, "three");
+ assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
result = testling.parseMessageBody("zero oNe two tHrEe");
assertText(result, 0, "zero ");
- assertHighlight(result, 1, "oNe");
+ assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction());
assertText(result, 2, " two ");
- assertHighlight(result, 3, "tHrEe");
+ assertHighlight(result, 3, "tHrEe", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", true, false)));
result = testling.parseMessageBody("zero oNe two tHrEe");
assertText(result, 0, "zero ");
- assertHighlight(result, 1, "oNe");
+ assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction());
assertText(result, 2, " two tHrEe");
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", true, false)));
@@ -174,19 +177,19 @@ public:
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
result = testling.parseMessageBody("zeroonetwothree");
assertText(result, 0, "zero");
- assertHighlight(result, 1, "one");
+ assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction());
assertText(result, 2, "two");
- assertHighlight(result, 3, "three");
+ assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", false, false)));
result = testling.parseMessageBody("zeroOnEtwoThReE");
assertText(result, 0, "zeroOnEtwo");
- assertHighlight(result, 1, "ThReE");
+ assertHighlight(result, 1, "ThReE", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, false)));
result = testling.parseMessageBody("zeroonetwothree");
assertText(result, 0, "zeroonetwo");
- assertHighlight(result, 1, "three");
+ assertHighlight(result, 1, "three", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true)));
result = testling.parseMessageBody("zeroonetwothree");
@@ -194,7 +197,7 @@ public:
testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
result = testling.parseMessageBody("Alice", "Alice");
- assertHighlight(result, 0, "Alice");
+ assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction());
testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
result = testling.parseMessageBody("TextAliceText", "Alice");
@@ -203,18 +206,18 @@ public:
testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
result = testling.parseMessageBody("Text Alice Text", "Alice");
assertText(result, 0, "Text ");
- assertHighlight(result, 1, "Alice");
+ assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction());
assertText(result, 2, " Text");
testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
result = testling.parseMessageBody("Alice Text", "Alice");
- assertHighlight(result, 0, "Alice");
+ assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction());
assertText(result, 1, " Text");
testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
result = testling.parseMessageBody("Text Alice", "Alice");
assertText(result, 0, "Text ");
- assertHighlight(result, 1, "Alice");
+ assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction());
}
void testOneEmoticon() {
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 4f8cf5a..31d54db 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -4,6 +4,9 @@
* See the COPYING file for more information.
*/
+#include <set>
+#include <map>
+
#include <boost/bind.hpp>
#include <cppunit/extensions/HelperMacros.h>
@@ -75,6 +78,8 @@ class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
CPPUNIT_TEST(testChatControllerPMPresenceHandling);
CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect);
+ CPPUNIT_TEST(testChatControllerHighlightingNotificationTesting);
+ CPPUNIT_TEST(testChatControllerHighlightingNotificationDeduplicateSounds);
CPPUNIT_TEST_SUITE_END();
public:
@@ -110,6 +115,9 @@ public:
wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsProvider_);
wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_);
highlightManager_ = new HighlightManager(settings_);
+ handledHighlightActions_ = 0;
+ soundsPlayed_.clear();
+ highlightManager_->onHighlight.connect(boost::bind(&ChatsManagerTest::handleHighlightAction, this, _1));
crypto_ = PlatformCryptoProvider::create();
vcardStorage_ = new VCardMemoryStorage(crypto_);
@@ -156,7 +164,7 @@ public:
void testFirstOpenWindowIncoming() {
JID messageJID("testling@test.com/resource1");
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
boost::shared_ptr<Message> message(new Message());
@@ -724,6 +732,77 @@ public:
CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0);
}
+ void testChatControllerHighlightingNotificationTesting() {
+ HighlightRule keywordRuleA;
+ keywordRuleA.setMatchChat(true);
+ std::vector<std::string> keywordsA;
+ keywordsA.push_back("Romeo");
+ keywordRuleA.setKeywords(keywordsA);
+ keywordRuleA.getAction().setTextColor("yellow");
+ keywordRuleA.getAction().setPlaySound(true);
+ highlightManager_->insertRule(0, keywordRuleA);
+
+ HighlightRule keywordRuleB;
+ keywordRuleB.setMatchChat(true);
+ std::vector<std::string> keywordsB;
+ keywordsB.push_back("Juliet");
+ keywordRuleB.setKeywords(keywordsB);
+ keywordRuleB.getAction().setTextColor("green");
+ keywordRuleB.getAction().setPlaySound(true);
+ keywordRuleB.getAction().setSoundFile("/tmp/someotherfile.wav");
+ highlightManager_->insertRule(0, keywordRuleB);
+
+ JID messageJID = JID("testling@test.com");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ boost::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This message should cause two sounds: Juliet and Romeo.");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(2, handledHighlightActions_);
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end());
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end());
+ }
+
+ void testChatControllerHighlightingNotificationDeduplicateSounds() {
+ HighlightRule keywordRuleA;
+ keywordRuleA.setMatchChat(true);
+ std::vector<std::string> keywordsA;
+ keywordsA.push_back("Romeo");
+ keywordRuleA.setKeywords(keywordsA);
+ keywordRuleA.getAction().setTextColor("yellow");
+ keywordRuleA.getAction().setPlaySound(true);
+ highlightManager_->insertRule(0, keywordRuleA);
+
+ HighlightRule keywordRuleB;
+ keywordRuleB.setMatchChat(true);
+ std::vector<std::string> keywordsB;
+ keywordsB.push_back("Juliet");
+ keywordRuleB.setKeywords(keywordsB);
+ keywordRuleB.getAction().setTextColor("green");
+ keywordRuleB.getAction().setPlaySound(true);
+ highlightManager_->insertRule(0, keywordRuleB);
+
+ JID messageJID = JID("testling@test.com");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ boost::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This message should cause one sound, because both actions have the same sound: Juliet and Romeo.");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(1, handledHighlightActions_);
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end());
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end());
+ }
+
private:
boost::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) {
boost::shared_ptr<Message> message = boost::make_shared<Message>();
@@ -738,6 +817,13 @@ private:
return static_cast<size_t>(i);
}
+ void handleHighlightAction(const HighlightAction& action) {
+ handledHighlightActions_++;
+ if (action.playSound()) {
+ soundsPlayed_.insert(action.getSoundFile());
+ }
+ }
+
private:
JID jid_;
ChatsManager* manager_;
@@ -775,6 +861,8 @@ private:
CryptoProvider* crypto_;
VCardStorage* vcardStorage_;
std::map<std::string, std::string> emoticons_;
+ int handledHighlightActions_;
+ std::set<std::string> soundsPlayed_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);