1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "remoting/host/host_change_notification_listener.h" 6 7 #include <set> 8 9 #include "base/bind.h" 10 #include "base/memory/ref_counted.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "remoting/base/constants.h" 14 #include "remoting/jingle_glue/mock_objects.h" 15 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 18 #include "third_party/libjingle/source/talk/xmpp/constants.h" 19 20 using buzz::QName; 21 using buzz::XmlElement; 22 23 using testing::NotNull; 24 using testing::Return; 25 26 namespace remoting { 27 28 namespace { 29 const char kHostId[] = "0"; 30 const char kTestJid[] = "user (at) gmail.com/chromoting123"; 31 const char kTestBotJid[] = "remotingunittest (at) bot.talk.google.com"; 32 } // namespace 33 34 ACTION_P(AddListener, list) { 35 list->insert(arg0); 36 } 37 38 ACTION_P(RemoveListener, list) { 39 EXPECT_TRUE(list->find(arg0) != list->end()); 40 list->erase(arg0); 41 } 42 43 44 class HostChangeNotificationListenerTest : public testing::Test { 45 protected: 46 class MockListener : public HostChangeNotificationListener::Listener { 47 public: 48 MOCK_METHOD0(OnHostDeleted, void()); 49 }; 50 51 virtual void SetUp() OVERRIDE { 52 EXPECT_CALL(signal_strategy_, AddListener(NotNull())) 53 .WillRepeatedly(AddListener(&signal_strategy_listeners_)); 54 EXPECT_CALL(signal_strategy_, RemoveListener(NotNull())) 55 .WillRepeatedly(RemoveListener(&signal_strategy_listeners_)); 56 EXPECT_CALL(signal_strategy_, GetLocalJid()) 57 .WillRepeatedly(Return(kTestJid)); 58 59 host_change_notification_listener_.reset(new HostChangeNotificationListener( 60 &mock_listener_, kHostId, &signal_strategy_, kTestBotJid)); 61 } 62 63 virtual void TearDown() OVERRIDE { 64 host_change_notification_listener_.reset(); 65 EXPECT_TRUE(signal_strategy_listeners_.empty()); 66 } 67 68 scoped_ptr<XmlElement> GetNotificationStanza(std::string operation, 69 std::string hostId, 70 std::string botJid) { 71 scoped_ptr<XmlElement> stanza(new XmlElement(buzz::QN_IQ)); 72 stanza->AddAttr(QName(std::string(), "type"), "set"); 73 XmlElement* host_changed = 74 new XmlElement(QName(kChromotingXmlNamespace, "host-changed")); 75 host_changed->AddAttr(QName(kChromotingXmlNamespace, "operation"), 76 operation); 77 host_changed->AddAttr(QName(kChromotingXmlNamespace, "hostid"), hostId); 78 stanza->AddElement(host_changed); 79 stanza->AddAttr(buzz::QN_FROM, botJid); 80 stanza->AddAttr(buzz::QN_TO, kTestJid); 81 return stanza.Pass(); 82 } 83 84 MockListener mock_listener_; 85 MockSignalStrategy signal_strategy_; 86 std::set<SignalStrategy::Listener*> signal_strategy_listeners_; 87 scoped_ptr<HostChangeNotificationListener> host_change_notification_listener_; 88 base::MessageLoop message_loop_; 89 }; 90 91 TEST_F(HostChangeNotificationListenerTest, ReceiveValidNotification) { 92 EXPECT_CALL(mock_listener_, OnHostDeleted()) 93 .WillOnce(Return()); 94 scoped_ptr<XmlElement> stanza = GetNotificationStanza( 95 "delete", kHostId, kTestBotJid); 96 host_change_notification_listener_->OnSignalStrategyIncomingStanza( 97 stanza.get()); 98 message_loop_.PostTask(FROM_HERE, 99 base::Bind(base::MessageLoop::QuitClosure())); 100 message_loop_.Run(); 101 } 102 103 TEST_F(HostChangeNotificationListenerTest, ReceiveNotificationBeforeDelete) { 104 EXPECT_CALL(mock_listener_, OnHostDeleted()) 105 .Times(0); 106 scoped_ptr<XmlElement> stanza = GetNotificationStanza( 107 "delete", kHostId, kTestBotJid); 108 host_change_notification_listener_->OnSignalStrategyIncomingStanza( 109 stanza.get()); 110 host_change_notification_listener_.reset(); 111 message_loop_.PostTask(FROM_HERE, 112 base::Bind(base::MessageLoop::QuitClosure())); 113 message_loop_.Run(); 114 } 115 116 117 TEST_F(HostChangeNotificationListenerTest, ReceiveInvalidHostIdNotification) { 118 EXPECT_CALL(mock_listener_, OnHostDeleted()) 119 .Times(0); 120 scoped_ptr<XmlElement> stanza = GetNotificationStanza( 121 "delete", "1", kTestBotJid); 122 host_change_notification_listener_->OnSignalStrategyIncomingStanza( 123 stanza.get()); 124 message_loop_.PostTask(FROM_HERE, 125 base::Bind(base::MessageLoop::QuitClosure())); 126 message_loop_.Run(); 127 } 128 129 TEST_F(HostChangeNotificationListenerTest, ReceiveInvalidBotJidNotification) { 130 EXPECT_CALL(mock_listener_, OnHostDeleted()) 131 .Times(0); 132 scoped_ptr<XmlElement> stanza = GetNotificationStanza( 133 "delete", kHostId, "notremotingbot (at) bot.talk.google.com"); 134 host_change_notification_listener_->OnSignalStrategyIncomingStanza( 135 stanza.get()); 136 message_loop_.PostTask(FROM_HERE, 137 base::Bind(base::MessageLoop::QuitClosure())); 138 message_loop_.Run(); 139 } 140 141 TEST_F(HostChangeNotificationListenerTest, ReceiveNonDeleteNotification) { 142 EXPECT_CALL(mock_listener_, OnHostDeleted()) 143 .Times(0); 144 scoped_ptr<XmlElement> stanza = GetNotificationStanza( 145 "update", kHostId, kTestBotJid); 146 host_change_notification_listener_->OnSignalStrategyIncomingStanza( 147 stanza.get()); 148 message_loop_.PostTask(FROM_HERE, 149 base::Bind(base::MessageLoop::QuitClosure())); 150 message_loop_.Run(); 151 } 152 153 } // namespace remoting 154