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