summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/UnitTest')
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp267
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp115
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp165
-rw-r--r--Swift/Controllers/Chat/UnitTest/MockChatListWindow.h9
4 files changed, 496 insertions, 60 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
new file mode 100644
index 0000000..2a07654
--- /dev/null
+++ b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
@@ -0,0 +1,267 @@
+/*
+ * 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;
+ }
+
+ static HighlightRulesListPtr ruleListWithNickHighlight()
+ {
+ HighlightRule rule;
+ rule.setMatchChat(true);
+ rule.setNickIsKeyword(true);
+ rule.setMatchCase(true);
+ rule.setMatchWholeWords(true);
+ boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>();
+ list->addRule(rule);
+ return list;
+ }
+
+ void testFullBody() {
+ 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, " ");
+ assertHighlight(result, 4, "trigger");
+ assertText(result, 5, " ");
+ assertEmoticon(result, 6, smile1_, smile1Path_);
+ assertText(result, 7, " ");
+ 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");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Alice", "Alice");
+ assertHighlight(result, 0, "Alice");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("TextAliceText", "Alice");
+ assertText(result, 0, "TextAliceText");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Text Alice Text", "Alice");
+ assertText(result, 0, "Text ");
+ assertHighlight(result, 1, "Alice");
+ assertText(result, 2, " Text");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Alice Text", "Alice");
+ assertHighlight(result, 0, "Alice");
+ assertText(result, 1, " Text");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Text Alice", "Alice");
+ assertText(result, 0, "Text ");
+ assertHighlight(result, 1, "Alice");
+ }
+
+ void testOneEmoticon() {
+ 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_, boost::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody(":)");
+ assertEmoticon(result, 0, smile1_, smile1Path_);
+ }
+
+ void testHiddenEmoticon() {
+ 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_, 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_, 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_, 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/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index bbfb22f..4c604ac 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -7,47 +7,56 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include "3rdParty/hippomocks.h"
+
+#include <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/ProfileSettingsProvider.h>
-#include "Swift/Controllers/FileTransfer/FileTransferOverview.h"
-#include "Swiften/Elements/DeliveryReceiptRequest.h"
-#include "Swiften/Elements/DeliveryReceipt.h"
+#include <Swiften/Avatars/AvatarMemoryStorage.h>
+#include <Swiften/Avatars/NullAvatarManager.h>
#include <Swiften/Base/Algorithm.h>
+#include <Swiften/Client/Client.h>
+#include <Swiften/Client/ClientBlockListManager.h>
+#include <Swiften/Client/DummyStanzaChannel.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
+#include <Swiften/Disco/CapsProvider.h>
+#include <Swiften/Disco/EntityCapsManager.h>
+#include <Swiften/Elements/DeliveryReceipt.h>
+#include <Swiften/Elements/DeliveryReceiptRequest.h>
+#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
+#include <Swiften/Jingle/JingleSessionManager.h>
+#include <Swiften/MUC/MUCManager.h>
+#include <Swiften/Presence/DirectedPresenceSender.h>
+#include <Swiften/Presence/PresenceOracle.h>
+#include <Swiften/Presence/StanzaChannelPresenceSender.h>
+#include <Swiften/Queries/DummyIQChannel.h>
+#include <Swiften/Roster/XMPPRosterImpl.h>
+#include <Swiften/VCards/VCardManager.h>
+#include <Swiften/VCards/VCardManager.h>
+#include <Swiften/VCards/VCardMemoryStorage.h>
+#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+
+#include <Swift/Controllers/Chat/ChatsManager.h>
+#include <Swift/Controllers/Chat/ChatController.h>
+#include <Swift/Controllers/Chat/MUCController.h>
+#include <Swift/Controllers/Chat/UnitTest/MockChatListWindow.h>
+#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
+#include <Swift/Controllers/ProfileSettingsProvider.h>
#include <Swift/Controllers/SettingConstants.h>
+#include <Swift/Controllers/Settings/DummySettingsProvider.h>
+#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
+#include <Swift/Controllers/UnitTest/MockChatWindow.h>
+#include <Swift/Controllers/WhiteboardManager.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
+
using namespace Swift;
@@ -101,19 +110,33 @@ public:
ftManager_ = new DummyFileTransferManager();
ftOverview_ = new FileTransferOverview(ftManager_);
+ avatarManager_ = new NullAvatarManager();
+ wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsManager_);
+ wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_);
+ highlightManager_ = new HighlightManager(settings_);
+ crypto_ = PlatformCryptoProvider::create();
+ vcardStorage_ = new VCardMemoryStorage(crypto_);
+ vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_);
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, settings_);
+ clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
+ 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_, NULL, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, NULL, vcardManager_);
- avatarManager_ = new NullAvatarManager();
manager_->setAvatarManager(avatarManager_);
- };
+ }
void tearDown() {
+ delete highlightManager_;
//delete chatListWindowFactory
delete profileSettings_;
delete avatarManager_;
delete manager_;
+ delete clientBlockListManager_;
+ delete vcardManager_;
+ delete vcardStorage_;
+ delete crypto_;
delete ftOverview_;
delete ftManager_;
+ delete wbSessionManager_;
+ delete wbManager_;
delete directedPresenceSender_;
delete presenceSender_;
@@ -434,4 +457,5 @@ private:
message->setFrom(from);
message->setID(id);
+ message->setBody("This will cause the window to open");
message->addPayload(boost::make_shared<DeliveryReceiptRequest>());
return message;
@@ -460,4 +484,5 @@ private:
UIEventStream* uiEventStream_;
ChatListWindowFactory* chatListWindowFactory_;
+ WhiteboardWindowFactory* whiteboardWindowFactory_;
MUCSearchWindowFactory* mucSearchWindowFactory_;
MUCRegistry* mucRegistry_;
@@ -471,4 +496,12 @@ private:
FileTransferOverview* ftOverview_;
FileTransferManager* ftManager_;
+ WhiteboardSessionManager* wbSessionManager_;
+ WhiteboardManager* wbManager_;
+ HighlightManager* highlightManager_;
+ ClientBlockListManager* clientBlockListManager_;
+ VCardManager* vcardManager_;
+ CryptoProvider* crypto_;
+ VCardStorage* vcardStorage_;
+ std::map<std::string, std::string> emoticons_;
};
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index d4fbcfd..bb22e43 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -8,6 +8,7 @@
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <boost/algorithm/string.hpp>
-#include "3rdParty/hippomocks.h"
+#include <hippomocks.h>
+#include "Swiften/Base/foreach.h"
#include "Swift/Controllers/XMPPEvents/EventController.h"
#include "Swiften/Presence/DirectedPresenceSender.h"
@@ -21,4 +22,5 @@
#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"
@@ -27,4 +29,14 @@
#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;
@@ -40,8 +52,11 @@ class MUCControllerTest : public CppUnit::TestFixture {
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";
@@ -53,4 +68,5 @@ public:
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
+ userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>();
presenceOracle_ = new PresenceOracle(stanzaChannel_);
presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
@@ -62,12 +78,21 @@ public:
mucRegistry_ = new MUCRegistry();
entityCapsProvider_ = new DummyEntityCapsProvider();
- muc_ = boost::make_shared<MUC>(stanzaChannel_, iqRouter_, directedPresenceSender_, mucJID_, mucRegistry_);
+ settings_ = new DummySettingsProvider();
+ highlightManager_ = new HighlightManager(settings_);
+ muc_ = boost::make_shared<MockMUC>(mucJID_);
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);
- controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_);
- };
+ 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 entityCapsProvider_;
delete controller_;
+ delete vcardManager_;
+ delete vcardStorage_;
+ delete highlightManager_;
+ delete settings_;
+ delete entityCapsProvider_;
delete eventController_;
delete presenceOracle_;
@@ -185,5 +210,5 @@ public:
void testMessageWithLabelItem() {
- SecurityLabel::ref label = boost::make_shared<SecurityLabel>();
+ boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>();
label->setLabel("a");
SecurityLabelsCatalog::Item labelItem;
@@ -211,4 +236,42 @@ public:
}
+ 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());
@@ -258,11 +321,11 @@ public:
std::vector<NickJoinPart> list;
list.push_back(NickJoinPart("Kev", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room"), MUCController::generateJoinPartString(list));
+ 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));
+ 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));
+ 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));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
}
@@ -270,11 +333,74 @@ public:
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));
+ 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));
+ 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));
+ 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));
+ 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());
+ }
+ }
}
@@ -282,5 +408,5 @@ private:
JID self_;
JID mucJID_;
- MUC::ref muc_;
+ MockMUC::ref muc_;
std::string nick_;
DummyStanzaChannel* stanzaChannel_;
@@ -289,4 +415,5 @@ private:
EventController* eventController_;
ChatWindowFactory* chatWindowFactory_;
+ UserSearchWindowFactory* userSearchWindowFactory_;
MUCController* controller_;
// NickResolver* nickResolver_;
@@ -300,4 +427,10 @@ private:
MUCRegistry* mucRegistry_;
DummyEntityCapsProvider* entityCapsProvider_;
+ DummySettingsProvider* settings_;
+ HighlightManager* highlightManager_;
+ boost::shared_ptr<ChatMessageParser> chatMessageParser_;
+ boost::shared_ptr<CryptoProvider> crypto_;
+ VCardManager* vcardManager_;
+ VCardMemoryStorage* vcardStorage_;
};
diff --git a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
index 6ac8d4a..287c4b9 100644
--- a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
+++ b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2011 Kevin Smith
+ * Copyright (c) 2011-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -13,12 +13,15 @@ namespace Swift {
class MockChatListWindow : public ChatListWindow {
public:
- MockChatListWindow() {};
- virtual ~MockChatListWindow() {};
+ MockChatListWindow() {}
+ virtual ~MockChatListWindow() {}
void addMUCBookmark(const MUCBookmark& /*bookmark*/) {}
void removeMUCBookmark(const MUCBookmark& /*bookmark*/) {}
+ void addWhiteboardSession(const ChatListWindow::Chat& /*chat*/) {}
+ void removeWhiteboardSession(const JID& /*jid*/) {}
void setBookmarksEnabled(bool /*enabled*/) {}
void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {}
void setUnreadCount(int /*unread*/) {}
void clearBookmarks() {}
+ void setOnline(bool /*isOnline*/) {}
};