diff options
Diffstat (limited to 'Swiften/Chat')
-rw-r--r-- | Swiften/Chat/ChatStateNotifier.cpp | 74 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateNotifier.h | 66 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateTracker.cpp | 30 | ||||
-rw-r--r-- | Swiften/Chat/ChatStateTracker.h | 20 | ||||
-rw-r--r-- | Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp | 292 |
5 files changed, 241 insertions, 241 deletions
diff --git a/Swiften/Chat/ChatStateNotifier.cpp b/Swiften/Chat/ChatStateNotifier.cpp index b2b7f4b..c623ce1 100644 --- a/Swiften/Chat/ChatStateNotifier.cpp +++ b/Swiften/Chat/ChatStateNotifier.cpp @@ -17,77 +17,77 @@ namespace Swift { ChatStateNotifier::ChatStateNotifier(StanzaChannel* stanzaChannel, const JID& contact, EntityCapsProvider* entityCapsManager) : stanzaChannel_(stanzaChannel), entityCapsManager_(entityCapsManager), contact_(contact) { - setContact(contact); - entityCapsManager_->onCapsChanged.connect(boost::bind(&ChatStateNotifier::handleCapsChanged, this, _1)); + setContact(contact); + entityCapsManager_->onCapsChanged.connect(boost::bind(&ChatStateNotifier::handleCapsChanged, this, _1)); } ChatStateNotifier::~ChatStateNotifier() { - entityCapsManager_->onCapsChanged.disconnect(boost::bind(&ChatStateNotifier::handleCapsChanged, this, _1)); + entityCapsManager_->onCapsChanged.disconnect(boost::bind(&ChatStateNotifier::handleCapsChanged, this, _1)); } void ChatStateNotifier::setContact(const JID& contact) { - contactHasSentActive_ = false; - userIsTyping_ = false; - contactIsOnline_ = false; - contact_ = contact; - handleCapsChanged(contact_); + contactHasSentActive_ = false; + userIsTyping_ = false; + contactIsOnline_ = false; + contact_ = contact; + handleCapsChanged(contact_); } void ChatStateNotifier::setContactIsOnline(bool online) { - contactIsOnline_ = online; + contactIsOnline_ = online; } void ChatStateNotifier::setUserIsTyping() { - bool should = contactShouldReceiveStates(); - if (should && !userIsTyping_) { - userIsTyping_ = true; - changeState(ChatState::Composing); - } + bool should = contactShouldReceiveStates(); + if (should && !userIsTyping_) { + userIsTyping_ = true; + changeState(ChatState::Composing); + } } void ChatStateNotifier::userSentMessage() { - userIsTyping_ = false; + userIsTyping_ = false; } void ChatStateNotifier::userCancelledNewMessage() { - if (userIsTyping_) { - userIsTyping_ = false; - changeState(ChatState::Active); - } + if (userIsTyping_) { + userIsTyping_ = false; + changeState(ChatState::Active); + } } void ChatStateNotifier::receivedMessageFromContact(bool hasActiveElement) { - contactHasSentActive_ = hasActiveElement; + 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. - *HOWEVER* it says that the MUST NOT send csn if you haven't received - active is OPTIONAL behaviour for if you haven't got caps.*/ - return contactIsOnline_ && (contactHasSentActive_ || contactHas85Caps_); + /* 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. + *HOWEVER* it says that the MUST NOT send csn if you haven't received + active is OPTIONAL behaviour for if you haven't got caps.*/ + return contactIsOnline_ && (contactHasSentActive_ || contactHas85Caps_); } void ChatStateNotifier::changeState(ChatState::ChatStateType state) { - boost::shared_ptr<Message> message(boost::make_shared<Message>()); - message->setTo(contact_); - message->addPayload(boost::make_shared<ChatState>(state)); - stanzaChannel_->sendMessage(message); + boost::shared_ptr<Message> message(boost::make_shared<Message>()); + message->setTo(contact_); + message->addPayload(boost::make_shared<ChatState>(state)); + stanzaChannel_->sendMessage(message); } void ChatStateNotifier::addChatStateRequest(Message::ref message) { - if (contactShouldReceiveStates()) { - message->addPayload(boost::make_shared<ChatState>(ChatState::Active)); - } + if (contactShouldReceiveStates()) { + message->addPayload(boost::make_shared<ChatState>(ChatState::Active)); + } } void ChatStateNotifier::handleCapsChanged(const JID& jid) { - if (jid == contact_) { - DiscoInfo::ref caps = entityCapsManager_->getCaps(contact_); - bool hasCSN = caps && caps->hasFeature(DiscoInfo::ChatStatesFeature); - contactHas85Caps_ = hasCSN; - } + if (jid == contact_) { + DiscoInfo::ref caps = entityCapsManager_->getCaps(contact_); + bool hasCSN = caps && caps->hasFeature(DiscoInfo::ChatStatesFeature); + contactHas85Caps_ = hasCSN; + } } } diff --git a/Swiften/Chat/ChatStateNotifier.h b/Swiften/Chat/ChatStateNotifier.h index 609fed4..a53fad8 100644 --- a/Swiften/Chat/ChatStateNotifier.h +++ b/Swiften/Chat/ChatStateNotifier.h @@ -15,37 +15,37 @@ #include <Swiften/JID/JID.h> namespace Swift { - class StanzaChannel; - class EntityCapsProvider; - - class SWIFTEN_API ChatStateNotifier { - public: - ChatStateNotifier(StanzaChannel* stanzaChannel, const JID& contact, EntityCapsProvider* entityCapsManager); - ~ChatStateNotifier(); - - void setContact(const JID& contact); - - void addChatStateRequest(Message::ref message); - - void setUserIsTyping(); - void userSentMessage(); - void userCancelledNewMessage(); - - void receivedMessageFromContact(bool hasActiveElement); - void setContactIsOnline(bool online); - - private: - bool contactShouldReceiveStates(); - void changeState(ChatState::ChatStateType type); - void handleCapsChanged(const JID& contact); - - private: - StanzaChannel* stanzaChannel_; - EntityCapsProvider* entityCapsManager_; - JID contact_; - bool contactHas85Caps_; - bool contactHasSentActive_; - bool userIsTyping_; - bool contactIsOnline_; - }; + class StanzaChannel; + class EntityCapsProvider; + + class SWIFTEN_API ChatStateNotifier { + public: + ChatStateNotifier(StanzaChannel* stanzaChannel, const JID& contact, EntityCapsProvider* entityCapsManager); + ~ChatStateNotifier(); + + void setContact(const JID& contact); + + void addChatStateRequest(Message::ref message); + + void setUserIsTyping(); + void userSentMessage(); + void userCancelledNewMessage(); + + void receivedMessageFromContact(bool hasActiveElement); + void setContactIsOnline(bool online); + + private: + bool contactShouldReceiveStates(); + void changeState(ChatState::ChatStateType type); + void handleCapsChanged(const JID& contact); + + private: + StanzaChannel* stanzaChannel_; + EntityCapsProvider* entityCapsManager_; + JID contact_; + bool contactHas85Caps_; + bool contactHasSentActive_; + bool userIsTyping_; + bool contactIsOnline_; + }; } diff --git a/Swiften/Chat/ChatStateTracker.cpp b/Swiften/Chat/ChatStateTracker.cpp index 34b7a04..5141872 100644 --- a/Swiften/Chat/ChatStateTracker.cpp +++ b/Swiften/Chat/ChatStateTracker.cpp @@ -8,30 +8,30 @@ namespace Swift { ChatStateTracker::ChatStateTracker() { - currentState_ = ChatState::Gone; + currentState_ = ChatState::Gone; } void ChatStateTracker::handleMessageReceived(boost::shared_ptr<Message> message) { - if (message->getType() == Message::Error) { - return; - } - boost::shared_ptr<ChatState> statePayload = message->getPayload<ChatState>(); - if (statePayload) { - changeState(statePayload->getChatState());; - } + if (message->getType() == Message::Error) { + return; + } + boost::shared_ptr<ChatState> statePayload = message->getPayload<ChatState>(); + if (statePayload) { + changeState(statePayload->getChatState());; + } } void ChatStateTracker::handlePresenceChange(boost::shared_ptr<Presence> newPresence) { - if (newPresence->getType() == Presence::Unavailable) { - onChatStateChange(ChatState::Gone); - } + if (newPresence->getType() == Presence::Unavailable) { + onChatStateChange(ChatState::Gone); + } } void ChatStateTracker::changeState(ChatState::ChatStateType state) { - if (state != currentState_) { - currentState_ = state; - onChatStateChange(state); - } + if (state != currentState_) { + currentState_ = state; + onChatStateChange(state); + } } } diff --git a/Swiften/Chat/ChatStateTracker.h b/Swiften/Chat/ChatStateTracker.h index b756b98..f31da0b 100644 --- a/Swiften/Chat/ChatStateTracker.h +++ b/Swiften/Chat/ChatStateTracker.h @@ -15,14 +15,14 @@ #include <Swiften/Elements/Presence.h> namespace Swift { - class SWIFTEN_API ChatStateTracker { - public: - ChatStateTracker(); - void handleMessageReceived(boost::shared_ptr<Message> message); - void handlePresenceChange(boost::shared_ptr<Presence> newPresence); - boost::signal<void (ChatState::ChatStateType)> onChatStateChange; - private: - void changeState(ChatState::ChatStateType state); - ChatState::ChatStateType currentState_; - }; + class SWIFTEN_API ChatStateTracker { + public: + ChatStateTracker(); + void handleMessageReceived(boost::shared_ptr<Message> message); + void handlePresenceChange(boost::shared_ptr<Presence> newPresence); + boost::signal<void (ChatState::ChatStateType)> onChatStateChange; + private: + void changeState(ChatState::ChatStateType state); + ChatState::ChatStateType currentState_; + }; } diff --git a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp index b293f9d..af43ced 100644 --- a/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp +++ b/Swiften/Chat/UnitTest/ChatStateNotifierTest.cpp @@ -17,153 +17,153 @@ using namespace Swift; 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(testTypeReplies_WentOffline); - CPPUNIT_TEST(testContactShouldReceiveStates_CapsOnly); - CPPUNIT_TEST(testContactShouldReceiveStates_CapsNorActive); - CPPUNIT_TEST(testContactShouldReceiveStates_ActiveOverrideOn); - CPPUNIT_TEST(testContactShouldReceiveStates_ActiveOverrideOff); - CPPUNIT_TEST_SUITE_END(); - + CPPUNIT_TEST_SUITE(ChatStateNotifierTest); + CPPUNIT_TEST(testStartTypingReply_CapsNotIncluded); + CPPUNIT_TEST(testStartTypingReply_CapsIncluded); + CPPUNIT_TEST(testCancelledNewMessage); + CPPUNIT_TEST(testContinueTypingReply_CapsIncluded); + CPPUNIT_TEST(testTypeReplies_WentOffline); + CPPUNIT_TEST(testContactShouldReceiveStates_CapsOnly); + CPPUNIT_TEST(testContactShouldReceiveStates_CapsNorActive); + CPPUNIT_TEST(testContactShouldReceiveStates_ActiveOverrideOn); + CPPUNIT_TEST(testContactShouldReceiveStates_ActiveOverrideOff); + CPPUNIT_TEST_SUITE_END(); + public: - void setUp() { - stanzaChannel = new DummyStanzaChannel(); - stanzaChannel->setAvailable(true); - entityCapsProvider = new DummyEntityCapsProvider(); - notifier_ = new ChatStateNotifier(stanzaChannel, JID("foo@bar.com/baz"), entityCapsProvider); - notifier_->setContactIsOnline(true); - } - - void tearDown() { - delete notifier_; - delete entityCapsProvider; - delete stanzaChannel; - } - - void testStartTypingReply_CapsNotIncluded() { - notifier_->setUserIsTyping(); - CPPUNIT_ASSERT_EQUAL(0, getComposingCount()); - } - - void testSendTwoMessages() { - setContactHas85Caps(); - notifier_->setUserIsTyping(); - notifier_->userSentMessage(); - notifier_->setUserIsTyping(); - notifier_->userSentMessage(); - CPPUNIT_ASSERT_EQUAL(2, getComposingCount()); - } - - void testCancelledNewMessage() { - setContactHas85Caps(); - notifier_->setUserIsTyping(); - notifier_->userCancelledNewMessage(); - CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); - CPPUNIT_ASSERT_EQUAL(1, getActiveCount()); - CPPUNIT_ASSERT_EQUAL(ChatState::Active, stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getPayload<ChatState>()->getChatState()); - } - - - void testContactShouldReceiveStates_CapsOnly() { - setContactHas85Caps(); - boost::shared_ptr<Message> message(new Message()); - notifier_->addChatStateRequest(message); - CPPUNIT_ASSERT(message->getPayload<ChatState>()); - CPPUNIT_ASSERT_EQUAL(ChatState::Active, message->getPayload<ChatState>()->getChatState()); - } - - void testContactShouldReceiveStates_CapsNorActive() { - boost::shared_ptr<Message> message(new Message()); - notifier_->addChatStateRequest(message); - CPPUNIT_ASSERT(!message->getPayload<ChatState>()); - } - - void testContactShouldReceiveStates_ActiveOverrideOn() { - notifier_->receivedMessageFromContact(true); - boost::shared_ptr<Message> message(new Message()); - notifier_->addChatStateRequest(message); - CPPUNIT_ASSERT(message->getPayload<ChatState>()); - CPPUNIT_ASSERT_EQUAL(ChatState::Active, message->getPayload<ChatState>()->getChatState()); - } - - void 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. - */ - boost::shared_ptr<Message> message(new Message()); - notifier_->addChatStateRequest(message); - CPPUNIT_ASSERT(message->getPayload<ChatState>()); - CPPUNIT_ASSERT_EQUAL(ChatState::Active, message->getPayload<ChatState>()->getChatState()); - } - - - void testStartTypingReply_CapsIncluded() { - setContactHas85Caps(); - notifier_->setUserIsTyping(); - CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); - } - - void testContinueTypingReply_CapsIncluded() { - setContactHas85Caps(); - notifier_->setUserIsTyping(); - notifier_->setUserIsTyping(); - notifier_->setUserIsTyping(); - CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); - notifier_->userSentMessage(); - notifier_->setUserIsTyping(); - CPPUNIT_ASSERT_EQUAL(2, getComposingCount()); - - } - - void testTypeReplies_WentOffline() { - setContactHas85Caps(); - notifier_->setUserIsTyping(); - CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); - notifier_->setContactIsOnline(false); - notifier_->userSentMessage(); - notifier_->setUserIsTyping(); - CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); - } - - private: - 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; - foreach(boost::shared_ptr<Stanza> stanza, stanzaChannel->sentStanzas) { - if (stanza->getPayload<ChatState>() && stanza->getPayload<ChatState>()->getChatState() == ChatState::Composing) { - result++; - } - } - return result; - } - - int getActiveCount() const { - int result = 0; - foreach(boost::shared_ptr<Stanza> stanza, stanzaChannel->sentStanzas) { - if (stanza->getPayload<ChatState>() && stanza->getPayload<ChatState>()->getChatState() == ChatState::Active) { - result++; - } - } - return result; - } - - private: - DummyStanzaChannel* stanzaChannel; - DummyEntityCapsProvider* entityCapsProvider; - ChatStateNotifier* notifier_; + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + stanzaChannel->setAvailable(true); + entityCapsProvider = new DummyEntityCapsProvider(); + notifier_ = new ChatStateNotifier(stanzaChannel, JID("foo@bar.com/baz"), entityCapsProvider); + notifier_->setContactIsOnline(true); + } + + void tearDown() { + delete notifier_; + delete entityCapsProvider; + delete stanzaChannel; + } + + void testStartTypingReply_CapsNotIncluded() { + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(0, getComposingCount()); + } + + void testSendTwoMessages() { + setContactHas85Caps(); + notifier_->setUserIsTyping(); + notifier_->userSentMessage(); + notifier_->setUserIsTyping(); + notifier_->userSentMessage(); + CPPUNIT_ASSERT_EQUAL(2, getComposingCount()); + } + + void testCancelledNewMessage() { + setContactHas85Caps(); + notifier_->setUserIsTyping(); + notifier_->userCancelledNewMessage(); + CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); + CPPUNIT_ASSERT_EQUAL(1, getActiveCount()); + CPPUNIT_ASSERT_EQUAL(ChatState::Active, stanzaChannel->sentStanzas[stanzaChannel->sentStanzas.size()-1]->getPayload<ChatState>()->getChatState()); + } + + + void testContactShouldReceiveStates_CapsOnly() { + setContactHas85Caps(); + boost::shared_ptr<Message> message(new Message()); + notifier_->addChatStateRequest(message); + CPPUNIT_ASSERT(message->getPayload<ChatState>()); + CPPUNIT_ASSERT_EQUAL(ChatState::Active, message->getPayload<ChatState>()->getChatState()); + } + + void testContactShouldReceiveStates_CapsNorActive() { + boost::shared_ptr<Message> message(new Message()); + notifier_->addChatStateRequest(message); + CPPUNIT_ASSERT(!message->getPayload<ChatState>()); + } + + void testContactShouldReceiveStates_ActiveOverrideOn() { + notifier_->receivedMessageFromContact(true); + boost::shared_ptr<Message> message(new Message()); + notifier_->addChatStateRequest(message); + CPPUNIT_ASSERT(message->getPayload<ChatState>()); + CPPUNIT_ASSERT_EQUAL(ChatState::Active, message->getPayload<ChatState>()->getChatState()); + } + + void 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. + */ + boost::shared_ptr<Message> message(new Message()); + notifier_->addChatStateRequest(message); + CPPUNIT_ASSERT(message->getPayload<ChatState>()); + CPPUNIT_ASSERT_EQUAL(ChatState::Active, message->getPayload<ChatState>()->getChatState()); + } + + + void testStartTypingReply_CapsIncluded() { + setContactHas85Caps(); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); + } + + void testContinueTypingReply_CapsIncluded() { + setContactHas85Caps(); + notifier_->setUserIsTyping(); + notifier_->setUserIsTyping(); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); + notifier_->userSentMessage(); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(2, getComposingCount()); + + } + + void testTypeReplies_WentOffline() { + setContactHas85Caps(); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); + notifier_->setContactIsOnline(false); + notifier_->userSentMessage(); + notifier_->setUserIsTyping(); + CPPUNIT_ASSERT_EQUAL(1, getComposingCount()); + } + + private: + 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; + foreach(boost::shared_ptr<Stanza> stanza, stanzaChannel->sentStanzas) { + if (stanza->getPayload<ChatState>() && stanza->getPayload<ChatState>()->getChatState() == ChatState::Composing) { + result++; + } + } + return result; + } + + int getActiveCount() const { + int result = 0; + foreach(boost::shared_ptr<Stanza> stanza, stanzaChannel->sentStanzas) { + if (stanza->getPayload<ChatState>() && stanza->getPayload<ChatState>()->getChatState() == ChatState::Active) { + result++; + } + } + return result; + } + + private: + DummyStanzaChannel* stanzaChannel; + DummyEntityCapsProvider* entityCapsProvider; + ChatStateNotifier* notifier_; }; CPPUNIT_TEST_SUITE_REGISTRATION(ChatStateNotifierTest); |