Upstream version 5.34.92.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/strings/utf_string_conversions.h"
8 #include "base/values.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/content_settings/cookie_settings.h"
11 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_info_cache.h"
14 #include "chrome/browser/profiles/profile_io_data.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
17 #include "chrome/browser/signin/fake_signin_manager.h"
18 #include "chrome/browser/signin/profile_oauth2_token_service.h"
19 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
20 #include "chrome/browser/signin/signin_manager.h"
21 #include "chrome/browser/signin/signin_manager_factory.h"
22 #include "chrome/browser/signin/signin_names_io_thread.h"
23 #include "chrome/browser/signin/signin_promo.h"
24 #include "chrome/browser/sync/profile_sync_service_factory.h"
25 #include "chrome/browser/sync/profile_sync_service_mock.h"
26 #include "chrome/browser/sync/test_profile_sync_service.h"
27 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
28 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
29 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
32 #include "chrome/test/base/testing_browser_process.h"
33 #include "chrome/test/base/testing_pref_service_syncable.h"
34 #include "chrome/test/base/testing_profile.h"
35 #include "chrome/test/base/testing_profile_manager.h"
36 #include "components/autofill/core/common/password_form.h"
37 #include "content/public/browser/browser_context.h"
38 #include "content/public/browser/navigation_details.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/common/frame_navigate_params.h"
41 #include "content/public/common/url_constants.h"
42 #include "content/public/test/mock_render_process_host.h"
43 #include "grit/chromium_strings.h"
44 #include "grit/generated_resources.h"
45 #include "testing/gtest/include/gtest/gtest.h"
46 #include "ui/base/l10n/l10n_util.h"
47
48 using ::testing::_;
49 using ::testing::AtLeast;
50 using ::testing::Return;
51
52 namespace {
53
54 class SigninManagerMock : public FakeSigninManager {
55  public:
56   explicit SigninManagerMock(Profile* profile) : FakeSigninManager(profile) {
57     Initialize(profile, NULL);
58   }
59   MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username));
60 };
61
62 static BrowserContextKeyedService* BuildSigninManagerMock(
63     content::BrowserContext* profile) {
64   return new SigninManagerMock(static_cast<Profile*>(profile));
65 }
66
67 class TestProfileIOData : public ProfileIOData {
68  public:
69   TestProfileIOData(bool is_incognito, PrefService* pref_service,
70                     PrefService* local_state, CookieSettings* cookie_settings)
71       : ProfileIOData(is_incognito) {
72     // Initialize the IO members required for these tests, but keep them on
73     // this thread since we don't use a background thread here.
74     google_services_username()->Init(prefs::kGoogleServicesUsername,
75                                      pref_service);
76     reverse_autologin_enabled()->Init(prefs::kReverseAutologinEnabled,
77                                       pref_service);
78     one_click_signin_rejected_email_list()->Init(
79         prefs::kReverseAutologinRejectedEmailList, pref_service);
80
81     google_services_username_pattern()->Init(
82         prefs::kGoogleServicesUsernamePattern, local_state);
83
84     sync_disabled()->Init(prefs::kSyncManaged, pref_service);
85
86     signin_allowed()->Init(prefs::kSigninAllowed, pref_service);
87
88     set_signin_names_for_testing(new SigninNamesOnIOThread());
89     SetCookieSettingsForTesting(cookie_settings);
90   }
91
92   virtual ~TestProfileIOData() {
93     signin_names()->ReleaseResourcesOnUIThread();
94   }
95
96   // ProfileIOData overrides:
97   virtual void InitializeInternal(
98       ProfileParams* profile_params,
99       content::ProtocolHandlerMap* protocol_handlers) const OVERRIDE {
100     NOTREACHED();
101   }
102   virtual void InitializeExtensionsRequestContext(
103       ProfileParams* profile_params) const OVERRIDE {
104     NOTREACHED();
105   }
106   virtual ChromeURLRequestContext* InitializeAppRequestContext(
107       ChromeURLRequestContext* main_context,
108       const StoragePartitionDescriptor& details,
109       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
110           protocol_handler_interceptor,
111       content::ProtocolHandlerMap* protocol_handlers) const OVERRIDE {
112     NOTREACHED();
113     return NULL;
114   }
115   virtual ChromeURLRequestContext* InitializeMediaRequestContext(
116       ChromeURLRequestContext* original_context,
117       const StoragePartitionDescriptor& details) const OVERRIDE {
118     NOTREACHED();
119     return NULL;
120   }
121   virtual ChromeURLRequestContext*
122       AcquireMediaRequestContext() const OVERRIDE {
123     NOTREACHED();
124     return NULL;
125   }
126   virtual ChromeURLRequestContext*
127       AcquireIsolatedAppRequestContext(
128           ChromeURLRequestContext* main_context,
129           const StoragePartitionDescriptor& partition_descriptor,
130           scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
131               protocol_handler_interceptor,
132           content::ProtocolHandlerMap* protocol_handlers) const OVERRIDE {
133     NOTREACHED();
134     return NULL;
135   }
136   virtual ChromeURLRequestContext*
137       AcquireIsolatedMediaRequestContext(
138           ChromeURLRequestContext* app_context,
139           const StoragePartitionDescriptor& partition_descriptor)
140           const OVERRIDE {
141     NOTREACHED();
142     return NULL;
143   }
144 };
145
146 class TestURLRequest : public base::SupportsUserData {
147 public:
148   TestURLRequest() {}
149   virtual ~TestURLRequest() {}
150 };
151
152 class OneClickTestProfileSyncService : public TestProfileSyncService {
153   public:
154    virtual ~OneClickTestProfileSyncService() {}
155
156    // Helper routine to be used in conjunction with
157    // BrowserContextKeyedServiceFactory::SetTestingFactory().
158    static BrowserContextKeyedService* Build(content::BrowserContext* profile) {
159      return new OneClickTestProfileSyncService(static_cast<Profile*>(profile));
160    }
161
162    // Need to control this for certain tests.
163    virtual bool FirstSetupInProgress() const OVERRIDE {
164      return first_setup_in_progress_;
165    }
166
167    // Controls return value of FirstSetupInProgress. Because some bits
168    // of UI depend on that value, it's useful to control it separately
169    // from the internal work and components that are triggered (such as
170    // ReconfigureDataTypeManager) to facilitate unit tests.
171    void set_first_setup_in_progress(bool in_progress) {
172      first_setup_in_progress_ = in_progress;
173    }
174
175    // Override ProfileSyncService::Shutdown() to avoid CHECK on
176    // |invalidator_registrar_|.
177    virtual void Shutdown() OVERRIDE {};
178
179   private:
180    explicit OneClickTestProfileSyncService(Profile* profile)
181        : TestProfileSyncService(NULL,
182                                 profile,
183                                 NULL,
184                                 NULL,
185                                 ProfileSyncService::MANUAL_START),
186          first_setup_in_progress_(false) {}
187
188    bool first_setup_in_progress_;
189 };
190
191 }  // namespace
192
193 class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
194  public:
195   OneClickSigninHelperTest();
196
197   virtual void SetUp() OVERRIDE;
198   virtual void TearDown() OVERRIDE;
199
200   // Creates the sign-in manager for tests.  If |username| is
201   // is not empty, the profile of the mock WebContents will be connected to
202   // the given account.
203   void CreateSigninManager(const std::string& username);
204
205   // Set the ID of the signin process that the test will assume to be the
206   // only process allowed to sign the user in to Chrome.
207   void SetTrustedSigninProcessID(int id);
208
209   void AddEmailToOneClickRejectedList(const std::string& email);
210   void EnableOneClick(bool enable);
211   void AllowSigninCookies(bool enable);
212   void SetAllowedUsernamePattern(const std::string& pattern);
213   ProfileSyncServiceMock* CreateProfileSyncServiceMock();
214   void SubmitGAIAPassword(OneClickSigninHelper* helper);
215
216   SigninManagerMock* signin_manager_;
217   FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
218
219  protected:
220   GoogleServiceAuthError no_error_;
221
222  private:
223   // ChromeRenderViewHostTestHarness overrides:
224   virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
225
226   // The ID of the signin process the test will assume to be trusted.
227   // By default, set to the test RenderProcessHost's process ID, but
228   // overridden by SetTrustedSigninProcessID.
229   int trusted_signin_process_id_;
230
231   DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperTest);
232 };
233
234 OneClickSigninHelperTest::OneClickSigninHelperTest()
235     : signin_manager_(NULL),
236       fake_oauth2_token_service_(NULL),
237       no_error_(GoogleServiceAuthError::NONE),
238       trusted_signin_process_id_(-1) {
239 }
240
241 void OneClickSigninHelperTest::SetUp() {
242   signin::ForceWebBasedSigninFlowForTesting(true);
243   content::RenderViewHostTestHarness::SetUp();
244   SetTrustedSigninProcessID(process()->GetID());
245 }
246
247 void OneClickSigninHelperTest::TearDown() {
248   signin::ForceWebBasedSigninFlowForTesting(false);
249   content::RenderViewHostTestHarness::TearDown();
250 }
251
252 void OneClickSigninHelperTest::SetTrustedSigninProcessID(int id) {
253   trusted_signin_process_id_ = id;
254 }
255
256 void OneClickSigninHelperTest::CreateSigninManager(
257     const std::string& username) {
258   signin_manager_ = static_cast<SigninManagerMock*>(
259       SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
260           profile(), BuildSigninManagerMock));
261   if (signin_manager_)
262     signin_manager_->SetSigninProcess(trusted_signin_process_id_);
263
264   if (!username.empty()) {
265     ASSERT_TRUE(signin_manager_);
266     signin_manager_->SetAuthenticatedUsername(username);
267   }
268 }
269
270 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
271   PrefService* pref_service = profile()->GetPrefs();
272   pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
273 }
274
275 void OneClickSigninHelperTest::AddEmailToOneClickRejectedList(
276     const std::string& email) {
277   PrefService* pref_service = profile()->GetPrefs();
278   ListPrefUpdate updater(pref_service,
279                          prefs::kReverseAutologinRejectedEmailList);
280   updater->AppendIfNotPresent(new base::StringValue(email));
281 }
282
283 void OneClickSigninHelperTest::AllowSigninCookies(bool enable) {
284   CookieSettings* cookie_settings =
285       CookieSettings::Factory::GetForProfile(profile()).get();
286   cookie_settings->SetDefaultCookieSetting(enable ? CONTENT_SETTING_ALLOW
287                                                   : CONTENT_SETTING_BLOCK);
288 }
289
290 void OneClickSigninHelperTest::SetAllowedUsernamePattern(
291     const std::string& pattern) {
292   PrefService* local_state = g_browser_process->local_state();
293   local_state->SetString(prefs::kGoogleServicesUsernamePattern, pattern);
294 }
295
296 ProfileSyncServiceMock*
297 OneClickSigninHelperTest::CreateProfileSyncServiceMock() {
298   ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>(
299       ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
300           profile(),
301           ProfileSyncServiceMock::BuildMockProfileSyncService));
302   EXPECT_CALL(*sync_service, FirstSetupInProgress()).WillRepeatedly(
303       Return(false));
304   EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true));
305   EXPECT_CALL(*sync_service, GetAuthError()).
306       WillRepeatedly(::testing::ReturnRef(no_error_));
307   EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(false));
308   sync_service->Initialize();
309   return sync_service;
310 }
311
312 void OneClickSigninHelperTest::SubmitGAIAPassword(
313     OneClickSigninHelper* helper) {
314   autofill::PasswordForm password_form;
315   password_form.origin = GURL("https://accounts.google.com");
316   password_form.signon_realm = "https://accounts.google.com";
317   password_form.password_value = base::UTF8ToUTF16("password");
318   helper->PasswordSubmitted(password_form);
319 }
320
321 content::BrowserContext* OneClickSigninHelperTest::CreateBrowserContext() {
322   TestingProfile::Builder builder;
323   builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
324                             FakeProfileOAuth2TokenService::Build);
325   scoped_ptr<TestingProfile> profile = builder.Build();
326
327   fake_oauth2_token_service_ =
328       static_cast<FakeProfileOAuth2TokenService*>(
329           ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get()));
330
331   return profile.release();
332 }
333
334 class OneClickSigninHelperIOTest : public OneClickSigninHelperTest {
335  public:
336   OneClickSigninHelperIOTest();
337
338   virtual void SetUp() OVERRIDE;
339
340   TestProfileIOData* CreateTestProfileIOData(bool is_incognito);
341
342  protected:
343   TestingProfileManager testing_profile_manager_;
344   TestURLRequest request_;
345   const GURL valid_gaia_url_;
346
347  private:
348   DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelperIOTest);
349 };
350
351 OneClickSigninHelperIOTest::OneClickSigninHelperIOTest()
352     : testing_profile_manager_(
353           TestingBrowserProcess::GetGlobal()),
354       valid_gaia_url_("https://accounts.google.com/") {
355 }
356
357 void OneClickSigninHelperIOTest::SetUp() {
358   OneClickSigninHelperTest::SetUp();
359   ASSERT_TRUE(testing_profile_manager_.SetUp());
360 }
361
362 TestProfileIOData* OneClickSigninHelperIOTest::CreateTestProfileIOData(
363     bool is_incognito) {
364   PrefService* pref_service = profile()->GetPrefs();
365   PrefService* local_state = g_browser_process->local_state();
366   CookieSettings* cookie_settings =
367       CookieSettings::Factory::GetForProfile(profile()).get();
368   TestProfileIOData* io_data = new TestProfileIOData(
369       is_incognito, pref_service, local_state, cookie_settings);
370   io_data->set_reverse_autologin_pending_email("user@gmail.com");
371   return io_data;
372 }
373
374 class OneClickSigninHelperIncognitoTest : public OneClickSigninHelperTest {
375  protected:
376   // content::RenderViewHostTestHarness.
377   virtual content::BrowserContext* CreateBrowserContext() OVERRIDE;
378 };
379
380 content::BrowserContext*
381 OneClickSigninHelperIncognitoTest::CreateBrowserContext() {
382   // Builds an incognito profile to run this test.
383   TestingProfile::Builder builder;
384   builder.SetIncognito();
385   return builder.Build().release();
386 }
387
388 TEST_F(OneClickSigninHelperTest, CanOfferNoContents) {
389   std::string error_message;
390   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
391       NULL, OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
392       "user@gmail.com", &error_message));
393   EXPECT_EQ("", error_message);
394   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
395       NULL, OneClickSigninHelper::CAN_OFFER_FOR_ALL,
396       "user@gmail.com", &error_message));
397   EXPECT_EQ("", error_message);
398   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
399       NULL,
400       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
401       std::string(),
402       &error_message));
403   EXPECT_EQ("", error_message);
404 }
405
406 TEST_F(OneClickSigninHelperTest, CanOffer) {
407   CreateSigninManager(std::string());
408
409   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
410         WillRepeatedly(Return(true));
411
412   EnableOneClick(true);
413   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
414       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
415       "user@gmail.com", NULL));
416   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
417       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
418       "user@gmail.com", NULL));
419   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
420       web_contents(),
421       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
422       std::string(),
423       NULL));
424
425   EnableOneClick(false);
426
427   std::string error_message;
428   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
429       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
430       "user@gmail.com", &error_message));
431   EXPECT_EQ("", error_message);
432
433   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
434       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
435       "user@gmail.com", &error_message));
436   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
437       web_contents(),
438       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
439       std::string(),
440       &error_message));
441   EXPECT_EQ("", error_message);
442 }
443
444 TEST_F(OneClickSigninHelperTest, CanOfferFirstSetup) {
445   CreateSigninManager(std::string());
446
447   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
448         WillRepeatedly(Return(true));
449
450   // Invoke OneClickTestProfileSyncService factory function and grab result.
451   OneClickTestProfileSyncService* sync =
452       static_cast<OneClickTestProfileSyncService*>(
453           ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
454               static_cast<Profile*>(browser_context()),
455               OneClickTestProfileSyncService::Build));
456
457   sync->set_first_setup_in_progress(true);
458
459   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
460       web_contents(),
461       OneClickSigninHelper::CAN_OFFER_FOR_ALL,
462       "foo@gmail.com", NULL));
463   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
464       web_contents(),
465       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
466       "foo@gmail.com", NULL));
467   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
468       web_contents(),
469       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
470       std::string(),
471       NULL));
472 }
473
474 TEST_F(OneClickSigninHelperTest, CanOfferProfileConnected) {
475   CreateSigninManager("foo@gmail.com");
476
477   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
478       WillRepeatedly(Return(true));
479
480   std::string error_message;
481   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
482       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
483       "foo@gmail.com", &error_message));
484   EXPECT_EQ("", error_message);
485   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
486       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
487       "foo", &error_message));
488   EXPECT_EQ("", error_message);
489   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
490       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
491       "user@gmail.com", &error_message));
492   EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL,
493                                       base::UTF8ToUTF16("foo@gmail.com")),
494             error_message);
495   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
496       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
497       "foo@gmail.com", &error_message));
498   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
499       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
500       "foo", &error_message));
501   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
502       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
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(),
509       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
510       std::string(),
511       &error_message));
512 }
513
514 TEST_F(OneClickSigninHelperTest, CanOfferUsernameNotAllowed) {
515   CreateSigninManager(std::string());
516
517   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
518       WillRepeatedly(Return(false));
519
520   std::string error_message;
521   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
522       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
523       "foo@gmail.com", &error_message));
524   EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED),
525             error_message);
526   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
527       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
528       "foo@gmail.com", &error_message));
529   EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED),
530             error_message);
531   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
532       web_contents(),
533       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
534       std::string(),
535       &error_message));
536 }
537
538 TEST_F(OneClickSigninHelperTest, CanOfferWithRejectedEmail) {
539   CreateSigninManager(std::string());
540
541   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
542         WillRepeatedly(Return(true));
543
544   AddEmailToOneClickRejectedList("foo@gmail.com");
545   AddEmailToOneClickRejectedList("user@gmail.com");
546
547   std::string error_message;
548   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
549       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
550       "foo@gmail.com", &error_message));
551   EXPECT_EQ("", error_message);
552   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
553       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
554       "user@gmail.com", &error_message));
555   EXPECT_EQ("", error_message);
556   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
557       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
558       "foo@gmail.com", &error_message));
559   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
560       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
561       "user@gmail.com", &error_message));
562   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
563       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
564       "john@gmail.com", &error_message));
565 }
566
567 TEST_F(OneClickSigninHelperIncognitoTest, CanOfferIncognito) {
568   CreateSigninManager(std::string());
569
570   std::string error_message;
571   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
572       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
573       "user@gmail.com", &error_message));
574   EXPECT_EQ("", error_message);
575   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
576       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
577       "user@gmail.com", &error_message));
578   EXPECT_EQ("", error_message);
579   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
580       web_contents(),
581       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
582       std::string(),
583       &error_message));
584   EXPECT_EQ("", error_message);
585 }
586
587 TEST_F(OneClickSigninHelperTest, CanOfferNoSigninCookies) {
588   CreateSigninManager(std::string());
589   AllowSigninCookies(false);
590
591   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
592         WillRepeatedly(Return(true));
593
594   std::string error_message;
595   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
596       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
597       "user@gmail.com", &error_message));
598   EXPECT_EQ("", error_message);
599   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
600       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
601       "user@gmail.com", &error_message));
602   EXPECT_EQ("", error_message);
603   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
604       web_contents(),
605       OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
606       std::string(),
607       &error_message));
608   EXPECT_EQ("", error_message);
609 }
610
611 TEST_F(OneClickSigninHelperTest, CanOfferDisabledByPolicy) {
612   CreateSigninManager(std::string());
613
614   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_)).
615         WillRepeatedly(Return(true));
616
617   EnableOneClick(true);
618   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
619       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
620       "user@gmail.com", NULL));
621
622   // Simulate a policy disabling signin by writing kSigninAllowed directly.
623   profile()->GetTestingPrefService()->SetManagedPref(
624       prefs::kSigninAllowed, base::Value::CreateBooleanValue(false));
625
626   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
627       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
628       "user@gmail.com", NULL));
629
630   // Reset the preference value to true.
631   profile()->GetTestingPrefService()->SetManagedPref(
632       prefs::kSigninAllowed, base::Value::CreateBooleanValue(true));
633
634   // Simulate a policy disabling sync by writing kSyncManaged directly.
635   profile()->GetTestingPrefService()->SetManagedPref(
636       prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
637
638   // Should still offer even if sync is disabled by policy.
639   EXPECT_TRUE(OneClickSigninHelper::CanOffer(
640       web_contents(), OneClickSigninHelper::CAN_OFFER_FOR_ALL,
641       "user@gmail.com", NULL));
642 }
643
644 // Should not crash if a helper instance is not associated with an incognito
645 // web contents.
646 TEST_F(OneClickSigninHelperIncognitoTest, ShowInfoBarUIThreadIncognito) {
647   CreateSigninManager(std::string());
648   OneClickSigninHelper* helper =
649       OneClickSigninHelper::FromWebContents(web_contents());
650   EXPECT_EQ(NULL, helper);
651
652   OneClickSigninHelper::ShowInfoBarUIThread(
653       "session_index", "email", OneClickSigninHelper::AUTO_ACCEPT_ACCEPTED,
654       signin::SOURCE_UNKNOWN, GURL(), process()->GetID(),
655       rvh()->GetRoutingID());
656 }
657
658 // If Chrome signin is triggered from a webstore install, and user chooses to
659 // config sync, then Chrome should redirect immediately to sync settings page,
660 // and upon successful setup, redirect back to webstore.
661 TEST_F(OneClickSigninHelperTest, SigninFromWebstoreWithConfigSyncfirst) {
662   CreateSigninManager(std::string());
663   EXPECT_CALL(*signin_manager_, IsAllowedUsername(_))
664       .WillRepeatedly(Return(true));
665
666   ProfileSyncServiceMock* sync_service = CreateProfileSyncServiceMock();
667   EXPECT_CALL(*sync_service, AddObserver(_)).Times(AtLeast(1));
668   EXPECT_CALL(*sync_service, RemoveObserver(_)).Times(AtLeast(1));
669   EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true));
670
671   content::WebContents* contents = web_contents();
672
673   OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
674   OneClickSigninHelper* helper =
675       OneClickSigninHelper::FromWebContents(contents);
676   helper->SetDoNotClearPendingEmailForTesting();
677   helper->set_do_not_start_sync_for_testing();
678
679   GURL continueUrl("https://chrome.google.com/webstore?source=5");
680   OneClickSigninHelper::ShowInfoBarUIThread(
681       "session_index", "user@gmail.com",
682       OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT,
683       signin::SOURCE_WEBSTORE_INSTALL,
684       continueUrl, process()->GetID(), rvh()->GetRoutingID());
685
686   SubmitGAIAPassword(helper);
687
688   NavigateAndCommit(GURL("https://chrome.google.com/webstore?source=3"));
689   helper->DidStopLoading(rvh());
690   helper->OnStateChanged();
691   EXPECT_EQ(GURL(continueUrl), contents->GetURL());
692 }
693
694 // Checks that the state of OneClickSigninHelper is cleaned when there is a
695 // navigation away from the sign in flow that is not triggered by the
696 // web contents.
697 TEST_F(OneClickSigninHelperTest, CleanTransientStateOnNavigate) {
698   content::WebContents* contents = web_contents();
699
700   OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
701   OneClickSigninHelper* helper =
702       OneClickSigninHelper::FromWebContents(contents);
703   helper->SetDoNotClearPendingEmailForTesting();
704   helper->auto_accept_ = OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT;
705
706   content::LoadCommittedDetails details;
707   content::FrameNavigateParams params;
708   params.url = GURL("http://crbug.com");
709   params.transition = content::PAGE_TRANSITION_TYPED;
710   helper->DidNavigateMainFrame(details, params);
711
712   EXPECT_EQ(OneClickSigninHelper::AUTO_ACCEPT_NONE, helper->auto_accept_);
713 }
714
715 // Checks that OneClickSigninHelper doesn't stay an observer of the profile
716 // sync service after it's deleted.
717 TEST_F(OneClickSigninHelperTest, RemoveObserverFromProfileSyncService) {
718   content::WebContents* contents = web_contents();
719
720   ProfileSyncServiceMock* sync_service = CreateProfileSyncServiceMock();
721
722   OneClickSigninHelper::CreateForWebContentsWithPasswordManager(contents, NULL);
723   OneClickSigninHelper* helper =
724       OneClickSigninHelper::FromWebContents(contents);
725   helper->SetDoNotClearPendingEmailForTesting();
726
727   EXPECT_CALL(*sync_service, RemoveObserver(helper));
728   SetContents(NULL);
729 }
730
731 // I/O thread tests
732
733 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThread) {
734   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
735   EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
736             OneClickSigninHelper::CanOfferOnIOThreadImpl(
737                 valid_gaia_url_, &request_, io_data.get()));
738 }
739
740 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadIncognito) {
741   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(true));
742   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
743             OneClickSigninHelper::CanOfferOnIOThreadImpl(
744                 valid_gaia_url_, &request_, io_data.get()));
745 }
746
747 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoIOData) {
748   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
749             OneClickSigninHelper::CanOfferOnIOThreadImpl(
750                 valid_gaia_url_, &request_, NULL));
751 }
752
753 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadBadURL) {
754   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
755   EXPECT_EQ(
756       OneClickSigninHelper::IGNORE_REQUEST,
757       OneClickSigninHelper::CanOfferOnIOThreadImpl(
758           GURL("https://foo.com/"), &request_, io_data.get()));
759   EXPECT_EQ(OneClickSigninHelper::IGNORE_REQUEST,
760             OneClickSigninHelper::CanOfferOnIOThreadImpl(
761                 GURL("http://accounts.google.com/"),
762                 &request_,
763                 io_data.get()));
764 }
765
766 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabled) {
767   EnableOneClick(false);
768   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
769   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
770             OneClickSigninHelper::CanOfferOnIOThreadImpl(
771                 valid_gaia_url_, &request_, io_data.get()));
772 }
773
774 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
775   PrefService* pref_service = profile()->GetPrefs();
776   pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
777
778   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
779   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
780             OneClickSigninHelper::CanOfferOnIOThreadImpl(
781                 valid_gaia_url_, &request_, io_data.get()));
782 }
783
784 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailNotAllowed) {
785   SetAllowedUsernamePattern("*@example.com");
786   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
787   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
788             OneClickSigninHelper::CanOfferOnIOThreadImpl(
789                 valid_gaia_url_,  &request_, io_data.get()));
790 }
791
792 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadEmailAlreadyUsed) {
793   ProfileInfoCache* cache = testing_profile_manager_.profile_info_cache();
794   const base::FilePath& user_data_dir = cache->GetUserDataDir();
795   cache->AddProfileToCache(user_data_dir.Append(FILE_PATH_LITERAL("user")),
796                            base::UTF8ToUTF16("user"),
797                            base::UTF8ToUTF16("user@gmail.com"), 0,
798                            std::string());
799
800   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
801   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
802             OneClickSigninHelper::CanOfferOnIOThreadImpl(
803                 valid_gaia_url_, &request_, io_data.get()));
804 }
805
806 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadWithRejectedEmail) {
807   AddEmailToOneClickRejectedList("user@gmail.com");
808   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
809   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
810             OneClickSigninHelper::CanOfferOnIOThreadImpl(
811                 valid_gaia_url_, &request_, io_data.get()));
812 }
813
814 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadNoSigninCookies) {
815   AllowSigninCookies(false);
816   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
817   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
818             OneClickSigninHelper::CanOfferOnIOThreadImpl(
819                 valid_gaia_url_, &request_, io_data.get()));
820 }
821
822 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadDisabledByPolicy) {
823   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
824   EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
825             OneClickSigninHelper::CanOfferOnIOThreadImpl(
826                 valid_gaia_url_, &request_, io_data.get()));
827
828   // Simulate a policy disabling signin by writing kSigninAllowed directly.
829   // We should not offer to sign in the browser.
830   profile()->GetTestingPrefService()->SetManagedPref(
831       prefs::kSigninAllowed, base::Value::CreateBooleanValue(false));
832   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
833             OneClickSigninHelper::CanOfferOnIOThreadImpl(
834                 valid_gaia_url_, &request_, io_data.get()));
835
836   // Reset the preference.
837   profile()->GetTestingPrefService()->SetManagedPref(
838       prefs::kSigninAllowed, base::Value::CreateBooleanValue(true));
839
840   // Simulate a policy disabling sync by writing kSyncManaged directly.
841   // We should still offer to sign in the browser.
842   profile()->GetTestingPrefService()->SetManagedPref(
843       prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
844   EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
845             OneClickSigninHelper::CanOfferOnIOThreadImpl(
846                 valid_gaia_url_, &request_, io_data.get()));
847 }