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.
5 #include "base/prefs/pref_service.h"
6 #include "base/prefs/scoped_user_pref_update.h"
7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/content_settings/cookie_settings.h"
12 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_info_cache.h"
15 #include "chrome/browser/profiles/profile_io_data.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/signin/chrome_signin_client.h"
18 #include "chrome/browser/signin/chrome_signin_client_factory.h"
19 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
20 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
21 #include "chrome/browser/signin/fake_signin_manager.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager_factory.h"
24 #include "chrome/browser/signin/signin_names_io_thread.h"
25 #include "chrome/browser/signin/signin_promo.h"
26 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
27 #include "chrome/browser/sync/profile_sync_service_factory.h"
28 #include "chrome/browser/sync/test_profile_sync_service.h"
29 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
30 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
31 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
34 #include "chrome/test/base/testing_browser_process.h"
35 #include "chrome/test/base/testing_pref_service_syncable.h"
36 #include "chrome/test/base/testing_profile.h"
37 #include "chrome/test/base/testing_profile_manager.h"
38 #include "components/autofill/core/common/password_form.h"
39 #include "components/signin/core/browser/profile_oauth2_token_service.h"
40 #include "components/signin/core/browser/signin_manager.h"
41 #include "components/sync_driver/pref_names.h"
42 #include "content/public/browser/browser_context.h"
43 #include "content/public/browser/navigation_details.h"
44 #include "content/public/browser/navigation_entry.h"
45 #include "content/public/browser/web_contents.h"
46 #include "content/public/browser/web_contents_delegate.h"
47 #include "content/public/common/frame_navigate_params.h"
48 #include "content/public/common/url_constants.h"
49 #include "content/public/test/mock_render_process_host.h"
50 #include "grit/chromium_strings.h"
51 #include "grit/generated_resources.h"
52 #include "testing/gmock/include/gmock/gmock.h"
53 #include "testing/gtest/include/gtest/gtest.h"
54 #include "ui/base/l10n/l10n_util.h"
57 using ::testing::AtLeast;
58 using ::testing::Return;
62 // Used to confirm OneClickSigninHelper does not trigger redirect when there is
63 // a pending navigation.
64 class MockWebContentsDelegate : public content::WebContentsDelegate {
66 MOCK_METHOD2(OpenURLFromTab,
67 content::WebContents*(content::WebContents* source,
68 const content::OpenURLParams& params));
71 class SigninManagerMock : public FakeSigninManager {
73 explicit SigninManagerMock(Profile* profile) : FakeSigninManager(profile) {
76 MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username));
79 static KeyedService* BuildSigninManagerMock(content::BrowserContext* profile) {
80 return new SigninManagerMock(static_cast<Profile*>(profile));
83 class TestProfileIOData : public ProfileIOData {
85 TestProfileIOData(Profile::ProfileType profile_type,
86 PrefService* pref_service, PrefService* local_state,
87 CookieSettings* cookie_settings)
88 : ProfileIOData(profile_type) {
89 // Initialize the IO members required for these tests, but keep them on
90 // this thread since we don't use a background thread here.
91 google_services_username()->Init(prefs::kGoogleServicesUsername,
93 reverse_autologin_enabled()->Init(prefs::kReverseAutologinEnabled,
95 one_click_signin_rejected_email_list()->Init(
96 prefs::kReverseAutologinRejectedEmailList, pref_service);
98 google_services_username_pattern()->Init(
99 prefs::kGoogleServicesUsernamePattern, local_state);
101 sync_disabled()->Init(sync_driver::prefs::kSyncManaged, pref_service);
103 signin_allowed()->Init(prefs::kSigninAllowed, pref_service);
105 set_signin_names_for_testing(new SigninNamesOnIOThread());
106 SetCookieSettingsForTesting(cookie_settings);
109 virtual ~TestProfileIOData() {
110 signin_names()->ReleaseResourcesOnUIThread();
113 // ProfileIOData overrides:
114 virtual void InitializeInternal(
115 ProfileParams* profile_params,
116 content::ProtocolHandlerMap* protocol_handlers,
117 content::URLRequestInterceptorScopedVector request_interceptors)
121 virtual void InitializeExtensionsRequestContext(
122 ProfileParams* profile_params) const OVERRIDE {
125 virtual net::URLRequestContext* InitializeAppRequestContext(
126 net::URLRequestContext* main_context,
127 const StoragePartitionDescriptor& details,
128 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
129 protocol_handler_interceptor,
130 content::ProtocolHandlerMap* protocol_handlers,
131 content::URLRequestInterceptorScopedVector request_interceptors)
136 virtual net::URLRequestContext* InitializeMediaRequestContext(
137 net::URLRequestContext* original_context,
138 const StoragePartitionDescriptor& details) const OVERRIDE {
142 virtual net::URLRequestContext*
143 AcquireMediaRequestContext() const OVERRIDE {
147 virtual net::URLRequestContext* AcquireIsolatedAppRequestContext(
148 net::URLRequestContext* main_context,
149 const StoragePartitionDescriptor& partition_descriptor,
150 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
151 protocol_handler_interceptor,
152 content::ProtocolHandlerMap* protocol_handlers,
153 content::URLRequestInterceptorScopedVector request_interceptors)
158 virtual net::URLRequestContext*
159 AcquireIsolatedMediaRequestContext(
160 net::URLRequestContext* app_context,
161 const StoragePartitionDescriptor& partition_descriptor)
168 class TestURLRequest : public base::SupportsUserData {
171 virtual ~TestURLRequest() {}
174 class OneClickTestProfileSyncService : public TestProfileSyncService {
176 virtual ~OneClickTestProfileSyncService() {}
178 // Helper routine to be used in conjunction with
179 // BrowserContextKeyedServiceFactory::SetTestingFactory().
180 static KeyedService* Build(content::BrowserContext* profile) {
181 return new OneClickTestProfileSyncService(static_cast<Profile*>(profile));
184 // Need to control this for certain tests.
185 virtual bool FirstSetupInProgress() const OVERRIDE {
186 return first_setup_in_progress_;
189 virtual bool sync_initialized() const OVERRIDE { return sync_initialized_; }
191 // Controls return value of FirstSetupInProgress. Because some bits
192 // of UI depend on that value, it's useful to control it separately
193 // from the internal work and components that are triggered (such as
194 // ReconfigureDataTypeManager) to facilitate unit tests.
195 void set_first_setup_in_progress(bool in_progress) {
196 first_setup_in_progress_ = in_progress;
199 void set_sync_initialized(bool initialized) {
200 sync_initialized_ = initialized;
204 explicit OneClickTestProfileSyncService(Profile* profile)
205 : TestProfileSyncService(
206 scoped_ptr<ProfileSyncComponentsFactory>(
207 new ProfileSyncComponentsFactoryMock()),
209 SigninManagerFactory::GetForProfile(profile),
210 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
211 browser_sync::MANUAL_START),
212 first_setup_in_progress_(false),
213 sync_initialized_(false) {}
215 bool first_setup_in_progress_;
216 bool sync_initialized_;
221 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
223 OneClickSigninHelperTest();
225 virtual void SetUp() OVERRIDE;
226 virtual void TearDown() OVERRIDE;
228 // Sets up the sign-in manager for tests. If |username| is
229 // is not empty, the profile of the mock WebContents will be connected to
230 // the given account.
231 void SetUpSigninManager(const std::string& username);
233 // Set the ID of the signin process that the test will assume to be the
234 // only process allowed to sign the user in to Chrome.
235 void SetTrustedSigninProcessID(int id);
237 void AddEmailToOneClickRejectedList(const std::string& email);
238 void EnableOneClick(bool enable);
239 void AllowSigninCookies(bool enable);
240 void SetAllowedUsernamePattern(const std::string& pattern);
241 void SubmitGAIAPassword(OneClickSigninHelper* helper);
243 SigninManagerMock* signin_manager_;
244 FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
247 GoogleServiceAuthError no_error_;
250 // ChromeRenderViewHostTestHarness overrides:
251 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
253 // The ID of the signin process the test will assume to be trusted.
254 // By default, set to the test RenderProcessHost's process ID, but
255 // overridden by SetTrustedSigninProcessID.
256 int trusted_signin_process_id_;
258 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest);
261 OneClickSigninHelperTest::OneClickSigninHelperTest()
262 : signin_manager_(NULL),
263 fake_oauth2_token_service_(NULL),
264 no_error_(GoogleServiceAuthError::NONE),
265 trusted_signin_process_id_(-1) {
268 void OneClickSigninHelperTest::SetUp() {
269 signin::ForceWebBasedSigninFlowForTesting(true);
270 content::RenderViewHostTestHarness::SetUp();
271 SetTrustedSigninProcessID(process()->GetID());
274 void OneClickSigninHelperTest::TearDown() {
275 signin::ForceWebBasedSigninFlowForTesting(false);
276 content::RenderViewHostTestHarness::TearDown();
279 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) {
280 trusted_signin_process_id_ = id;
283 void OneClickSigninHelperTest::SetUpSigninManager(const std::string& username) {
284 SigninClient* signin_client =
285 ChromeSigninClientFactory::GetForProfile(profile());
287 signin_client->SetSigninProcess(trusted_signin_process_id_);
289 signin_manager_ = static_cast<SigninManagerMock*>(
290 SigninManagerFactory::GetForProfile(profile()));
291 if (!username.empty()) {
292 ASSERT_TRUE(signin_manager_);
293 signin_manager_->SetAuthenticatedUsername(username);
297 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
298 PrefService* pref_service = profile()->GetPrefs();
299 pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
302 void OneClickSigninHelperTest::AddEmailToOneClickRejectedList(
303 const std::string& email) {
304 PrefService* pref_service = profile()->GetPrefs();
305 ListPrefUpdate updater(pref_service,
306 prefs::kReverseAutologinRejectedEmailList);
307 updater->AppendIfNotPresent(new base::StringValue(email));
310 void OneClickSigninHelperTest::AllowSigninCookies(bool enable) {
311 CookieSettings* cookie_settings =
312 CookieSettings::Factory::GetForProfile(profile()).get();
313 cookie_settings->SetDefaultCookieSetting(enable ? CONTENT_SETTING_ALLOW
314 : CONTENT_SETTING_BLOCK);
317 void OneClickSigninHelperTest::SetAllowedUsernamePattern(
318 const std::string& pattern) {
319 PrefService* local_state = g_browser_process->local_state();
320 local_state->SetString(prefs::kGoogleServicesUsernamePattern, pattern);
323 void OneClickSigninHelperTest::SubmitGAIAPassword(
324 OneClickSigninHelper* helper) {
325 autofill::PasswordForm password_form;
326 password_form.origin = GURL("https://accounts.google.com");
327 password_form.signon_realm = "https://accounts.google.com";
328 password_form.password_value = base::UTF8ToUTF16("password");
329 helper->PasswordSubmitted(password_form);
332 content::BrowserContext* OneClickSigninHelperTest::CreateBrowserContext() {
333 TestingProfile::Builder builder;
334 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
335 BuildFakeProfileOAuth2TokenService);
336 builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
337 BuildSigninManagerMock);
338 scoped_ptr<TestingProfile> profile = builder.Build();
340 fake_oauth2_token_service_ =
341 static_cast<FakeProfileOAuth2TokenService*>(
342 ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get()));
344 return profile.release();
347 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest {
349 OneClickSigninHelperIOTest();
351 virtual void SetUp() OVERRIDE;
353 TestProfileIOData* CreateTestProfileIOData(Profile::ProfileType profile_type);
356 TestingProfileManager testing_profile_manager_;
357 TestURLRequest request_;
358 const GURL valid_gaia_url_;
361 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest);
364 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest()
365 : testing_profile_manager_(
366 TestingBrowserProcess::GetGlobal()),
367 valid_gaia_url_("https://accounts.google.com/") {
370 void OneClickSigninHelperIOTest::SetUp() {
371 OneClickSigninHelperTest::SetUp();
372 ASSERT_TRUE(testing_profile_manager_.SetUp());
375 TestProfileIOData* OneClickSigninHelperIOTest::CreateTestProfileIOData(
376 Profile::ProfileType profile_type) {
377 PrefService* pref_service = profile()->GetPrefs();
378 PrefService* local_state = g_browser_process->local_state();
379 CookieSettings* cookie_settings =
380 CookieSettings::Factory::GetForProfile(profile()).get();
381 TestProfileIOData* io_data = new TestProfileIOData(
382 profile_type, pref_service, local_state, cookie_settings);
383 io_data->set_reverse_autologin_pending_email("user@gmail.com");
387 class OneClickSigninHelperIncognitoTest : public OneClickSigninHelperTest {
389 // content::RenderViewHostTestHarness.
390 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
393 content::BrowserContext*
394 OneClickSigninHelperIncognitoTest::CreateBrowserContext() {
395 // Builds an incognito profile to run this test.
396 TestingProfile::Builder builder;
397 builder.SetIncognito();
398 return builder.Build().release();
401 TEST_F(OneClickSigninHelperTest, CanOfferNoContents) {
402 std::string error_message;
403 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
404 NULL, OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
405 "user@gmail.com", &error_message));
406 EXPECT_EQ("", error_message);
407 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
408 NULL, OneClickSigninHelper::CAN_OFFER_FOR_ALL,
409 "user@gmail.com", &error_message));
410 EXPECT_EQ("", error_message);
411 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
413 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
416 EXPECT_EQ("", error_message);
419 TEST_F(OneClickSigninHelperTest, CanOffer) {
420 SetUpSigninManager(std::string());
422 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
423 WillRepeatedly(Return(true));
425 EnableOneClick(true);
426 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
427 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
428 "user@gmail.com", NULL));
429 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
430 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
431 "user@gmail.com", NULL));
432 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
434 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
438 EnableOneClick(false);
440 std::string error_message;
441 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
442 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
443 "user@gmail.com", &error_message));
444 EXPECT_EQ("", error_message);
446 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
447 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
448 "user@gmail.com", &error_message));
449 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
451 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
454 EXPECT_EQ("", error_message);
457 TEST_F(OneClickSigninHelperTest, CanOfferFirstSetup) {
458 SetUpSigninManager(std::string());
460 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
461 WillRepeatedly(Return(true));
463 // Invoke OneClickTestProfileSyncService factory function and grab result.
464 OneClickTestProfileSyncService* sync =
465 static_cast<OneClickTestProfileSyncService*>(
466 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
467 profile(), OneClickTestProfileSyncService::Build));
468 sync->set_sync_initialized(false);
470 sync->set_sync_initialized(true);
471 sync->set_first_setup_in_progress(true);
473 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
475 OneClickSigninHelper::CAN_OFFER_FOR_ALL,
476 "foo@gmail.com", NULL));
477 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
479 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
480 "foo@gmail.com", NULL));
481 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
483 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
488 TEST_F(OneClickSigninHelperTest, CanOfferProfileConnected) {
489 SetUpSigninManager("foo@gmail.com");
491 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
492 WillRepeatedly(Return(true));
494 std::string error_message;
495 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
496 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
497 "foo@gmail.com", &error_message));
498 EXPECT_EQ("", error_message);
499 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
500 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
501 "foo", &error_message));
502 EXPECT_EQ("", error_message);
503 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
504 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
505 "user@gmail.com", &error_message));
506 EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL,
507 base::UTF8ToUTF16("foo@gmail.com")),
509 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
510 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
511 "foo@gmail.com", &error_message));
512 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
513 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
514 "foo", &error_message));
515 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
516 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
517 "user@gmail.com", &error_message));
518 EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL,
519 base::UTF8ToUTF16("foo@gmail.com")),
521 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
523 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
528 TEST_F(OneClickSigninHelperTest, CanOfferUsernameNotAllowed) {
529 SetUpSigninManager(std::string());
531 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
532 WillRepeatedly(Return(false));
534 std::string error_message;
535 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
536 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
537 "foo@gmail.com", &error_message));
538 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED),
540 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
541 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
542 "foo@gmail.com", &error_message));
543 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED),
545 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
547 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
552 TEST_F(OneClickSigninHelperTest, CanOfferWithRejectedEmail) {
553 SetUpSigninManager(std::string());
555 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
556 WillRepeatedly(Return(true));
558 AddEmailToOneClickRejectedList("foo@gmail.com");
559 AddEmailToOneClickRejectedList("user@gmail.com");
561 std::string error_message;
562 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
563 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
564 "foo@gmail.com", &error_message));
565 EXPECT_EQ("", error_message);
566 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
567 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
568 "user@gmail.com", &error_message));
569 EXPECT_EQ("", error_message);
570 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
571 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
572 "foo@gmail.com", &error_message));
573 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
574 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
575 "user@gmail.com", &error_message));
576 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
577 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
578 "john@gmail.com", &error_message));
581 TEST_F(OneClickSigninHelperIncognitoTest, CanOfferIncognito) {
582 SetUpSigninManager(std::string());
584 std::string error_message;
585 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
586 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
587 "user@gmail.com", &error_message));
588 EXPECT_EQ("", error_message);
589 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
590 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
591 "user@gmail.com", &error_message));
592 EXPECT_EQ("", error_message);
593 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
595 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
598 EXPECT_EQ("", error_message);
601 TEST_F(OneClickSigninHelperTest, CanOfferNoSigninCookies) {
602 SetUpSigninManager(std::string());
603 AllowSigninCookies(false);
605 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
606 WillRepeatedly(Return(true));
608 std::string error_message;
609 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
610 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
611 "user@gmail.com", &error_message));
612 EXPECT_EQ("", error_message);
613 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
614 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
615 "user@gmail.com", &error_message));
616 EXPECT_EQ("", error_message);
617 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
619 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
622 EXPECT_EQ("", error_message);
625 TEST_F(OneClickSigninHelperTest, CanOfferDisabledByPolicy) {
626 SetUpSigninManager(std::string());
628 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
629 WillRepeatedly(Return(true));
631 EnableOneClick(true);
632 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
633 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
634 "user@gmail.com", NULL));
636 // Simulate a policy disabling signin by writing kSigninAllowed directly.
637 profile()->GetTestingPrefService()->SetManagedPref(
638 prefs::kSigninAllowed, new base::FundamentalValue(false));
640 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
641 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
642 "user@gmail.com", NULL));
644 // Reset the preference value to true.
645 profile()->GetTestingPrefService()->SetManagedPref(
646 prefs::kSigninAllowed, new base::FundamentalValue(true));
648 // Simulate a policy disabling sync by writing kSyncManaged directly.
649 profile()->GetTestingPrefService()->SetManagedPref(
650 sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
652 // Should still offer even if sync is disabled by policy.
653 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
654 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
655 "user@gmail.com", NULL));
658 // Should not crash if a helper instance is not associated with an incognito
660 TEST_F(OneClickSigninHelperIncognitoTest, ShowInfoBarUIThreadIncognito) {
661 SetUpSigninManager(std::string());
662 OneClickSigninHelper* helper =
663 OneClickSigninHelper::FromWebContents(web_contents());
664 EXPECT_EQ(NULL, helper);
666 OneClickSigninHelper::ShowInfoBarUIThread(
667 "session_index", "email", OneClickSigninHelper::AUTO_ACCEPT_ACCEPTED,
668 signin::SOURCE_UNKNOWN, GURL(), process()->GetID(),
669 rvh()->GetRoutingID());
672 // If Chrome signin is triggered from a webstore install, and user chooses to
673 // config sync, then Chrome should redirect immediately to sync settings page,
674 // and upon successful setup, redirect back to webstore.
675 TEST_F(OneClickSigninHelperTest, SigninFromWebstoreWithConfigSyncfirst) {
676 SetUpSigninManager(std::string());
677 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_))
678 .WillRepeatedly(Return(true));
680 OneClickTestProfileSyncService* sync_service =
681 static_cast<OneClickTestProfileSyncService*>(
682 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
683 profile(), OneClickTestProfileSyncService::Build));
684 sync_service->set_sync_initialized(true);
686 content::WebContents* contents = web_contents();
688 OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
689 OneClickSigninHelper* helper =
690 OneClickSigninHelper::FromWebContents(contents);
691 helper->SetDoNotClearPendingEmailForTesting();
692 helper->set_do_not_start_sync_for_testing();
694 GURL continueUrl("https://chrome.google.com/webstore?source=5");
695 OneClickSigninHelper::ShowInfoBarUIThread(
696 "session_index", "user@gmail.com",
697 OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT,
698 signin::SOURCE_WEBSTORE_INSTALL,
699 continueUrl, process()->GetID(), rvh()->GetRoutingID());
701 SubmitGAIAPassword(helper);
703 NavigateAndCommit(GURL("https://chrome.google.com/webstore?source=3"));
704 helper->DidStopLoading(rvh());
705 sync_service->NotifyObservers();
706 EXPECT_EQ(GURL(continueUrl), contents->GetVisibleURL());
709 // Checks that the state of OneClickSigninHelper is cleaned when there is a
710 // navigation away from the sign in flow that is not triggered by the
712 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) {
713 content::WebContents* contents = web_contents();
715 OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
716 OneClickSigninHelper* helper =
717 OneClickSigninHelper::FromWebContents(contents);
718 helper->SetDoNotClearPendingEmailForTesting();
719 helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT;
721 content::LoadCommittedDetails details;
722 content::FrameNavigateParams params;
723 params.url = GURL("http://crbug.com");
724 params.transition = content::PAGE_TRANSITION_TYPED;
725 helper->DidNavigateMainFrame(details, params);
727 EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_);
730 TEST_F(OneClickSigninHelperTest, NoRedirectToNTPWithPendingEntry) {
731 content::NavigationController& controller = web_contents()->GetController();
732 EXPECT_FALSE(controller.GetPendingEntry());
734 const GURL fooWebUIURL("chrome://foo");
735 controller.LoadURL(fooWebUIURL, content::Referrer(),
736 content::PAGE_TRANSITION_TYPED, std::string());
737 EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
739 MockWebContentsDelegate delegate;
740 EXPECT_CALL(delegate, OpenURLFromTab(_, _)).Times(0);
741 web_contents()->SetDelegate(&delegate);
742 OneClickSigninHelper::RedirectToNtpOrAppsPage(
743 web_contents(), signin::SOURCE_UNKNOWN);
745 EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
750 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThread) {
751 scoped_ptr<TestProfileIOData> io_data(
752 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
753 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
754 OneClickSigninHelper::CanOfferOnIOThreadImpl(
755 valid_gaia_url_, &request_, io_data.get()));
758 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadIncognito) {
759 scoped_ptr<TestProfileIOData> io_data(
760 CreateTestProfileIOData(Profile::INCOGNITO_PROFILE));
761 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
762 OneClickSigninHelper::CanOfferOnIOThreadImpl(
763 valid_gaia_url_, &request_, io_data.get()));
766 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) {
767 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
768 OneClickSigninHelper::CanOfferOnIOThreadImpl(
769 valid_gaia_url_, &request_, NULL));
772 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) {
773 scoped_ptr<TestProfileIOData> io_data(
774 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
776 OneClickSigninHelper::IGNORE_REQUEST,
777 OneClickSigninHelper::CanOfferOnIOThreadImpl(
778 GURL("https://foo.com/"), &request_, io_data.get()));
779 EXPECT_EQ(OneClickSigninHelper::IGNORE_REQUEST,
780 OneClickSigninHelper::CanOfferOnIOThreadImpl(
781 GURL("http://accounts.google.com/"),
786 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabled) {
787 EnableOneClick(false);
788 scoped_ptr<TestProfileIOData> io_data(
789 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
790 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
791 OneClickSigninHelper::CanOfferOnIOThreadImpl(
792 valid_gaia_url_, &request_, io_data.get()));
795 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
796 PrefService* pref_service = profile()->GetPrefs();
797 pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
799 scoped_ptr<TestProfileIOData> io_data(
800 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
801 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
802 OneClickSigninHelper::CanOfferOnIOThreadImpl(
803 valid_gaia_url_, &request_, io_data.get()));
806 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailNotAllowed) {
807 SetAllowedUsernamePattern("*@example.com");
808 scoped_ptr<TestProfileIOData> io_data(
809 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
810 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
811 OneClickSigninHelper::CanOfferOnIOThreadImpl(
812 valid_gaia_url_, &request_, io_data.get()));
815 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailAlreadyUsed) {
816 ProfileInfoCache* cache = testing_profile_manager_.profile_info_cache();
817 const base::FilePath& user_data_dir = cache->GetUserDataDir();
818 cache->AddProfileToCache(user_data_dir.Append(FILE_PATH_LITERAL("user")),
819 base::UTF8ToUTF16("user"),
820 base::UTF8ToUTF16("user@gmail.com"), 0,
823 scoped_ptr<TestProfileIOData> io_data(
824 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
825 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
826 OneClickSigninHelper::CanOfferOnIOThreadImpl(
827 valid_gaia_url_, &request_, io_data.get()));
830 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadWithRejectedEmail) {
831 AddEmailToOneClickRejectedList("user@gmail.com");
832 scoped_ptr<TestProfileIOData> io_data(
833 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
834 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
835 OneClickSigninHelper::CanOfferOnIOThreadImpl(
836 valid_gaia_url_, &request_, io_data.get()));
839 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoSigninCookies) {
840 AllowSigninCookies(false);
841 scoped_ptr<TestProfileIOData> io_data(
842 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
843 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
844 OneClickSigninHelper::CanOfferOnIOThreadImpl(
845 valid_gaia_url_, &request_, io_data.get()));
848 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabledByPolicy) {
849 scoped_ptr<TestProfileIOData> io_data(
850 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
851 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
852 OneClickSigninHelper::CanOfferOnIOThreadImpl(
853 valid_gaia_url_, &request_, io_data.get()));
855 // Simulate a policy disabling signin by writing kSigninAllowed directly.
856 // We should not offer to sign in the browser.
857 profile()->GetTestingPrefService()->SetManagedPref(
858 prefs::kSigninAllowed, new base::FundamentalValue(false));
859 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
860 OneClickSigninHelper::CanOfferOnIOThreadImpl(
861 valid_gaia_url_, &request_, io_data.get()));
863 // Reset the preference.
864 profile()->GetTestingPrefService()->SetManagedPref(
865 prefs::kSigninAllowed, new base::FundamentalValue(true));
867 // Simulate a policy disabling sync by writing kSyncManaged directly.
868 // We should still offer to sign in the browser.
869 profile()->GetTestingPrefService()->SetManagedPref(
870 sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
871 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
872 OneClickSigninHelper::CanOfferOnIOThreadImpl(
873 valid_gaia_url_, &request_, io_data.get()));
877 class MockStarterWrapper
878 : public testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper> {
881 const OneClickSigninHelper::StartSyncArgs& args,
882 OneClickSigninSyncStarter::StartSyncMode start_mode);
884 MOCK_METHOD1(DisplayErrorBubble, void(const std::string& error_message));
885 MOCK_METHOD0(StartSigninOAuthHelper, void());
886 MOCK_METHOD2(StartOneClickSigninSyncStarter,
887 void(const std::string& email,
888 const std::string& refresh_token));
891 MockStarterWrapper::MockStarterWrapper(
892 const OneClickSigninHelper::StartSyncArgs& args,
893 OneClickSigninSyncStarter::StartSyncMode start_mode)
894 : testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper>(
898 class OneClickSyncStarterWrapperTest : public testing::Test {
900 virtual void SetUp() OVERRIDE {
901 TestingProfile::Builder builder;
902 profile_ = builder.Build();
905 virtual void TearDown() OVERRIDE {
906 // Let the SyncStarterWrapper delete itself.
907 base::RunLoop().RunUntilIdle();
910 void SetCookie(const std::string& value) {
911 // Set a valid LSID cookie in the test cookie store.
912 scoped_refptr<net::CookieMonster> cookie_monster =
913 profile()->GetCookieMonster();
914 net::CookieOptions options;
915 options.set_include_httponly();
916 cookie_monster->SetCookieWithOptionsAsync(
917 GURL("https://accounts.google.com"),
919 net::CookieMonster::SetCookiesCallback());
922 void SimulateRefreshTokenFetched(
923 SigninOAuthHelper::Consumer* consumer,
924 const std::string& email,
925 const std::string& display_email,
926 const std::string& refresh_token) {
927 consumer->OnSigninOAuthInformationAvailable(
928 email, display_email, refresh_token);
931 TestingProfile* profile() { return profile_.get(); }
934 content::TestBrowserThreadBundle thread_bundle_;
935 scoped_ptr<TestingProfile> profile_;
938 TEST_F(OneClickSyncStarterWrapperTest, SignInWithRefreshToken) {
939 OneClickSigninHelper::StartSyncArgs args;
940 args.email = "foo@gmail.com";
941 args.password = "password";
942 args.refresh_token = "refresh_token";
943 MockStarterWrapper* wrapper = new MockStarterWrapper(
944 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
946 EXPECT_CALL(*wrapper,
947 StartOneClickSigninSyncStarter("foo@gmail.com",
952 TEST_F(OneClickSyncStarterWrapperTest, SignInWithPasswordNoRefreshToken) {
953 OneClickSigninHelper::StartSyncArgs args;
954 args.email = "foo@gmail.com";
955 args.password = "password";
956 MockStarterWrapper* wrapper = new MockStarterWrapper(
957 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
959 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
960 EXPECT_CALL(*wrapper,
961 StartOneClickSigninSyncStarter("foo@gmail.com",
964 SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
968 TEST_F(OneClickSyncStarterWrapperTest, SignInWithWrongEmail) {
969 OneClickSigninHelper::StartSyncArgs args;
970 args.email = "foo@gmail.com";
971 args.password = "password";
972 MockStarterWrapper* wrapper = new MockStarterWrapper(
973 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
975 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
976 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
978 SimulateRefreshTokenFetched(wrapper, "bar@gmail.com", "bar@gmail.com",
982 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordValidCookie) {
983 OneClickSigninHelper::StartSyncArgs args;
984 args.email = "foo@gmail.com";
985 args.profile = profile();
986 MockStarterWrapper* wrapper = new MockStarterWrapper(
987 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
988 SetCookie("LSID=1234; secure; httponly");
990 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
991 EXPECT_CALL(*wrapper,
992 StartOneClickSigninSyncStarter("foo@gmail.com",
995 base::RunLoop().RunUntilIdle();
996 SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
1000 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordNoCookie) {
1001 OneClickSigninHelper::StartSyncArgs args;
1002 args.email = "foo@gmail.com";
1003 args.profile = profile();
1004 MockStarterWrapper* wrapper = new MockStarterWrapper(
1005 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
1007 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
1009 base::RunLoop().RunUntilIdle();
1012 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordInvalidCookie) {
1013 OneClickSigninHelper::StartSyncArgs args;
1014 args.email = "foo@gmail.com";
1015 args.profile = profile();
1016 MockStarterWrapper* wrapper = new MockStarterWrapper(
1017 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
1018 SetCookie("LSID=1234; domain=google.com; secure; httponly");
1020 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
1022 base::RunLoop().RunUntilIdle();