Home | History | Annotate | Download | only in webui
      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 "chrome/browser/ui/webui/sync_setup_handler.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/command_line.h"
     10 #include "base/json/json_writer.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/prefs/pref_service.h"
     13 #include "base/stl_util.h"
     14 #include "base/values.h"
     15 #include "chrome/browser/signin/fake_signin_manager.h"
     16 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     17 #include "chrome/browser/signin/signin_manager_factory.h"
     18 #include "chrome/browser/sync/profile_sync_service_factory.h"
     19 #include "chrome/browser/sync/profile_sync_service_mock.h"
     20 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
     21 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
     22 #include "chrome/common/chrome_switches.h"
     23 #include "chrome/common/pref_names.h"
     24 #include "chrome/test/base/scoped_testing_local_state.h"
     25 #include "chrome/test/base/testing_browser_process.h"
     26 #include "chrome/test/base/testing_profile.h"
     27 #include "components/signin/core/browser/fake_auth_status_provider.h"
     28 #include "components/signin/core/browser/profile_oauth2_token_service.h"
     29 #include "components/signin/core/browser/signin_manager.h"
     30 #include "components/sync_driver/sync_prefs.h"
     31 #include "content/public/browser/web_ui.h"
     32 #include "content/public/test/test_browser_thread.h"
     33 #include "content/public/test/test_browser_thread_bundle.h"
     34 #include "testing/gtest/include/gtest/gtest.h"
     35 #include "ui/base/layout.h"
     36 
     37 using ::testing::_;
     38 using ::testing::Mock;
     39 using ::testing::Return;
     40 using ::testing::ReturnRef;
     41 using ::testing::Values;
     42 
     43 typedef GoogleServiceAuthError AuthError;
     44 
     45 namespace {
     46 
     47 MATCHER_P(ModelTypeSetMatches, value, "") { return arg.Equals(value); }
     48 
     49 const char kTestUser[] = "chrome.p13n.test (at) gmail.com";
     50 
     51 // Returns a ModelTypeSet with all user selectable types set.
     52 syncer::ModelTypeSet GetAllTypes() {
     53   return syncer::UserSelectableTypes();
     54 }
     55 
     56 enum SyncAllDataConfig {
     57   SYNC_ALL_DATA,
     58   CHOOSE_WHAT_TO_SYNC,
     59   SYNC_NOTHING
     60 };
     61 
     62 enum EncryptAllConfig {
     63   ENCRYPT_ALL_DATA,
     64   ENCRYPT_PASSWORDS
     65 };
     66 
     67 // Create a json-format string with the key/value pairs appropriate for a call
     68 // to HandleConfigure(). If |extra_values| is non-null, then the values from
     69 // the passed dictionary are added to the json.
     70 std::string GetConfiguration(const base::DictionaryValue* extra_values,
     71                              SyncAllDataConfig sync_all,
     72                              syncer::ModelTypeSet types,
     73                              const std::string& passphrase,
     74                              EncryptAllConfig encrypt_all) {
     75   base::DictionaryValue result;
     76   if (extra_values)
     77     result.MergeDictionary(extra_values);
     78   result.SetBoolean("syncAllDataTypes", sync_all == SYNC_ALL_DATA);
     79   result.SetBoolean("syncNothing", sync_all == SYNC_NOTHING);
     80   result.SetBoolean("encryptAllData", encrypt_all == ENCRYPT_ALL_DATA);
     81   result.SetBoolean("usePassphrase", !passphrase.empty());
     82   if (!passphrase.empty())
     83     result.SetString("passphrase", passphrase);
     84   // Add all of our data types.
     85   result.SetBoolean("appsSynced", types.Has(syncer::APPS));
     86   result.SetBoolean("autofillSynced", types.Has(syncer::AUTOFILL));
     87   result.SetBoolean("bookmarksSynced", types.Has(syncer::BOOKMARKS));
     88   result.SetBoolean("extensionsSynced", types.Has(syncer::EXTENSIONS));
     89   result.SetBoolean("passwordsSynced", types.Has(syncer::PASSWORDS));
     90   result.SetBoolean("preferencesSynced", types.Has(syncer::PREFERENCES));
     91   result.SetBoolean("tabsSynced", types.Has(syncer::PROXY_TABS));
     92   result.SetBoolean("themesSynced", types.Has(syncer::THEMES));
     93   result.SetBoolean("typedUrlsSynced", types.Has(syncer::TYPED_URLS));
     94   std::string args;
     95   base::JSONWriter::Write(&result, &args);
     96   return args;
     97 }
     98 
     99 // Checks whether the passed |dictionary| contains a |key| with the given
    100 // |expected_value|. If |omit_if_false| is true, then the value should only
    101 // be present if |expected_value| is true.
    102 void CheckBool(const base::DictionaryValue* dictionary,
    103                const std::string& key,
    104                bool expected_value,
    105                bool omit_if_false) {
    106   if (omit_if_false && !expected_value) {
    107     EXPECT_FALSE(dictionary->HasKey(key)) <<
    108         "Did not expect to find value for " << key;
    109   } else {
    110     bool actual_value;
    111     EXPECT_TRUE(dictionary->GetBoolean(key, &actual_value)) <<
    112         "No value found for " << key;
    113     EXPECT_EQ(actual_value, expected_value) <<
    114         "Mismatch found for " << key;
    115   }
    116 }
    117 
    118 void CheckBool(const base::DictionaryValue* dictionary,
    119                const std::string& key,
    120                bool expected_value) {
    121   return CheckBool(dictionary, key, expected_value, false);
    122 }
    123 
    124 // Checks to make sure that the values stored in |dictionary| match the values
    125 // expected by the showSyncSetupPage() JS function for a given set of data
    126 // types.
    127 void CheckConfigDataTypeArguments(base::DictionaryValue* dictionary,
    128                                   SyncAllDataConfig config,
    129                                   syncer::ModelTypeSet types) {
    130   CheckBool(dictionary, "syncAllDataTypes", config == SYNC_ALL_DATA);
    131   CheckBool(dictionary, "syncNothing", config == SYNC_NOTHING);
    132   CheckBool(dictionary, "appsSynced", types.Has(syncer::APPS));
    133   CheckBool(dictionary, "autofillSynced", types.Has(syncer::AUTOFILL));
    134   CheckBool(dictionary, "bookmarksSynced", types.Has(syncer::BOOKMARKS));
    135   CheckBool(dictionary, "extensionsSynced", types.Has(syncer::EXTENSIONS));
    136   CheckBool(dictionary, "passwordsSynced", types.Has(syncer::PASSWORDS));
    137   CheckBool(dictionary, "preferencesSynced", types.Has(syncer::PREFERENCES));
    138   CheckBool(dictionary, "tabsSynced", types.Has(syncer::PROXY_TABS));
    139   CheckBool(dictionary, "themesSynced", types.Has(syncer::THEMES));
    140   CheckBool(dictionary, "typedUrlsSynced", types.Has(syncer::TYPED_URLS));
    141 }
    142 
    143 
    144 }  // namespace
    145 
    146 // Test instance of WebUI that tracks the data passed to
    147 // CallJavascriptFunction().
    148 class TestWebUI : public content::WebUI {
    149  public:
    150   virtual ~TestWebUI() {
    151     ClearTrackedCalls();
    152   }
    153 
    154   void ClearTrackedCalls() {
    155     // Manually free the arguments stored in CallData, since there's no good
    156     // way to use a self-freeing reference like scoped_ptr in a std::vector.
    157     for (std::vector<CallData>::iterator i = call_data_.begin();
    158          i != call_data_.end();
    159          ++i) {
    160       delete i->arg1;
    161       delete i->arg2;
    162     }
    163     call_data_.clear();
    164   }
    165 
    166   virtual void CallJavascriptFunction(const std::string& function_name)
    167       OVERRIDE {
    168     call_data_.push_back(CallData());
    169     call_data_.back().function_name = function_name;
    170   }
    171 
    172   virtual void CallJavascriptFunction(const std::string& function_name,
    173                                       const base::Value& arg1) OVERRIDE {
    174     call_data_.push_back(CallData());
    175     call_data_.back().function_name = function_name;
    176     call_data_.back().arg1 = arg1.DeepCopy();
    177   }
    178 
    179   virtual void CallJavascriptFunction(const std::string& function_name,
    180                                       const base::Value& arg1,
    181                                       const base::Value& arg2) OVERRIDE {
    182     call_data_.push_back(CallData());
    183     call_data_.back().function_name = function_name;
    184     call_data_.back().arg1 = arg1.DeepCopy();
    185     call_data_.back().arg2 = arg2.DeepCopy();
    186   }
    187 
    188   virtual content::WebContents* GetWebContents() const OVERRIDE {
    189     return NULL;
    190   }
    191   virtual content::WebUIController* GetController() const OVERRIDE {
    192     return NULL;
    193   }
    194   virtual void SetController(content::WebUIController* controller) OVERRIDE {}
    195   virtual float GetDeviceScaleFactor() const OVERRIDE {
    196     return 1.0f;
    197   }
    198   virtual const base::string16& GetOverriddenTitle() const OVERRIDE {
    199     return temp_string_;
    200   }
    201   virtual void OverrideTitle(const base::string16& title) OVERRIDE {}
    202   virtual ui::PageTransition GetLinkTransitionType() const OVERRIDE {
    203     return ui::PAGE_TRANSITION_LINK;
    204   }
    205   virtual void SetLinkTransitionType(ui::PageTransition type) OVERRIDE {}
    206   virtual int GetBindings() const OVERRIDE {
    207     return 0;
    208   }
    209   virtual void SetBindings(int bindings) OVERRIDE {}
    210   virtual void OverrideJavaScriptFrame(
    211       const std::string& frame_name) OVERRIDE {}
    212   virtual void AddMessageHandler(
    213       content::WebUIMessageHandler* handler) OVERRIDE {}
    214   virtual void RegisterMessageCallback(
    215       const std::string& message,
    216       const MessageCallback& callback) OVERRIDE {}
    217   virtual void ProcessWebUIMessage(const GURL& source_url,
    218                                    const std::string& message,
    219                                    const base::ListValue& args) OVERRIDE {}
    220   virtual void CallJavascriptFunction(const std::string& function_name,
    221                                       const base::Value& arg1,
    222                                       const base::Value& arg2,
    223                                       const base::Value& arg3) OVERRIDE {}
    224   virtual void CallJavascriptFunction(const std::string& function_name,
    225                                       const base::Value& arg1,
    226                                       const base::Value& arg2,
    227                                       const base::Value& arg3,
    228                                       const base::Value& arg4) OVERRIDE {}
    229   virtual void CallJavascriptFunction(
    230       const std::string& function_name,
    231       const std::vector<const base::Value*>& args) OVERRIDE {}
    232 
    233   class CallData {
    234    public:
    235     CallData() : arg1(NULL), arg2(NULL) {}
    236     std::string function_name;
    237     base::Value* arg1;
    238     base::Value* arg2;
    239   };
    240   const std::vector<CallData>& call_data() { return call_data_; }
    241  private:
    242   std::vector<CallData> call_data_;
    243   base::string16 temp_string_;
    244 };
    245 
    246 class TestingSyncSetupHandler : public SyncSetupHandler {
    247  public:
    248   TestingSyncSetupHandler(content::WebUI* web_ui, Profile* profile)
    249       : SyncSetupHandler(NULL),
    250         profile_(profile) {
    251     set_web_ui(web_ui);
    252   }
    253   virtual ~TestingSyncSetupHandler() {
    254     set_web_ui(NULL);
    255   }
    256 
    257   virtual void FocusUI() OVERRIDE {}
    258 
    259   virtual Profile* GetProfile() const OVERRIDE { return profile_; }
    260 
    261   using SyncSetupHandler::is_configuring_sync;
    262 
    263  private:
    264 #if !defined(OS_CHROMEOS)
    265   virtual void DisplayGaiaLoginInNewTabOrWindow() OVERRIDE {}
    266 #endif
    267 
    268   // Weak pointer to parent profile.
    269   Profile* profile_;
    270   DISALLOW_COPY_AND_ASSIGN(TestingSyncSetupHandler);
    271 };
    272 
    273 // The boolean parameter indicates whether the test is run with ClientOAuth
    274 // or not.  The test parameter is a bool: whether or not to test with/
    275 // /ClientLogin enabled or not.
    276 class SyncSetupHandlerTest : public testing::Test {
    277  public:
    278   SyncSetupHandlerTest() : error_(GoogleServiceAuthError::NONE) {}
    279   virtual void SetUp() OVERRIDE {
    280     error_ = GoogleServiceAuthError::AuthErrorNone();
    281 
    282     TestingProfile::Builder builder;
    283     builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
    284                               FakeSigninManagerBase::Build);
    285     profile_ = builder.Build();
    286 
    287     // Sign in the user.
    288     mock_signin_ = static_cast<SigninManagerBase*>(
    289         SigninManagerFactory::GetForProfile(profile_.get()));
    290     mock_signin_->SetAuthenticatedUsername(GetTestUser());
    291     profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
    292                                     GetTestUser());
    293 
    294     mock_pss_ = static_cast<ProfileSyncServiceMock*>(
    295         ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
    296             profile_.get(),
    297             ProfileSyncServiceMock::BuildMockProfileSyncService));
    298     EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
    299     ON_CALL(*mock_pss_, GetPassphraseType()).WillByDefault(
    300         Return(syncer::IMPLICIT_PASSPHRASE));
    301     ON_CALL(*mock_pss_, GetPassphraseTime()).WillByDefault(
    302         Return(base::Time()));
    303     ON_CALL(*mock_pss_, GetExplicitPassphraseTime()).WillByDefault(
    304         Return(base::Time()));
    305     ON_CALL(*mock_pss_, GetRegisteredDataTypes())
    306         .WillByDefault(Return(syncer::ModelTypeSet()));
    307 
    308     mock_pss_->Initialize();
    309 
    310     handler_.reset(new TestingSyncSetupHandler(&web_ui_, profile_.get()));
    311   }
    312 
    313   // Setup the expectations for calls made when displaying the config page.
    314   void SetDefaultExpectationsForConfigPage() {
    315     EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn()).
    316         WillRepeatedly(Return(true));
    317     EXPECT_CALL(*mock_pss_, GetRegisteredDataTypes()).
    318         WillRepeatedly(Return(GetAllTypes()));
    319     EXPECT_CALL(*mock_pss_, GetPreferredDataTypes()).
    320         WillRepeatedly(Return(GetAllTypes()));
    321     EXPECT_CALL(*mock_pss_, GetActiveDataTypes()).
    322         WillRepeatedly(Return(GetAllTypes()));
    323     EXPECT_CALL(*mock_pss_, EncryptEverythingAllowed()).
    324         WillRepeatedly(Return(true));
    325     EXPECT_CALL(*mock_pss_, EncryptEverythingEnabled()).
    326         WillRepeatedly(Return(false));
    327   }
    328 
    329   void SetupInitializedProfileSyncService() {
    330     // An initialized ProfileSyncService will have already completed sync setup
    331     // and will have an initialized sync backend.
    332     ASSERT_TRUE(mock_signin_->IsInitialized());
    333     EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(true));
    334   }
    335 
    336   void ExpectConfig() {
    337     ASSERT_EQ(1U, web_ui_.call_data().size());
    338     const TestWebUI::CallData& data = web_ui_.call_data()[0];
    339     EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name);
    340     std::string page;
    341     ASSERT_TRUE(data.arg1->GetAsString(&page));
    342     EXPECT_EQ(page, "configure");
    343   }
    344 
    345   void ExpectDone() {
    346     ASSERT_EQ(1U, web_ui_.call_data().size());
    347     const TestWebUI::CallData& data = web_ui_.call_data()[0];
    348     EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name);
    349     std::string page;
    350     ASSERT_TRUE(data.arg1->GetAsString(&page));
    351     EXPECT_EQ(page, "done");
    352   }
    353 
    354   void ExpectSpinnerAndClose() {
    355     // We expect a call to SyncSetupOverlay.showSyncSetupPage.
    356     EXPECT_EQ(1U, web_ui_.call_data().size());
    357     const TestWebUI::CallData& data = web_ui_.call_data()[0];
    358     EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name);
    359 
    360     std::string page;
    361     ASSERT_TRUE(data.arg1->GetAsString(&page));
    362     EXPECT_EQ(page, "spinner");
    363     // Cancelling the spinner dialog will cause CloseSyncSetup().
    364     handler_->CloseSyncSetup();
    365     EXPECT_EQ(NULL,
    366               LoginUIServiceFactory::GetForProfile(
    367                   profile_.get())->current_login_ui());
    368   }
    369 
    370   // It's difficult to notify sync listeners when using a ProfileSyncServiceMock
    371   // so this helper routine dispatches an OnStateChanged() notification to the
    372   // SyncStartupTracker.
    373   void NotifySyncListeners() {
    374     if (handler_->sync_startup_tracker_)
    375       handler_->sync_startup_tracker_->OnStateChanged();
    376   }
    377 
    378   virtual std::string GetTestUser() {
    379     return std::string(kTestUser);
    380   }
    381 
    382   content::TestBrowserThreadBundle thread_bundle_;
    383   scoped_ptr<Profile> profile_;
    384   ProfileSyncServiceMock* mock_pss_;
    385   GoogleServiceAuthError error_;
    386   SigninManagerBase* mock_signin_;
    387   TestWebUI web_ui_;
    388   scoped_ptr<TestingSyncSetupHandler> handler_;
    389 };
    390 
    391 class SyncSetupHandlerFirstSigninTest : public SyncSetupHandlerTest {
    392   virtual std::string GetTestUser() OVERRIDE { return std::string(); }
    393 };
    394 
    395 TEST_F(SyncSetupHandlerTest, Basic) {
    396 }
    397 
    398 #if !defined(OS_CHROMEOS)
    399 TEST_F(SyncSetupHandlerFirstSigninTest, DisplayBasicLogin) {
    400   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    401       .WillRepeatedly(Return(false));
    402   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    403       .WillRepeatedly(Return(false));
    404   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    405       .WillRepeatedly(Return(false));
    406   // Ensure that the user is not signed in before calling |HandleStartSignin()|.
    407   SigninManager* manager = static_cast<SigninManager*>(mock_signin_);
    408   manager->SignOut(signin_metrics::SIGNOUT_TEST);
    409   handler_->HandleStartSignin(NULL);
    410 
    411   // Sync setup hands off control to the gaia login tab.
    412   EXPECT_EQ(NULL,
    413             LoginUIServiceFactory::GetForProfile(
    414                 profile_.get())->current_login_ui());
    415 
    416   ASSERT_FALSE(handler_->is_configuring_sync());
    417 
    418   handler_->CloseSyncSetup();
    419   EXPECT_EQ(NULL,
    420             LoginUIServiceFactory::GetForProfile(
    421                 profile_.get())->current_login_ui());
    422 }
    423 
    424 TEST_F(SyncSetupHandlerTest, ShowSyncSetupWhenNotSignedIn) {
    425   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    426       .WillRepeatedly(Return(false));
    427   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    428       .WillRepeatedly(Return(false));
    429   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    430       .WillRepeatedly(Return(false));
    431   handler_->HandleShowSetupUI(NULL);
    432 
    433   // We expect a call to SyncSetupOverlay.showSyncSetupPage.
    434   ASSERT_EQ(1U, web_ui_.call_data().size());
    435   const TestWebUI::CallData& data = web_ui_.call_data()[0];
    436   EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name);
    437 
    438   ASSERT_FALSE(handler_->is_configuring_sync());
    439   EXPECT_EQ(NULL,
    440             LoginUIServiceFactory::GetForProfile(
    441                 profile_.get())->current_login_ui());
    442 }
    443 #endif  // !defined(OS_CHROMEOS)
    444 
    445 // Verifies that the sync setup is terminated correctly when the
    446 // sync is disabled.
    447 TEST_F(SyncSetupHandlerTest, HandleSetupUIWhenSyncDisabled) {
    448   EXPECT_CALL(*mock_pss_, IsManaged()).WillRepeatedly(Return(true));
    449   handler_->HandleShowSetupUI(NULL);
    450 
    451   // Sync setup is closed when sync is disabled.
    452   EXPECT_EQ(NULL,
    453             LoginUIServiceFactory::GetForProfile(
    454                 profile_.get())->current_login_ui());
    455   ASSERT_FALSE(handler_->is_configuring_sync());
    456 }
    457 
    458 // Verifies that the handler correctly handles a cancellation when
    459 // it is displaying the spinner to the user.
    460 TEST_F(SyncSetupHandlerTest, DisplayConfigureWithBackendDisabledAndCancel) {
    461   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    462       .WillRepeatedly(Return(true));
    463   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    464       .WillRepeatedly(Return(true));
    465   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    466       .WillRepeatedly(Return(false));
    467   error_ = GoogleServiceAuthError::AuthErrorNone();
    468   EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(false));
    469 
    470   // We're simulating a user setting up sync, which would cause the backend to
    471   // kick off initialization, but not download user data types. The sync
    472   // backend will try to download control data types (e.g encryption info), but
    473   // that won't finish for this test as we're simulating cancelling while the
    474   // spinner is showing.
    475   handler_->HandleShowSetupUI(NULL);
    476 
    477   EXPECT_EQ(handler_.get(),
    478             LoginUIServiceFactory::GetForProfile(
    479                 profile_.get())->current_login_ui());
    480 
    481   ExpectSpinnerAndClose();
    482 }
    483 
    484 // Verifies that the handler correctly transitions from showing the spinner
    485 // to showing a configuration page when sync setup completes successfully.
    486 TEST_F(SyncSetupHandlerTest,
    487        DisplayConfigureWithBackendDisabledAndSyncStartupCompleted) {
    488   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    489       .WillRepeatedly(Return(true));
    490   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    491       .WillRepeatedly(Return(true));
    492   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    493       .WillRepeatedly(Return(false));
    494   error_ = GoogleServiceAuthError::AuthErrorNone();
    495   // Sync backend is stopped initially, and will start up.
    496   EXPECT_CALL(*mock_pss_, sync_initialized())
    497       .WillRepeatedly(Return(false));
    498   SetDefaultExpectationsForConfigPage();
    499 
    500   handler_->OpenSyncSetup();
    501 
    502   // We expect a call to SyncSetupOverlay.showSyncSetupPage.
    503   EXPECT_EQ(1U, web_ui_.call_data().size());
    504 
    505   const TestWebUI::CallData& data0 = web_ui_.call_data()[0];
    506   EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data0.function_name);
    507   std::string page;
    508   ASSERT_TRUE(data0.arg1->GetAsString(&page));
    509   EXPECT_EQ(page, "spinner");
    510 
    511   Mock::VerifyAndClearExpectations(mock_pss_);
    512   // Now, act as if the ProfileSyncService has started up.
    513   SetDefaultExpectationsForConfigPage();
    514   EXPECT_CALL(*mock_pss_, sync_initialized())
    515       .WillRepeatedly(Return(true));
    516   error_ = GoogleServiceAuthError::AuthErrorNone();
    517   EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
    518   NotifySyncListeners();
    519 
    520   // We expect a second call to SyncSetupOverlay.showSyncSetupPage.
    521   EXPECT_EQ(2U, web_ui_.call_data().size());
    522   const TestWebUI::CallData& data1 = web_ui_.call_data().back();
    523   EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data1.function_name);
    524   ASSERT_TRUE(data1.arg1->GetAsString(&page));
    525   EXPECT_EQ(page, "configure");
    526   base::DictionaryValue* dictionary;
    527   ASSERT_TRUE(data1.arg2->GetAsDictionary(&dictionary));
    528   CheckBool(dictionary, "passphraseFailed", false);
    529   CheckBool(dictionary, "showSyncEverythingPage", false);
    530   CheckBool(dictionary, "syncAllDataTypes", true);
    531   CheckBool(dictionary, "encryptAllDataAllowed", true);
    532   CheckBool(dictionary, "encryptAllData", false);
    533   CheckBool(dictionary, "usePassphrase", false);
    534 }
    535 
    536 // Verifies the case where the user cancels after the sync backend has
    537 // initialized (meaning it already transitioned from the spinner to a proper
    538 // configuration page, tested by
    539 // DisplayConfigureWithBackendDisabledAndSigninSuccess), but before the user
    540 // before the user has continued on.
    541 TEST_F(SyncSetupHandlerTest,
    542        DisplayConfigureWithBackendDisabledAndCancelAfterSigninSuccess) {
    543   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    544       .WillRepeatedly(Return(true));
    545   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    546       .WillRepeatedly(Return(true));
    547   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    548       .WillRepeatedly(Return(false));
    549   error_ = GoogleServiceAuthError::AuthErrorNone();
    550   EXPECT_CALL(*mock_pss_, sync_initialized())
    551       .WillOnce(Return(false))
    552       .WillRepeatedly(Return(true));
    553   SetDefaultExpectationsForConfigPage();
    554   handler_->OpenSyncSetup();
    555 
    556   // It's important to tell sync the user cancelled the setup flow before we
    557   // tell it we're through with the setup progress.
    558   testing::InSequence seq;
    559   EXPECT_CALL(*mock_pss_, DisableForUser());
    560   EXPECT_CALL(*mock_pss_, SetSetupInProgress(false));
    561 
    562   handler_->CloseSyncSetup();
    563   EXPECT_EQ(NULL,
    564             LoginUIServiceFactory::GetForProfile(
    565                 profile_.get())->current_login_ui());
    566 }
    567 
    568 TEST_F(SyncSetupHandlerTest,
    569        DisplayConfigureWithBackendDisabledAndSigninFailed) {
    570   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    571       .WillRepeatedly(Return(true));
    572   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    573       .WillRepeatedly(Return(true));
    574   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    575       .WillRepeatedly(Return(false));
    576   error_ = GoogleServiceAuthError::AuthErrorNone();
    577   EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(false));
    578 
    579   handler_->OpenSyncSetup();
    580   const TestWebUI::CallData& data = web_ui_.call_data()[0];
    581   EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name);
    582   std::string page;
    583   ASSERT_TRUE(data.arg1->GetAsString(&page));
    584   EXPECT_EQ(page, "spinner");
    585   Mock::VerifyAndClearExpectations(mock_pss_);
    586   error_ = GoogleServiceAuthError(
    587       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
    588   EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
    589   NotifySyncListeners();
    590 
    591   // On failure, the dialog will be closed.
    592   EXPECT_EQ(NULL,
    593             LoginUIServiceFactory::GetForProfile(
    594                 profile_.get())->current_login_ui());
    595 }
    596 
    597 #if !defined(OS_CHROMEOS)
    598 
    599 class SyncSetupHandlerNonCrosTest : public SyncSetupHandlerTest {
    600  public:
    601   SyncSetupHandlerNonCrosTest() {}
    602 };
    603 
    604 TEST_F(SyncSetupHandlerNonCrosTest, HandleGaiaAuthFailure) {
    605   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    606       .WillRepeatedly(Return(false));
    607   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    608       .WillRepeatedly(Return(false));
    609   EXPECT_CALL(*mock_pss_, HasUnrecoverableError())
    610       .WillRepeatedly(Return(false));
    611   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    612       .WillRepeatedly(Return(false));
    613   // Open the web UI.
    614   handler_->OpenSyncSetup();
    615 
    616   ASSERT_FALSE(handler_->is_configuring_sync());
    617 }
    618 
    619 // TODO(kochi): We need equivalent tests for ChromeOS.
    620 TEST_F(SyncSetupHandlerNonCrosTest, UnrecoverableErrorInitializingSync) {
    621   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    622       .WillRepeatedly(Return(false));
    623   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    624       .WillRepeatedly(Return(false));
    625   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    626       .WillRepeatedly(Return(false));
    627   // Open the web UI.
    628   handler_->OpenSyncSetup();
    629 
    630   ASSERT_FALSE(handler_->is_configuring_sync());
    631 }
    632 
    633 TEST_F(SyncSetupHandlerNonCrosTest, GaiaErrorInitializingSync) {
    634   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    635       .WillRepeatedly(Return(false));
    636   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    637       .WillRepeatedly(Return(false));
    638   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
    639       .WillRepeatedly(Return(false));
    640   // Open the web UI.
    641   handler_->OpenSyncSetup();
    642 
    643   ASSERT_FALSE(handler_->is_configuring_sync());
    644 }
    645 
    646 #endif  // #if !defined(OS_CHROMEOS)
    647 
    648 TEST_F(SyncSetupHandlerTest, TestSyncEverything) {
    649   std::string args = GetConfiguration(
    650       NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), ENCRYPT_PASSWORDS);
    651   base::ListValue list_args;
    652   list_args.Append(new base::StringValue(args));
    653   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    654       .WillRepeatedly(Return(false));
    655   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    656       .WillRepeatedly(Return(false));
    657   SetupInitializedProfileSyncService();
    658   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(true, _));
    659   handler_->HandleConfigure(&list_args);
    660 
    661   // Ensure that we navigated to the "done" state since we don't need a
    662   // passphrase.
    663   ExpectDone();
    664 }
    665 
    666 TEST_F(SyncSetupHandlerTest, TestSyncNothing) {
    667   std::string args = GetConfiguration(
    668       NULL, SYNC_NOTHING, GetAllTypes(), std::string(), ENCRYPT_PASSWORDS);
    669   base::ListValue list_args;
    670   list_args.Append(new base::StringValue(args));
    671   EXPECT_CALL(*mock_pss_, DisableForUser());
    672   SetupInitializedProfileSyncService();
    673   handler_->HandleConfigure(&list_args);
    674 
    675   // We expect a call to SyncSetupOverlay.showSyncSetupPage.
    676   ASSERT_EQ(1U, web_ui_.call_data().size());
    677   const TestWebUI::CallData& data = web_ui_.call_data()[0];
    678   EXPECT_EQ("SyncSetupOverlay.showSyncSetupPage", data.function_name);
    679 }
    680 
    681 TEST_F(SyncSetupHandlerTest, TurnOnEncryptAll) {
    682   std::string args = GetConfiguration(
    683       NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), ENCRYPT_ALL_DATA);
    684   base::ListValue list_args;
    685   list_args.Append(new base::StringValue(args));
    686   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    687       .WillRepeatedly(Return(false));
    688   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    689       .WillRepeatedly(Return(false));
    690   EXPECT_CALL(*mock_pss_, EncryptEverythingAllowed())
    691       .WillRepeatedly(Return(true));
    692   SetupInitializedProfileSyncService();
    693   EXPECT_CALL(*mock_pss_, EnableEncryptEverything());
    694   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(true, _));
    695   handler_->HandleConfigure(&list_args);
    696 
    697   // Ensure that we navigated to the "done" state since we don't need a
    698   // passphrase.
    699   ExpectDone();
    700 }
    701 
    702 TEST_F(SyncSetupHandlerTest, TestPassphraseStillRequired) {
    703   std::string args = GetConfiguration(
    704       NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), ENCRYPT_PASSWORDS);
    705   base::ListValue list_args;
    706   list_args.Append(new base::StringValue(args));
    707   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    708       .WillRepeatedly(Return(true));
    709   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    710       .WillRepeatedly(Return(true));
    711   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    712       .WillRepeatedly(Return(false));
    713   SetupInitializedProfileSyncService();
    714   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _));
    715   SetDefaultExpectationsForConfigPage();
    716 
    717   // We should navigate back to the configure page since we need a passphrase.
    718   handler_->HandleConfigure(&list_args);
    719 
    720   ExpectConfig();
    721 }
    722 
    723 TEST_F(SyncSetupHandlerTest, SuccessfullySetPassphrase) {
    724   base::DictionaryValue dict;
    725   dict.SetBoolean("isGooglePassphrase", true);
    726   std::string args = GetConfiguration(&dict,
    727                                       SYNC_ALL_DATA,
    728                                       GetAllTypes(),
    729                                       "gaiaPassphrase",
    730                                       ENCRYPT_PASSWORDS);
    731   base::ListValue list_args;
    732   list_args.Append(new base::StringValue(args));
    733   // Act as if an encryption passphrase is required the first time, then never
    734   // again after that.
    735   EXPECT_CALL(*mock_pss_, IsPassphraseRequired()).WillOnce(Return(true));
    736   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    737       .WillRepeatedly(Return(false));
    738   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    739       .WillRepeatedly(Return(false));
    740   SetupInitializedProfileSyncService();
    741   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _));
    742   EXPECT_CALL(*mock_pss_, SetDecryptionPassphrase("gaiaPassphrase")).
    743       WillOnce(Return(true));
    744 
    745   handler_->HandleConfigure(&list_args);
    746   // We should navigate to "done" page since we finished configuring.
    747   ExpectDone();
    748 }
    749 
    750 TEST_F(SyncSetupHandlerTest, SelectCustomEncryption) {
    751   base::DictionaryValue dict;
    752   dict.SetBoolean("isGooglePassphrase", false);
    753   std::string args = GetConfiguration(&dict,
    754                                       SYNC_ALL_DATA,
    755                                       GetAllTypes(),
    756                                       "custom_passphrase",
    757                                       ENCRYPT_PASSWORDS);
    758   base::ListValue list_args;
    759   list_args.Append(new base::StringValue(args));
    760   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    761       .WillRepeatedly(Return(false));
    762   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    763       .WillRepeatedly(Return(false));
    764   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    765       .WillRepeatedly(Return(false));
    766   SetupInitializedProfileSyncService();
    767   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _));
    768   EXPECT_CALL(*mock_pss_,
    769               SetEncryptionPassphrase("custom_passphrase",
    770                                       ProfileSyncService::EXPLICIT));
    771 
    772   handler_->HandleConfigure(&list_args);
    773   // We should navigate to "done" page since we finished configuring.
    774   ExpectDone();
    775 }
    776 
    777 TEST_F(SyncSetupHandlerTest, UnsuccessfullySetPassphrase) {
    778   base::DictionaryValue dict;
    779   dict.SetBoolean("isGooglePassphrase", true);
    780   std::string args = GetConfiguration(&dict,
    781                                       SYNC_ALL_DATA,
    782                                       GetAllTypes(),
    783                                       "invalid_passphrase",
    784                                       ENCRYPT_PASSWORDS);
    785   base::ListValue list_args;
    786   list_args.Append(new base::StringValue(args));
    787   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    788       .WillRepeatedly(Return(true));
    789   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    790       .WillRepeatedly(Return(true));
    791   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    792       .WillRepeatedly(Return(false));
    793   SetupInitializedProfileSyncService();
    794   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(_, _));
    795   EXPECT_CALL(*mock_pss_, SetDecryptionPassphrase("invalid_passphrase")).
    796       WillOnce(Return(false));
    797 
    798   SetDefaultExpectationsForConfigPage();
    799   // We should navigate back to the configure page since we need a passphrase.
    800   handler_->HandleConfigure(&list_args);
    801 
    802   ExpectConfig();
    803 
    804   // Make sure we display an error message to the user due to the failed
    805   // passphrase.
    806   const TestWebUI::CallData& data = web_ui_.call_data()[0];
    807   base::DictionaryValue* dictionary;
    808   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
    809   CheckBool(dictionary, "passphraseFailed", true);
    810 }
    811 
    812 // Walks through each user selectable type, and tries to sync just that single
    813 // data type.
    814 TEST_F(SyncSetupHandlerTest, TestSyncIndividualTypes) {
    815   syncer::ModelTypeSet user_selectable_types = GetAllTypes();
    816   syncer::ModelTypeSet::Iterator it;
    817   for (it = user_selectable_types.First(); it.Good(); it.Inc()) {
    818     syncer::ModelTypeSet type_to_set;
    819     type_to_set.Put(it.Get());
    820     std::string args = GetConfiguration(NULL,
    821                                         CHOOSE_WHAT_TO_SYNC,
    822                                         type_to_set,
    823                                         std::string(),
    824                                         ENCRYPT_PASSWORDS);
    825     base::ListValue list_args;
    826     list_args.Append(new base::StringValue(args));
    827     EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    828         .WillRepeatedly(Return(false));
    829     EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    830         .WillRepeatedly(Return(false));
    831     SetupInitializedProfileSyncService();
    832     EXPECT_CALL(*mock_pss_,
    833                 OnUserChoseDatatypes(false, ModelTypeSetMatches(type_to_set)));
    834     handler_->HandleConfigure(&list_args);
    835 
    836     ExpectDone();
    837     Mock::VerifyAndClearExpectations(mock_pss_);
    838     web_ui_.ClearTrackedCalls();
    839   }
    840 }
    841 
    842 TEST_F(SyncSetupHandlerTest, TestSyncAllManually) {
    843   std::string args = GetConfiguration(NULL,
    844                                       CHOOSE_WHAT_TO_SYNC,
    845                                       GetAllTypes(),
    846                                       std::string(),
    847                                       ENCRYPT_PASSWORDS);
    848   base::ListValue list_args;
    849   list_args.Append(new base::StringValue(args));
    850   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
    851       .WillRepeatedly(Return(false));
    852   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    853       .WillRepeatedly(Return(false));
    854   SetupInitializedProfileSyncService();
    855   EXPECT_CALL(*mock_pss_,
    856               OnUserChoseDatatypes(false, ModelTypeSetMatches(GetAllTypes())));
    857   handler_->HandleConfigure(&list_args);
    858 
    859   ExpectDone();
    860 }
    861 
    862 TEST_F(SyncSetupHandlerTest, ShowSyncSetup) {
    863   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    864       .WillRepeatedly(Return(false));
    865   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    866       .WillRepeatedly(Return(false));
    867   SetupInitializedProfileSyncService();
    868   // This should display the sync setup dialog (not login).
    869   SetDefaultExpectationsForConfigPage();
    870   handler_->OpenSyncSetup();
    871 
    872   ExpectConfig();
    873 }
    874 
    875 // We do not display signin on chromeos in the case of auth error.
    876 TEST_F(SyncSetupHandlerTest, ShowSigninOnAuthError) {
    877   // Initialize the system to a signed in state, but with an auth error.
    878   error_ = GoogleServiceAuthError(
    879       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
    880 
    881   SetupInitializedProfileSyncService();
    882   mock_signin_->SetAuthenticatedUsername(kTestUser);
    883   FakeAuthStatusProvider provider(
    884       ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get())->
    885           signin_error_controller());
    886   provider.SetAuthError(kTestUser, kTestUser, error_);
    887   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
    888       .WillRepeatedly(Return(true));
    889   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
    890       .WillRepeatedly(Return(true));
    891   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    892       .WillRepeatedly(Return(false));
    893   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    894       .WillRepeatedly(Return(false));
    895   EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(false));
    896 
    897 #if defined(OS_CHROMEOS)
    898   // On ChromeOS, auth errors are ignored - instead we just try to start the
    899   // sync backend (which will fail due to the auth error). This should only
    900   // happen if the user manually navigates to chrome://settings/syncSetup -
    901   // clicking on the button in the UI will sign the user out rather than
    902   // displaying a spinner. Should be no visible UI on ChromeOS in this case.
    903   EXPECT_EQ(NULL, LoginUIServiceFactory::GetForProfile(
    904       profile_.get())->current_login_ui());
    905 #else
    906 
    907   // On ChromeOS, this should display the spinner while we try to startup the
    908   // sync backend, and on desktop this displays the login dialog.
    909   handler_->OpenSyncSetup();
    910 
    911   // Sync setup is closed when re-auth is in progress.
    912   EXPECT_EQ(NULL,
    913             LoginUIServiceFactory::GetForProfile(
    914                 profile_.get())->current_login_ui());
    915 
    916   ASSERT_FALSE(handler_->is_configuring_sync());
    917 #endif
    918 }
    919 
    920 TEST_F(SyncSetupHandlerTest, ShowSetupSyncEverything) {
    921   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    922       .WillRepeatedly(Return(false));
    923   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    924       .WillRepeatedly(Return(false));
    925   SetupInitializedProfileSyncService();
    926   SetDefaultExpectationsForConfigPage();
    927   // This should display the sync setup dialog (not login).
    928   handler_->OpenSyncSetup();
    929 
    930   ExpectConfig();
    931   const TestWebUI::CallData& data = web_ui_.call_data()[0];
    932   base::DictionaryValue* dictionary;
    933   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
    934   CheckBool(dictionary, "showSyncEverythingPage", false);
    935   CheckBool(dictionary, "syncAllDataTypes", true);
    936   CheckBool(dictionary, "appsRegistered", true);
    937   CheckBool(dictionary, "autofillRegistered", true);
    938   CheckBool(dictionary, "bookmarksRegistered", true);
    939   CheckBool(dictionary, "extensionsRegistered", true);
    940   CheckBool(dictionary, "passwordsRegistered", true);
    941   CheckBool(dictionary, "preferencesRegistered", true);
    942   CheckBool(dictionary, "tabsRegistered", true);
    943   CheckBool(dictionary, "themesRegistered", true);
    944   CheckBool(dictionary, "typedUrlsRegistered", true);
    945   CheckBool(dictionary, "showPassphrase", false);
    946   CheckBool(dictionary, "usePassphrase", false);
    947   CheckBool(dictionary, "passphraseFailed", false);
    948   CheckBool(dictionary, "encryptAllData", false);
    949   CheckConfigDataTypeArguments(dictionary, SYNC_ALL_DATA, GetAllTypes());
    950 }
    951 
    952 TEST_F(SyncSetupHandlerTest, ShowSetupManuallySyncAll) {
    953   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    954       .WillRepeatedly(Return(false));
    955   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    956       .WillRepeatedly(Return(false));
    957   SetupInitializedProfileSyncService();
    958   sync_driver::SyncPrefs sync_prefs(profile_->GetPrefs());
    959   sync_prefs.SetKeepEverythingSynced(false);
    960   SetDefaultExpectationsForConfigPage();
    961   // This should display the sync setup dialog (not login).
    962   handler_->OpenSyncSetup();
    963 
    964   ExpectConfig();
    965   const TestWebUI::CallData& data = web_ui_.call_data()[0];
    966   base::DictionaryValue* dictionary;
    967   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
    968   CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, GetAllTypes());
    969 }
    970 
    971 TEST_F(SyncSetupHandlerTest, ShowSetupSyncForAllTypesIndividually) {
    972   syncer::ModelTypeSet user_selectable_types = GetAllTypes();
    973   syncer::ModelTypeSet::Iterator it;
    974   for (it = user_selectable_types.First(); it.Good(); it.Inc()) {
    975     EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
    976         .WillRepeatedly(Return(false));
    977     EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
    978         .WillRepeatedly(Return(false));
    979     SetupInitializedProfileSyncService();
    980     sync_driver::SyncPrefs sync_prefs(profile_->GetPrefs());
    981     sync_prefs.SetKeepEverythingSynced(false);
    982     SetDefaultExpectationsForConfigPage();
    983     syncer::ModelTypeSet types;
    984     types.Put(it.Get());
    985     EXPECT_CALL(*mock_pss_, GetPreferredDataTypes()).
    986         WillRepeatedly(Return(types));
    987 
    988     // This should display the sync setup dialog (not login).
    989     handler_->OpenSyncSetup();
    990 
    991     ExpectConfig();
    992     // Close the config overlay.
    993     LoginUIServiceFactory::GetForProfile(profile_.get())->LoginUIClosed(
    994         handler_.get());
    995     const TestWebUI::CallData& data = web_ui_.call_data()[0];
    996     base::DictionaryValue* dictionary;
    997     ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
    998     CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, types);
    999     Mock::VerifyAndClearExpectations(mock_pss_);
   1000     // Clean up so we can loop back to display the dialog again.
   1001     web_ui_.ClearTrackedCalls();
   1002   }
   1003 }
   1004 
   1005 TEST_F(SyncSetupHandlerTest, ShowSetupGaiaPassphraseRequired) {
   1006   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
   1007       .WillRepeatedly(Return(true));
   1008   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
   1009       .WillRepeatedly(Return(false));
   1010   SetupInitializedProfileSyncService();
   1011   SetDefaultExpectationsForConfigPage();
   1012 
   1013   // This should display the sync setup dialog (not login).
   1014   handler_->OpenSyncSetup();
   1015 
   1016   ExpectConfig();
   1017   const TestWebUI::CallData& data = web_ui_.call_data()[0];
   1018   base::DictionaryValue* dictionary;
   1019   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
   1020   CheckBool(dictionary, "showPassphrase", true);
   1021   CheckBool(dictionary, "usePassphrase", false);
   1022   CheckBool(dictionary, "passphraseFailed", false);
   1023 }
   1024 
   1025 TEST_F(SyncSetupHandlerTest, ShowSetupCustomPassphraseRequired) {
   1026   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
   1027       .WillRepeatedly(Return(true));
   1028   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
   1029       .WillRepeatedly(Return(true));
   1030   EXPECT_CALL(*mock_pss_, GetPassphraseType())
   1031       .WillRepeatedly(Return(syncer::CUSTOM_PASSPHRASE));
   1032   SetupInitializedProfileSyncService();
   1033   SetDefaultExpectationsForConfigPage();
   1034 
   1035   // This should display the sync setup dialog (not login).
   1036   handler_->OpenSyncSetup();
   1037 
   1038   ExpectConfig();
   1039   const TestWebUI::CallData& data = web_ui_.call_data()[0];
   1040   base::DictionaryValue* dictionary;
   1041   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
   1042   CheckBool(dictionary, "showPassphrase", true);
   1043   CheckBool(dictionary, "usePassphrase", true);
   1044   CheckBool(dictionary, "passphraseFailed", false);
   1045 }
   1046 
   1047 TEST_F(SyncSetupHandlerTest, ShowSetupEncryptAll) {
   1048   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
   1049       .WillRepeatedly(Return(false));
   1050   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
   1051       .WillRepeatedly(Return(false));
   1052   SetupInitializedProfileSyncService();
   1053   SetDefaultExpectationsForConfigPage();
   1054   EXPECT_CALL(*mock_pss_, EncryptEverythingEnabled()).
   1055       WillRepeatedly(Return(true));
   1056 
   1057   // This should display the sync setup dialog (not login).
   1058   handler_->OpenSyncSetup();
   1059 
   1060   ExpectConfig();
   1061   const TestWebUI::CallData& data = web_ui_.call_data()[0];
   1062   base::DictionaryValue* dictionary;
   1063   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
   1064   CheckBool(dictionary, "encryptAllData", true);
   1065 }
   1066 
   1067 TEST_F(SyncSetupHandlerTest, ShowSetupEncryptAllDisallowed) {
   1068   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
   1069       .WillRepeatedly(Return(false));
   1070   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
   1071       .WillRepeatedly(Return(false));
   1072   SetupInitializedProfileSyncService();
   1073   SetDefaultExpectationsForConfigPage();
   1074   EXPECT_CALL(*mock_pss_, EncryptEverythingAllowed()).
   1075       WillRepeatedly(Return(false));
   1076 
   1077   // This should display the sync setup dialog (not login).
   1078   handler_->OpenSyncSetup();
   1079 
   1080   ExpectConfig();
   1081   const TestWebUI::CallData& data = web_ui_.call_data()[0];
   1082   base::DictionaryValue* dictionary;
   1083   ASSERT_TRUE(data.arg2->GetAsDictionary(&dictionary));
   1084   CheckBool(dictionary, "encryptAllData", false);
   1085   CheckBool(dictionary, "encryptAllDataAllowed", false);
   1086 }
   1087 
   1088 TEST_F(SyncSetupHandlerTest, TurnOnEncryptAllDisallowed) {
   1089   std::string args = GetConfiguration(
   1090       NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), ENCRYPT_ALL_DATA);
   1091   base::ListValue list_args;
   1092   list_args.Append(new base::StringValue(args));
   1093   EXPECT_CALL(*mock_pss_, IsPassphraseRequiredForDecryption())
   1094       .WillRepeatedly(Return(false));
   1095   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
   1096       .WillRepeatedly(Return(false));
   1097   SetupInitializedProfileSyncService();
   1098   EXPECT_CALL(*mock_pss_, EncryptEverythingAllowed()).
   1099       WillRepeatedly(Return(false));
   1100   EXPECT_CALL(*mock_pss_, EnableEncryptEverything()).Times(0);
   1101   EXPECT_CALL(*mock_pss_, OnUserChoseDatatypes(true, _));
   1102   handler_->HandleConfigure(&list_args);
   1103 
   1104   // Ensure that we navigated to the "done" state since we don't need a
   1105   // passphrase.
   1106   ExpectDone();
   1107 }
   1108 
   1109