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