diff options
Diffstat (limited to 'Swiften/Chat')
-rw-r--r-- | Swiften/Chat/ChatStateActionProvider.h | 7 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateMessageSender.cpp | 5 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateMessageSender.h | 7 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateNotifier.cpp | 45 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateNotifier.h | 25 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateTracker.cpp | 5 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateTracker.h | 7 | ||||
-rw-r--r-- | Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp | 132 |
8 files changed, 233 insertions, 0 deletions
diff --git a/Swiften/Chat/ChatStateActionProvider.h b/Swiften/Chat/ChatStateActionProvider.h new file mode 100644 index 0000000..82bed3f --- /dev/null +++ b/Swiften/Chat/ChatStateActionProvider.h @@ -0,0 +1,7 @@ +#pragma once + +namespace Swift { + class ChatState { + + }; +} diff --git a/Swiften/Chat/ChatStateMessageSender.cpp b/Swiften/Chat/ChatStateMessageSender.cpp new file mode 100644 index 0000000..d053cb5 --- /dev/null +++ b/Swiften/Chat/ChatStateMessageSender.cpp @@ -0,0 +1,5 @@ +#include "Swiften/Chat/ChatStateMessageSender.h" + +namespace Swift { + +} diff --git a/Swiften/Chat/ChatStateMessageSender.h b/Swiften/Chat/ChatStateMessageSender.h new file mode 100644 index 0000000..d27973d --- /dev/null +++ b/Swiften/Chat/ChatStateMessageSender.h @@ -0,0 +1,7 @@ +#pragma once + +namespace Swift { + class ChatStateMessageSender { + + }; +} diff --git a/Swiften/Chat/ChatStateNotifier.cpp b/Swiften/Chat/ChatStateNotifier.cpp new file mode 100644 index 0000000..432f708 --- /dev/null +++ b/Swiften/Chat/ChatStateNotifier.cpp @@ -0,0 +1,45 @@ +#include "Swiften/Chat/ChatStateNotifier.h" + +namespace Swift { + +ChatStateNotifier::ChatStateNotifier() { + contactHas85Caps_ = false; + isInConversation_ = false; + contactHasSentActive_ = false; + userIsTyping_ = false; +} + +void ChatStateNotifier::setContactHas85Caps(bool hasCaps) { + contactHas85Caps_ = hasCaps; +} + +void ChatStateNotifier::setUserIsTyping() { + if (contactShouldReceiveStates() && !userIsTyping_) { + userIsTyping_ = true; + onChatStateChanged(Composing); + } +} + +void ChatStateNotifier::userSentMessage() { + userIsTyping_ = false; +} + +void ChatStateNotifier::userCancelledNewMessage() { + if (userIsTyping_) { + userIsTyping_ = false; + onChatStateChanged(Active); + } +} + +void ChatStateNotifier::receivedMessageFromContact(bool hasActiveElement) { + isInConversation_ = true; + contactHasSentActive_ = hasActiveElement; +} + +bool ChatStateNotifier::contactShouldReceiveStates() { + /* So, yes, the XEP says to look at caps, but it also says that once you've + heard from the contact, the active state overrides this.*/ + return contactHasSentActive_ || (contactHas85Caps_ && !isInConversation_);; +} + +} diff --git a/Swiften/Chat/ChatStateNotifier.h b/Swiften/Chat/ChatStateNotifier.h new file mode 100644 index 0000000..90228b7 --- /dev/null +++ b/Swiften/Chat/ChatStateNotifier.h @@ -0,0 +1,25 @@ +#pragma once + +#include <boost/signals.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + class ChatStateNotifier { + public: + enum ChatState {Active, Composing, Paused, Inactive, Gone}; + ChatStateNotifier(); + void setContactHas85Caps(bool hasCaps); + void setUserIsTyping(); + void userSentMessage(); + void userCancelledNewMessage(); + void receivedMessageFromContact(bool hasActiveElement); + bool contactShouldReceiveStates(); + + boost::signal<void (ChatState)> onChatStateChanged; + private: + bool contactHas85Caps_; + bool isInConversation_; + bool contactHasSentActive_; + bool userIsTyping_; + }; +} diff --git a/Swiften/Chat/ChatStateTracker.cpp b/Swiften/Chat/ChatStateTracker.cpp new file mode 100644 index 0000000..553d2f4 --- /dev/null +++ b/Swiften/Chat/ChatStateTracker.cpp @@ -0,0 +1,5 @@ +#include "Swiften/Chat/ChatStateTracker.h" + +namespace Swift { + +} diff --git a/Swiften/Chat/ChatStateTracker.h b/Swiften/Chat/ChatStateTracker.h new file mode 100644 index 0000000..005c479 --- /dev/null +++ b/Swiften/Chat/ChatStateTracker.h @@ -0,0 +1,7 @@ +#pragma once + +namespace Swift { + class ChatStateTracker { + + }; +} diff --git a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp new file mode 100644 index 0000000..bacfc3a --- /dev/null +++ b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp @@ -0,0 +1,132 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <boost/bind.hpp> + +#include "Swiften/Chat/ChatStateNotifier.h" + +using namespace Swift; + + +class ChatStateMonitor { +public: + ChatStateMonitor(ChatStateNotifier* notifier) { + notifier_ = notifier; + composingCallCount = 0; + activeCallCount = 0; + notifier->onChatStateChanged.connect(boost::bind(&ChatStateMonitor::handleChatStateChanged, this, _1)); + }; + + int composingCallCount; + int activeCallCount; + ChatStateNotifier::ChatState currentState; + +private: + void handleChatStateChanged(ChatStateNotifier::ChatState newState) { + switch (newState) { + case ChatStateNotifier::Composing: + composingCallCount++; + break; + case ChatStateNotifier::Active: + activeCallCount++; + break; + default: + break; + } + currentState = newState; + }; + + ChatStateNotifier* notifier_; +}; + +class ChatStateNotifierTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(ChatStateNotifierTest); + CPPUNIT_TEST(testStartTypingReply_CapsNotIncluded); + CPPUNIT_TEST(testStartTypingReply_CapsIncluded); + CPPUNIT_TEST(testCancelledNewMessage); + CPPUNIT_TEST(testContinueTypingReply_CapsIncluded); + CPPUNIT_TEST(testContactShouldReceiveStates_CapsOnly); + CPPUNIT_TEST(testContactShouldReceiveStates_CapsNorActive); + CPPUNIT_TEST(testContactShouldReceiveStates_ActiveOverrideOn); + CPPUNIT_TEST(testContactShouldReceiveStates_ActiveOverrideOff); + CPPUNIT_TEST_SUITE_END(); + +private: + ChatStateNotifier* notifier_; + ChatStateMonitor* monitor_; + +public: + void setUp() { + notifier_ = new ChatStateNotifier(); + monitor_ = new ChatStateMonitor(notifier_); + } + + void tearDown() { + delete notifier_; + delete monitor_; + } + + void testStartTypingReply_CapsNotIncluded() { + notifier_->setContactHas85Caps(false); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(0, monitor_->composingCallCount); + } + + void testSendTwoMessages() { + notifier_->setContactHas85Caps(true); + notifier_->setUserIsTyping(); + notifier_->userSentMessage(); + notifier_->setUserIsTyping(); + notifier_->userSentMessage(); + CPPUNIT_ASSERT_EQUAL(2, monitor_->composingCallCount); + } + + void testCancelledNewMessage() { + notifier_->setContactHas85Caps(true); + notifier_->setUserIsTyping(); + notifier_->userCancelledNewMessage(); + CPPUNIT_ASSERT_EQUAL(1, monitor_->composingCallCount); + CPPUNIT_ASSERT_EQUAL(1, monitor_->activeCallCount); + CPPUNIT_ASSERT_EQUAL(ChatStateNotifier::Active, monitor_->currentState); + } + + + void testContactShouldReceiveStates_CapsOnly() { + notifier_->setContactHas85Caps(true); + CPPUNIT_ASSERT_EQUAL(true, notifier_->contactShouldReceiveStates()); + } + + void testContactShouldReceiveStates_CapsNorActive() { + CPPUNIT_ASSERT_EQUAL(false, notifier_->contactShouldReceiveStates()); + } + + void testContactShouldReceiveStates_ActiveOverrideOn() { + notifier_->setContactHas85Caps(false); + notifier_->receivedMessageFromContact(true); + CPPUNIT_ASSERT_EQUAL(true, notifier_->contactShouldReceiveStates()); + } + + void testContactShouldReceiveStates_ActiveOverrideOff() { + notifier_->setContactHas85Caps(true); + notifier_->receivedMessageFromContact(false); + CPPUNIT_ASSERT_EQUAL(false, notifier_->contactShouldReceiveStates()); + } + + + void testStartTypingReply_CapsIncluded() { + notifier_->setContactHas85Caps(true); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(1, monitor_->composingCallCount); + } + + void testContinueTypingReply_CapsIncluded() { + notifier_->setContactHas85Caps(true); + notifier_->setUserIsTyping(); + notifier_->setUserIsTyping(); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(1, monitor_->composingCallCount); + } + + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ChatStateNotifierTest); |