Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / sync / one_click_signin_helper_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/prefs/pref_service.h"
6 #include "base/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"
55
56 using ::testing::_;
57 using ::testing::AtLeast;
58 using ::testing::Return;
59
60 namespace {
61
62 // Used to confirm OneClickSigninHelper does not trigger redirect when there is
63 // a pending navigation.
64 class MockWebContentsDelegate : public content::WebContentsDelegate {
65  public:
66    MOCK_METHOD2(OpenURLFromTab,
67                 content::WebContents*(content::WebContents* source,
68                                       const content::OpenURLParams& params));
69 };
70
71 class SigninManagerMock : public FakeSigninManager {
72  public:
73   explicit SigninManagerMock(Profile* profile) : FakeSigninManager(profile) {
74     Initialize(NULL);
75   }
76   MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username));
77 };
78
79 static KeyedService* BuildSigninManagerMock(content::BrowserContext* profile) {
80   return new SigninManagerMock(static_cast<Profile*>(profile));
81 }
82
83 class TestProfileIOData : public ProfileIOData {
84  public:
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,
92                                      pref_service);
93     reverse_autologin_enabled()->Init(prefs::kReverseAutologinEnabled,
94                                       pref_service);
95     one_click_signin_rejected_email_list()->Init(
96         prefs::kReverseAutologinRejectedEmailList, pref_service);
97
98     google_services_username_pattern()->Init(
99         prefs::kGoogleServicesUsernamePattern, local_state);
100
101     sync_disabled()->Init(sync_driver::prefs::kSyncManaged, pref_service);
102
103     signin_allowed()->Init(prefs::kSigninAllowed, pref_service);
104
105     set_signin_names_for_testing(new SigninNamesOnIOThread());
106     SetCookieSettingsForTesting(cookie_settings);
107   }
108
109   virtual ~TestProfileIOData() {
110     signin_names()->ReleaseResourcesOnUIThread();
111   }
112
113   // ProfileIOData overrides:
114   virtual void InitializeInternal(
115       ProfileParams* profile_params,
116       content::ProtocolHandlerMap* protocol_handlers,
117       content::URLRequestInterceptorScopedVector request_interceptors)
118       const OVERRIDE {
119     NOTREACHED();
120   }
121   virtual void InitializeExtensionsRequestContext(
122       ProfileParams* profile_params) const OVERRIDE {
123     NOTREACHED();
124   }
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)
132       const OVERRIDE {
133     NOTREACHED();
134     return NULL;
135   }
136   virtual net::URLRequestContext* InitializeMediaRequestContext(
137       net::URLRequestContext* original_context,
138       const StoragePartitionDescriptor& details) const OVERRIDE {
139     NOTREACHED();
140     return NULL;
141   }
142   virtual net::URLRequestContext*
143       AcquireMediaRequestContext() const OVERRIDE {
144     NOTREACHED();
145     return NULL;
146   }
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)
154       const OVERRIDE {
155     NOTREACHED();
156     return NULL;
157   }
158   virtual net::URLRequestContext*
159       AcquireIsolatedMediaRequestContext(
160           net::URLRequestContext* app_context,
161           const StoragePartitionDescriptor& partition_descriptor)
162           const OVERRIDE {
163     NOTREACHED();
164     return NULL;
165   }
166 };
167
168 class TestURLRequest : public base::SupportsUserData {
169 public:
170   TestURLRequest() {}
171   virtual ~TestURLRequest() {}
172 };
173
174 class OneClickTestProfileSyncService : public TestProfileSyncService {
175  public:
176   virtual ~OneClickTestProfileSyncService() {}
177
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));
182   }
183
184   // Need to control this for certain tests.
185   virtual bool FirstSetupInProgress() const OVERRIDE {
186     return first_setup_in_progress_;
187   }
188
189   virtual bool sync_initialized() const OVERRIDE { return sync_initialized_; }
190
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;
197   }
198
199   void set_sync_initialized(bool initialized) {
200     sync_initialized_ = initialized;
201   }
202
203  private:
204   explicit OneClickTestProfileSyncService(Profile* profile)
205       : TestProfileSyncService(
206           scoped_ptr<ProfileSyncComponentsFactory>(
207               new ProfileSyncComponentsFactoryMock()),
208           profile,
209           SigninManagerFactory::GetForProfile(profile),
210           ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
211           browser_sync::MANUAL_START),
212         first_setup_in_progress_(false),
213         sync_initialized_(false) {}
214
215   bool first_setup_in_progress_;
216   bool sync_initialized_;
217 };
218
219 }  // namespace
220
221 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
222  public:
223   OneClickSigninHelperTest();
224
225   virtual void SetUp() OVERRIDE;
226   virtual void TearDown() OVERRIDE;
227
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);
232
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);
236
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);
242
243   SigninManagerMock* signin_manager_;
244   FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
245
246  protected:
247   GoogleServiceAuthError no_error_;
248
249  private:
250   // ChromeRenderViewHostTestHarness overrides:
251   virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
252
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_;
257
258   DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest);
259 };
260
261 OneClickSigninHelperTest::OneClickSigninHelperTest()
262     : signin_manager_(NULL),
263       fake_oauth2_token_service_(NULL),
264       no_error_(GoogleServiceAuthError::NONE),
265       trusted_signin_process_id_(-1) {
266 }
267
268 void OneClickSigninHelperTest::SetUp() {
269   signin::ForceWebBasedSigninFlowForTesting(true);
270   content::RenderViewHostTestHarness::SetUp();
271   SetTrustedSigninProcessID(process()->GetID());
272 }
273
274 void OneClickSigninHelperTest::TearDown() {
275   signin::ForceWebBasedSigninFlowForTesting(false);
276   content::RenderViewHostTestHarness::TearDown();
277 }
278
279 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) {
280   trusted_signin_process_id_ = id;
281 }
282
283 void OneClickSigninHelperTest::SetUpSigninManager(const std::string& username) {
284   SigninClient* signin_client =
285       ChromeSigninClientFactory::GetForProfile(profile());
286   if (signin_client)
287     signin_client->SetSigninProcess(trusted_signin_process_id_);
288
289   signin_manager_ = static_cast<SigninManagerMock*>(
290       SigninManagerFactory::GetForProfile(profile()));
291   if (!username.empty()) {
292     ASSERT_TRUE(signin_manager_);
293     signin_manager_->SetAuthenticatedUsername(username);
294   }
295 }
296
297 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
298   PrefService* pref_service = profile()->GetPrefs();
299   pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
300 }
301
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));
308 }
309
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);
315 }
316
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);
321 }
322
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);
330 }
331
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();
339
340   fake_oauth2_token_service_ =
341       static_cast<FakeProfileOAuth2TokenService*>(
342           ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get()));
343
344   return profile.release();
345 }
346
347 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest {
348  public:
349   OneClickSigninHelperIOTest();
350
351   virtual void SetUp() OVERRIDE;
352
353   TestProfileIOData* CreateTestProfileIOData(Profile::ProfileType profile_type);
354
355  protected:
356   TestingProfileManager testing_profile_manager_;
357   TestURLRequest request_;
358   const GURL valid_gaia_url_;
359
360  private:
361   DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest);
362 };
363
364 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest()
365     : testing_profile_manager_(
366           TestingBrowserProcess::GetGlobal()),
367       valid_gaia_url_("https://accounts.google.com/") {
368 }
369
370 void OneClickSigninHelperIOTest::SetUp() {
371   OneClickSigninHelperTest::SetUp();
372   ASSERT_TRUE(testing_profile_manager_.SetUp());
373 }
374
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");
384   return io_data;
385 }
386
387 class OneClickSigninHelperIncognitoTest : public OneClickSigninHelperTest {
388  protected:
389   // content::RenderViewHostTestHarness.
390   virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
391 };
392
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();
399 }
400
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(
412       NULL,
413       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
414       std::string(),
415       &error_message));
416   EXPECT_EQ("", error_message);
417 }
418
419 TEST_F(OneClickSigninHelperTest, CanOffer) {
420   SetUpSigninManager(std::string());
421
422   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
423         WillRepeatedly(Return(true));
424
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(
433       web_contents(),
434       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
435       std::string(),
436       NULL));
437
438   EnableOneClick(false);
439
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);
445
446   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
447       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
448       "user@gmail.com", &error_message));
449   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
450       web_contents(),
451       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
452       std::string(),
453       &error_message));
454   EXPECT_EQ("", error_message);
455 }
456
457 TEST_F(OneClickSigninHelperTest, CanOfferFirstSetup) {
458   SetUpSigninManager(std::string());
459
460   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
461         WillRepeatedly(Return(true));
462
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);
469   sync->Initialize();
470   sync->set_sync_initialized(true);
471   sync->set_first_setup_in_progress(true);
472
473   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
474       web_contents(),
475       OneClickSigninHelper::CAN_OFFER_FOR_ALL,
476       "foo@gmail.com", NULL));
477   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
478       web_contents(),
479       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
480       "foo@gmail.com", NULL));
481   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
482       web_contents(),
483       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
484       std::string(),
485       NULL));
486 }
487
488 TEST_F(OneClickSigninHelperTest, CanOfferProfileConnected) {
489   SetUpSigninManager("foo@gmail.com");
490
491   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
492       WillRepeatedly(Return(true));
493
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")),
508             error_message);
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")),
520             error_message);
521   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
522       web_contents(),
523       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
524       std::string(),
525       &error_message));
526 }
527
528 TEST_F(OneClickSigninHelperTest, CanOfferUsernameNotAllowed) {
529   SetUpSigninManager(std::string());
530
531   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
532       WillRepeatedly(Return(false));
533
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),
539             error_message);
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),
544             error_message);
545   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
546       web_contents(),
547       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
548       std::string(),
549       &error_message));
550 }
551
552 TEST_F(OneClickSigninHelperTest, CanOfferWithRejectedEmail) {
553   SetUpSigninManager(std::string());
554
555   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
556         WillRepeatedly(Return(true));
557
558   AddEmailToOneClickRejectedList("foo@gmail.com");
559   AddEmailToOneClickRejectedList("user@gmail.com");
560
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));
579 }
580
581 TEST_F(OneClickSigninHelperIncognitoTest, CanOfferIncognito) {
582   SetUpSigninManager(std::string());
583
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(
594       web_contents(),
595       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
596       std::string(),
597       &error_message));
598   EXPECT_EQ("", error_message);
599 }
600
601 TEST_F(OneClickSigninHelperTest, CanOfferNoSigninCookies) {
602   SetUpSigninManager(std::string());
603   AllowSigninCookies(false);
604
605   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
606         WillRepeatedly(Return(true));
607
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(
618       web_contents(),
619       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
620       std::string(),
621       &error_message));
622   EXPECT_EQ("", error_message);
623 }
624
625 TEST_F(OneClickSigninHelperTest, CanOfferDisabledByPolicy) {
626   SetUpSigninManager(std::string());
627
628   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
629         WillRepeatedly(Return(true));
630
631   EnableOneClick(true);
632   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
633       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
634       "user@gmail.com", NULL));
635
636   // Simulate a policy disabling signin by writing kSigninAllowed directly.
637   profile()->GetTestingPrefService()->SetManagedPref(
638       prefs::kSigninAllowed, new base::FundamentalValue(false));
639
640   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
641       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
642       "user@gmail.com", NULL));
643
644   // Reset the preference value to true.
645   profile()->GetTestingPrefService()->SetManagedPref(
646       prefs::kSigninAllowed, new base::FundamentalValue(true));
647
648   // Simulate a policy disabling sync by writing kSyncManaged directly.
649   profile()->GetTestingPrefService()->SetManagedPref(
650       sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
651
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));
656 }
657
658 // Should not crash if a helper instance is not associated with an incognito
659 // web contents.
660 TEST_F(OneClickSigninHelperIncognitoTest, ShowInfoBarUIThreadIncognito) {
661   SetUpSigninManager(std::string());
662   OneClickSigninHelper* helper =
663       OneClickSigninHelper::FromWebContents(web_contents());
664   EXPECT_EQ(NULL, helper);
665
666   OneClickSigninHelper::ShowInfoBarUIThread(
667       "session_index", "email", OneClickSigninHelper::AUTO_ACCEPT_ACCEPTED,
668       signin::SOURCE_UNKNOWN, GURL(), process()->GetID(),
669       rvh()->GetRoutingID());
670 }
671
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));
679
680   OneClickTestProfileSyncService* sync_service =
681       static_cast<OneClickTestProfileSyncService*>(
682           ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
683               profile(), OneClickTestProfileSyncService::Build));
684   sync_service->set_sync_initialized(true);
685
686   content::WebContents* contents = web_contents();
687
688   OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
689   OneClickSigninHelper* helper =
690       OneClickSigninHelper::FromWebContents(contents);
691   helper->SetDoNotClearPendingEmailForTesting();
692   helper->set_do_not_start_sync_for_testing();
693
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());
700
701   SubmitGAIAPassword(helper);
702
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());
707 }
708
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
711 // web contents.
712 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) {
713   content::WebContents* contents = web_contents();
714
715   OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
716   OneClickSigninHelper* helper =
717       OneClickSigninHelper::FromWebContents(contents);
718   helper->SetDoNotClearPendingEmailForTesting();
719   helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT;
720
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);
726
727   EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_);
728 }
729
730 TEST_F(OneClickSigninHelperTest, NoRedirectToNTPWithPendingEntry) {
731   content::NavigationController& controller = web_contents()->GetController();
732   EXPECT_FALSE(controller.GetPendingEntry());
733
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());
738
739   MockWebContentsDelegate delegate;
740   EXPECT_CALL(delegate, OpenURLFromTab(_, _)).Times(0);
741   web_contents()->SetDelegate(&delegate);
742   OneClickSigninHelper::RedirectToNtpOrAppsPage(
743       web_contents(), signin::SOURCE_UNKNOWN);
744
745   EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
746 }
747
748 // I/O thread tests
749
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()));
756 }
757
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()));
764 }
765
766 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) {
767   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
768             OneClickSigninHelper::CanOfferOnIOThreadImpl(
769                 valid_gaia_url_, &request_, NULL));
770 }
771
772 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) {
773   scoped_ptr<TestProfileIOData> io_data(
774       CreateTestProfileIOData(Profile::REGULAR_PROFILE));
775   EXPECT_EQ(
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/"),
782                 &request_,
783                 io_data.get()));
784 }
785
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()));
793 }
794
795 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
796   PrefService* pref_service = profile()->GetPrefs();
797   pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
798
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()));
804 }
805
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()));
813 }
814
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,
821                            std::string());
822
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()));
828 }
829
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()));
837 }
838
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()));
846 }
847
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()));
854
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()));
862
863   // Reset the preference.
864   profile()->GetTestingPrefService()->SetManagedPref(
865       prefs::kSigninAllowed, new base::FundamentalValue(true));
866
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()));
874 }
875
876
877 class MockStarterWrapper
878     : public testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper> {
879  public:
880   MockStarterWrapper(
881       const OneClickSigninHelper::StartSyncArgs& args,
882       OneClickSigninSyncStarter::StartSyncMode start_mode);
883
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));
889 };
890
891 MockStarterWrapper::MockStarterWrapper(
892     const OneClickSigninHelper::StartSyncArgs& args,
893     OneClickSigninSyncStarter::StartSyncMode start_mode)
894     : testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper>(
895           args, start_mode) {
896 }
897
898 class OneClickSyncStarterWrapperTest : public testing::Test {
899  public:
900   virtual void SetUp() OVERRIDE {
901     TestingProfile::Builder builder;
902     profile_ = builder.Build();
903   }
904
905   virtual void TearDown() OVERRIDE {
906     // Let the SyncStarterWrapper delete itself.
907     base::RunLoop().RunUntilIdle();
908   }
909
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"),
918           value, options,
919           net::CookieMonster::SetCookiesCallback());
920   }
921
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);
929   }
930
931   TestingProfile* profile() { return profile_.get(); }
932
933  private:
934   content::TestBrowserThreadBundle thread_bundle_;
935   scoped_ptr<TestingProfile> profile_;
936 };
937
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);
945
946   EXPECT_CALL(*wrapper,
947               StartOneClickSigninSyncStarter("foo@gmail.com",
948                                              "refresh_token"));
949   wrapper->Start();
950 }
951
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);
958
959   EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
960   EXPECT_CALL(*wrapper,
961               StartOneClickSigninSyncStarter("foo@gmail.com",
962                                              "refresh_token"));
963   wrapper->Start();
964   SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
965                               "refresh_token");
966 }
967
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);
974
975   EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
976   EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
977   wrapper->Start();
978   SimulateRefreshTokenFetched(wrapper, "bar@gmail.com", "bar@gmail.com",
979                               "refresh_token");
980 }
981
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");
989
990   EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
991   EXPECT_CALL(*wrapper,
992               StartOneClickSigninSyncStarter("foo@gmail.com",
993                                              "refresh_token"));
994   wrapper->Start();
995   base::RunLoop().RunUntilIdle();
996   SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
997                               "refresh_token");
998 }
999
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);
1006
1007   EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
1008   wrapper->Start();
1009   base::RunLoop().RunUntilIdle();
1010 }
1011
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");
1019
1020   EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
1021   wrapper->Start();
1022   base::RunLoop().RunUntilIdle();
1023 }