1 // Copyright (c) 2012 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 <string> 6 7 #include "base/command_line.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/prefs/testing_pref_service.h" 11 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" 12 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h" 13 #include "chrome/browser/service/service_process_control.h" 14 #include "chrome/browser/ui/startup/startup_browser_creator.h" 15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/cloud_print/cloud_print_proxy_info.h" 17 #include "chrome/common/pref_names.h" 18 #include "chrome/common/service_messages.h" 19 #include "chrome/test/base/testing_browser_process.h" 20 #include "chrome/test/base/testing_pref_service_syncable.h" 21 #include "chrome/test/base/testing_profile.h" 22 #include "chrome/test/base/testing_profile_manager.h" 23 #include "content/public/browser/browser_thread.h" 24 #include "content/public/test/test_browser_thread.h" 25 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gtest/include/gtest/gtest.h" 27 28 using ::testing::Assign; 29 using ::testing::AtMost; 30 using ::testing::DeleteArg; 31 using ::testing::DoAll; 32 using ::testing::Invoke; 33 using ::testing::Property; 34 using ::testing::Return; 35 using ::testing::ReturnPointee; 36 using ::testing::WithArgs; 37 using ::testing::WithoutArgs; 38 using ::testing::_; 39 40 class MockServiceProcessControl : public ServiceProcessControl { 41 public: 42 static std::string EnabledUserId(); 43 44 MockServiceProcessControl() : connected_(false) { } 45 46 MOCK_CONST_METHOD0(IsConnected, bool()); 47 48 MOCK_METHOD2(Launch, void(const base::Closure&, const base::Closure&)); 49 MOCK_METHOD0(Disconnect, void()); 50 51 MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&)); 52 MOCK_METHOD1(OnChannelConnected, void(int32 peer_pid)); 53 MOCK_METHOD0(OnChannelError, void()); 54 55 MOCK_METHOD1(Send, bool(IPC::Message*)); 56 57 typedef enum { 58 kServiceStateDisabled, 59 kServiceStateEnabled, 60 kServiceStateNone 61 } ServiceState; 62 63 void SetConnectSuccessMockExpectations(ServiceState state, bool post_task); 64 65 void SetServiceEnabledExpectations(); 66 void SetServiceDisabledExpectations(); 67 void SetWillBeEnabledExpectations(); 68 void SetWillBeDisabledExpectations(); 69 70 bool SendEnabledInfo(); 71 bool SendDisabledInfo(); 72 73 private: 74 bool connected_; 75 cloud_print::CloudPrintProxyInfo info_; 76 }; 77 78 // static 79 std::string MockServiceProcessControl::EnabledUserId() { 80 return std::string("dorothy (at) somewhere.otr"); 81 } 82 83 void CallTask(const base::Closure& task) { 84 if (!task.is_null()) 85 task.Run(); 86 } 87 88 void PostTask(const base::Closure& task) { 89 if (!task.is_null()) 90 base::MessageLoop::current()->PostTask(FROM_HERE, task); 91 } 92 93 void MockServiceProcessControl::SetConnectSuccessMockExpectations( 94 ServiceState service_state, 95 bool post_task) { 96 EXPECT_CALL(*this, IsConnected()).WillRepeatedly(ReturnPointee(&connected_)); 97 98 EXPECT_CALL(*this, Launch(_, _)) 99 .WillRepeatedly( 100 DoAll(Assign(&connected_, true), 101 WithArgs<0>(Invoke(post_task ? PostTask : CallTask)))); 102 103 EXPECT_CALL(*this, Disconnect()).Times(AtMost(1)) 104 .WillRepeatedly(Assign(&connected_, false)); 105 106 EXPECT_CALL(*this, Send(_)).Times(0); 107 108 if (service_state == kServiceStateEnabled) 109 SetServiceEnabledExpectations(); 110 else if (service_state == kServiceStateDisabled) 111 SetServiceDisabledExpectations(); 112 } 113 114 void MockServiceProcessControl::SetServiceEnabledExpectations() { 115 EXPECT_CALL( 116 *this, 117 Send(Property(&IPC::Message::type, 118 static_cast<int32>(ServiceMsg_GetCloudPrintProxyInfo::ID)))) 119 .Times(1).WillOnce( 120 DoAll( 121 DeleteArg<0>(), 122 WithoutArgs( 123 Invoke(this, &MockServiceProcessControl::SendEnabledInfo)))); 124 } 125 126 void MockServiceProcessControl::SetServiceDisabledExpectations() { 127 EXPECT_CALL( 128 *this, 129 Send(Property(&IPC::Message::type, 130 static_cast<int32>(ServiceMsg_GetCloudPrintProxyInfo::ID)))) 131 .Times(1).WillOnce( 132 DoAll( 133 DeleteArg<0>(), 134 WithoutArgs( 135 Invoke(this, &MockServiceProcessControl::SendDisabledInfo)))); 136 } 137 138 void MockServiceProcessControl::SetWillBeEnabledExpectations() { 139 int32 message_id = ServiceMsg_EnableCloudPrintProxyWithRobot::ID; 140 EXPECT_CALL( 141 *this, 142 Send(Property(&IPC::Message::type, message_id))) 143 .Times(1).WillOnce(DoAll(DeleteArg<0>(), Return(true))); 144 } 145 146 void MockServiceProcessControl::SetWillBeDisabledExpectations() { 147 EXPECT_CALL( 148 *this, 149 Send(Property(&IPC::Message::type, 150 static_cast<int32>(ServiceMsg_DisableCloudPrintProxy::ID)))) 151 .Times(1).WillOnce(DoAll(DeleteArg<0>(), Return(true))); 152 } 153 154 bool MockServiceProcessControl::SendEnabledInfo() { 155 info_.enabled = true; 156 info_.email = EnabledUserId(); 157 OnCloudPrintProxyInfo(info_); 158 return true; 159 } 160 161 bool MockServiceProcessControl::SendDisabledInfo() { 162 info_.enabled = false; 163 info_.email = std::string(); 164 OnCloudPrintProxyInfo(info_); 165 return true; 166 } 167 168 class TestCloudPrintProxyService : public CloudPrintProxyService { 169 public: 170 explicit TestCloudPrintProxyService(Profile* profile) 171 : CloudPrintProxyService(profile) { } 172 173 virtual ServiceProcessControl* GetServiceProcessControl() OVERRIDE { 174 return &process_control_; 175 } 176 MockServiceProcessControl* GetMockServiceProcessControl() { 177 return &process_control_; 178 } 179 180 void EnableForUser() { 181 EnableForUserWithRobot("123", "123 (at) gmail.com", 182 MockServiceProcessControl::EnabledUserId(), 183 base::DictionaryValue()); 184 } 185 186 private: 187 MockServiceProcessControl process_control_; 188 }; 189 190 class CloudPrintProxyPolicyTest : public ::testing::Test { 191 public: 192 CloudPrintProxyPolicyTest() 193 : ui_thread_(content::BrowserThread::UI, &message_loop_) { 194 } 195 196 bool LaunchBrowser(const CommandLine& command_line, Profile* profile) { 197 int return_code = 0; 198 StartupBrowserCreator browser_creator; 199 return StartupBrowserCreator::ProcessCmdLineImpl( 200 command_line, base::FilePath(), false, profile, 201 StartupBrowserCreator::Profiles(), &return_code, &browser_creator); 202 } 203 204 protected: 205 base::MessageLoopForUI message_loop_; 206 content::TestBrowserThread ui_thread_; 207 TestingProfile profile_; 208 }; 209 210 TEST_F(CloudPrintProxyPolicyTest, VerifyExpectations) { 211 MockServiceProcessControl mock_control; 212 mock_control.SetConnectSuccessMockExpectations( 213 MockServiceProcessControl::kServiceStateNone, false); 214 215 EXPECT_FALSE(mock_control.IsConnected()); 216 mock_control.Launch(base::Closure(), base::Closure()); 217 EXPECT_TRUE(mock_control.IsConnected()); 218 mock_control.Launch(base::Closure(), base::Closure()); 219 EXPECT_TRUE(mock_control.IsConnected()); 220 mock_control.Disconnect(); 221 EXPECT_FALSE(mock_control.IsConnected()); 222 } 223 224 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyDisabled) { 225 TestCloudPrintProxyService service(&profile_); 226 227 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 228 MockServiceProcessControl::kServiceStateDisabled, false); 229 230 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 231 prefs->SetUserPref(prefs::kCloudPrintEmail, 232 Value::CreateStringValue( 233 MockServiceProcessControl::EnabledUserId())); 234 235 service.Initialize(); 236 237 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 238 } 239 240 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyEnabled) { 241 TestCloudPrintProxyService service(&profile_); 242 243 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 244 MockServiceProcessControl::kServiceStateEnabled, false); 245 246 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 247 prefs->SetUserPref(prefs::kCloudPrintEmail, 248 Value::CreateStringValue(std::string())); 249 250 service.Initialize(); 251 service.RefreshStatusFromService(); 252 253 EXPECT_EQ(MockServiceProcessControl::EnabledUserId(), 254 prefs->GetString(prefs::kCloudPrintEmail)); 255 } 256 257 TEST_F(CloudPrintProxyPolicyTest, StartWithPolicySetProxyDisabled) { 258 TestCloudPrintProxyService service(&profile_); 259 260 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 261 MockServiceProcessControl::kServiceStateDisabled, false); 262 263 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 264 prefs->SetUserPref(prefs::kCloudPrintEmail, 265 Value::CreateStringValue(std::string())); 266 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 267 Value::CreateBooleanValue(false)); 268 269 service.Initialize(); 270 271 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 272 } 273 274 TEST_F(CloudPrintProxyPolicyTest, StartWithPolicySetProxyEnabled) { 275 TestCloudPrintProxyService service(&profile_); 276 277 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 278 MockServiceProcessControl::kServiceStateEnabled, false); 279 service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations(); 280 281 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 282 prefs->SetUserPref(prefs::kCloudPrintEmail, 283 Value::CreateStringValue(std::string())); 284 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 285 Value::CreateBooleanValue(false)); 286 287 service.Initialize(); 288 289 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 290 } 291 292 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyDisabledThenSetPolicy) { 293 TestCloudPrintProxyService service(&profile_); 294 295 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 296 MockServiceProcessControl::kServiceStateDisabled, false); 297 298 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 299 prefs->SetUserPref(prefs::kCloudPrintEmail, 300 Value::CreateStringValue( 301 MockServiceProcessControl::EnabledUserId())); 302 303 service.Initialize(); 304 305 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 306 307 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 308 Value::CreateBooleanValue(false)); 309 310 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 311 } 312 313 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyEnabledThenSetPolicy) { 314 TestCloudPrintProxyService service(&profile_); 315 316 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 317 MockServiceProcessControl::kServiceStateEnabled, false); 318 319 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 320 prefs->SetUserPref(prefs::kCloudPrintEmail, 321 Value::CreateStringValue(std::string())); 322 323 service.Initialize(); 324 service.RefreshStatusFromService(); 325 326 EXPECT_EQ(MockServiceProcessControl::EnabledUserId(), 327 prefs->GetString(prefs::kCloudPrintEmail)); 328 329 service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations(); 330 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 331 Value::CreateBooleanValue(false)); 332 333 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 334 } 335 336 TEST_F(CloudPrintProxyPolicyTest, 337 StartWithPolicySetProxyDisabledThenClearPolicy) { 338 TestCloudPrintProxyService service(&profile_); 339 340 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 341 MockServiceProcessControl::kServiceStateDisabled, false); 342 343 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 344 prefs->SetUserPref(prefs::kCloudPrintEmail, 345 Value::CreateStringValue(std::string())); 346 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 347 Value::CreateBooleanValue(false)); 348 349 service.Initialize(); 350 351 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 352 prefs->RemoveManagedPref(prefs::kCloudPrintProxyEnabled); 353 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 354 } 355 356 TEST_F(CloudPrintProxyPolicyTest, 357 StartWithPolicySetProxyEnabledThenClearPolicy) { 358 TestCloudPrintProxyService service(&profile_); 359 360 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 361 MockServiceProcessControl::kServiceStateEnabled, false); 362 service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations(); 363 364 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 365 prefs->SetUserPref(prefs::kCloudPrintEmail, 366 Value::CreateStringValue(std::string())); 367 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 368 Value::CreateBooleanValue(false)); 369 370 service.Initialize(); 371 372 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 373 prefs->RemoveManagedPref(prefs::kCloudPrintProxyEnabled); 374 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 375 } 376 377 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyDisabledThenEnable) { 378 TestCloudPrintProxyService service(&profile_); 379 380 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 381 MockServiceProcessControl::kServiceStateDisabled, false); 382 383 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 384 prefs->SetUserPref(prefs::kCloudPrintEmail, 385 Value::CreateStringValue( 386 MockServiceProcessControl::EnabledUserId())); 387 388 service.Initialize(); 389 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 390 391 service.GetMockServiceProcessControl()->SetWillBeEnabledExpectations(); 392 service.EnableForUser(); 393 394 EXPECT_EQ(MockServiceProcessControl::EnabledUserId(), 395 prefs->GetString(prefs::kCloudPrintEmail)); 396 } 397 398 TEST_F(CloudPrintProxyPolicyTest, 399 StartWithPolicySetProxyEnabledThenClearPolicyAndEnable) { 400 TestCloudPrintProxyService service(&profile_); 401 402 service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 403 MockServiceProcessControl::kServiceStateEnabled, false); 404 service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations(); 405 406 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 407 prefs->SetUserPref(prefs::kCloudPrintEmail, 408 Value::CreateStringValue(std::string())); 409 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 410 Value::CreateBooleanValue(false)); 411 412 service.Initialize(); 413 414 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 415 service.EnableForUser(); 416 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 417 418 prefs->RemoveManagedPref(prefs::kCloudPrintProxyEnabled); 419 EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail)); 420 421 service.GetMockServiceProcessControl()->SetWillBeEnabledExpectations(); 422 service.EnableForUser(); 423 424 EXPECT_EQ(MockServiceProcessControl::EnabledUserId(), 425 prefs->GetString(prefs::kCloudPrintEmail)); 426 } 427 428 BrowserContextKeyedService* TestCloudPrintProxyServiceFactory( 429 content::BrowserContext* profile) { 430 TestCloudPrintProxyService* service = 431 new TestCloudPrintProxyService(static_cast<Profile*>(profile)); 432 433 service->GetMockServiceProcessControl()->SetConnectSuccessMockExpectations( 434 MockServiceProcessControl::kServiceStateEnabled, true); 435 service->GetMockServiceProcessControl()->SetWillBeDisabledExpectations(); 436 437 service->Initialize(); 438 base::MessageLoop::current()->RunUntilIdle(); 439 return service; 440 } 441 442 TEST_F(CloudPrintProxyPolicyTest, StartupBrowserCreatorWithCommandLine) { 443 TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); 444 prefs->SetUserPref(prefs::kCloudPrintEmail, 445 Value::CreateStringValue(std::string())); 446 prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, 447 Value::CreateBooleanValue(false)); 448 449 CloudPrintProxyServiceFactory::GetInstance()-> 450 SetTestingFactory(&profile_, TestCloudPrintProxyServiceFactory); 451 452 CommandLine command_line(CommandLine::NO_PROGRAM); 453 command_line.AppendSwitch(switches::kCheckCloudPrintConnectorPolicy); 454 455 EXPECT_FALSE(LaunchBrowser(command_line, &profile_)); 456 base::MessageLoop::current()->RunUntilIdle(); 457 } 458