/* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include #include #include #include #include #include using namespace Swift; class ChatStateNotifierTest : public ::testing::Test { protected: virtual void SetUp() { stanzaChannel = new DummyStanzaChannel(); stanzaChannel->setAvailable(true); entityCapsProvider = new DummyEntityCapsProvider(); timerFactory_ = new DummyTimerFactory(); notifier_ = new ChatStateNotifier(stanzaChannel, JID("foo@bar.com/baz"), entityCapsProvider, timerFactory_, 2); notifier_->setContactIsOnline(true); } virtual void TearDown() { delete notifier_; delete timerFactory_; delete entityCapsProvider; delete stanzaChannel; } void setContactHas85Caps() { DiscoInfo::ref caps(new DiscoInfo()); caps->addFeature(DiscoInfo::ChatStatesFeature); entityCapsProvider->caps[JID("foo@bar.com/baz")] = caps; entityCapsProvider->onCapsChanged(JID("foo@bar.com/baz")); } int getComposingCount() const { int result = 0; for (auto&& stanza : stanzaChannel->sentStanzas) { if (stanza->getPayload() && stanza->getPayload()->getChatState() == ChatState::Composing) { result++; } } return result; } int getActiveCount() const { int result = 0; for (auto&& stanza : stanzaChannel->sentStanzas) { if (stanza->getPayload() && stanza->getPayload()->getChatState() == ChatState::Active) { result++; } } return result; } DummyStanzaChannel* stanzaChannel; DummyEntityCapsProvider* entityCapsProvider; DummyTimerFactory* timerFactory_; ChatStateNotifier* notifier_; }; TEST_F(ChatStateNotifierTest, testStartTypingReply_CapsNotIncluded) { notifier_->setUserIsTyping(); ASSERT_EQ(0, getComposingCount()); } TEST_F(ChatStateNotifierTest, testSendTwoMessages) { setContactHas85Caps(); notifier_->setUserIsTyping(); notifier_->userSentMessage(); notifier_->setUserIsTyping(); notifier_->userSentMessage(); ASSERT_EQ(2, getComposingCount()); } TEST_F(ChatStateNotifierTest, testCancelledNewMessage) { setContactHas85Caps(); notifier_->setUserIsTyping(); notifier_->userCancelledNewMessage(); ASSERT_EQ(1, getComposingCount()); ASSERT_EQ(1, getActiveCount()); ASSERT_EQ(ChatState::Active, stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size() - 1]->getPayload()->getChatState()); } TEST_F(ChatStateNotifierTest, testIdleWhileTypingNewMessage) { setContactHas85Caps(); //The channel should be empty ASSERT_EQ(0, getComposingCount()); ASSERT_EQ(0, getActiveCount()); notifier_->setUserIsTyping(); timerFactory_->setTime(1); //1 Composing stanza is expected ASSERT_EQ(1, getComposingCount()); ASSERT_EQ(0, getActiveCount()); timerFactory_->setTime(2); //The idleTimer period has expired, the channel should have 1 composing and 1 active status stanza ASSERT_EQ(1, getComposingCount()); ASSERT_EQ(1, getActiveCount()); ASSERT_EQ(ChatState::Active, stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size() - 1]->getPayload()->getChatState()); timerFactory_->setTime(4); //At the second tick no further state stanzas should be sent. ASSERT_EQ(1, getComposingCount()); ASSERT_EQ(1, getActiveCount()); ASSERT_EQ(ChatState::Active, stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size() - 1]->getPayload()->getChatState()); } TEST_F(ChatStateNotifierTest, testIdleWhileTypingNewMessageNoCaps) { notifier_->setUserIsTyping(); timerFactory_->setTime(3); ASSERT_EQ(0, getComposingCount()); ASSERT_EQ(0, getActiveCount()); } TEST_F(ChatStateNotifierTest, testContactShouldReceiveStates_CapsOnly) { setContactHas85Caps(); std::shared_ptr message(new Message()); notifier_->addChatStateRequest(message); EXPECT_TRUE(message->getPayload()); ASSERT_EQ(ChatState::Active, message->getPayload()->getChatState()); } TEST_F(ChatStateNotifierTest, testContactShouldReceiveStates_CapsNorActive) { std::shared_ptr message(new Message()); notifier_->addChatStateRequest(message); EXPECT_TRUE(!message->getPayload()); } TEST_F(ChatStateNotifierTest, testContactShouldReceiveStates_ActiveOverrideOn) { notifier_->receivedMessageFromContact(true); std::shared_ptr message(new Message()); notifier_->addChatStateRequest(message); EXPECT_TRUE(message->getPayload()); ASSERT_EQ(ChatState::Active, message->getPayload()->getChatState()); } TEST_F(ChatStateNotifierTest, testContactShouldReceiveStates_ActiveOverrideOff) { setContactHas85Caps(); notifier_->receivedMessageFromContact(false); /* I originally read the MUST NOT send after receiving without Active and * thought this should check for false, but I later found it was OPTIONAL * (MAY) behaviour only for if you didn't receive caps. */ std::shared_ptr message(new Message()); notifier_->addChatStateRequest(message); EXPECT_TRUE(message->getPayload()); ASSERT_EQ(ChatState::Active, message->getPayload()->getChatState()); } TEST_F(ChatStateNotifierTest, testStartTypingReply_CapsIncluded) { setContactHas85Caps(); notifier_->setUserIsTyping(); ASSERT_EQ(1, getComposingCount()); } TEST_F(ChatStateNotifierTest, testContinueTypingReply_CapsIncluded) { setContactHas85Caps(); notifier_->setUserIsTyping(); notifier_->setUserIsTyping(); notifier_->setUserIsTyping(); ASSERT_EQ(1, getComposingCount()); notifier_->userSentMessage(); notifier_->setUserIsTyping(); ASSERT_EQ(2, getComposingCount()); } TEST_F(ChatStateNotifierTest, testTypeReplies_WentOffline) { setContactHas85Caps(); notifier_->setUserIsTyping(); ASSERT_EQ(1, getComposingCount()); notifier_->setContactIsOnline(false); notifier_->userSentMessage(); notifier_->setUserIsTyping(); ASSERT_EQ(1, getComposingCount()); }