diff options
Diffstat (limited to 'Swift/Controllers/Chat/UnitTest')
-rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 8 | ||||
-rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 170 |
2 files changed, 176 insertions, 2 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index 8f6c3a8..e06a3c7 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -749,61 +749,61 @@ public: presence->setShow(StatusShow::None); presence->setType(Presence::Unavailable); stanzaChannel_->onPresenceReceived(presence); CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedLastMessage_)); } void testChatControllerMucPmUnavailableErrorHandling() { auto mucJID = JID("test@rooms.test.com"); auto participantA = mucJID.withResource("participantA"); auto participantB = mucJID.withResource("participantB"); auto mucWindow = new MockChatWindow(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(mucJID, uiEventStream_).Return(mucWindow); uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(mucJID, participantB.getResource())); CPPUNIT_ASSERT_EQUAL(true, mucWindow->mucType_.is_initialized()); auto window = new MockChatWindow(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window); uiEventStream_->send(std::make_shared<RequestChatUIEvent>(participantA)); CPPUNIT_ASSERT_EQUAL(false, window->mucType_.is_initialized()); Presence::ref presence = Presence::create(); presence->setFrom(participantA); presence->setShow(StatusShow::Online); stanzaChannel_->onPresenceReceived(presence); CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_)); // send message to participantA auto messageBody = std::string("message body to send"); window->onSendMessageRequest(messageBody, false); - auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(2); + auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(3); CPPUNIT_ASSERT_EQUAL(messageBody, *sendMessageStanza->getBody()); // receive reply with error auto messageErrorReply = std::make_shared<Message>(); messageErrorReply->setID(stanzaChannel_->getNewIQID()); messageErrorReply->setType(Message::Error); messageErrorReply->setFrom(participantA); messageErrorReply->setTo(jid_); messageErrorReply->addPayload(std::make_shared<ErrorPayload>(ErrorPayload::ItemNotFound, ErrorPayload::Cancel, "Recipient not in room")); auto lastMUCWindowErrorMessageBeforeError = MockChatWindow::bodyFromMessage(mucWindow->lastAddedErrorMessage_); manager_->handleIncomingMessage(messageErrorReply); // assert that error is not routed to MUC window CPPUNIT_ASSERT_EQUAL(lastMUCWindowErrorMessageBeforeError, MockChatWindow::bodyFromMessage(mucWindow->lastAddedErrorMessage_)); // assert that error is routed to PM CPPUNIT_ASSERT_EQUAL(std::string("This user could not be found in the room."), MockChatWindow::bodyFromMessage(window->lastAddedErrorMessage_)); } void testLocalMUCServiceDiscoveryResetOnDisconnect() { JID ownJID("test@test.com/resource"); JID sender("foo@test.com"); manager_->setOnline(true); // Open chat window to a sender. MockChatWindow* window = new MockChatWindow(); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); uiEventStream_->send(std::make_shared<RequestChatUIEvent>(sender)); @@ -1510,61 +1510,65 @@ public: mucMirrored->addPayload(std::make_shared<Replace>("fooBlaID_2")); manager_->handleIncomingMessage(mucMirrored); } CPPUNIT_ASSERT_EQUAL(std::string("Some correctly spelled message."), window->bodyFromMessage(window->lastReplacedMessage_)); } void impromptuChatSetup(MockChatWindow* window) { stanzaChannel_->uniqueIDs_ = true; JID mucJID("795B7BBE-9099-4A0D-81BA-C816F78E275C@test.com"); manager_->setOnline(true); std::shared_ptr<IQ> infoRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[1]); CPPUNIT_ASSERT(infoRequest); std::shared_ptr<IQ> infoResponse = IQ::createResult(infoRequest->getFrom(), infoRequest->getTo(), infoRequest->getID()); DiscoInfo info; info.addIdentity(DiscoInfo::Identity("Shakespearean Chat Service", "conference", "text")); info.addFeature("http://jabber.org/protocol/muc"); infoResponse->addPayload(std::make_shared<DiscoInfo>(info)); stanzaChannel_->onIQReceived(infoResponse); std::vector<JID> jids; jids.emplace_back("foo@test.com"); jids.emplace_back("bar@test.com"); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(mucJID, uiEventStream_).Return(window); uiEventStream_->send(std::make_shared<CreateImpromptuMUCUIEvent>(jids, mucJID, "")); CPPUNIT_ASSERT_EQUAL(std::string("bar@test.com, foo@test.com"), manager_->getRecentChats()[0].getTitle()); - auto mucJoinPresence = std::dynamic_pointer_cast<Presence>(stanzaChannel_->sentStanzas[2]); + // Check the MUC security marking request + auto mucInfoRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[2]); + CPPUNIT_ASSERT(mucInfoRequest); + + auto mucJoinPresence = std::dynamic_pointer_cast<Presence>(stanzaChannel_->sentStanzas[3]); CPPUNIT_ASSERT(mucJoinPresence); // MUC presence reply auto mucResponse = Presence::create(); mucResponse->setTo(jid_); mucResponse->setFrom(mucJoinPresence->getTo()); mucResponse->addPayload([]() { auto mucUser = std::make_shared<MUCUserPayload>(); mucUser->addItem(MUCItem(MUCOccupant::Member, MUCOccupant::Participant)); mucUser->addStatusCode(MUCUserPayload::StatusCode(110)); mucUser->addStatusCode(MUCUserPayload::StatusCode(210)); return mucUser; }()); stanzaChannel_->onPresenceReceived(mucResponse); // Before people join the impromptu room, the title is based on names coming from Roster CPPUNIT_ASSERT_EQUAL(std::string("bar@test.com, foo@test.com"), manager_->getRecentChats()[0].getTitle()); auto mucParticipantJoined = [&](const JID& jid) { auto participantJoinedPresence = Presence::create(); participantJoinedPresence->setTo(jid_); participantJoinedPresence->setFrom(mucJID.withResource(jid.toString())); auto mucUser = std::make_shared<MUCUserPayload>(); mucUser->addItem(MUCItem(MUCOccupant::Member, MUCOccupant::Participant)); participantJoinedPresence->addPayload(mucUser); return participantJoinedPresence; }; for (const auto& participantJID : jids) { stanzaChannel_->onPresenceReceived(mucParticipantJoined(participantJID)); diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index 1f69f4f..06486d3 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -41,60 +41,68 @@ #include <Swift/Controllers/UIInterfaces/ChatWindow.h> #include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> #include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h> #include <Swift/Controllers/UnitTest/MockChatWindow.h> #include <Swift/Controllers/XMPPEvents/EventController.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(testSubjectChangeCorrect); CPPUNIT_TEST(testSubjectChangeIncorrectA); CPPUNIT_TEST(testSubjectChangeIncorrectB); CPPUNIT_TEST(testSubjectChangeIncorrectC); CPPUNIT_TEST(testHandleOccupantNicknameChanged); CPPUNIT_TEST(testHandleOccupantNicknameChangedRoster); CPPUNIT_TEST(testHandleChangeSubjectRequest); CPPUNIT_TEST(testNonImpromptuMUCWindowTitle); + CPPUNIT_TEST(testSecurityMarkingRequestCompleteMarking); + CPPUNIT_TEST(testSecurityMarkingRequestCompleteMarkingWithExtraForm); + CPPUNIT_TEST(testSecurityMarkingRequestEmptyMarking); + CPPUNIT_TEST(testSecurityMarkingRequestWithMarkingNoFormType); + CPPUNIT_TEST(testSecurityMarkingRequestNoMarking); + CPPUNIT_TEST(testSecurityMarkingRequestNoForm); + CPPUNIT_TEST(testSecurityMarkingRequestError); + CPPUNIT_TEST_SUITE_END(); public: void setUp() { crypto_ = std::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>(); xmppRoster_ = new XMPPRosterImpl(); presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); uiEventStream_ = new UIEventStream(); avatarManager_ = new NullAvatarManager(); TimerFactory* timerFactory = nullptr; window_ = new MockChatWindow(); mucRegistry_ = new MUCRegistry(); entityCapsProvider_ = new DummyEntityCapsProvider(); settings_ = new DummySettingsProvider(); highlightManager_ = new HighlightManager(settings_); highlightManager_->resetToDefaultConfiguration(); muc_ = std::make_shared<MockMUC>(mucJID_); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_); @@ -566,60 +574,222 @@ public: } void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) { /* verify that the roster is in sync */ GroupRosterItem* group = window_->getRosterModel()->getRoot(); for (auto rosterItem : group->getChildren()) { GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem); CPPUNIT_ASSERT(child); for (auto 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()); } } } void testHandleChangeSubjectRequest() { std::string testStr("New Subject"); CPPUNIT_ASSERT_EQUAL(std::string(""), muc_->newSubjectSet_); window_->onChangeSubjectRequest(testStr); CPPUNIT_ASSERT_EQUAL(testStr, muc_->newSubjectSet_); } void testNonImpromptuMUCWindowTitle() { CPPUNIT_ASSERT_EQUAL(muc_->getJID().getNode(), window_->name_); } + void testSecurityMarkingRequestCompleteMarking() { + auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); + auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); + auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Black"); + auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Red"); + formTypeField->setName("FORM_TYPE"); + markingField->setName("x-isode#roominfo_marking"); + markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); + markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + + auto form = std::make_shared<Form>(Form::Type::ResultType); + form->addField(formTypeField); + form->addField(markingField); + form->addField(markingForegroundColorField); + form->addField(markingBackgroundColorField); + + auto discoInfoRef = std::make_shared<DiscoInfo>(); + discoInfoRef->addExtension(form); + + auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string("Test | Highest Possible Security"), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string("Black"), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string("Red"), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestCompleteMarkingWithExtraForm() { + auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); + auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); + auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Black"); + auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Red"); + formTypeField->setName("FORM_TYPE"); + markingField->setName("x-isode#roominfo_marking"); + markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); + markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + + auto extraForm = std::make_shared<Form>(Form::Type::ResultType); + auto form = std::make_shared<Form>(Form::Type::ResultType); + form->addField(formTypeField); + form->addField(markingField); + form->addField(markingForegroundColorField); + form->addField(markingBackgroundColorField); + + auto discoInfoRef = std::make_shared<DiscoInfo>(); + discoInfoRef->addExtension(extraForm); + discoInfoRef->addExtension(form); + + auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string("Test | Highest Possible Security"), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string("Black"), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string("Red"), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestNoColorsInMarking() { + auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); + auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); + auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); + auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); + formTypeField->setName("FORM_TYPE"); + markingField->setName("x-isode#roominfo_marking"); + markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); + markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + + auto form = std::make_shared<Form>(Form::Type::ResultType); + form->addField(formTypeField); + form->addField(markingField); + form->addField(markingForegroundColorField); + form->addField(markingBackgroundColorField); + + auto discoInfoRef = std::make_shared<DiscoInfo>(); + discoInfoRef->addExtension(form); + + auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string("Test | Highest Possible Security"), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string("Black"), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string("White"), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestEmptyMarking() { + auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); + auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); + auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); + auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); + formTypeField->setName("FORM_TYPE"); + markingField->setName("x-isode#roominfo_marking"); + markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); + markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + + auto form = std::make_shared<Form>(Form::Type::ResultType); + form->addField(formTypeField); + form->addField(markingField); + form->addField(markingForegroundColorField); + form->addField(markingBackgroundColorField); + + auto discoInfoRef = std::make_shared<DiscoInfo>(); + discoInfoRef->addExtension(form); + + auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestWithMarkingNoFormType() { + auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); + auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Black"); + auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Red"); + markingField->setName("x-isode#roominfo_marking"); + markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); + markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + + auto form = std::make_shared<Form>(Form::Type::ResultType); + form->addField(markingField); + form->addField(markingForegroundColorField); + form->addField(markingBackgroundColorField); + + auto discoInfoRef = std::make_shared<DiscoInfo>(); + discoInfoRef->addExtension(form); + + auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestNoMarking() { + auto form = std::make_shared<Form>(Form::Type::ResultType); + + auto discoInfoRef = std::make_shared<DiscoInfo>(); + discoInfoRef->addExtension(form); + + auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestNoForm() { + auto discoInfoRef = std::make_shared<DiscoInfo>(); + + auto infoResponse = IQ::createResult( self_, mucJID_, "test-id", discoInfoRef); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); + } + + void testSecurityMarkingRequestError() { + auto errorPayload = std::make_shared<ErrorPayload>(ErrorPayload::Condition::NotAuthorized, ErrorPayload::Type::Auth); + + auto infoResponse = IQ::createResult( self_, mucJID_, "test-id", errorPayload); + iqChannel_->onIQReceived(infoResponse); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); + CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); + } + 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_; std::shared_ptr<ChatMessageParser> chatMessageParser_; std::shared_ptr<CryptoProvider> crypto_; VCardManager* vcardManager_; VCardMemoryStorage* vcardStorage_; ClientBlockListManager* clientBlockListManager_; MUCBookmarkManager* mucBookmarkManager_; |