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