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_service_factory.h"
27 #include "chrome/browser/sync/test_profile_sync_service.h"
28 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
29 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
30 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
33 #include "chrome/test/base/testing_browser_process.h"
34 #include "chrome/test/base/testing_pref_service_syncable.h"
35 #include "chrome/test/base/testing_profile.h"
36 #include "chrome/test/base/testing_profile_manager.h"
37 #include "components/autofill/core/common/password_form.h"
38 #include "components/signin/core/browser/profile_oauth2_token_service.h"
39 #include "components/signin/core/browser/signin_manager.h"
40 #include "components/sync_driver/pref_names.h"
41 #include "content/public/browser/browser_context.h"
42 #include "content/public/browser/navigation_details.h"
43 #include "content/public/browser/navigation_entry.h"
44 #include "content/public/browser/web_contents.h"
45 #include "content/public/browser/web_contents_delegate.h"
46 #include "content/public/common/frame_navigate_params.h"
47 #include "content/public/common/url_constants.h"
48 #include "content/public/test/mock_render_process_host.h"
49 #include "grit/chromium_strings.h"
50 #include "grit/generated_resources.h"
51 #include "testing/gmock/include/gmock/gmock.h"
52 #include "testing/gtest/include/gtest/gtest.h"
53 #include "ui/base/l10n/l10n_util.h"
56 using ::testing::AtLeast;
57 using ::testing::Return;
61 // Used to confirm OneClickSigninHelper does not trigger redirect when there is
62 // a pending navigation.
63 class MockWebContentsDelegate : public content::WebContentsDelegate {
65 MOCK_METHOD2(OpenURLFromTab,
66 content::WebContents*(content::WebContents* source,
67 const content::OpenURLParams& params));
70 class SigninManagerMock : public FakeSigninManager {
72 explicit SigninManagerMock(Profile* profile) : FakeSigninManager(profile) {
75 MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username));
78 static KeyedService* BuildSigninManagerMock(content::BrowserContext* profile) {
79 return new SigninManagerMock(static_cast<Profile*>(profile));
82 class TestProfileIOData : public ProfileIOData {
84 TestProfileIOData(Profile::ProfileType profile_type,
85 PrefService* pref_service, PrefService* local_state,
86 CookieSettings* cookie_settings)
87 : ProfileIOData(profile_type) {
88 // Initialize the IO members required for these tests, but keep them on
89 // this thread since we don't use a background thread here.
90 google_services_username()->Init(prefs::kGoogleServicesUsername,
92 reverse_autologin_enabled()->Init(prefs::kReverseAutologinEnabled,
94 one_click_signin_rejected_email_list()->Init(
95 prefs::kReverseAutologinRejectedEmailList, pref_service);
97 google_services_username_pattern()->Init(
98 prefs::kGoogleServicesUsernamePattern, local_state);
100 sync_disabled()->Init(sync_driver::prefs::kSyncManaged, pref_service);
102 signin_allowed()->Init(prefs::kSigninAllowed, pref_service);
104 set_signin_names_for_testing(new SigninNamesOnIOThread());
105 SetCookieSettingsForTesting(cookie_settings);
108 virtual ~TestProfileIOData() {
109 signin_names()->ReleaseResourcesOnUIThread();
112 // ProfileIOData overrides:
113 virtual void InitializeInternal(
114 ProfileParams* profile_params,
115 content::ProtocolHandlerMap* protocol_handlers,
116 content::ProtocolHandlerScopedVector protocol_interceptors)
120 virtual void InitializeExtensionsRequestContext(
121 ProfileParams* profile_params) const OVERRIDE {
124 virtual ChromeURLRequestContext* InitializeAppRequestContext(
125 ChromeURLRequestContext* main_context,
126 const StoragePartitionDescriptor& details,
127 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
128 protocol_handler_interceptor,
129 content::ProtocolHandlerMap* protocol_handlers,
130 content::ProtocolHandlerScopedVector protocol_interceptors)
135 virtual ChromeURLRequestContext* InitializeMediaRequestContext(
136 ChromeURLRequestContext* original_context,
137 const StoragePartitionDescriptor& details) const OVERRIDE {
141 virtual ChromeURLRequestContext*
142 AcquireMediaRequestContext() const OVERRIDE {
146 virtual ChromeURLRequestContext* AcquireIsolatedAppRequestContext(
147 ChromeURLRequestContext* main_context,
148 const StoragePartitionDescriptor& partition_descriptor,
149 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
150 protocol_handler_interceptor,
151 content::ProtocolHandlerMap* protocol_handlers,
152 content::ProtocolHandlerScopedVector protocol_interceptors)
157 virtual ChromeURLRequestContext*
158 AcquireIsolatedMediaRequestContext(
159 ChromeURLRequestContext* app_context,
160 const StoragePartitionDescriptor& partition_descriptor)
167 class TestURLRequest : public base::SupportsUserData {
170 virtual ~TestURLRequest() {}
173 class OneClickTestProfileSyncService : public TestProfileSyncService {
175 virtual ~OneClickTestProfileSyncService() {}
177 // Helper routine to be used in conjunction with
178 // BrowserContextKeyedServiceFactory::SetTestingFactory().
179 static KeyedService* Build(content::BrowserContext* profile) {
180 return new OneClickTestProfileSyncService(static_cast<Profile*>(profile));
183 // Need to control this for certain tests.
184 virtual bool FirstSetupInProgress() const OVERRIDE {
185 return first_setup_in_progress_;
188 virtual bool sync_initialized() const OVERRIDE { return sync_initialized_; }
190 // Controls return value of FirstSetupInProgress. Because some bits
191 // of UI depend on that value, it's useful to control it separately
192 // from the internal work and components that are triggered (such as
193 // ReconfigureDataTypeManager) to facilitate unit tests.
194 void set_first_setup_in_progress(bool in_progress) {
195 first_setup_in_progress_ = in_progress;
198 void set_sync_initialized(bool initialized) {
199 sync_initialized_ = initialized;
203 explicit OneClickTestProfileSyncService(Profile* profile)
204 : TestProfileSyncService(
207 SigninManagerFactory::GetForProfile(profile),
208 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
209 browser_sync::MANUAL_START),
210 first_setup_in_progress_(false),
211 sync_initialized_(false) {}
213 bool first_setup_in_progress_;
214 bool sync_initialized_;
219 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
221 OneClickSigninHelperTest();
223 virtual void SetUp() OVERRIDE;
224 virtual void TearDown() OVERRIDE;
226 // Sets up the sign-in manager for tests. If |username| is
227 // is not empty, the profile of the mock WebContents will be connected to
228 // the given account.
229 void SetUpSigninManager(const std::string& username);
231 // Set the ID of the signin process that the test will assume to be the
232 // only process allowed to sign the user in to Chrome.
233 void SetTrustedSigninProcessID(int id);
235 void AddEmailToOneClickRejectedList(const std::string& email);
236 void EnableOneClick(bool enable);
237 void AllowSigninCookies(bool enable);
238 void SetAllowedUsernamePattern(const std::string& pattern);
239 void SubmitGAIAPassword(OneClickSigninHelper* helper);
241 SigninManagerMock* signin_manager_;
242 FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
245 GoogleServiceAuthError no_error_;
248 // ChromeRenderViewHostTestHarness overrides:
249 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
251 // The ID of the signin process the test will assume to be trusted.
252 // By default, set to the test RenderProcessHost's process ID, but
253 // overridden by SetTrustedSigninProcessID.
254 int trusted_signin_process_id_;
256 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest);
259 OneClickSigninHelperTest::OneClickSigninHelperTest()
260 : signin_manager_(NULL),
261 fake_oauth2_token_service_(NULL),
262 no_error_(GoogleServiceAuthError::NONE),
263 trusted_signin_process_id_(-1) {
266 void OneClickSigninHelperTest::SetUp() {
267 signin::ForceWebBasedSigninFlowForTesting(true);
268 content::RenderViewHostTestHarness::SetUp();
269 SetTrustedSigninProcessID(process()->GetID());
272 void OneClickSigninHelperTest::TearDown() {
273 signin::ForceWebBasedSigninFlowForTesting(false);
274 content::RenderViewHostTestHarness::TearDown();
277 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) {
278 trusted_signin_process_id_ = id;
281 void OneClickSigninHelperTest::SetUpSigninManager(const std::string& username) {
282 ChromeSigninClient* signin_client =
283 ChromeSigninClientFactory::GetForProfile(profile());
285 signin_client->SetSigninProcess(trusted_signin_process_id_);
287 signin_manager_ = static_cast<SigninManagerMock*>(
288 SigninManagerFactory::GetForProfile(profile()));
289 if (!username.empty()) {
290 ASSERT_TRUE(signin_manager_);
291 signin_manager_->SetAuthenticatedUsername(username);
295 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
296 PrefService* pref_service = profile()->GetPrefs();
297 pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
300 void OneClickSigninHelperTest::AddEmailToOneClickRejectedList(
301 const std::string& email) {
302 PrefService* pref_service = profile()->GetPrefs();
303 ListPrefUpdate updater(pref_service,
304 prefs::kReverseAutologinRejectedEmailList);
305 updater->AppendIfNotPresent(new base::StringValue(email));
308 void OneClickSigninHelperTest::AllowSigninCookies(bool enable) {
309 CookieSettings* cookie_settings =
310 CookieSettings::Factory::GetForProfile(profile()).get();
311 cookie_settings->SetDefaultCookieSetting(enable ? CONTENT_SETTING_ALLOW
312 : CONTENT_SETTING_BLOCK);
315 void OneClickSigninHelperTest::SetAllowedUsernamePattern(
316 const std::string& pattern) {
317 PrefService* local_state = g_browser_process->local_state();
318 local_state->SetString(prefs::kGoogleServicesUsernamePattern, pattern);
321 void OneClickSigninHelperTest::SubmitGAIAPassword(
322 OneClickSigninHelper* helper) {
323 autofill::PasswordForm password_form;
324 password_form.origin = GURL("https://accounts.google.com");
325 password_form.signon_realm = "https://accounts.google.com";
326 password_form.password_value = base::UTF8ToUTF16("password");
327 helper->PasswordSubmitted(password_form);
330 content::BrowserContext* OneClickSigninHelperTest::CreateBrowserContext() {
331 TestingProfile::Builder builder;
332 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
333 BuildFakeProfileOAuth2TokenService);
334 builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
335 BuildSigninManagerMock);
336 scoped_ptr<TestingProfile> profile = builder.Build();
338 fake_oauth2_token_service_ =
339 static_cast<FakeProfileOAuth2TokenService*>(
340 ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get()));
342 return profile.release();
345 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest {
347 OneClickSigninHelperIOTest();
349 virtual void SetUp() OVERRIDE;
351 TestProfileIOData* CreateTestProfileIOData(Profile::ProfileType profile_type);
354 TestingProfileManager testing_profile_manager_;
355 TestURLRequest request_;
356 const GURL valid_gaia_url_;
359 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest);
362 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest()
363 : testing_profile_manager_(
364 TestingBrowserProcess::GetGlobal()),
365 valid_gaia_url_("https://accounts.google.com/") {
368 void OneClickSigninHelperIOTest::SetUp() {
369 OneClickSigninHelperTest::SetUp();
370 ASSERT_TRUE(testing_profile_manager_.SetUp());
373 TestProfileIOData* OneClickSigninHelperIOTest::CreateTestProfileIOData(
374 Profile::ProfileType profile_type) {
375 PrefService* pref_service = profile()->GetPrefs();
376 PrefService* local_state = g_browser_process->local_state();
377 CookieSettings* cookie_settings =
378 CookieSettings::Factory::GetForProfile(profile()).get();
379 TestProfileIOData* io_data = new TestProfileIOData(
380 profile_type, pref_service, local_state, cookie_settings);
381 io_data->set_reverse_autologin_pending_email("user@gmail.com");
385 class OneClickSigninHelperIncognitoTest : public OneClickSigninHelperTest {
387 // content::RenderViewHostTestHarness.
388 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
391 content::BrowserContext*
392 OneClickSigninHelperIncognitoTest::CreateBrowserContext() {
393 // Builds an incognito profile to run this test.
394 TestingProfile::Builder builder;
395 builder.SetIncognito();
396 return builder.Build().release();
399 TEST_F(OneClickSigninHelperTest, CanOfferNoContents) {
400 std::string error_message;
401 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
402 NULL, OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
403 "user@gmail.com", &error_message));
404 EXPECT_EQ("", error_message);
405 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
406 NULL, OneClickSigninHelper::CAN_OFFER_FOR_ALL,
407 "user@gmail.com", &error_message));
408 EXPECT_EQ("", error_message);
409 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
411 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
414 EXPECT_EQ("", error_message);
417 TEST_F(OneClickSigninHelperTest, CanOffer) {
418 SetUpSigninManager(std::string());
420 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
421 WillRepeatedly(Return(true));
423 EnableOneClick(true);
424 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
425 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
426 "user@gmail.com", NULL));
427 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
428 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
429 "user@gmail.com", NULL));
430 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
432 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
436 EnableOneClick(false);
438 std::string error_message;
439 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
440 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
441 "user@gmail.com", &error_message));
442 EXPECT_EQ("", error_message);
444 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
445 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
446 "user@gmail.com", &error_message));
447 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
449 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
452 EXPECT_EQ("", error_message);
455 TEST_F(OneClickSigninHelperTest, CanOfferFirstSetup) {
456 SetUpSigninManager(std::string());
458 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
459 WillRepeatedly(Return(true));
461 // Invoke OneClickTestProfileSyncService factory function and grab result.
462 OneClickTestProfileSyncService* sync =
463 static_cast<OneClickTestProfileSyncService*>(
464 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
465 profile(), OneClickTestProfileSyncService::Build));
466 sync->set_sync_initialized(false);
468 sync->set_sync_initialized(true);
469 sync->set_first_setup_in_progress(true);
471 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
473 OneClickSigninHelper::CAN_OFFER_FOR_ALL,
474 "foo@gmail.com", NULL));
475 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
477 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
478 "foo@gmail.com", NULL));
479 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
481 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
486 TEST_F(OneClickSigninHelperTest, CanOfferProfileConnected) {
487 SetUpSigninManager("foo@gmail.com");
489 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
490 WillRepeatedly(Return(true));
492 std::string error_message;
493 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
494 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
495 "foo@gmail.com", &error_message));
496 EXPECT_EQ("", error_message);
497 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
498 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
499 "foo", &error_message));
500 EXPECT_EQ("", error_message);
501 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
502 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
503 "user@gmail.com", &error_message));
504 EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL,
505 base::UTF8ToUTF16("foo@gmail.com")),
507 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
508 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
509 "foo@gmail.com", &error_message));
510 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
511 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
512 "foo", &error_message));
513 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
514 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
515 "user@gmail.com", &error_message));
516 EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL,
517 base::UTF8ToUTF16("foo@gmail.com")),
519 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
521 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
526 TEST_F(OneClickSigninHelperTest, CanOfferUsernameNotAllowed) {
527 SetUpSigninManager(std::string());
529 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
530 WillRepeatedly(Return(false));
532 std::string error_message;
533 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
534 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
535 "foo@gmail.com", &error_message));
536 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED),
538 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
539 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
540 "foo@gmail.com", &error_message));
541 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED),
543 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
545 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
550 TEST_F(OneClickSigninHelperTest, CanOfferWithRejectedEmail) {
551 SetUpSigninManager(std::string());
553 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
554 WillRepeatedly(Return(true));
556 AddEmailToOneClickRejectedList("foo@gmail.com");
557 AddEmailToOneClickRejectedList("user@gmail.com");
559 std::string error_message;
560 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
561 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
562 "foo@gmail.com", &error_message));
563 EXPECT_EQ("", error_message);
564 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
565 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
566 "user@gmail.com", &error_message));
567 EXPECT_EQ("", error_message);
568 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
569 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
570 "foo@gmail.com", &error_message));
571 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
572 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
573 "user@gmail.com", &error_message));
574 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
575 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
576 "john@gmail.com", &error_message));
579 TEST_F(OneClickSigninHelperIncognitoTest, CanOfferIncognito) {
580 SetUpSigninManager(std::string());
582 std::string error_message;
583 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
584 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
585 "user@gmail.com", &error_message));
586 EXPECT_EQ("", error_message);
587 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
588 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
589 "user@gmail.com", &error_message));
590 EXPECT_EQ("", error_message);
591 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
593 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
596 EXPECT_EQ("", error_message);
599 TEST_F(OneClickSigninHelperTest, CanOfferNoSigninCookies) {
600 SetUpSigninManager(std::string());
601 AllowSigninCookies(false);
603 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
604 WillRepeatedly(Return(true));
606 std::string error_message;
607 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
608 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
609 "user@gmail.com", &error_message));
610 EXPECT_EQ("", error_message);
611 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
612 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
613 "user@gmail.com", &error_message));
614 EXPECT_EQ("", error_message);
615 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
617 OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
620 EXPECT_EQ("", error_message);
623 TEST_F(OneClickSigninHelperTest, CanOfferDisabledByPolicy) {
624 SetUpSigninManager(std::string());
626 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
627 WillRepeatedly(Return(true));
629 EnableOneClick(true);
630 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
631 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
632 "user@gmail.com", NULL));
634 // Simulate a policy disabling signin by writing kSigninAllowed directly.
635 profile()->GetTestingPrefService()->SetManagedPref(
636 prefs::kSigninAllowed, base::Value::CreateBooleanValue(false));
638 EXPECT_FALSE(OneClickSigninHelper::CanOffer(
639 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
640 "user@gmail.com", NULL));
642 // Reset the preference value to true.
643 profile()->GetTestingPrefService()->SetManagedPref(
644 prefs::kSigninAllowed, base::Value::CreateBooleanValue(true));
646 // Simulate a policy disabling sync by writing kSyncManaged directly.
647 profile()->GetTestingPrefService()->SetManagedPref(
648 sync_driver::prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
650 // Should still offer even if sync is disabled by policy.
651 EXPECT_TRUE(OneClickSigninHelper::CanOffer(
652 web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
653 "user@gmail.com", NULL));
656 // Should not crash if a helper instance is not associated with an incognito
658 TEST_F(OneClickSigninHelperIncognitoTest, ShowInfoBarUIThreadIncognito) {
659 SetUpSigninManager(std::string());
660 OneClickSigninHelper* helper =
661 OneClickSigninHelper::FromWebContents(web_contents());
662 EXPECT_EQ(NULL, helper);
664 OneClickSigninHelper::ShowInfoBarUIThread(
665 "session_index", "email", OneClickSigninHelper::AUTO_ACCEPT_ACCEPTED,
666 signin::SOURCE_UNKNOWN, GURL(), process()->GetID(),
667 rvh()->GetRoutingID());
670 // If Chrome signin is triggered from a webstore install, and user chooses to
671 // config sync, then Chrome should redirect immediately to sync settings page,
672 // and upon successful setup, redirect back to webstore.
673 TEST_F(OneClickSigninHelperTest, SigninFromWebstoreWithConfigSyncfirst) {
674 SetUpSigninManager(std::string());
675 EXPECT_CALL(*signin_manager_, IsAllowedUsername(_))
676 .WillRepeatedly(Return(true));
678 OneClickTestProfileSyncService* sync_service =
679 static_cast<OneClickTestProfileSyncService*>(
680 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
681 profile(), OneClickTestProfileSyncService::Build));
682 sync_service->set_sync_initialized(true);
684 content::WebContents* contents = web_contents();
686 OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
687 OneClickSigninHelper* helper =
688 OneClickSigninHelper::FromWebContents(contents);
689 helper->SetDoNotClearPendingEmailForTesting();
690 helper->set_do_not_start_sync_for_testing();
692 GURL continueUrl("https://chrome.google.com/webstore?source=5");
693 OneClickSigninHelper::ShowInfoBarUIThread(
694 "session_index", "user@gmail.com",
695 OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT,
696 signin::SOURCE_WEBSTORE_INSTALL,
697 continueUrl, process()->GetID(), rvh()->GetRoutingID());
699 SubmitGAIAPassword(helper);
701 NavigateAndCommit(GURL("https://chrome.google.com/webstore?source=3"));
702 helper->DidStopLoading(rvh());
703 sync_service->NotifyObservers();
704 EXPECT_EQ(GURL(continueUrl), contents->GetVisibleURL());
707 // Checks that the state of OneClickSigninHelper is cleaned when there is a
708 // navigation away from the sign in flow that is not triggered by the
710 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) {
711 content::WebContents* contents = web_contents();
713 OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
714 OneClickSigninHelper* helper =
715 OneClickSigninHelper::FromWebContents(contents);
716 helper->SetDoNotClearPendingEmailForTesting();
717 helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT;
719 content::LoadCommittedDetails details;
720 content::FrameNavigateParams params;
721 params.url = GURL("http://crbug.com");
722 params.transition = content::PAGE_TRANSITION_TYPED;
723 helper->DidNavigateMainFrame(details, params);
725 EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_);
728 TEST_F(OneClickSigninHelperTest, NoRedirectToNTPWithPendingEntry) {
729 content::NavigationController& controller = web_contents()->GetController();
730 EXPECT_FALSE(controller.GetPendingEntry());
732 const GURL fooWebUIURL("chrome://foo");
733 controller.LoadURL(fooWebUIURL, content::Referrer(),
734 content::PAGE_TRANSITION_TYPED, std::string());
735 EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
737 MockWebContentsDelegate delegate;
738 EXPECT_CALL(delegate, OpenURLFromTab(_, _)).Times(0);
739 web_contents()->SetDelegate(&delegate);
740 OneClickSigninHelper::RedirectToNtpOrAppsPage(
741 web_contents(), signin::SOURCE_UNKNOWN);
743 EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
748 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThread) {
749 scoped_ptr<TestProfileIOData> io_data(
750 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
751 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
752 OneClickSigninHelper::CanOfferOnIOThreadImpl(
753 valid_gaia_url_, &request_, io_data.get()));
756 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadIncognito) {
757 scoped_ptr<TestProfileIOData> io_data(
758 CreateTestProfileIOData(Profile::INCOGNITO_PROFILE));
759 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
760 OneClickSigninHelper::CanOfferOnIOThreadImpl(
761 valid_gaia_url_, &request_, io_data.get()));
764 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) {
765 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
766 OneClickSigninHelper::CanOfferOnIOThreadImpl(
767 valid_gaia_url_, &request_, NULL));
770 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) {
771 scoped_ptr<TestProfileIOData> io_data(
772 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
774 OneClickSigninHelper::IGNORE_REQUEST,
775 OneClickSigninHelper::CanOfferOnIOThreadImpl(
776 GURL("https://foo.com/"), &request_, io_data.get()));
777 EXPECT_EQ(OneClickSigninHelper::IGNORE_REQUEST,
778 OneClickSigninHelper::CanOfferOnIOThreadImpl(
779 GURL("http://accounts.google.com/"),
784 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabled) {
785 EnableOneClick(false);
786 scoped_ptr<TestProfileIOData> io_data(
787 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
788 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
789 OneClickSigninHelper::CanOfferOnIOThreadImpl(
790 valid_gaia_url_, &request_, io_data.get()));
793 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
794 PrefService* pref_service = profile()->GetPrefs();
795 pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
797 scoped_ptr<TestProfileIOData> io_data(
798 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
799 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
800 OneClickSigninHelper::CanOfferOnIOThreadImpl(
801 valid_gaia_url_, &request_, io_data.get()));
804 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailNotAllowed) {
805 SetAllowedUsernamePattern("*@example.com");
806 scoped_ptr<TestProfileIOData> io_data(
807 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
808 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
809 OneClickSigninHelper::CanOfferOnIOThreadImpl(
810 valid_gaia_url_, &request_, io_data.get()));
813 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailAlreadyUsed) {
814 ProfileInfoCache* cache = testing_profile_manager_.profile_info_cache();
815 const base::FilePath& user_data_dir = cache->GetUserDataDir();
816 cache->AddProfileToCache(user_data_dir.Append(FILE_PATH_LITERAL("user")),
817 base::UTF8ToUTF16("user"),
818 base::UTF8ToUTF16("user@gmail.com"), 0,
821 scoped_ptr<TestProfileIOData> io_data(
822 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
823 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
824 OneClickSigninHelper::CanOfferOnIOThreadImpl(
825 valid_gaia_url_, &request_, io_data.get()));
828 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadWithRejectedEmail) {
829 AddEmailToOneClickRejectedList("user@gmail.com");
830 scoped_ptr<TestProfileIOData> io_data(
831 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
832 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
833 OneClickSigninHelper::CanOfferOnIOThreadImpl(
834 valid_gaia_url_, &request_, io_data.get()));
837 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoSigninCookies) {
838 AllowSigninCookies(false);
839 scoped_ptr<TestProfileIOData> io_data(
840 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
841 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
842 OneClickSigninHelper::CanOfferOnIOThreadImpl(
843 valid_gaia_url_, &request_, io_data.get()));
846 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabledByPolicy) {
847 scoped_ptr<TestProfileIOData> io_data(
848 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
849 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
850 OneClickSigninHelper::CanOfferOnIOThreadImpl(
851 valid_gaia_url_, &request_, io_data.get()));
853 // Simulate a policy disabling signin by writing kSigninAllowed directly.
854 // We should not offer to sign in the browser.
855 profile()->GetTestingPrefService()->SetManagedPref(
856 prefs::kSigninAllowed, base::Value::CreateBooleanValue(false));
857 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
858 OneClickSigninHelper::CanOfferOnIOThreadImpl(
859 valid_gaia_url_, &request_, io_data.get()));
861 // Reset the preference.
862 profile()->GetTestingPrefService()->SetManagedPref(
863 prefs::kSigninAllowed, base::Value::CreateBooleanValue(true));
865 // Simulate a policy disabling sync by writing kSyncManaged directly.
866 // We should still offer to sign in the browser.
867 profile()->GetTestingPrefService()->SetManagedPref(
868 sync_driver::prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
869 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
870 OneClickSigninHelper::CanOfferOnIOThreadImpl(
871 valid_gaia_url_, &request_, io_data.get()));
875 class MockStarterWrapper
876 : public testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper> {
879 const OneClickSigninHelper::StartSyncArgs& args,
880 OneClickSigninSyncStarter::StartSyncMode start_mode);
882 MOCK_METHOD1(DisplayErrorBubble, void(const std::string& error_message));
883 MOCK_METHOD0(StartSigninOAuthHelper, void());
884 MOCK_METHOD2(StartOneClickSigninSyncStarter,
885 void(const std::string& email,
886 const std::string& refresh_token));
889 MockStarterWrapper::MockStarterWrapper(
890 const OneClickSigninHelper::StartSyncArgs& args,
891 OneClickSigninSyncStarter::StartSyncMode start_mode)
892 : testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper>(
896 class OneClickSyncStarterWrapperTest : public testing::Test {
898 virtual void SetUp() OVERRIDE {
899 TestingProfile::Builder builder;
900 profile_ = builder.Build();
903 virtual void TearDown() OVERRIDE {
904 // Let the SyncStarterWrapper delete itself.
905 base::RunLoop().RunUntilIdle();
908 void SetCookie(const std::string& value) {
909 // Set a valid LSID cookie in the test cookie store.
910 scoped_refptr<net::CookieMonster> cookie_monster =
911 profile()->GetCookieMonster();
912 net::CookieOptions options;
913 options.set_include_httponly();
914 cookie_monster->SetCookieWithOptionsAsync(
915 GURL("https://accounts.google.com"),
917 net::CookieMonster::SetCookiesCallback());
920 void SimulateRefreshTokenFetched(
921 SigninOAuthHelper::Consumer* consumer,
922 const std::string& email,
923 const std::string& display_email,
924 const std::string& refresh_token) {
925 consumer->OnSigninOAuthInformationAvailable(
926 email, display_email, refresh_token);
929 TestingProfile* profile() { return profile_.get(); }
932 content::TestBrowserThreadBundle thread_bundle_;
933 scoped_ptr<TestingProfile> profile_;
936 TEST_F(OneClickSyncStarterWrapperTest, SignInWithRefreshToken) {
937 OneClickSigninHelper::StartSyncArgs args;
938 args.email = "foo@gmail.com";
939 args.password = "password";
940 args.refresh_token = "refresh_token";
941 MockStarterWrapper* wrapper = new MockStarterWrapper(
942 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
944 EXPECT_CALL(*wrapper,
945 StartOneClickSigninSyncStarter("foo@gmail.com",
950 TEST_F(OneClickSyncStarterWrapperTest, SignInWithPasswordNoRefreshToken) {
951 OneClickSigninHelper::StartSyncArgs args;
952 args.email = "foo@gmail.com";
953 args.password = "password";
954 MockStarterWrapper* wrapper = new MockStarterWrapper(
955 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
957 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
958 EXPECT_CALL(*wrapper,
959 StartOneClickSigninSyncStarter("foo@gmail.com",
962 SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
966 TEST_F(OneClickSyncStarterWrapperTest, SignInWithWrongEmail) {
967 OneClickSigninHelper::StartSyncArgs args;
968 args.email = "foo@gmail.com";
969 args.password = "password";
970 MockStarterWrapper* wrapper = new MockStarterWrapper(
971 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
973 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
974 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
976 SimulateRefreshTokenFetched(wrapper, "bar@gmail.com", "bar@gmail.com",
980 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordValidCookie) {
981 OneClickSigninHelper::StartSyncArgs args;
982 args.email = "foo@gmail.com";
983 args.profile = profile();
984 MockStarterWrapper* wrapper = new MockStarterWrapper(
985 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
986 SetCookie("LSID=1234; secure; httponly");
988 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
989 EXPECT_CALL(*wrapper,
990 StartOneClickSigninSyncStarter("foo@gmail.com",
993 base::RunLoop().RunUntilIdle();
994 SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
998 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordNoCookie) {
999 OneClickSigninHelper::StartSyncArgs args;
1000 args.email = "foo@gmail.com";
1001 args.profile = profile();
1002 MockStarterWrapper* wrapper = new MockStarterWrapper(
1003 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
1005 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
1007 base::RunLoop().RunUntilIdle();
1010 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordInvalidCookie) {
1011 OneClickSigninHelper::StartSyncArgs args;
1012 args.email = "foo@gmail.com";
1013 args.profile = profile();
1014 MockStarterWrapper* wrapper = new MockStarterWrapper(
1015 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
1016 SetCookie("LSID=1234; domain=google.com; secure; httponly");
1018 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
1020 base::RunLoop().RunUntilIdle();