summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-01-13 15:26:24 (GMT)
committerSwift Review <review@swift.im>2014-07-09 14:01:41 (GMT)
commitf2bcc401477dcb5ca52b5d9d5e85f4bf7bae9285 (patch)
tree01cf807b2ad59f5ea6504fd28d12e0f994e2f907 /Swift/Controllers/Chat/UnitTest
parent8e03583fe21bcd5e0025da81d8f4a34ed05cd058 (diff)
downloadswift-contrib-f2bcc401477dcb5ca52b5d9d5e85f4bf7bae9285.zip
swift-contrib-f2bcc401477dcb5ca52b5d9d5e85f4bf7bae9285.tar.bz2
Reworked highlight rules dialog. Added support for highlighting individual words in messages.
Change-Id: I378fa69077c29008db4ef7c2265e5212924bc2ce
Diffstat (limited to 'Swift/Controllers/Chat/UnitTest')
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp134
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp7
2 files changed, 123 insertions, 18 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
index 0a14303..5dca63a 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
@@ -1,125 +1,231 @@
/*
* Copyright (c) 2013-2014 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 <hippomocks.h>
#include <Swift/Controllers/Chat/ChatMessageParser.h>
using namespace Swift;
class ChatMessageParserTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ChatMessageParserTest);
CPPUNIT_TEST(testFullBody);
CPPUNIT_TEST(testOneEmoticon);
CPPUNIT_TEST(testBareEmoticon);
CPPUNIT_TEST(testHiddenEmoticon);
CPPUNIT_TEST(testEndlineEmoticon);
CPPUNIT_TEST(testBoundedEmoticons);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
smile1_ = ":)";
smile1Path_ = "/blah/smile1.png";
smile2_ = ":(";
smile2Path_ = "/blah/smile2.jpg";
emoticons_[smile1_] = smile1Path_;
emoticons_[smile2_] = smile2Path_;
}
void tearDown() {
emoticons_.clear();
}
void assertText(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
boost::shared_ptr<ChatWindow::ChatTextMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(result.getParts()[index]);
CPPUNIT_ASSERT_EQUAL(text, part->text);
}
void assertEmoticon(const ChatWindow::ChatMessage& result, size_t index, const std::string& text, const std::string& path) {
boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(result.getParts()[index]);
CPPUNIT_ASSERT(!!part);
CPPUNIT_ASSERT_EQUAL(text, part->alternativeText);
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);
+ }
+
void assertURL(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
boost::shared_ptr<ChatWindow::ChatURIMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(result.getParts()[index]);
CPPUNIT_ASSERT_EQUAL(text, part->target);
}
+ static HighlightRule ruleFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord)
+ {
+ HighlightRule rule;
+ std::vector<std::string> keywords;
+ keywords.push_back(keyword);
+ rule.setKeywords(keywords);
+ rule.setMatchCase(matchCase);
+ rule.setMatchWholeWords(matchWholeWord);
+ rule.setMatchChat(true);
+ return rule;
+ }
+
+ static const HighlightRulesListPtr ruleListFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord)
+ {
+ boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>();
+ list->addRule(ruleFromKeyword(keyword, matchCase, matchWholeWord));
+ return list;
+ }
+
+ static const HighlightRulesListPtr ruleListFromKeywords(const HighlightRule &rule1, const HighlightRule &rule2)
+ {
+ boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>();
+ list->addRule(rule1);
+ list->addRule(rule2);
+ return list;
+ }
+
void testFullBody() {
- ChatMessageParser testling(emoticons_);
- ChatWindow::ChatMessage result = testling.parseMessageBody(":) shiny :( :) http://wonderland.lit/blah http://denmark.lit boom boom");
+ const std::string no_special_message = "a message with no special content";
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody(no_special_message);
+ assertText(result, 0, no_special_message);
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ 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, " ");
- assertEmoticon(result, 4, smile1_, smile1Path_);
+ assertHighlight(result, 4, "trigger");
assertText(result, 5, " ");
- assertURL(result, 6, "http://wonderland.lit/blah");
+ assertEmoticon(result, 6, smile1_, smile1Path_);
assertText(result, 7, " ");
- assertURL(result, 8, "http://denmark.lit");
- assertText(result, 9, " boom boom");
+ assertURL(result, 8, "http://wonderland.lit/blah");
+ assertText(result, 9, " ");
+ assertURL(result, 10, "http://denmark.lit");
+ assertText(result, 11, " boom boom");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ result = testling.parseMessageBody("testtriggermessage");
+ assertText(result, 0, "test");
+ assertHighlight(result, 1, "trigger");
+ assertText(result, 2, "message");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, true));
+ result = testling.parseMessageBody("testtriggermessage");
+ assertText(result, 0, "testtriggermessage");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", true, false));
+ result = testling.parseMessageBody("TrIgGeR");
+ assertText(result, 0, "TrIgGeR");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ result = testling.parseMessageBody("TrIgGeR");
+ assertHighlight(result, 0, "TrIgGeR");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ result = testling.parseMessageBody("partialTrIgGeRmatch");
+ assertText(result, 0, "partial");
+ assertHighlight(result, 1, "TrIgGeR");
+ 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");
+ assertText(result, 2, " two ");
+ assertHighlight(result, 3, "three");
+
+ 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");
+ assertText(result, 2, " two ");
+ assertHighlight(result, 3, "tHrEe");
+
+ 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");
+ assertText(result, 2, " two tHrEe");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", true, false)));
+ result = testling.parseMessageBody("zero oNe two tHrEe");
+ assertText(result, 0, "zero oNe two tHrEe");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zeroonetwothree");
+ assertText(result, 0, "zero");
+ assertHighlight(result, 1, "one");
+ assertText(result, 2, "two");
+ assertHighlight(result, 3, "three");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zeroOnEtwoThReE");
+ assertText(result, 0, "zeroOnEtwo");
+ assertHighlight(result, 1, "ThReE");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zeroonetwothree");
+ assertText(result, 0, "zeroonetwo");
+ assertHighlight(result, 1, "three");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true)));
+ result = testling.parseMessageBody("zeroonetwothree");
+ assertText(result, 0, "zeroonetwothree");
}
void testOneEmoticon() {
- ChatMessageParser testling(emoticons_);
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
ChatWindow::ChatMessage result = testling.parseMessageBody(" :) ");
assertText(result, 0, " ");
assertEmoticon(result, 1, smile1_, smile1Path_);
assertText(result, 2, " ");
}
void testBareEmoticon() {
- ChatMessageParser testling(emoticons_);
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
ChatWindow::ChatMessage result = testling.parseMessageBody(":)");
assertEmoticon(result, 0, smile1_, smile1Path_);
}
void testHiddenEmoticon() {
- ChatMessageParser testling(emoticons_);
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
ChatWindow::ChatMessage result = testling.parseMessageBody("b:)a");
assertText(result, 0, "b:)a");
}
void testEndlineEmoticon() {
- ChatMessageParser testling(emoticons_);
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
ChatWindow::ChatMessage result = testling.parseMessageBody("Lazy:)");
assertText(result, 0, "Lazy");
assertEmoticon(result, 1, smile1_, smile1Path_);
}
void testBoundedEmoticons() {
- ChatMessageParser testling(emoticons_);
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
ChatWindow::ChatMessage result = testling.parseMessageBody(":)Lazy:(");
assertEmoticon(result, 0, smile1_, smile1Path_);
assertText(result, 1, "Lazy");
assertEmoticon(result, 2, smile2_, smile2Path_);
}
void testEmoticonParenthesis() {
- ChatMessageParser testling(emoticons_);
+ ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
ChatWindow::ChatMessage result = testling.parseMessageBody("(Like this :))");
assertText(result, 0, "(Like this ");
assertEmoticon(result, 1, smile1_, smile1Path_);
assertText(result, 2, ")");
}
-
private:
std::map<std::string, std::string> emoticons_;
std::string smile1_;
std::string smile1Path_;
std::string smile2_;
std::string smile2Path_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatMessageParserTest);
-
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index 7268878..bb22e43 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -1,439 +1,438 @@
/*
- * Copyright (c) 2010-2013 Kevin Smith
+ * Copyright (c) 2010-2014 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 <boost/algorithm/string.hpp>
#include <hippomocks.h>
#include "Swiften/Base/foreach.h"
#include "Swift/Controllers/XMPPEvents/EventController.h"
#include "Swiften/Presence/DirectedPresenceSender.h"
#include "Swiften/Presence/StanzaChannelPresenceSender.h"
#include "Swiften/Avatars/NullAvatarManager.h"
#include "Swift/Controllers/Chat/MUCController.h"
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swiften/Client/NickResolver.h"
#include "Swiften/Roster/XMPPRoster.h"
#include "Swift/Controllers/UIEvents/UIEventStream.h"
#include "Swift/Controllers/UnitTest/MockChatWindow.h"
#include "Swiften/MUC/UnitTest/MockMUC.h"
#include "Swiften/Client/DummyStanzaChannel.h"
#include "Swiften/Queries/DummyIQChannel.h"
#include "Swiften/Presence/PresenceOracle.h"
#include "Swiften/Network/TimerFactory.h"
#include "Swiften/Elements/MUCUserPayload.h"
#include "Swiften/Disco/DummyEntityCapsProvider.h"
#include <Swiften/VCards/VCardMemoryStorage.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#include <Swiften/VCards/VCardManager.h>
#include <Swift/Controllers/Settings/DummySettingsProvider.h>
#include <Swift/Controllers/Chat/ChatMessageParser.h>
#include <Swift/Controllers/Chat/UserSearchController.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swiften/Crypto/CryptoProvider.h>
using namespace Swift;
class MUCControllerTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MUCControllerTest);
CPPUNIT_TEST(testJoinPartStringContructionSimple);
CPPUNIT_TEST(testJoinPartStringContructionMixed);
CPPUNIT_TEST(testAppendToJoinParts);
CPPUNIT_TEST(testAddressedToSelf);
CPPUNIT_TEST(testNotAddressedToSelf);
CPPUNIT_TEST(testAddressedToSelfBySelf);
CPPUNIT_TEST(testMessageWithEmptyLabelItem);
CPPUNIT_TEST(testMessageWithLabelItem);
CPPUNIT_TEST(testCorrectMessageWithLabelItem);
CPPUNIT_TEST(testRoleAffiliationStates);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
crypto_ = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
self_ = JID("girl@wonderland.lit/rabbithole");
nick_ = "aLiCe";
mucJID_ = JID("teaparty@rooms.wonderland.lit");
mocks_ = new MockRepository();
stanzaChannel_ = new DummyStanzaChannel();
iqChannel_ = new DummyIQChannel();
iqRouter_ = new IQRouter(iqChannel_);
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>();
presenceOracle_ = new PresenceOracle(stanzaChannel_);
presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
uiEventStream_ = new UIEventStream();
avatarManager_ = new NullAvatarManager();
TimerFactory* timerFactory = NULL;
window_ = new MockChatWindow();
mucRegistry_ = new MUCRegistry();
entityCapsProvider_ = new DummyEntityCapsProvider();
settings_ = new DummySettingsProvider();
highlightManager_ = new HighlightManager(settings_);
muc_ = boost::make_shared<MockMUC>(mucJID_);
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);
- chatMessageParser_ = new ChatMessageParser(std::map<std::string, std::string>());
+ chatMessageParser_ = boost::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true);
vcardStorage_ = new VCardMemoryStorage(crypto_.get());
vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_);
controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, chatMessageParser_, false, NULL, vcardManager_);
}
void tearDown() {
delete controller_;
delete vcardManager_;
delete vcardStorage_;
delete highlightManager_;
delete settings_;
delete entityCapsProvider_;
delete eventController_;
delete presenceOracle_;
delete mocks_;
delete uiEventStream_;
delete stanzaChannel_;
delete presenceSender_;
delete directedPresenceSender_;
delete iqRouter_;
delete iqChannel_;
delete mucRegistry_;
delete avatarManager_;
- delete chatMessageParser_;
}
void finishJoin() {
Presence::ref presence(new Presence());
presence->setFrom(JID(muc_->getJID().toString() + "/" + nick_));
MUCUserPayload::ref status(new MUCUserPayload());
MUCUserPayload::StatusCode code;
code.code = 110;
status->addStatusCode(code);
presence->addPayload(status);
stanzaChannel_->onPresenceReceived(presence);
}
void testAddressedToSelf() {
finishJoin();
Message::ref message(new Message());
message = Message::ref(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/otherperson"));
message->setBody("basic " + nick_ + " test.");
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)1, eventController_->getEvents().size());
message = Message::ref(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/otherperson"));
message->setBody(nick_ + ": hi there");
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)2, eventController_->getEvents().size());
message->setFrom(JID(muc_->getJID().toString() + "/other"));
message->setBody("Hi there " + nick_);
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)3, eventController_->getEvents().size());
message = Message::ref(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/other2"));
message->setBody("Hi " + boost::to_lower_copy(nick_) + ".");
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
message = Message::ref(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/other3"));
message->setBody("Hi bert.");
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
message = Message::ref(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/other2"));
message->setBody("Hi " + boost::to_lower_copy(nick_) + "ie.");
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
}
void testNotAddressedToSelf() {
finishJoin();
Message::ref message(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/other3"));
message->setBody("Hi there Hatter");
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size());
}
void testAddressedToSelfBySelf() {
finishJoin();
Message::ref message(new Message());
message->setFrom(JID(muc_->getJID().toString() + "/" + nick_));
message->setBody("Hi there " + nick_);
message->setType(Message::Groupchat);
controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size());
}
void testMessageWithEmptyLabelItem() {
SecurityLabelsCatalog::Item label;
label.setSelector("Bob");
window_->label_ = label;
boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>();
features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
controller_->setAvailableServerFeatures(features);
IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>();
labelPayload->addItem(label);
IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
iqChannel_->onIQReceived(result);
std::string messageBody("agamemnon");
window_->onSendMessageRequest(messageBody, false);
boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
CPPUNIT_ASSERT(window_->labelsEnabled_);
CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
CPPUNIT_ASSERT(message);
CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody());
CPPUNIT_ASSERT(!message->getPayload<SecurityLabel>());
}
void testMessageWithLabelItem() {
boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>();
label->setLabel("a");
SecurityLabelsCatalog::Item labelItem;
labelItem.setSelector("Bob");
labelItem.setLabel(label);
window_->label_ = labelItem;
boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>();
features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
controller_->setAvailableServerFeatures(features);
IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>();
labelPayload->addItem(labelItem);
IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
iqChannel_->onIQReceived(result);
std::string messageBody("agamemnon");
window_->onSendMessageRequest(messageBody, false);
boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
CPPUNIT_ASSERT(window_->labelsEnabled_);
CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
CPPUNIT_ASSERT(message);
CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody());
CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
}
void testCorrectMessageWithLabelItem() {
boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>();
label->setLabel("a");
SecurityLabelsCatalog::Item labelItem;
labelItem.setSelector("Bob");
labelItem.setLabel(label);
boost::shared_ptr<SecurityLabel> label2 = boost::make_shared<SecurityLabel>();
label->setLabel("b");
SecurityLabelsCatalog::Item labelItem2;
labelItem2.setSelector("Charlie");
labelItem2.setLabel(label2);
window_->label_ = labelItem;
boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>();
features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
controller_->setAvailableServerFeatures(features);
IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>();
labelPayload->addItem(labelItem);
IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
iqChannel_->onIQReceived(result);
std::string messageBody("agamemnon");
window_->onSendMessageRequest(messageBody, false);
boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
CPPUNIT_ASSERT(window_->labelsEnabled_);
CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
CPPUNIT_ASSERT(message);
CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody());
CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
window_->label_ = labelItem2;
window_->onSendMessageRequest(messageBody, true);
rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
message = boost::dynamic_pointer_cast<Message>(rawStanza);
CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody());
CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
}
void checkEqual(const std::vector<NickJoinPart>& expected, const std::vector<NickJoinPart>& actual) {
CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size());
for (size_t i = 0; i < expected.size(); i++) {
CPPUNIT_ASSERT_EQUAL(expected[i].nick, actual[i].nick);
CPPUNIT_ASSERT_EQUAL(expected[i].type, actual[i].type);
}
}
void testAppendToJoinParts() {
std::vector<NickJoinPart> list;
std::vector<NickJoinPart> gold;
MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join));
gold.push_back(NickJoinPart("Kev", Join));
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Remko", Join));
gold.push_back(NickJoinPart("Remko", Join));
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Bert", Join));
gold.push_back(NickJoinPart("Bert", Join));
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Bert", Part));
gold[2].type = JoinThenPart;
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Kev", Part));
gold[0].type = JoinThenPart;
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Remko", Part));
gold[1].type = JoinThenPart;
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part));
gold.push_back(NickJoinPart("Ernie", Part));
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Join));
gold[3].type = PartThenJoin;
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join));
gold[0].type = Join;
checkEqual(gold, list);
MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part));
gold[3].type = Part;
checkEqual(gold, list);
}
void testJoinPartStringContructionSimple() {
std::vector<NickJoinPart> list;
list.push_back(NickJoinPart("Kev", Join));
CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room"), MUCController::generateJoinPartString(list, false));
list.push_back(NickJoinPart("Remko", Part));
CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
list.push_back(NickJoinPart("Bert", Join));
CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
list.push_back(NickJoinPart("Ernie", Join));
CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
}
void testJoinPartStringContructionMixed() {
std::vector<NickJoinPart> list;
list.push_back(NickJoinPart("Kev", JoinThenPart));
CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered then left the room"), MUCController::generateJoinPartString(list, false));
list.push_back(NickJoinPart("Remko", Part));
CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room and Kev has entered then left the room"), MUCController::generateJoinPartString(list, false));
list.push_back(NickJoinPart("Bert", PartThenJoin));
CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev has entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));
list.push_back(NickJoinPart("Ernie", JoinThenPart));
CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));
}
JID jidFromOccupant(const MUCOccupant& occupant) {
return JID(mucJID_.toString()+"/"+occupant.getNick());
}
void testRoleAffiliationStates() {
typedef std::map<std::string, MUCOccupant> occupant_map;
occupant_map occupants;
occupants.insert(occupant_map::value_type("Kev", MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Owner)));
occupants.insert(occupant_map::value_type("Remko", MUCOccupant("Remko", MUCOccupant::Participant, MUCOccupant::Owner)));
occupants.insert(occupant_map::value_type("Bert", MUCOccupant("Bert", MUCOccupant::Participant, MUCOccupant::Owner)));
occupants.insert(occupant_map::value_type("Ernie", MUCOccupant("Ernie", MUCOccupant::Participant, MUCOccupant::Owner)));
/* populate the MUC with fake users */
typedef const std::pair<std::string,MUCOccupant> occupantIterator;
foreach(occupantIterator &occupant, occupants) {
muc_->insertOccupant(occupant.second);
}
std::vector<MUCOccupant> alterations;
alterations.push_back(MUCOccupant("Kev", MUCOccupant::Visitor, MUCOccupant::Admin));
alterations.push_back(MUCOccupant("Remko", MUCOccupant::Moderator, MUCOccupant::Member));
alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::Outcast));
alterations.push_back(MUCOccupant("Ernie", MUCOccupant::NoRole, MUCOccupant::Member));
alterations.push_back(MUCOccupant("Bert", MUCOccupant::Moderator, MUCOccupant::Owner));
alterations.push_back(MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Outcast));
alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::NoAffiliation));
alterations.push_back(MUCOccupant("Remko", MUCOccupant::NoRole, MUCOccupant::NoAffiliation));
alterations.push_back(MUCOccupant("Ernie", MUCOccupant::Visitor, MUCOccupant::Outcast));
foreach(const MUCOccupant& alteration, alterations) {
/* perform an alteration to a user's role and affiliation */
occupant_map::iterator occupant = occupants.find(alteration.getNick());
CPPUNIT_ASSERT(occupant != occupants.end());
const JID jid = jidFromOccupant(occupant->second);
/* change the affiliation, leave the role in place */
muc_->changeAffiliation(jid, alteration.getAffiliation());
occupant->second = MUCOccupant(occupant->first, occupant->second.getRole(), alteration.getAffiliation());
testRoleAffiliationStatesVerify(occupants);
/* change the role, leave the affiliation in place */
muc_->changeOccupantRole(jid, alteration.getRole());
occupant->second = MUCOccupant(occupant->first, alteration.getRole(), occupant->second.getAffiliation());
testRoleAffiliationStatesVerify(occupants);
}
}
void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) {
/* verify that the roster is in sync */
GroupRosterItem* group = window_->getRosterModel()->getRoot();
foreach(RosterItem* rosterItem, group->getChildren()) {
GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem);
CPPUNIT_ASSERT(child);
foreach(RosterItem* childItem, child->getChildren()) {
ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(childItem);
CPPUNIT_ASSERT(item);
std::map<std::string, MUCOccupant>::const_iterator occupant = occupants.find(item->getJID().getResource());
CPPUNIT_ASSERT(occupant != occupants.end());
CPPUNIT_ASSERT(item->getMUCRole() == occupant->second.getRole());
CPPUNIT_ASSERT(item->getMUCAffiliation() == occupant->second.getAffiliation());
}
}
}
private:
JID self_;
JID mucJID_;
MockMUC::ref muc_;
std::string nick_;
DummyStanzaChannel* stanzaChannel_;
DummyIQChannel* iqChannel_;
IQRouter* iqRouter_;
EventController* eventController_;
ChatWindowFactory* chatWindowFactory_;
UserSearchWindowFactory* userSearchWindowFactory_;
MUCController* controller_;
// NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
StanzaChannelPresenceSender* presenceSender_;
DirectedPresenceSender* directedPresenceSender_;
MockRepository* mocks_;
UIEventStream* uiEventStream_;
MockChatWindow* window_;
MUCRegistry* mucRegistry_;
DummyEntityCapsProvider* entityCapsProvider_;
DummySettingsProvider* settings_;
HighlightManager* highlightManager_;
- ChatMessageParser* chatMessageParser_;
+ boost::shared_ptr<ChatMessageParser> chatMessageParser_;
boost::shared_ptr<CryptoProvider> crypto_;
VCardManager* vcardManager_;
VCardMemoryStorage* vcardStorage_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest);