Update To 11.40.268.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/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"
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   ~TestProfileIOData() override {
110     signin_names()->ReleaseResourcesOnUIThread();
111   }
112
113   // ProfileIOData overrides:
114   void InitializeInternal(ProfileParams* profile_params,
115                           content::ProtocolHandlerMap* protocol_handlers,
116                           content::URLRequestInterceptorScopedVector
117                               request_interceptors) const override {
118     NOTREACHED();
119   }
120   void InitializeExtensionsRequestContext(
121       ProfileParams* profile_params) const override {
122     NOTREACHED();
123   }
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)
131       const override {
132     NOTREACHED();
133     return NULL;
134   }
135   net::URLRequestContext* InitializeMediaRequestContext(
136       net::URLRequestContext* original_context,
137       const StoragePartitionDescriptor& details) const override {
138     NOTREACHED();
139     return NULL;
140   }
141   net::URLRequestContext* AcquireMediaRequestContext() const override {
142     NOTREACHED();
143     return NULL;
144   }
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)
152       const override {
153     NOTREACHED();
154     return NULL;
155   }
156   net::URLRequestContext* AcquireIsolatedMediaRequestContext(
157       net::URLRequestContext* app_context,
158       const StoragePartitionDescriptor& partition_descriptor) const override {
159     NOTREACHED();
160     return NULL;
161   }
162 };
163
164 class TestURLRequest : public base::SupportsUserData {
165  public:
166   TestURLRequest() {}
167   ~TestURLRequest() override {}
168 };
169
170 class OneClickTestProfileSyncService : public TestProfileSyncService {
171  public:
172   ~OneClickTestProfileSyncService() override {}
173
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));
178   }
179
180   // Need to control this for certain tests.
181   bool FirstSetupInProgress() const override {
182     return first_setup_in_progress_;
183   }
184
185   bool SyncActive() const override { return sync_active_; }
186
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;
193   }
194
195   void set_sync_active(bool active) {
196     sync_active_ = active;
197   }
198
199  private:
200   explicit OneClickTestProfileSyncService(Profile* profile)
201       : TestProfileSyncService(
202           scoped_ptr<ProfileSyncComponentsFactory>(
203               new ProfileSyncComponentsFactoryMock()),
204           profile,
205           SigninManagerFactory::GetForProfile(profile),
206           ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
207           browser_sync::MANUAL_START),
208         first_setup_in_progress_(false),
209         sync_active_(false) {}
210
211   bool first_setup_in_progress_;
212   bool sync_active_;
213 };
214
215 }  // namespace
216
217 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
218  public:
219   OneClickSigninHelperTest();
220
221   void SetUp() override;
222   void TearDown() override;
223
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);
228
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);
232
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);
238
239   SigninManagerMock* signin_manager_;
240   FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
241
242  protected:
243   GoogleServiceAuthError no_error_;
244
245  private:
246   // ChromeRenderViewHostTestHarness overrides:
247   content::BrowserContext* CreateBrowserContext() override;
248
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_;
253
254   DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest);
255 };
256
257 OneClickSigninHelperTest::OneClickSigninHelperTest()
258     : signin_manager_(NULL),
259       fake_oauth2_token_service_(NULL),
260       no_error_(GoogleServiceAuthError::NONE),
261       trusted_signin_process_id_(-1) {
262 }
263
264 void OneClickSigninHelperTest::SetUp() {
265   signin::ForceWebBasedSigninFlowForTesting(true);
266   content::RenderViewHostTestHarness::SetUp();
267   SetTrustedSigninProcessID(process()->GetID());
268 }
269
270 void OneClickSigninHelperTest::TearDown() {
271   signin::ForceWebBasedSigninFlowForTesting(false);
272   content::RenderViewHostTestHarness::TearDown();
273 }
274
275 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) {
276   trusted_signin_process_id_ = id;
277 }
278
279 void OneClickSigninHelperTest::SetUpSigninManager(const std::string& username) {
280   SigninClient* signin_client =
281       ChromeSigninClientFactory::GetForProfile(profile());
282   if (signin_client)
283     signin_client->SetSigninProcess(trusted_signin_process_id_);
284
285   signin_manager_ = static_cast<SigninManagerMock*>(
286       SigninManagerFactory::GetForProfile(profile()));
287   if (!username.empty()) {
288     ASSERT_TRUE(signin_manager_);
289     signin_manager_->SetAuthenticatedUsername(username);
290   }
291 }
292
293 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
294   PrefService* pref_service = profile()->GetPrefs();
295   pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
296 }
297
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));
304 }
305
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);
311 }
312
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);
317 }
318
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);
326 }
327
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();
335
336   fake_oauth2_token_service_ =
337       static_cast<FakeProfileOAuth2TokenService*>(
338           ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get()));
339
340   return profile.release();
341 }
342
343 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest {
344  public:
345   OneClickSigninHelperIOTest();
346
347   void SetUp() override;
348
349   TestProfileIOData* CreateTestProfileIOData(Profile::ProfileType profile_type);
350
351  protected:
352   TestingProfileManager testing_profile_manager_;
353   TestURLRequest request_;
354   const GURL valid_gaia_url_;
355
356  private:
357   DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest);
358 };
359
360 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest()
361     : testing_profile_manager_(
362           TestingBrowserProcess::GetGlobal()),
363       valid_gaia_url_("https://accounts.google.com/") {
364 }
365
366 void OneClickSigninHelperIOTest::SetUp() {
367   OneClickSigninHelperTest::SetUp();
368   ASSERT_TRUE(testing_profile_manager_.SetUp());
369 }
370
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");
380   return io_data;
381 }
382
383 class OneClickSigninHelperIncognitoTest : public OneClickSigninHelperTest {
384  protected:
385   // content::RenderViewHostTestHarness.
386   content::BrowserContext* CreateBrowserContext() override;
387 };
388
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();
397 }
398
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(
410       NULL,
411       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
412       std::string(),
413       &error_message));
414   EXPECT_EQ("", error_message);
415 }
416
417 TEST_F(OneClickSigninHelperTest, CanOffer) {
418   SetUpSigninManager(std::string());
419
420   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
421         WillRepeatedly(Return(true));
422
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(
431       web_contents(),
432       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
433       std::string(),
434       NULL));
435
436   EnableOneClick(false);
437
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);
443
444   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
445       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
446       "user@gmail.com", &error_message));
447   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
448       web_contents(),
449       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
450       std::string(),
451       &error_message));
452   EXPECT_EQ("", error_message);
453 }
454
455 TEST_F(OneClickSigninHelperTest, CanOfferFirstSetup) {
456   SetUpSigninManager(std::string());
457
458   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
459         WillRepeatedly(Return(true));
460
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);
467   sync->Initialize();
468   sync->set_sync_active(true);
469   sync->set_first_setup_in_progress(true);
470
471   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
472       web_contents(),
473       OneClickSigninHelper::CAN_OFFER_FOR_ALL,
474       "foo@gmail.com", NULL));
475   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
476       web_contents(),
477       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
478       "foo@gmail.com", NULL));
479   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
480       web_contents(),
481       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
482       std::string(),
483       NULL));
484 }
485
486 TEST_F(OneClickSigninHelperTest, CanOfferProfileConnected) {
487   SetUpSigninManager("foo@gmail.com");
488
489   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
490       WillRepeatedly(Return(true));
491
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")),
506             error_message);
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")),
518             error_message);
519   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
520       web_contents(),
521       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
522       std::string(),
523       &error_message));
524 }
525
526 TEST_F(OneClickSigninHelperTest, CanOfferUsernameNotAllowed) {
527   SetUpSigninManager(std::string());
528
529   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
530       WillRepeatedly(Return(false));
531
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),
537             error_message);
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),
542             error_message);
543   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
544       web_contents(),
545       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
546       std::string(),
547       &error_message));
548 }
549
550 TEST_F(OneClickSigninHelperTest, CanOfferWithRejectedEmail) {
551   SetUpSigninManager(std::string());
552
553   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
554         WillRepeatedly(Return(true));
555
556   AddEmailToOneClickRejectedList("foo@gmail.com");
557   AddEmailToOneClickRejectedList("user@gmail.com");
558
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));
577 }
578
579 TEST_F(OneClickSigninHelperIncognitoTest, CanOfferIncognito) {
580   SetUpSigninManager(std::string());
581
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(
592       web_contents(),
593       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
594       std::string(),
595       &error_message));
596   EXPECT_EQ("", error_message);
597 }
598
599 TEST_F(OneClickSigninHelperTest, CanOfferNoSigninCookies) {
600   SetUpSigninManager(std::string());
601   AllowSigninCookies(false);
602
603   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
604         WillRepeatedly(Return(true));
605
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(
616       web_contents(),
617       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
618       std::string(),
619       &error_message));
620   EXPECT_EQ("", error_message);
621 }
622
623 TEST_F(OneClickSigninHelperTest, CanOfferDisabledByPolicy) {
624   SetUpSigninManager(std::string());
625
626   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
627         WillRepeatedly(Return(true));
628
629   EnableOneClick(true);
630   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
631       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
632       "user@gmail.com", NULL));
633
634   // Simulate a policy disabling signin by writing kSigninAllowed directly.
635   profile()->GetTestingPrefService()->SetManagedPref(
636       prefs::kSigninAllowed, new base::FundamentalValue(false));
637
638   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
639       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
640       "user@gmail.com", NULL));
641
642   // Reset the preference value to true.
643   profile()->GetTestingPrefService()->SetManagedPref(
644       prefs::kSigninAllowed, new base::FundamentalValue(true));
645
646   // Simulate a policy disabling sync by writing kSyncManaged directly.
647   profile()->GetTestingPrefService()->SetManagedPref(
648       sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
649
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));
654 }
655
656 // Should not crash if a helper instance is not associated with an incognito
657 // web contents.
658 TEST_F(OneClickSigninHelperIncognitoTest, ShowInfoBarUIThreadIncognito) {
659   SetUpSigninManager(std::string());
660   OneClickSigninHelper* helper =
661       OneClickSigninHelper::FromWebContents(web_contents());
662   EXPECT_EQ(NULL, helper);
663
664   OneClickSigninHelper::ShowInfoBarUIThread(
665       "session_index", "email", OneClickSigninHelper::AUTO_ACCEPT_ACCEPTED,
666       signin::SOURCE_UNKNOWN, GURL(), process()->GetID(),
667       rvh()->GetRoutingID());
668 }
669
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
672 // web contents.
673 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) {
674   content::WebContents* contents = web_contents();
675
676   OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
677   OneClickSigninHelper* helper =
678       OneClickSigninHelper::FromWebContents(contents);
679   helper->SetDoNotClearPendingEmailForTesting();
680   helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT;
681
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);
687
688   EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_);
689 }
690
691 TEST_F(OneClickSigninHelperTest, NoRedirectToNTPWithPendingEntry) {
692   content::NavigationController& controller = web_contents()->GetController();
693   EXPECT_FALSE(controller.GetPendingEntry());
694
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());
699
700   MockWebContentsDelegate delegate;
701   EXPECT_CALL(delegate, OpenURLFromTab(_, _)).Times(0);
702   web_contents()->SetDelegate(&delegate);
703   OneClickSigninHelper::RedirectToNtpOrAppsPage(
704       web_contents(), signin::SOURCE_UNKNOWN);
705
706   EXPECT_EQ(fooWebUIURL, controller.GetPendingEntry()->GetURL());
707 }
708
709 // I/O thread tests
710
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()));
717 }
718
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()));
725 }
726
727 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) {
728   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
729             OneClickSigninHelper::CanOfferOnIOThreadImpl(
730                 valid_gaia_url_, &request_, NULL));
731 }
732
733 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) {
734   scoped_ptr<TestProfileIOData> io_data(
735       CreateTestProfileIOData(Profile::REGULAR_PROFILE));
736   EXPECT_EQ(
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/"),
743                 &request_,
744                 io_data.get()));
745 }
746
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()));
754 }
755
756 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
757   PrefService* pref_service = profile()->GetPrefs();
758   pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
759
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()));
765 }
766
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()));
774 }
775
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,
782                            std::string());
783
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()));
789 }
790
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()));
798 }
799
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()));
807 }
808
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()));
815
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()));
823
824   // Reset the preference.
825   profile()->GetTestingPrefService()->SetManagedPref(
826       prefs::kSigninAllowed, new base::FundamentalValue(true));
827
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()));
835 }
836
837
838 class MockStarterWrapper
839     : public testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper> {
840  public:
841   MockStarterWrapper(
842       const OneClickSigninHelper::StartSyncArgs& args,
843       OneClickSigninSyncStarter::StartSyncMode start_mode);
844
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));
850 };
851
852 MockStarterWrapper::MockStarterWrapper(
853     const OneClickSigninHelper::StartSyncArgs& args,
854     OneClickSigninSyncStarter::StartSyncMode start_mode)
855     : testing::StrictMock<OneClickSigninHelper::SyncStarterWrapper>(
856           args, start_mode) {
857 }
858
859 class OneClickSyncStarterWrapperTest : public testing::Test {
860  public:
861   void SetUp() override {
862     TestingProfile::Builder builder;
863     profile_ = builder.Build();
864   }
865
866   void TearDown() override {
867     // Let the SyncStarterWrapper delete itself.
868     base::RunLoop().RunUntilIdle();
869   }
870
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"),
879           value, options,
880           net::CookieMonster::SetCookiesCallback());
881   }
882
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);
890   }
891
892   TestingProfile* profile() { return profile_.get(); }
893
894  private:
895   content::TestBrowserThreadBundle thread_bundle_;
896   scoped_ptr<TestingProfile> profile_;
897 };
898
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);
906
907   EXPECT_CALL(*wrapper,
908               StartOneClickSigninSyncStarter("foo@gmail.com",
909                                              "refresh_token"));
910   wrapper->Start();
911 }
912
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);
919
920   EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
921   EXPECT_CALL(*wrapper,
922               StartOneClickSigninSyncStarter("foo@gmail.com",
923                                              "refresh_token"));
924   wrapper->Start();
925   SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
926                               "refresh_token");
927 }
928
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);
935
936   EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
937   EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
938   wrapper->Start();
939   SimulateRefreshTokenFetched(wrapper, "bar@gmail.com", "bar@gmail.com",
940                               "refresh_token");
941 }
942
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");
950
951   EXPECT_CALL(*wrapper, StartSigninOAuthHelper());
952   EXPECT_CALL(*wrapper,
953               StartOneClickSigninSyncStarter("foo@gmail.com",
954                                              "refresh_token"));
955   wrapper->Start();
956   base::RunLoop().RunUntilIdle();
957   SimulateRefreshTokenFetched(wrapper, "foo@gmail.com", "foo@gmail.com",
958                               "refresh_token");
959 }
960
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);
967
968   EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
969   wrapper->Start();
970   base::RunLoop().RunUntilIdle();
971 }
972
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");
980
981   EXPECT_CALL(*wrapper, DisplayErrorBubble(_));
982   wrapper->Start();
983   base::RunLoop().RunUntilIdle();
984 }