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/grit/chromium_strings.h"
34 #include "chrome/grit/generated_resources.h"
35 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
36 #include "chrome/test/base/testing_browser_process.h"
37 #include "chrome/test/base/testing_pref_service_syncable.h"
38 #include "chrome/test/base/testing_profile.h"
39 #include "chrome/test/base/testing_profile_manager.h"
40 #include "components/autofill/core/common/password_form.h"
41 #include "components/signin/core/browser/profile_oauth2_token_service.h"
42 #include "components/signin/core/browser/signin_manager.h"
43 #include "components/sync_driver/pref_names.h"
44 #include "content/public/browser/browser_context.h"
45 #include "content/public/browser/navigation_details.h"
46 #include "content/public/browser/navigation_entry.h"
47 #include "content/public/browser/web_contents.h"
48 #include "content/public/browser/web_contents_delegate.h"
49 #include "content/public/common/frame_navigate_params.h"
50 #include "content/public/common/url_constants.h"
51 #include "content/public/test/mock_render_process_host.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 ~TestProfileIOData() override {
110 signin_names()->ReleaseResourcesOnUIThread();
113 // ProfileIOData overrides:
114 void InitializeInternal(ProfileParams* profile_params,
115 content::ProtocolHandlerMap* protocol_handlers,
116 content::URLRequestInterceptorScopedVector
117 request_interceptors) const override {
120 void InitializeExtensionsRequestContext(
121 ProfileParams* profile_params) const override {
124 net::URLRequestContext* InitializeAppRequestContext(
125 net::URLRequestContext* main_context,
126 const StoragePartitionDescriptor& details,
127 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
128 protocol_handler_interceptor,
129 content::ProtocolHandlerMap* protocol_handlers,
130 content::URLRequestInterceptorScopedVector request_interceptors)
135 net::URLRequestContext* InitializeMediaRequestContext(
136 net::URLRequestContext* original_context,
137 const StoragePartitionDescriptor& details) const override {
141 net::URLRequestContext* AcquireMediaRequestContext() const override {
145 net::URLRequestContext* AcquireIsolatedAppRequestContext(
146 net::URLRequestContext* main_context,
147 const StoragePartitionDescriptor& partition_descriptor,
148 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
149 protocol_handler_interceptor,
150 content::ProtocolHandlerMap* protocol_handlers,
151 content::URLRequestInterceptorScopedVector request_interceptors)
156 net::URLRequestContext* AcquireIsolatedMediaRequestContext(
157 net::URLRequestContext* app_context,
158 const StoragePartitionDescriptor& partition_descriptor) const override {
164 class TestURLRequest : public base::SupportsUserData {
167 ~TestURLRequest() override {}
170 class OneClickTestProfileSyncService : public TestProfileSyncService {
172 ~OneClickTestProfileSyncService() override {}
174 // Helper routine to be used in conjunction with
175 // BrowserContextKeyedServiceFactory::SetTestingFactory().
176 static KeyedService* Build(content::BrowserContext* profile) {
177 return new OneClickTestProfileSyncService(static_cast<Profile*>(profile));
180 // Need to control this for certain tests.
181 bool FirstSetupInProgress() const override {
182 return first_setup_in_progress_;
185 bool SyncActive() const override { return sync_active_; }
187 // Controls return value of FirstSetupInProgress. Because some bits
188 // of UI depend on that value, it's useful to control it separately
189 // from the internal work and components that are triggered (such as
190 // ReconfigureDataTypeManager) to facilitate unit tests.
191 void set_first_setup_in_progress(bool in_progress) {
192 first_setup_in_progress_ = in_progress;
195 void set_sync_active(bool active) {
196 sync_active_ = active;
200 explicit OneClickTestProfileSyncService(Profile* profile)
201 : TestProfileSyncService(
202 scoped_ptr<ProfileSyncComponentsFactory>(
203 new ProfileSyncComponentsFactoryMock()),
205 SigninManagerFactory::GetForProfile(profile),
206 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
207 browser_sync::MANUAL_START),
208 first_setup_in_progress_(false),
209 sync_active_(false) {}
211 bool first_setup_in_progress_;
217 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
219 OneClickSigninHelperTest();
221 void SetUp() override;
222 void TearDown() override;
224 // Sets up the sign-in manager for tests. If |username| is
225 // is not empty, the profile of the mock WebContents will be connected to
226 // the given account.
227 void SetUpSigninManager(const std::string& username);
229 // Set the ID of the signin process that the test will assume to be the
230 // only process allowed to sign the user in to Chrome.
231 void SetTrustedSigninProcessID(int id);
233 void AddEmailToOneClickRejectedList(const std::string& email);
234 void EnableOneClick(bool enable);
235 void AllowSigninCookies(bool enable);
236 void SetAllowedUsernamePattern(const std::string& pattern);
237 void SubmitGAIAPassword(OneClickSigninHelper* helper);
239 SigninManagerMock* signin_manager_;
240 FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
243 GoogleServiceAuthError no_error_;
246 // ChromeRenderViewHostTestHarness overrides:
247 content::BrowserContext* CreateBrowserContext() override;
249 // The ID of the signin process the test will assume to be trusted.
250 // By default, set to the test RenderProcessHost's process ID, but
251 // overridden by SetTrustedSigninProcessID.
252 int trusted_signin_process_id_;
254 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest);
257 OneClickSigninHelperTest::OneClickSigninHelperTest()
258 : signin_manager_(NULL),
259 fake_oauth2_token_service_(NULL),
260 no_error_(GoogleServiceAuthError::NONE),
261 trusted_signin_process_id_(-1) {
264 void OneClickSigninHelperTest::SetUp() {
265 signin::ForceWebBasedSigninFlowForTesting(true);
266 content::RenderViewHostTestHarness::SetUp();
267 SetTrustedSigninProcessID(process()->GetID());
270 void OneClickSigninHelperTest::TearDown() {
271 signin::ForceWebBasedSigninFlowForTesting(false);
272 content::RenderViewHostTestHarness::TearDown();
275 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) {
276 trusted_signin_process_id_ = id;
279 void OneClickSigninHelperTest::SetUpSigninManager(const std::string& username) {
280 SigninClient* signin_client =
281 ChromeSigninClientFactory::GetForProfile(profile());
283 signin_client->SetSigninProcess(trusted_signin_process_id_);
285 signin_manager_ = static_cast<SigninManagerMock*>(
286 SigninManagerFactory::GetForProfile(profile()));
287 if (!username.empty()) {
288 ASSERT_TRUE(signin_manager_);
289 signin_manager_->SetAuthenticatedUsername(username);
293 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
294 PrefService* pref_service = profile()->GetPrefs();
295 pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
298 void OneClickSigninHelperTest::AddEmailToOneClickRejectedList(
299 const std::string& email) {
300 PrefService* pref_service = profile()->GetPrefs();
301 ListPrefUpdate updater(pref_service,
302 prefs::kReverseAutologinRejectedEmailList);
303 updater->AppendIfNotPresent(new base::StringValue(email));
306 void OneClickSigninHelperTest::AllowSigninCookies(bool enable) {
307 CookieSettings* cookie_settings =
308 CookieSettings::Factory::GetForProfile(profile()).get();
309 cookie_settings->SetDefaultCookieSetting(enable ? CONTENT_SETTING_ALLOW
310 : CONTENT_SETTING_BLOCK);
313 void OneClickSigninHelperTest::SetAllowedUsernamePattern(
314 const std::string& pattern) {
315 PrefService* local_state = g_browser_process->local_state();
316 local_state->SetString(prefs::kGoogleServicesUsernamePattern, pattern);
319 void OneClickSigninHelperTest::SubmitGAIAPassword(
320 OneClickSigninHelper* helper) {
321 autofill::PasswordForm password_form;
322 password_form.origin = GURL("https://accounts.google.com");
323 password_form.signon_realm = "https://accounts.google.com";
324 password_form.password_value = base::UTF8ToUTF16("password");
325 helper->PasswordSubmitted(password_form);
328 content::BrowserContext* OneClickSigninHelperTest::CreateBrowserContext() {
329 TestingProfile::Builder builder;
330 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
331 BuildFakeProfileOAuth2TokenService);
332 builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
333 BuildSigninManagerMock);
334 scoped_ptr<TestingProfile> profile = builder.Build();
336 fake_oauth2_token_service_ =
337 static_cast<FakeProfileOAuth2TokenService*>(
338 ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get()));
340 return profile.release();
343 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest {
345 OneClickSigninHelperIOTest();
347 void SetUp() override;
349 TestProfileIOData* CreateTestProfileIOData(Profile::ProfileType profile_type);
352 TestingProfileManager testing_profile_manager_;
353 TestURLRequest request_;
354 const GURL valid_gaia_url_;
357 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest);
360 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest()
361 : testing_profile_manager_(
362 TestingBrowserProcess::GetGlobal()),
363 valid_gaia_url_("https://accounts.google.com/") {
366 void OneClickSigninHelperIOTest::SetUp() {
367 OneClickSigninHelperTest::SetUp();
368 ASSERT_TRUE(testing_profile_manager_.SetUp());
371 TestProfileIOData* OneClickSigninHelperIOTest::CreateTestProfileIOData(
372 Profile::ProfileType profile_type) {
373 PrefService* pref_service = profile()->GetPrefs();
374 PrefService* local_state = g_browser_process->local_state();
375 CookieSettings* cookie_settings =
376 CookieSettings::Factory::GetForProfile(profile()).get();
377 TestProfileIOData* io_data = new TestProfileIOData(
378 profile_type, pref_service, local_state, cookie_settings);
379 io_data->set_reverse_autologin_pending_email("user@gmail.com");
383 class OneClickSigninHelperIncognitoTest : public OneClickSigninHelperTest {
385 // content::RenderViewHostTestHarness.
386 content::BrowserContext* CreateBrowserContext() override;
389 content::BrowserContext*
390 OneClickSigninHelperIncognitoTest::CreateBrowserContext() {
391 // Simulate an incognito profile to run this test. RenderViewHostTestHarness
392 // takes ownership of the return value, so it can't be a "proper" incognito
393 // profile, since they are owned by their parent, non-incognito profile.
394 scoped_ptr<TestingProfile> profile = TestingProfile::Builder().Build();
395 profile->ForceIncognito(true);
396 return profile.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_active(false);
468 sync->set_sync_active(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, new base::FundamentalValue(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, new base::FundamentalValue(true));
646 // Simulate a policy disabling sync by writing kSyncManaged directly.
647 profile()->GetTestingPrefService()->SetManagedPref(
648 sync_driver::prefs::kSyncManaged, new base::FundamentalValue(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 // Checks that the state of OneClickSigninHelper is cleaned when there is a
671 // navigation away from the sign in flow that is not triggered by the
673 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) {
674 content::WebContents* contents = web_contents();
676 OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
677 OneClickSigninHelper* helper =
678 OneClickSigninHelper::FromWebContents(contents);
679 helper->SetDoNotClearPendingEmailForTesting();
680 helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT;
682 content::LoadCommittedDetails details;
683 content::FrameNavigateParams params;
684 params.url = GURL("http://crbug.com");
685 params.transition = ui::PAGE_TRANSITION_TYPED;
686 helper->DidNavigateMainFrame(details, params);
688 EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_);
691 TEST_F(OneClickSigninHelperTest, NoRedirectToNTPWithPendingEntry) {
692 content::NavigationController& controller = web_contents()->GetController();
693 EXPECT_FALSE(controller.GetPendingEntry());
695 const GURL fooWebUIURL("chrome://foo");
696 controller.LoadURL(fooWebUIURL, content::Referrer(),
697 ui::PAGE_TRANSITION_TYPED, std::string());
698 EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
700 MockWebContentsDelegate delegate;
701 EXPECT_CALL(delegate, OpenURLFromTab(_, _)).Times(0);
702 web_contents()->SetDelegate(&delegate);
703 OneClickSigninHelper::RedirectToNtpOrAppsPage(
704 web_contents(), signin::SOURCE_UNKNOWN);
706 EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
711 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThread) {
712 scoped_ptr<TestProfileIOData> io_data(
713 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
714 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
715 OneClickSigninHelper::CanOfferOnIOThreadImpl(
716 valid_gaia_url_, &request_, io_data.get()));
719 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadIncognito) {
720 scoped_ptr<TestProfileIOData> io_data(
721 CreateTestProfileIOData(Profile::INCOGNITO_PROFILE));
722 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
723 OneClickSigninHelper::CanOfferOnIOThreadImpl(
724 valid_gaia_url_, &request_, io_data.get()));
727 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) {
728 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
729 OneClickSigninHelper::CanOfferOnIOThreadImpl(
730 valid_gaia_url_, &request_, NULL));
733 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) {
734 scoped_ptr<TestProfileIOData> io_data(
735 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
737 OneClickSigninHelper::IGNORE_REQUEST,
738 OneClickSigninHelper::CanOfferOnIOThreadImpl(
739 GURL("https://foo.com/"), &request_, io_data.get()));
740 EXPECT_EQ(OneClickSigninHelper::IGNORE_REQUEST,
741 OneClickSigninHelper::CanOfferOnIOThreadImpl(
742 GURL("http://accounts.google.com/"),
747 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabled) {
748 EnableOneClick(false);
749 scoped_ptr<TestProfileIOData> io_data(
750 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
751 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
752 OneClickSigninHelper::CanOfferOnIOThreadImpl(
753 valid_gaia_url_, &request_, io_data.get()));
756 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
757 PrefService* pref_service = profile()->GetPrefs();
758 pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
760 scoped_ptr<TestProfileIOData> io_data(
761 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
762 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
763 OneClickSigninHelper::CanOfferOnIOThreadImpl(
764 valid_gaia_url_, &request_, io_data.get()));
767 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailNotAllowed) {
768 SetAllowedUsernamePattern("*@example.com");
769 scoped_ptr<TestProfileIOData> io_data(
770 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
771 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
772 OneClickSigninHelper::CanOfferOnIOThreadImpl(
773 valid_gaia_url_, &request_, io_data.get()));
776 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailAlreadyUsed) {
777 ProfileInfoCache* cache = testing_profile_manager_.profile_info_cache();
778 const base::FilePath& user_data_dir = cache->GetUserDataDir();
779 cache->AddProfileToCache(user_data_dir.Append(FILE_PATH_LITERAL("user")),
780 base::UTF8ToUTF16("user"),
781 base::UTF8ToUTF16("user@gmail.com"), 0,
784 scoped_ptr<TestProfileIOData> io_data(
785 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
786 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
787 OneClickSigninHelper::CanOfferOnIOThreadImpl(
788 valid_gaia_url_, &request_, io_data.get()));
791 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadWithRejectedEmail) {
792 AddEmailToOneClickRejectedList("user@gmail.com");
793 scoped_ptr<TestProfileIOData> io_data(
794 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
795 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
796 OneClickSigninHelper::CanOfferOnIOThreadImpl(
797 valid_gaia_url_, &request_, io_data.get()));
800 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoSigninCookies) {
801 AllowSigninCookies(false);
802 scoped_ptr<TestProfileIOData> io_data(
803 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
804 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
805 OneClickSigninHelper::CanOfferOnIOThreadImpl(
806 valid_gaia_url_, &request_, io_data.get()));
809 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabledByPolicy) {
810 scoped_ptr<TestProfileIOData> io_data(
811 CreateTestProfileIOData(Profile::REGULAR_PROFILE));
812 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
813 OneClickSigninHelper::CanOfferOnIOThreadImpl(
814 valid_gaia_url_, &request_, io_data.get()));
816 // Simulate a policy disabling signin by writing kSigninAllowed directly.
817 // We should not offer to sign in the browser.
818 profile()->GetTestingPrefService()->SetManagedPref(
819 prefs::kSigninAllowed, new base::FundamentalValue(false));
820 EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
821 OneClickSigninHelper::CanOfferOnIOThreadImpl(
822 valid_gaia_url_, &request_, io_data.get()));
824 // Reset the preference.
825 profile()->GetTestingPrefService()->SetManagedPref(
826 prefs::kSigninAllowed, new base::FundamentalValue(true));
828 // Simulate a policy disabling sync by writing kSyncManaged directly.
829 // We should still offer to sign in the browser.
830 profile()->GetTestingPrefService()->SetManagedPref(
831 sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
832 EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
833 OneClickSigninHelper::CanOfferOnIOThreadImpl(
834 valid_gaia_url_, &request_, io_data.get()));
838 class MockStarterWrapper
839 : public testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper> {
842 const OneClickSigninHelper::StartSyncArgs& args,
843 OneClickSigninSyncStarter::StartSyncMode start_mode);
845 MOCK_METHOD1(DisplayErrorBubble, void(const std::string& error_message));
846 MOCK_METHOD0(StartSigninOAuthHelper, void());
847 MOCK_METHOD2(StartOneClickSigninSyncStarter,
848 void(const std::string& email,
849 const std::string& refresh_token));
852 MockStarterWrapper::MockStarterWrapper(
853 const OneClickSigninHelper::StartSyncArgs& args,
854 OneClickSigninSyncStarter::StartSyncMode start_mode)
855 : testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper>(
859 class OneClickSyncStarterWrapperTest : public testing::Test {
861 void SetUp() override {
862 TestingProfile::Builder builder;
863 profile_ = builder.Build();
866 void TearDown() override {
867 // Let the SyncStarterWrapper delete itself.
868 base::RunLoop().RunUntilIdle();
871 void SetCookie(const std::string& value) {
872 // Set a valid LSID cookie in the test cookie store.
873 scoped_refptr<net::CookieMonster> cookie_monster =
874 profile()->GetCookieMonster();
875 net::CookieOptions options;
876 options.set_include_httponly();
877 cookie_monster->SetCookieWithOptionsAsync(
878 GURL("https://accounts.google.com"),
880 net::CookieMonster::SetCookiesCallback());
883 void SimulateRefreshTokenFetched(
884 SigninOAuthHelper::Consumer* consumer,
885 const std::string& email,
886 const std::string& display_email,
887 const std::string& refresh_token) {
888 consumer->OnSigninOAuthInformationAvailable(
889 email, display_email, refresh_token);
892 TestingProfile* profile() { return profile_.get(); }
895 content::TestBrowserThreadBundle thread_bundle_;
896 scoped_ptr<TestingProfile> profile_;
899 TEST_F(OneClickSyncStarterWrapperTest, SignInWithRefreshToken) {
900 OneClickSigninHelper::StartSyncArgs args;
901 args.email = "foo@gmail.com";
902 args.password = "password";
903 args.refresh_token = "refresh_token";
904 MockStarterWrapper* wrapper = new MockStarterWrapper(
905 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
907 EXPECT_CALL(*wrapper,
908 StartOneClickSigninSyncStarter("foo@gmail.com",
913 TEST_F(OneClickSyncStarterWrapperTest, SignInWithPasswordNoRefreshToken) {
914 OneClickSigninHelper::StartSyncArgs args;
915 args.email = "foo@gmail.com";
916 args.password = "password";
917 MockStarterWrapper* wrapper = new MockStarterWrapper(
918 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
920 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
921 EXPECT_CALL(*wrapper,
922 StartOneClickSigninSyncStarter("foo@gmail.com",
925 SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
929 TEST_F(OneClickSyncStarterWrapperTest, SignInWithWrongEmail) {
930 OneClickSigninHelper::StartSyncArgs args;
931 args.email = "foo@gmail.com";
932 args.password = "password";
933 MockStarterWrapper* wrapper = new MockStarterWrapper(
934 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
936 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
937 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
939 SimulateRefreshTokenFetched(wrapper, "bar@gmail.com", "bar@gmail.com",
943 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordValidCookie) {
944 OneClickSigninHelper::StartSyncArgs args;
945 args.email = "foo@gmail.com";
946 args.profile = profile();
947 MockStarterWrapper* wrapper = new MockStarterWrapper(
948 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
949 SetCookie("LSID=1234; secure; httponly");
951 EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
952 EXPECT_CALL(*wrapper,
953 StartOneClickSigninSyncStarter("foo@gmail.com",
956 base::RunLoop().RunUntilIdle();
957 SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
961 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordNoCookie) {
962 OneClickSigninHelper::StartSyncArgs args;
963 args.email = "foo@gmail.com";
964 args.profile = profile();
965 MockStarterWrapper* wrapper = new MockStarterWrapper(
966 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
968 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
970 base::RunLoop().RunUntilIdle();
973 TEST_F(OneClickSyncStarterWrapperTest, SignInWithEmptyPasswordInvalidCookie) {
974 OneClickSigninHelper::StartSyncArgs args;
975 args.email = "foo@gmail.com";
976 args.profile = profile();
977 MockStarterWrapper* wrapper = new MockStarterWrapper(
978 args, OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS);
979 SetCookie("LSID=1234; domain=google.com; secure; httponly");
981 EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
983 base::RunLoop().RunUntilIdle();