summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/UnitTest')
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp71
1 files changed, 59 insertions, 12 deletions
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index a5e68cf..cff54f8 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -54,64 +54,67 @@
#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;
class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ChatsManagerTest);
CPPUNIT_TEST(testFirstOpenWindowIncoming);
CPPUNIT_TEST(testSecondOpenWindowIncoming);
CPPUNIT_TEST(testFirstOpenWindowOutgoing);
CPPUNIT_TEST(testFirstOpenWindowBareToFull);
CPPUNIT_TEST(testSecondWindow);
CPPUNIT_TEST(testUnbindRebind);
CPPUNIT_TEST(testNoDuplicateUnbind);
CPPUNIT_TEST(testThreeMUCWindows);
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnRemoveFromRoster);
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster);
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth);
CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom);
CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt);
CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
- CPPUNIT_TEST(testChatControllerPMPresenceHandling);
CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect);
CPPUNIT_TEST(testPresenceChangeDoesNotReplaceMUCInvite);
+ // MUC PM Tests
+ CPPUNIT_TEST(testChatControllerPMPresenceHandling);
+ CPPUNIT_TEST(testChatControllerMucPmUnavailableErrorHandling);
+
// Highlighting tests
CPPUNIT_TEST(testChatControllerHighlightingNotificationTesting);
CPPUNIT_TEST(testChatControllerHighlightingNotificationDeduplicateSounds);
CPPUNIT_TEST(testChatControllerMeMessageHandling);
CPPUNIT_TEST(testRestartingMUCComponentCrash);
CPPUNIT_TEST(testChatControllerMeMessageHandlingInMUC);
// Carbons tests
CPPUNIT_TEST(testCarbonsForwardedIncomingMessageToSecondResource);
CPPUNIT_TEST(testCarbonsForwardedOutgoingMessageFromSecondResource);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
mocks_ = new MockRepository();
jid_ = JID("test@test.com/resource");
stanzaChannel_ = new DummyStanzaChannel();
iqRouter_ = new IQRouter(stanzaChannel_);
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>();
xmppRoster_ = new XMPPRosterImpl();
mucRegistry_ = new MUCRegistry();
nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, nullptr, mucRegistry_);
presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
serverDiscoInfo_ = std::make_shared<DiscoInfo>();
presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_);
@@ -163,202 +166,202 @@ public:
delete mucRegistry_;
delete iqRouter_;
delete stanzaChannel_;
delete eventController_;
delete uiEventStream_;
delete mucManager_;
delete xmppRoster_;
delete entityCapsProvider_;
delete chatListWindow_;
delete mocks_;
delete settings_;
}
void testFirstOpenWindowIncoming() {
JID messageJID("testling@test.com/resource1");
MockChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
std::shared_ptr<Message> message(new Message());
message->setFrom(messageJID);
std::string body("This is a legible message. >HEH@)oeueu");
message->setBody(body);
manager_->handleIncomingMessage(message);
CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
}
void testSecondOpenWindowIncoming() {
JID messageJID1("testling@test.com/resource1");
- MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window1 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
std::shared_ptr<Message> message1(new Message());
message1->setFrom(messageJID1);
std::string body1("This is a legible message. >HEH@)oeueu");
message1->setBody(body1);
manager_->handleIncomingMessage(message1);
CPPUNIT_ASSERT_EQUAL(body1, MockChatWindow::bodyFromMessage(window1->lastAddedMessage_));
JID messageJID2("testling@test.com/resource2");
std::shared_ptr<Message> message2(new Message());
message2->setFrom(messageJID2);
std::string body2("This is a legible message. .cmaulm.chul");
message2->setBody(body2);
manager_->handleIncomingMessage(message2);
CPPUNIT_ASSERT_EQUAL(body2, MockChatWindow::bodyFromMessage(window1->lastAddedMessage_));
}
void testFirstOpenWindowOutgoing() {
std::string messageJIDString("testling@test.com");
- ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ ChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString), uiEventStream_).Return(window);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString)));
}
void testFirstOpenWindowBareToFull() {
std::string bareJIDString("testling@test.com");
std::string fullJIDString("testling@test.com/resource1");
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(bareJIDString)));
std::shared_ptr<Message> message(new Message());
message->setFrom(JID(fullJIDString));
std::string body("This is a legible message. mjuga3089gm8G(*>M)@*(");
message->setBody(body);
manager_->handleIncomingMessage(message);
CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
}
void testSecondWindow() {
std::string messageJIDString1("testling1@test.com");
- ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ ChatWindow* window1 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString1)));
std::string messageJIDString2("testling2@test.com");
- ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ ChatWindow* window2 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString2)));
}
/** Complete cycle.
Create unbound window.
Bind it.
Unbind it.
Rebind it.
*/
void testUnbindRebind() {
std::string bareJIDString("testling@test.com");
std::string fullJIDString1("testling@test.com/resource1");
std::string fullJIDString2("testling@test.com/resource2");
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(bareJIDString)));
std::shared_ptr<Message> message1(new Message());
message1->setFrom(JID(fullJIDString1));
std::string messageBody1("This is a legible message.");
message1->setBody(messageBody1);
manager_->handleIncomingMessage(message1);
CPPUNIT_ASSERT_EQUAL(messageBody1, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
std::shared_ptr<Presence> jid1Online(new Presence());
jid1Online->setFrom(JID(fullJIDString1));
std::shared_ptr<Presence> jid1Offline(new Presence());
jid1Offline->setFrom(JID(fullJIDString1));
jid1Offline->setType(Presence::Unavailable);
presenceOracle_->onPresenceChange(jid1Offline);
std::shared_ptr<Message> message2(new Message());
message2->setFrom(JID(fullJIDString2));
std::string messageBody2("This is another legible message.");
message2->setBody(messageBody2);
manager_->handleIncomingMessage(message2);
CPPUNIT_ASSERT_EQUAL(messageBody2, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
}
/**
* Test that MUC PMs get opened in the right windows
*/
void testThreeMUCWindows() {
JID muc("testling@test.com");
ChatWindow* mucWindow = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc, uiEventStream_).Return(mucWindow);
uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(muc, std::string("nick")));
std::string messageJIDString1("testling@test.com/1");
- ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ ChatWindow* window1 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString1)));
std::string messageJIDString2("testling@test.com/2");
- ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ ChatWindow* window2 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString2)));
std::string messageJIDString3("testling@test.com/3");
- ChatWindow* window3 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ ChatWindow* window3 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString3), uiEventStream_).Return(window3);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString3)));
/* Refetch an earlier window */
/* We do not expect a new window to be created */
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString1)));
}
/**
Test that a second window isn't unbound where there's already an unbound one.
Bind 1
Bind 2
Unbind 1
Unbind 2 (but it doesn't)
Sent to bound 2
Rebind 1
*/
void testNoDuplicateUnbind() {
JID messageJID1("testling@test.com/resource1");
- MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window1 = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
std::shared_ptr<Message> message1(new Message());
message1->setFrom(messageJID1);
message1->setBody("This is a legible message1.");
manager_->handleIncomingMessage(message1);
JID messageJID2("testling@test.com/resource2");
std::shared_ptr<Message> message2(new Message());
message2->setFrom(messageJID2);
message2->setBody("This is a legible message2.");
manager_->handleIncomingMessage(message2);
std::shared_ptr<Presence> jid1Online(new Presence());
jid1Online->setFrom(JID(messageJID1));
std::shared_ptr<Presence> jid1Offline(new Presence());
jid1Offline->setFrom(JID(messageJID1));
jid1Offline->setType(Presence::Unavailable);
presenceOracle_->onPresenceChange(jid1Offline);
std::shared_ptr<Presence> jid2Online(new Presence());
jid2Online->setFrom(JID(messageJID2));
std::shared_ptr<Presence> jid2Offline(new Presence());
jid2Offline->setFrom(JID(messageJID2));
jid2Offline->setType(Presence::Unavailable);
presenceOracle_->onPresenceChange(jid2Offline);
JID messageJID3("testling@test.com/resource3");
@@ -380,61 +383,61 @@ public:
/**
* Test that ChatController doesn't send receipts anymore after removal of the contact from the roster.
*/
void testChatControllerPresenceAccessUpdatedOnRemoveFromRoster() {
JID messageJID("testling@test.com/resource1");
xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both);
MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
std::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
manager_->handleIncomingMessage(message);
Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(1);
CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != nullptr);
xmppRoster_->removeContact(messageJID);
message->setID("2");
manager_->handleIncomingMessage(message);
CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
}
/**
* Test that ChatController sends receipts after the contact has been added to the roster.
*/
void testChatControllerPresenceAccessUpdatedOnAddToRoster() {
JID messageJID("testling@test.com/resource1");
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ MockChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
std::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
manager_->handleIncomingMessage(message);
CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->countSentStanzaOfType<Message>());
xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both);
message->setID("2");
manager_->handleIncomingMessage(message);
CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(1);
CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != nullptr);
}
/**
* Test that ChatController sends receipts if requested after change from subscription state To to subscription state Both.
*/
void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth() {
testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::Both);
}
/**
* Test that ChatController sends receipts if requested after change from subscription state To to subscription state From.
*/
void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom() {
testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From);
}
@@ -661,60 +664,104 @@ public:
void testChatControllerPMPresenceHandling() {
JID participantA = JID("test@rooms.test.com/participantA");
JID participantB = JID("test@rooms.test.com/participantB");
mucRegistry_->addMUC("test@rooms.test.com");
MockChatWindow* window = new MockChatWindow();
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window);
uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(participantA)));
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_));
presence = Presence::create();
presence->setFrom(participantB);
presence->setShow(StatusShow::Away);
stanzaChannel_->onPresenceReceived(presence);
presence = Presence::create();
presence->setFrom(participantA);
presence->setShow(StatusShow::None);
presence->setType(Presence::Unavailable);
stanzaChannel_->onPresenceReceived(presence);
CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_));
}
+ 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);
+ 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));
CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_);
std::shared_ptr<IQ> infoRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[1]);
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);
CPPUNIT_ASSERT_EQUAL(true, window->impromptuMUCSupported_);
manager_->setOnline(false);
CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_);
}
void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) {
JID messageJID("testling@test.com/resource1");