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 "base/prefs/pref_service.h" 6 #include "base/strings/utf_string_conversions.h" 7 #include "base/values.h" 8 #include "chrome/browser/content_settings/cookie_settings.h" 9 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" 10 #include "chrome/browser/prefs/scoped_user_pref_update.h" 11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile_info_cache.h" 13 #include "chrome/browser/profiles/profile_io_data.h" 14 #include "chrome/browser/profiles/profile_manager.h" 15 #include "chrome/browser/signin/fake_signin_manager.h" 16 #include "chrome/browser/signin/signin_manager.h" 17 #include "chrome/browser/signin/signin_manager_factory.h" 18 #include "chrome/browser/signin/signin_names_io_thread.h" 19 #include "chrome/browser/signin/signin_promo.h" 20 #include "chrome/browser/sync/profile_sync_service_factory.h" 21 #include "chrome/browser/sync/profile_sync_service_mock.h" 22 #include "chrome/browser/sync/test_profile_sync_service.h" 23 #include "chrome/browser/ui/sync/one_click_signin_helper.h" 24 #include "chrome/common/pref_names.h" 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 26 #include "chrome/test/base/testing_browser_process.h" 27 #include "chrome/test/base/testing_pref_service_syncable.h" 28 #include "chrome/test/base/testing_profile.h" 29 #include "chrome/test/base/testing_profile_manager.h" 30 #include "content/public/browser/browser_context.h" 31 #include "content/public/browser/navigation_details.h" 32 #include "content/public/browser/web_contents.h" 33 #include "content/public/common/frame_navigate_params.h" 34 #include "content/public/common/password_form.h" 35 #include "content/public/common/url_constants.h" 36 #include "content/public/test/mock_render_process_host.h" 37 #include "grit/chromium_strings.h" 38 #include "grit/generated_resources.h" 39 #include "testing/gtest/include/gtest/gtest.h" 40 #include "ui/base/l10n/l10n_util.h" 41 42 using ::testing::_; 43 using ::testing::AtLeast; 44 using ::testing::Return; 45 46 namespace { 47 48 // Explicit URLs are sign in URLs created by chrome for specific sign in access 49 // points. Implicit URLs are those to sign for some Google service, like gmail 50 // or drive. In former case, with a valid URL, we don't want to offer the 51 // interstitial. In all other cases we do. 52 53 const char kImplicitURLString[] = 54 "https://accounts.google.com/ServiceLogin" 55 "?service=foo&continue=http://foo.google.com"; 56 57 class SigninManagerMock : public FakeSigninManager { 58 public: 59 explicit SigninManagerMock(Profile* profile) : FakeSigninManager(profile) { 60 Initialize(profile, NULL); 61 } 62 MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username)); 63 }; 64 65 class TestProfileIOData : public ProfileIOData { 66 public: 67 TestProfileIOData(bool is_incognito, PrefService* pref_service, 68 PrefService* local_state, CookieSettings* cookie_settings) 69 : ProfileIOData(is_incognito) { 70 // Initialize the IO members required for these tests, but keep them on 71 // this thread since we don't use a background thread here. 72 google_services_username()->Init(prefs::kGoogleServicesUsername, 73 pref_service); 74 reverse_autologin_enabled()->Init(prefs::kReverseAutologinEnabled, 75 pref_service); 76 one_click_signin_rejected_email_list()->Init( 77 prefs::kReverseAutologinRejectedEmailList, pref_service); 78 79 google_services_username_pattern()->Init( 80 prefs::kGoogleServicesUsernamePattern, local_state); 81 82 sync_disabled()->Init(prefs::kSyncManaged, pref_service); 83 84 signin_allowed()->Init(prefs::kSigninAllowed, pref_service); 85 86 set_signin_names_for_testing(new SigninNamesOnIOThread()); 87 SetCookieSettingsForTesting(cookie_settings); 88 } 89 90 virtual ~TestProfileIOData() { 91 signin_names()->ReleaseResourcesOnUIThread(); 92 } 93 94 // ProfileIOData overrides: 95 virtual void InitializeInternal( 96 ProfileParams* profile_params, 97 content::ProtocolHandlerMap* protocol_handlers) const OVERRIDE { 98 NOTREACHED(); 99 } 100 virtual void InitializeExtensionsRequestContext( 101 ProfileParams* profile_params) const OVERRIDE { 102 NOTREACHED(); 103 } 104 virtual ChromeURLRequestContext* InitializeAppRequestContext( 105 ChromeURLRequestContext* main_context, 106 const StoragePartitionDescriptor& details, 107 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> 108 protocol_handler_interceptor, 109 content::ProtocolHandlerMap* protocol_handlers) const OVERRIDE { 110 NOTREACHED(); 111 return NULL; 112 } 113 virtual ChromeURLRequestContext* InitializeMediaRequestContext( 114 ChromeURLRequestContext* original_context, 115 const StoragePartitionDescriptor& details) const OVERRIDE { 116 NOTREACHED(); 117 return NULL; 118 } 119 virtual ChromeURLRequestContext* 120 AcquireMediaRequestContext() const OVERRIDE { 121 NOTREACHED(); 122 return NULL; 123 } 124 virtual ChromeURLRequestContext* 125 AcquireIsolatedAppRequestContext( 126 ChromeURLRequestContext* main_context, 127 const StoragePartitionDescriptor& partition_descriptor, 128 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> 129 protocol_handler_interceptor, 130 content::ProtocolHandlerMap* protocol_handlers) const OVERRIDE { 131 NOTREACHED(); 132 return NULL; 133 } 134 virtual ChromeURLRequestContext* 135 AcquireIsolatedMediaRequestContext( 136 ChromeURLRequestContext* app_context, 137 const StoragePartitionDescriptor& partition_descriptor) 138 const OVERRIDE { 139 NOTREACHED(); 140 return NULL; 141 } 142 virtual chrome_browser_net::LoadTimeStats* GetLoadTimeStats( 143 IOThread::Globals* io_thread_globals) const OVERRIDE { 144 NOTREACHED(); 145 return NULL; 146 } 147 }; 148 149 class TestURLRequest : public base::SupportsUserData { 150 public: 151 TestURLRequest() {} 152 virtual ~TestURLRequest() {} 153 }; 154 155 class OneClickTestProfileSyncService : public TestProfileSyncService { 156 public: 157 virtual ~OneClickTestProfileSyncService() {} 158 159 // Helper routine to be used in conjunction with 160 // BrowserContextKeyedServiceFactory::SetTestingFactory(). 161 static BrowserContextKeyedService* Build(content::BrowserContext* profile) { 162 return new OneClickTestProfileSyncService(static_cast<Profile*>(profile)); 163 } 164 165 // Need to control this for certain tests. 166 virtual bool FirstSetupInProgress() const OVERRIDE { 167 return first_setup_in_progress_; 168 } 169 170 // Controls return value of FirstSetupInProgress. Because some bits 171 // of UI depend on that value, it's useful to control it separately 172 // from the internal work and components that are triggered (such as 173 // ReconfigureDataTypeManager) to facilitate unit tests. 174 void set_first_setup_in_progress(bool in_progress) { 175 first_setup_in_progress_ = in_progress; 176 } 177 178 // Override ProfileSyncService::Shutdown() to avoid CHECK on 179 // |invalidator_registrar_|. 180 virtual void Shutdown() OVERRIDE {}; 181 182 private: 183 explicit OneClickTestProfileSyncService(Profile* profile) 184 : TestProfileSyncService(NULL, 185 profile, 186 NULL, 187 ProfileSyncService::MANUAL_START, 188 false), // synchronous_backend_init 189 first_setup_in_progress_(false) {} 190 191 bool first_setup_in_progress_; 192 }; 193 194 static BrowserContextKeyedService* BuildSigninManagerMock( 195 content::BrowserContext* profile) { 196 return new SigninManagerMock(static_cast<Profile*>(profile)); 197 } 198 199 } // namespace 200 201 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness { 202 public: 203 OneClickSigninHelperTest(); 204 205 virtual void SetUp() OVERRIDE; 206 virtual void TearDown() OVERRIDE; 207 208 // Creates the sign-in manager for tests. If |use_incognito| is true then 209 // a WebContents for an incognito profile is created. If |username| is 210 // is not empty, the profile of the mock WebContents will be connected to 211 // the given account. 212 void CreateSigninManager(bool use_incognito, const std::string& username); 213 214 // Set the ID of the signin process that the test will assume to be the 215 // only process allowed to sign the user in to Chrome. 216 void SetTrustedSigninProcessID(int id); 217 218 void AddEmailToOneClickRejectedList(const std::string& email); 219 void EnableOneClick(bool enable); 220 void AllowSigninCookies(bool enable); 221 void SetAllowedUsernamePattern(const std::string& pattern); 222 ProfileSyncServiceMock* CreateProfileSyncServiceMock(); 223 void SubmitGAIAPassword(OneClickSigninHelper* helper); 224 OneClickSigninHelper* SetupHelperForSignin(); 225 226 SigninManagerMock* signin_manager_; 227 228 protected: 229 GoogleServiceAuthError no_error_; 230 231 private: 232 // The ID of the signin process the test will assume to be trusted. 233 // By default, set to the test RenderProcessHost's process ID, but 234 // overridden by SetTrustedSigninProcessID. 235 int trusted_signin_process_id_; 236 237 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest); 238 }; 239 240 OneClickSigninHelperTest::OneClickSigninHelperTest() 241 : no_error_(GoogleServiceAuthError::NONE), 242 trusted_signin_process_id_(-1) { 243 } 244 245 void OneClickSigninHelperTest::SetUp() { 246 signin::ForceWebBasedSigninFlowForTesting(true); 247 content::RenderViewHostTestHarness::SetUp(); 248 SetTrustedSigninProcessID(process()->GetID()); 249 } 250 251 void OneClickSigninHelperTest::TearDown() { 252 signin::ForceWebBasedSigninFlowForTesting(false); 253 content::RenderViewHostTestHarness::TearDown(); 254 } 255 256 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) { 257 trusted_signin_process_id_ = id; 258 } 259 260 void OneClickSigninHelperTest::CreateSigninManager( 261 bool use_incognito, 262 const std::string& username) { 263 profile()->set_incognito(use_incognito); 264 signin_manager_ = static_cast<SigninManagerMock*>( 265 SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse( 266 profile(), BuildSigninManagerMock)); 267 if (signin_manager_) 268 signin_manager_->SetSigninProcess(trusted_signin_process_id_); 269 270 if (!username.empty()) { 271 ASSERT_TRUE(signin_manager_); 272 signin_manager_->SetAuthenticatedUsername(username); 273 } 274 } 275 276 void OneClickSigninHelperTest::EnableOneClick(bool enable) { 277 PrefService* pref_service = profile()->GetPrefs(); 278 pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable); 279 } 280 281 void OneClickSigninHelperTest::AddEmailToOneClickRejectedList( 282 const std::string& email) { 283 PrefService* pref_service = profile()->GetPrefs(); 284 ListPrefUpdate updater(pref_service, 285 prefs::kReverseAutologinRejectedEmailList); 286 updater->AppendIfNotPresent(new base::StringValue(email)); 287 } 288 289 void OneClickSigninHelperTest::AllowSigninCookies(bool enable) { 290 CookieSettings* cookie_settings = 291 CookieSettings::Factory::GetForProfile(profile()).get(); 292 cookie_settings->SetDefaultCookieSetting(enable ? CONTENT_SETTING_ALLOW 293 : CONTENT_SETTING_BLOCK); 294 } 295 296 void OneClickSigninHelperTest::SetAllowedUsernamePattern( 297 const std::string& pattern) { 298 PrefService* local_state = g_browser_process->local_state(); 299 local_state->SetString(prefs::kGoogleServicesUsernamePattern, pattern); 300 } 301 302 ProfileSyncServiceMock* 303 OneClickSigninHelperTest::CreateProfileSyncServiceMock() { 304 ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>( 305 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( 306 profile(), 307 ProfileSyncServiceMock::BuildMockProfileSyncService)); 308 EXPECT_CALL(*sync_service, SetSetupInProgress(true)); 309 EXPECT_CALL(*sync_service, AddObserver(_)).Times(AtLeast(1)); 310 EXPECT_CALL(*sync_service, FirstSetupInProgress()).WillRepeatedly( 311 Return(false)); 312 EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true)); 313 EXPECT_CALL(*sync_service, RemoveObserver(_)).Times(AtLeast(1)); 314 EXPECT_CALL(*sync_service, GetAuthError()). 315 WillRepeatedly(::testing::ReturnRef(no_error_)); 316 EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(false)); 317 sync_service->Initialize(); 318 EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true)); 319 return sync_service; 320 } 321 322 void OneClickSigninHelperTest::SubmitGAIAPassword( 323 OneClickSigninHelper* helper) { 324 content::PasswordForm password_form; 325 password_form.origin = GURL("https://accounts.google.com"); 326 password_form.signon_realm = "https://accounts.google.com"; 327 password_form.password_value = UTF8ToUTF16("password"); 328 helper->OnFormSubmitted(password_form); 329 } 330 331 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest { 332 public: 333 OneClickSigninHelperIOTest(); 334 335 virtual void SetUp() OVERRIDE; 336 337 TestProfileIOData* CreateTestProfileIOData(bool is_incognito); 338 339 protected: 340 TestingProfileManager testing_profile_manager_; 341 TestURLRequest request_; 342 const GURL valid_gaia_url_; 343 344 private: 345 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest); 346 }; 347 348 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest() 349 : testing_profile_manager_( 350 TestingBrowserProcess::GetGlobal()), 351 valid_gaia_url_("https://accounts.google.com/") { 352 } 353 354 void OneClickSigninHelperIOTest::SetUp() { 355 OneClickSigninHelperTest::SetUp(); 356 ASSERT_TRUE(testing_profile_manager_.SetUp()); 357 } 358 359 TestProfileIOData* OneClickSigninHelperIOTest::CreateTestProfileIOData( 360 bool is_incognito) { 361 PrefService* pref_service = profile()->GetPrefs(); 362 PrefService* local_state = g_browser_process->local_state(); 363 CookieSettings* cookie_settings = 364 CookieSettings::Factory::GetForProfile(profile()).get(); 365 TestProfileIOData* io_data = new TestProfileIOData( 366 is_incognito, pref_service, local_state, cookie_settings); 367 io_data->set_reverse_autologin_pending_email("user (at) gmail.com"); 368 return io_data; 369 } 370 371 TEST_F(OneClickSigninHelperTest, CanOfferNoContents) { 372 std::string error_message; 373 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 374 NULL, OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 375 "user (at) gmail.com", &error_message)); 376 EXPECT_EQ("", error_message); 377 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 378 NULL, OneClickSigninHelper::CAN_OFFER_FOR_ALL, 379 "user (at) gmail.com", &error_message)); 380 EXPECT_EQ("", error_message); 381 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 382 NULL, 383 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 384 std::string(), 385 &error_message)); 386 EXPECT_EQ("", error_message); 387 } 388 389 TEST_F(OneClickSigninHelperTest, CanOffer) { 390 CreateSigninManager(false, std::string()); 391 392 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 393 WillRepeatedly(Return(true)); 394 395 EnableOneClick(true); 396 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 397 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 398 "user (at) gmail.com", NULL)); 399 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 400 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 401 "user (at) gmail.com", NULL)); 402 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 403 web_contents(), 404 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 405 std::string(), 406 NULL)); 407 408 EnableOneClick(false); 409 410 std::string error_message; 411 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 412 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 413 "user (at) gmail.com", &error_message)); 414 EXPECT_EQ("", error_message); 415 416 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 417 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 418 "user (at) gmail.com", &error_message)); 419 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 420 web_contents(), 421 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 422 std::string(), 423 &error_message)); 424 EXPECT_EQ("", error_message); 425 } 426 427 TEST_F(OneClickSigninHelperTest, CanOfferFirstSetup) { 428 CreateSigninManager(false, std::string()); 429 430 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 431 WillRepeatedly(Return(true)); 432 433 // Invoke OneClickTestProfileSyncService factory function and grab result. 434 OneClickTestProfileSyncService* sync = 435 static_cast<OneClickTestProfileSyncService*>( 436 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( 437 static_cast<Profile*>(browser_context()), 438 OneClickTestProfileSyncService::Build)); 439 440 sync->set_first_setup_in_progress(true); 441 442 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 443 web_contents(), 444 OneClickSigninHelper::CAN_OFFER_FOR_ALL, 445 "foo (at) gmail.com", NULL)); 446 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 447 web_contents(), 448 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 449 "foo (at) gmail.com", NULL)); 450 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 451 web_contents(), 452 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 453 std::string(), 454 NULL)); 455 } 456 457 TEST_F(OneClickSigninHelperTest, CanOfferProfileConnected) { 458 CreateSigninManager(false, "foo (at) gmail.com"); 459 460 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 461 WillRepeatedly(Return(true)); 462 463 std::string error_message; 464 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 465 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 466 "foo (at) gmail.com", &error_message)); 467 EXPECT_EQ("", error_message); 468 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 469 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 470 "foo", &error_message)); 471 EXPECT_EQ("", error_message); 472 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 473 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 474 "user (at) gmail.com", &error_message)); 475 EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL, 476 UTF8ToUTF16("foo (at) gmail.com")), 477 error_message); 478 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 479 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 480 "foo (at) gmail.com", &error_message)); 481 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 482 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 483 "foo", &error_message)); 484 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 485 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 486 "user (at) gmail.com", &error_message)); 487 EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL, 488 UTF8ToUTF16("foo (at) gmail.com")), 489 error_message); 490 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 491 web_contents(), 492 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 493 std::string(), 494 &error_message)); 495 } 496 497 TEST_F(OneClickSigninHelperTest, CanOfferUsernameNotAllowed) { 498 CreateSigninManager(false, std::string()); 499 500 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 501 WillRepeatedly(Return(false)); 502 503 std::string error_message; 504 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 505 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 506 "foo (at) gmail.com", &error_message)); 507 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED), 508 error_message); 509 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 510 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 511 "foo (at) gmail.com", &error_message)); 512 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED), 513 error_message); 514 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 515 web_contents(), 516 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 517 std::string(), 518 &error_message)); 519 } 520 521 TEST_F(OneClickSigninHelperTest, CanOfferWithRejectedEmail) { 522 CreateSigninManager(false, std::string()); 523 524 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 525 WillRepeatedly(Return(true)); 526 527 AddEmailToOneClickRejectedList("foo (at) gmail.com"); 528 AddEmailToOneClickRejectedList("user (at) gmail.com"); 529 530 std::string error_message; 531 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 532 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 533 "foo (at) gmail.com", &error_message)); 534 EXPECT_EQ("", error_message); 535 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 536 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 537 "user (at) gmail.com", &error_message)); 538 EXPECT_EQ("", error_message); 539 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 540 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 541 "foo (at) gmail.com", &error_message)); 542 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 543 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 544 "user (at) gmail.com", &error_message)); 545 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 546 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 547 "john (at) gmail.com", &error_message)); 548 } 549 550 TEST_F(OneClickSigninHelperTest, CanOfferIncognito) { 551 CreateSigninManager(true, std::string()); 552 553 std::string error_message; 554 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 555 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 556 "user (at) gmail.com", &error_message)); 557 EXPECT_EQ("", error_message); 558 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 559 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 560 "user (at) gmail.com", &error_message)); 561 EXPECT_EQ("", error_message); 562 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 563 web_contents(), 564 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 565 std::string(), 566 &error_message)); 567 EXPECT_EQ("", error_message); 568 } 569 570 TEST_F(OneClickSigninHelperTest, CanOfferNoSigninCookies) { 571 CreateSigninManager(false, std::string()); 572 AllowSigninCookies(false); 573 574 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 575 WillRepeatedly(Return(true)); 576 577 std::string error_message; 578 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 579 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 580 "user (at) gmail.com", &error_message)); 581 EXPECT_EQ("", error_message); 582 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 583 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 584 "user (at) gmail.com", &error_message)); 585 EXPECT_EQ("", error_message); 586 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 587 web_contents(), 588 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY, 589 std::string(), 590 &error_message)); 591 EXPECT_EQ("", error_message); 592 } 593 594 TEST_F(OneClickSigninHelperTest, CanOfferDisabledByPolicy) { 595 CreateSigninManager(false, std::string()); 596 597 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)). 598 WillRepeatedly(Return(true)); 599 600 EnableOneClick(true); 601 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 602 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 603 "user (at) gmail.com", NULL)); 604 605 // Simulate a policy disabling signin by writing kSigninAllowed directly. 606 profile()->GetTestingPrefService()->SetManagedPref( 607 prefs::kSigninAllowed, base::Value::CreateBooleanValue(false)); 608 609 EXPECT_FALSE(OneClickSigninHelper::CanOffer( 610 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 611 "user (at) gmail.com", NULL)); 612 613 // Reset the preference value to true. 614 profile()->GetTestingPrefService()->SetManagedPref( 615 prefs::kSigninAllowed, base::Value::CreateBooleanValue(true)); 616 617 // Simulate a policy disabling sync by writing kSyncManaged directly. 618 profile()->GetTestingPrefService()->SetManagedPref( 619 prefs::kSyncManaged, base::Value::CreateBooleanValue(true)); 620 621 // Should still offer even if sync is disabled by policy. 622 EXPECT_TRUE(OneClickSigninHelper::CanOffer( 623 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL, 624 "user (at) gmail.com", NULL)); 625 } 626 627 // Should not crash if a helper instance is not associated with an incognito 628 // web contents. 629 TEST_F(OneClickSigninHelperTest, ShowInfoBarUIThreadIncognito) { 630 CreateSigninManager(true, std::string()); 631 OneClickSigninHelper* helper = 632 OneClickSigninHelper::FromWebContents(web_contents()); 633 EXPECT_EQ(NULL, helper); 634 635 OneClickSigninHelper::ShowInfoBarUIThread( 636 "session_index", "email", OneClickSigninHelper::AUTO_ACCEPT_ACCEPTED, 637 signin::SOURCE_UNKNOWN, GURL(), process()->GetID(), 638 rvh()->GetRoutingID()); 639 } 640 641 // If Chrome signin is triggered from a webstore install, and user chooses to 642 // config sync, then Chrome should redirect immediately to sync settings page, 643 // and upon successful setup, redirect back to webstore. 644 TEST_F(OneClickSigninHelperTest, SigninFromWebstoreWithConfigSyncfirst) { 645 CreateSigninManager(false, std::string()); 646 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)) 647 .WillRepeatedly(Return(true)); 648 649 CreateProfileSyncServiceMock(); 650 651 content::WebContents* contents = web_contents(); 652 653 OneClickSigninHelper::CreateForWebContents(contents); 654 OneClickSigninHelper* helper = 655 OneClickSigninHelper::FromWebContents(contents); 656 helper->SetDoNotClearPendingEmailForTesting(); 657 658 GURL continueUrl("https://chrome.google.com/webstore?source=5"); 659 OneClickSigninHelper::ShowInfoBarUIThread( 660 "session_index", "user (at) gmail.com", 661 OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT, 662 signin::SOURCE_WEBSTORE_INSTALL, 663 continueUrl, process()->GetID(), rvh()->GetRoutingID()); 664 665 SubmitGAIAPassword(helper); 666 667 NavigateAndCommit(GURL("https://chrome.google.com/webstore?source=3")); 668 helper->DidStopLoading(rvh()); 669 670 helper->OnStateChanged(); 671 EXPECT_EQ(GURL(continueUrl), contents->GetURL()); 672 EXPECT_EQ("user (at) gmail.com", signin_manager_->GetAuthenticatedUsername()); 673 } 674 675 // Checks that the state of OneClickSigninHelper is cleaned when there is a 676 // navigation away from the sign in flow that is not triggered by the 677 // web contents. 678 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) { 679 content::WebContents* contents = web_contents(); 680 681 OneClickSigninHelper::CreateForWebContents(contents); 682 OneClickSigninHelper* helper = 683 OneClickSigninHelper::FromWebContents(contents); 684 helper->SetDoNotClearPendingEmailForTesting(); 685 helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT; 686 687 content::LoadCommittedDetails details; 688 content::FrameNavigateParams params; 689 params.url = GURL("http://crbug.com"); 690 params.transition = content::PAGE_TRANSITION_TYPED; 691 helper->DidNavigateMainFrame(details, params); 692 693 EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_); 694 } 695 696 // I/O thread tests 697 698 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThread) { 699 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 700 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 701 OneClickSigninHelper::CanOfferOnIOThreadImpl( 702 valid_gaia_url_, std::string(), &request_, io_data.get())); 703 } 704 705 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadIncognito) { 706 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(true)); 707 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 708 OneClickSigninHelper::CanOfferOnIOThreadImpl( 709 valid_gaia_url_, std::string(), &request_, io_data.get())); 710 } 711 712 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) { 713 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 714 OneClickSigninHelper::CanOfferOnIOThreadImpl( 715 valid_gaia_url_, std::string(), &request_, NULL)); 716 } 717 718 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) { 719 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 720 EXPECT_EQ( 721 OneClickSigninHelper::IGNORE_REQUEST, 722 OneClickSigninHelper::CanOfferOnIOThreadImpl( 723 GURL("https://foo.com/"), std::string(), &request_, io_data.get())); 724 EXPECT_EQ(OneClickSigninHelper::IGNORE_REQUEST, 725 OneClickSigninHelper::CanOfferOnIOThreadImpl( 726 GURL("http://accounts.google.com/"), 727 std::string(), 728 &request_, 729 io_data.get())); 730 } 731 732 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadReferrer) { 733 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 734 std::string continue_url(signin::GetPromoURL( 735 signin::SOURCE_START_PAGE, false).spec()); 736 737 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 738 OneClickSigninHelper::CanOfferOnIOThreadImpl( 739 valid_gaia_url_, continue_url, &request_, io_data.get())); 740 741 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 742 OneClickSigninHelper::CanOfferOnIOThreadImpl( 743 valid_gaia_url_, kImplicitURLString, &request_, io_data.get())); 744 745 std::string bad_url_1 = continue_url; 746 const std::string service_name = "chromiumsync"; 747 bad_url_1.replace(bad_url_1.find(service_name), service_name.length(), 748 "foo"); 749 750 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 751 OneClickSigninHelper::CanOfferOnIOThreadImpl( 752 valid_gaia_url_, bad_url_1, &request_, io_data.get())); 753 754 std::string bad_url_2 = continue_url; 755 const std::string source_num = "%3D0"; 756 bad_url_2.replace(bad_url_1.find(source_num), source_num.length(), "%3D10"); 757 758 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 759 OneClickSigninHelper::CanOfferOnIOThreadImpl( 760 valid_gaia_url_, bad_url_2, &request_, io_data.get())); 761 762 std::string bad_url_3 = continue_url; 763 const std::string source = "source%3D0"; 764 bad_url_3.erase(bad_url_1.find(source), source.length()); 765 766 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 767 OneClickSigninHelper::CanOfferOnIOThreadImpl( 768 valid_gaia_url_, bad_url_3, &request_, io_data.get())); 769 } 770 771 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabled) { 772 EnableOneClick(false); 773 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 774 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 775 OneClickSigninHelper::CanOfferOnIOThreadImpl( 776 valid_gaia_url_, std::string(), &request_, io_data.get())); 777 } 778 779 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) { 780 PrefService* pref_service = profile()->GetPrefs(); 781 pref_service->SetString(prefs::kGoogleServicesUsername, "user (at) gmail.com"); 782 783 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 784 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 785 OneClickSigninHelper::CanOfferOnIOThreadImpl( 786 valid_gaia_url_, std::string(), &request_, io_data.get())); 787 } 788 789 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailNotAllowed) { 790 SetAllowedUsernamePattern("*@example.com"); 791 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 792 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 793 OneClickSigninHelper::CanOfferOnIOThreadImpl( 794 valid_gaia_url_, std::string(), &request_, io_data.get())); 795 } 796 797 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailAlreadyUsed) { 798 ProfileInfoCache* cache = testing_profile_manager_.profile_info_cache(); 799 const base::FilePath& user_data_dir = cache->GetUserDataDir(); 800 cache->AddProfileToCache(user_data_dir.Append(FILE_PATH_LITERAL("user")), 801 UTF8ToUTF16("user"), 802 UTF8ToUTF16("user (at) gmail.com"), 0, std::string()); 803 804 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 805 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 806 OneClickSigninHelper::CanOfferOnIOThreadImpl( 807 valid_gaia_url_, std::string(), &request_, io_data.get())); 808 } 809 810 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadWithRejectedEmail) { 811 AddEmailToOneClickRejectedList("user (at) gmail.com"); 812 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 813 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 814 OneClickSigninHelper::CanOfferOnIOThreadImpl( 815 valid_gaia_url_, std::string(), &request_, io_data.get())); 816 } 817 818 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoSigninCookies) { 819 AllowSigninCookies(false); 820 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 821 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 822 OneClickSigninHelper::CanOfferOnIOThreadImpl( 823 valid_gaia_url_, std::string(), &request_, io_data.get())); 824 } 825 826 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabledByPolicy) { 827 scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false)); 828 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 829 OneClickSigninHelper::CanOfferOnIOThreadImpl( 830 valid_gaia_url_, std::string(), &request_, io_data.get())); 831 832 // Simulate a policy disabling signin by writing kSigninAllowed directly. 833 // We should not offer to sign in the browser. 834 profile()->GetTestingPrefService()->SetManagedPref( 835 prefs::kSigninAllowed, base::Value::CreateBooleanValue(false)); 836 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER, 837 OneClickSigninHelper::CanOfferOnIOThreadImpl( 838 valid_gaia_url_, std::string(), &request_, io_data.get())); 839 840 // Reset the preference. 841 profile()->GetTestingPrefService()->SetManagedPref( 842 prefs::kSigninAllowed, base::Value::CreateBooleanValue(true)); 843 844 // Simulate a policy disabling sync by writing kSyncManaged directly. 845 // We should still offer to sign in the browser. 846 profile()->GetTestingPrefService()->SetManagedPref( 847 prefs::kSyncManaged, base::Value::CreateBooleanValue(true)); 848 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER, 849 OneClickSigninHelper::CanOfferOnIOThreadImpl( 850 valid_gaia_url_, std::string(), &request_, io_data.get())); 851 } 852