1 // Copyright 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 "chrome/browser/local_discovery/privet_http_asynchronous_factory.h" 6 7 #include "chrome/browser/local_discovery/privet_http_impl.h" 8 #include "chrome/browser/local_discovery/privet_notifications.h" 9 #include "net/url_request/test_url_fetcher_factory.h" 10 #include "net/url_request/url_request_test_util.h" 11 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 using testing::StrictMock; 15 16 using ::testing::_; 17 using ::testing::SaveArg; 18 19 namespace local_discovery { 20 21 namespace { 22 23 const char kExampleDeviceName[] = "test._privet._tcp.local"; 24 const char kExampleDeviceHumanName[] = "Test device"; 25 const char kExampleDeviceDescription[] = "Testing testing"; 26 const char kExampleDeviceID[] = "__test__id"; 27 const char kDeviceInfoURL[] = "http://1.2.3.4:8080/privet/info"; 28 29 const char kInfoResponseUptime20[] = "{\"uptime\": 20}"; 30 const char kInfoResponseUptime3600[] = "{\"uptime\": 3600}"; 31 const char kInfoResponseNoUptime[] = "{}"; 32 33 class MockPrivetNotificationsListenerDeleagate 34 : public PrivetNotificationsListener::Delegate { 35 public: 36 MOCK_METHOD2(PrivetNotify, void(bool multiple, bool added)); 37 MOCK_METHOD0(PrivetRemoveNotification, void()); 38 }; 39 40 class MockPrivetHttpFactory : public PrivetHTTPAsynchronousFactory { 41 public: 42 class MockResolution : public PrivetHTTPResolution { 43 public: 44 MockResolution( 45 const std::string& name, 46 net::URLRequestContextGetter* request_context, 47 const ResultCallback& callback) 48 : name_(name), request_context_(request_context), callback_(callback) { 49 } 50 51 virtual ~MockResolution() { 52 } 53 54 virtual void Start() OVERRIDE { 55 callback_.Run(scoped_ptr<PrivetHTTPClient>(new PrivetHTTPClientImpl( 56 name_, net::HostPortPair("1.2.3.4", 8080), request_context_.get()))); 57 } 58 59 virtual const std::string& GetName() OVERRIDE { 60 return name_; 61 } 62 63 private: 64 std::string name_; 65 scoped_refptr<net::URLRequestContextGetter> request_context_; 66 ResultCallback callback_; 67 }; 68 69 explicit MockPrivetHttpFactory(net::URLRequestContextGetter* request_context) 70 : request_context_(request_context) { 71 } 72 73 virtual scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP( 74 const std::string& name, 75 const net::HostPortPair& address, 76 const ResultCallback& callback) OVERRIDE { 77 return scoped_ptr<PrivetHTTPResolution>( 78 new MockResolution(name, request_context_.get(), callback)); 79 } 80 81 private: 82 scoped_refptr<net::URLRequestContextGetter> request_context_; 83 }; 84 85 class PrivetNotificationsListenerTest : public ::testing::Test { 86 public: 87 PrivetNotificationsListenerTest() : request_context_( 88 new net::TestURLRequestContextGetter(base::MessageLoopProxy::current())) { 89 notification_listener_.reset(new PrivetNotificationsListener( 90 scoped_ptr<PrivetHTTPAsynchronousFactory>( 91 new MockPrivetHttpFactory(request_context_.get())), 92 &mock_delegate_)); 93 94 description_.name = kExampleDeviceHumanName; 95 description_.description = kExampleDeviceDescription; 96 } 97 98 virtual ~PrivetNotificationsListenerTest() { 99 } 100 101 bool SuccessfulResponseToInfo(const std::string& response) { 102 net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); 103 EXPECT_TRUE(fetcher); 104 EXPECT_EQ(GURL(kDeviceInfoURL), fetcher->GetOriginalURL()); 105 106 if (!fetcher || GURL(kDeviceInfoURL) != fetcher->GetOriginalURL()) 107 return false; 108 109 fetcher->SetResponseString(response); 110 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 111 net::OK)); 112 fetcher->set_response_code(200); 113 fetcher->delegate()->OnURLFetchComplete(fetcher); 114 return true; 115 } 116 117 protected: 118 StrictMock<MockPrivetNotificationsListenerDeleagate> mock_delegate_; 119 scoped_ptr<PrivetNotificationsListener> notification_listener_; 120 base::MessageLoop message_loop_; 121 scoped_refptr<net::TestURLRequestContextGetter> request_context_; 122 net::TestURLFetcherFactory fetcher_factory_; 123 DeviceDescription description_; 124 }; 125 126 TEST_F(PrivetNotificationsListenerTest, DisappearReappearTest) { 127 128 EXPECT_CALL(mock_delegate_, PrivetNotify( 129 false, 130 true)); 131 132 notification_listener_->DeviceChanged( 133 true, 134 kExampleDeviceName, 135 description_); 136 137 SuccessfulResponseToInfo(kInfoResponseUptime20); 138 139 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification()); 140 141 notification_listener_->DeviceRemoved( 142 kExampleDeviceName); 143 144 notification_listener_->DeviceChanged( 145 true, 146 kExampleDeviceName, 147 description_); 148 149 description_.id = kExampleDeviceID; 150 151 notification_listener_->DeviceChanged( 152 true, 153 kExampleDeviceName, 154 description_); 155 } 156 157 TEST_F(PrivetNotificationsListenerTest, RegisterTest) { 158 EXPECT_CALL(mock_delegate_, PrivetNotify( 159 false, 160 true)); 161 162 notification_listener_->DeviceChanged( 163 true, 164 kExampleDeviceName, 165 description_); 166 167 SuccessfulResponseToInfo(kInfoResponseUptime20); 168 169 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification()); 170 171 description_.id = kExampleDeviceID; 172 173 notification_listener_->DeviceChanged( 174 true, 175 kExampleDeviceName, 176 description_); 177 } 178 179 TEST_F(PrivetNotificationsListenerTest, HighUptimeTest) { 180 notification_listener_->DeviceChanged( 181 true, 182 kExampleDeviceName, 183 description_); 184 185 SuccessfulResponseToInfo(kInfoResponseUptime3600); 186 187 description_.id = kExampleDeviceID; 188 189 notification_listener_->DeviceChanged( 190 true, 191 kExampleDeviceName, 192 description_); 193 } 194 195 TEST_F(PrivetNotificationsListenerTest, HTTPErrorTest) { 196 notification_listener_->DeviceChanged( 197 true, 198 kExampleDeviceName, 199 description_); 200 201 net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); 202 203 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 204 net::OK)); 205 fetcher->set_response_code(200); 206 fetcher->delegate()->OnURLFetchComplete(fetcher); 207 } 208 209 TEST_F(PrivetNotificationsListenerTest, DictionaryErrorTest) { 210 notification_listener_->DeviceChanged( 211 true, 212 kExampleDeviceName, 213 description_); 214 215 SuccessfulResponseToInfo(kInfoResponseNoUptime); 216 } 217 218 } // namespace 219 220 } // namespace local_discovery 221