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_notifications.h" 8 #include "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 using testing::StrictMock; 12 13 using ::testing::_; 14 using ::testing::SaveArg; 15 16 namespace local_discovery { 17 18 namespace { 19 20 const char kExampleDeviceName[] = "test._privet._tcp.local"; 21 const char kExampleDeviceHumanName[] = "Test device"; 22 const char kExampleDeviceDescription[] = "Testing testing"; 23 const char kExampleDeviceID[] = "__test__id"; 24 25 class MockPrivetNotificationsListenerDeleagate 26 : public PrivetNotificationsListener::Delegate { 27 public: 28 MOCK_METHOD2(PrivetNotify, void(bool multiple, bool added)); 29 MOCK_METHOD0(PrivetRemoveNotification, void()); 30 }; 31 32 // TODO(noamsml): Migrate this test to use a real privet info operation and a 33 // fake URL fetcher. 34 class MockPrivetInfoOperation : public PrivetInfoOperation { 35 public: 36 class DelegateForTests { 37 public: 38 virtual ~DelegateForTests() {} 39 virtual void InfoOperationStarted(MockPrivetInfoOperation* operation) = 0; 40 }; 41 42 MockPrivetInfoOperation(PrivetHTTPClient* client, 43 DelegateForTests* delegate_for_tests, 44 Delegate* delegate) 45 : client_(client), 46 delegate_for_tests_(delegate_for_tests), 47 delegate_(delegate) { 48 } 49 50 virtual ~MockPrivetInfoOperation() { 51 } 52 53 virtual void Start() OVERRIDE { 54 delegate_for_tests_->InfoOperationStarted(this); 55 } 56 57 virtual PrivetHTTPClient* GetHTTPClient() OVERRIDE { 58 return client_; 59 } 60 61 Delegate* delegate() { return delegate_; } 62 63 private: 64 PrivetHTTPClient* client_; 65 DelegateForTests* delegate_for_tests_; 66 Delegate* delegate_; 67 }; 68 69 class MockPrivetHTTPClient : public PrivetHTTPClient { 70 public: 71 MockPrivetHTTPClient( 72 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests, 73 const std::string& name) : delegate_for_tests_(delegate_for_tests), 74 name_(name) { 75 } 76 77 virtual scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation( 78 const std::string& user, 79 PrivetRegisterOperation::Delegate* delegate) OVERRIDE { 80 return scoped_ptr<PrivetRegisterOperation>(); 81 } 82 83 virtual scoped_ptr<PrivetInfoOperation> CreateInfoOperation( 84 PrivetInfoOperation::Delegate* delegate) OVERRIDE { 85 return scoped_ptr<PrivetInfoOperation>(new MockPrivetInfoOperation( 86 this, delegate_for_tests_, delegate)); 87 } 88 89 virtual scoped_ptr<PrivetCapabilitiesOperation> CreateCapabilitiesOperation( 90 PrivetCapabilitiesOperation::Delegate* delegate) OVERRIDE { 91 NOTIMPLEMENTED(); 92 return scoped_ptr<PrivetCapabilitiesOperation>(); 93 } 94 95 virtual scoped_ptr<PrivetLocalPrintOperation> CreateLocalPrintOperation( 96 PrivetLocalPrintOperation::Delegate* delegate) OVERRIDE { 97 NOTIMPLEMENTED(); 98 return scoped_ptr<PrivetLocalPrintOperation>(); 99 } 100 101 virtual const std::string& GetName() OVERRIDE { return name_; } 102 103 virtual const base::DictionaryValue* GetCachedInfo() const OVERRIDE { 104 NOTIMPLEMENTED(); 105 return NULL; 106 } 107 108 private: 109 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests_; 110 std::string name_; 111 }; 112 113 class MockPrivetHttpFactory : public PrivetHTTPAsynchronousFactory { 114 public: 115 class MockResolution : public PrivetHTTPResolution { 116 public: 117 MockResolution( 118 const std::string& name, 119 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests, 120 const ResultCallback& callback) 121 : name_(name), delegate_for_tests_(delegate_for_tests), 122 callback_(callback) { 123 } 124 125 virtual ~MockResolution() { 126 } 127 128 virtual void Start() OVERRIDE { 129 callback_.Run(scoped_ptr<PrivetHTTPClient>( 130 new MockPrivetHTTPClient(delegate_for_tests_, name_))); 131 } 132 133 virtual const std::string& GetName() OVERRIDE { 134 return name_; 135 } 136 137 private: 138 std::string name_; 139 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests_; 140 ResultCallback callback_; 141 }; 142 143 MockPrivetHttpFactory( 144 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests) 145 : delegate_for_tests_(delegate_for_tests) { 146 } 147 148 virtual scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP( 149 const std::string& name, 150 const net::HostPortPair& address, 151 const ResultCallback& callback) OVERRIDE { 152 return scoped_ptr<PrivetHTTPResolution>( 153 new MockResolution(name, delegate_for_tests_, callback)); 154 } 155 156 private: 157 MockPrivetInfoOperation::DelegateForTests* delegate_for_tests_; 158 }; 159 160 class MockDelegateForTests : public MockPrivetInfoOperation::DelegateForTests { 161 public: 162 MOCK_METHOD1(InfoOperationStarted, void(MockPrivetInfoOperation* operation)); 163 }; 164 165 class PrivetNotificationsListenerTest : public ::testing::Test { 166 public: 167 PrivetNotificationsListenerTest() { 168 notification_listener_.reset(new PrivetNotificationsListener( 169 scoped_ptr<PrivetHTTPAsynchronousFactory>( 170 new MockPrivetHttpFactory(&mock_delegate_for_tests_)), 171 &mock_delegate_)); 172 173 description_.name = kExampleDeviceHumanName; 174 description_.description = kExampleDeviceDescription; 175 } 176 177 virtual ~PrivetNotificationsListenerTest() { 178 } 179 180 virtual void ExpectInfoOperation() { 181 EXPECT_CALL(mock_delegate_for_tests_, InfoOperationStarted(_)) 182 .WillOnce(SaveArg<0>(&info_operation_)); 183 } 184 185 protected: 186 StrictMock<MockPrivetNotificationsListenerDeleagate> mock_delegate_; 187 StrictMock<MockDelegateForTests> mock_delegate_for_tests_; 188 scoped_ptr<PrivetNotificationsListener> notification_listener_; 189 MockPrivetInfoOperation* info_operation_; 190 DeviceDescription description_; 191 }; 192 193 TEST_F(PrivetNotificationsListenerTest, DisappearReappearTest) { 194 ExpectInfoOperation(); 195 196 EXPECT_CALL(mock_delegate_, PrivetNotify( 197 false, 198 true)); 199 200 notification_listener_->DeviceChanged( 201 true, 202 kExampleDeviceName, 203 description_); 204 205 base::DictionaryValue value; 206 207 value.SetInteger("uptime", 20); 208 209 info_operation_->delegate()->OnPrivetInfoDone(info_operation_, 210 200, &value); 211 212 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification()); 213 214 notification_listener_->DeviceRemoved( 215 kExampleDeviceName); 216 217 notification_listener_->DeviceChanged( 218 true, 219 kExampleDeviceName, 220 description_); 221 222 description_.id = kExampleDeviceID; 223 224 notification_listener_->DeviceChanged( 225 true, 226 kExampleDeviceName, 227 description_); 228 } 229 230 TEST_F(PrivetNotificationsListenerTest, RegisterTest) { 231 ExpectInfoOperation(); 232 233 EXPECT_CALL(mock_delegate_, PrivetNotify( 234 false, 235 true)); 236 237 notification_listener_->DeviceChanged( 238 true, 239 kExampleDeviceName, 240 description_); 241 242 base::DictionaryValue value; 243 244 value.SetInteger("uptime", 20); 245 246 info_operation_->delegate()->OnPrivetInfoDone(info_operation_, 247 200, &value); 248 249 EXPECT_CALL(mock_delegate_, PrivetRemoveNotification()); 250 251 description_.id = kExampleDeviceID; 252 253 notification_listener_->DeviceChanged( 254 true, 255 kExampleDeviceName, 256 description_); 257 } 258 259 TEST_F(PrivetNotificationsListenerTest, HighUptimeTest) { 260 ExpectInfoOperation(); 261 262 notification_listener_->DeviceChanged( 263 true, 264 kExampleDeviceName, 265 description_); 266 267 base::DictionaryValue value; 268 269 value.SetInteger("uptime", 3600); 270 271 info_operation_->delegate()->OnPrivetInfoDone(info_operation_, 272 200, &value); 273 274 description_.id = kExampleDeviceID; 275 276 notification_listener_->DeviceChanged( 277 true, 278 kExampleDeviceName, 279 description_); 280 } 281 282 TEST_F(PrivetNotificationsListenerTest, HTTPErrorTest) { 283 ExpectInfoOperation(); 284 285 notification_listener_->DeviceChanged( 286 true, 287 kExampleDeviceName, 288 description_); 289 290 info_operation_->delegate()->OnPrivetInfoDone(info_operation_, 291 404, NULL); 292 } 293 294 TEST_F(PrivetNotificationsListenerTest, DictionaryErrorTest) { 295 ExpectInfoOperation(); 296 297 notification_listener_->DeviceChanged( 298 true, 299 kExampleDeviceName, 300 description_); 301 302 base::DictionaryValue value; 303 value.SetString("error", "internal_error"); 304 305 info_operation_->delegate()->OnPrivetInfoDone(info_operation_, 306 200, &value); 307 } 308 309 } // namespace 310 311 } // namespace local_discovery 312