1 // Copyright (c) 2013 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/profile_resetter/profile_resetter.h" 6 7 #include "base/json/json_string_value_serializer.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "chrome/browser/content_settings/host_content_settings_map.h" 11 #include "chrome/browser/extensions/extension_service_unittest.h" 12 #include "chrome/browser/extensions/tab_helper.h" 13 #include "chrome/browser/notifications/desktop_notification_service.h" 14 #include "chrome/browser/notifications/desktop_notification_service_factory.h" 15 #include "chrome/browser/prefs/session_startup_pref.h" 16 #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h" 17 #include "chrome/browser/profile_resetter/profile_resetter_test_base.h" 18 #include "chrome/browser/profile_resetter/resettable_settings_snapshot.h" 19 #include "chrome/browser/search_engines/template_url_service.h" 20 #include "chrome/browser/search_engines/template_url_service_factory.h" 21 #include "chrome/browser/themes/theme_service.h" 22 #include "chrome/browser/themes/theme_service_factory.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" 24 #include "chrome/common/extensions/extension.h" 25 #include "chrome/common/extensions/extension_manifest_constants.h" 26 #include "chrome/common/pref_names.h" 27 #include "chrome/test/base/browser_with_test_window_test.h" 28 #include "content/public/browser/web_contents.h" 29 #include "content/public/test/test_browser_thread.h" 30 #include "net/http/http_response_headers.h" 31 #include "net/url_request/test_url_fetcher_factory.h" 32 33 34 namespace { 35 36 const char kDistributionConfig[] = "{" 37 " \"homepage\" : \"http://www.foo.com\"," 38 " \"homepage_is_newtabpage\" : false," 39 " \"browser\" : {" 40 " \"show_home_button\" : true" 41 " }," 42 " \"session\" : {" 43 " \"restore_on_startup\" : 4," 44 " \"urls_to_restore_on_startup\" : [\"http://goo.gl\", \"http://foo.de\"]" 45 " }," 46 " \"search_provider_overrides\" : [" 47 " {" 48 " \"name\" : \"first\"," 49 " \"keyword\" : \"firstkey\"," 50 " \"search_url\" : \"http://www.foo.com/s?q={searchTerms}\"," 51 " \"favicon_url\" : \"http://www.foo.com/favicon.ico\"," 52 " \"suggest_url\" : \"http://www.foo.com/s?q={searchTerms}\"," 53 " \"encoding\" : \"UTF-8\"," 54 " \"id\" : 1001" 55 " }" 56 " ]," 57 " \"extensions\" : {" 58 " \"settings\" : {" 59 " \"placeholder_for_id\": {" 60 " }" 61 " }" 62 " }" 63 "}"; 64 65 const char kXmlConfig[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 66 "<response protocol=\"3.0\" server=\"prod\">" 67 "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">" 68 "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" " 69 "name=\"install\" status=\"ok\">" 70 "placeholder_for_data" 71 "</data>" 72 "</app>" 73 "</response>"; 74 75 using extensions::Extension; 76 using extensions::Manifest; 77 78 79 // ProfileResetterTest -------------------------------------------------------- 80 81 // ProfileResetterTest sets up the extension, WebData and TemplateURL services. 82 class ProfileResetterTest : public ExtensionServiceTestBase, 83 public ProfileResetterTestBase { 84 protected: 85 virtual void SetUp() OVERRIDE; 86 87 TestingProfile* profile() { return profile_.get(); } 88 89 static BrowserContextKeyedService* CreateTemplateURLService( 90 content::BrowserContext* context); 91 }; 92 93 void ProfileResetterTest::SetUp() { 94 ExtensionServiceTestBase::SetUp(); 95 InitializeEmptyExtensionService(); 96 97 profile()->CreateWebDataService(); 98 TemplateURLServiceFactory::GetInstance()->SetTestingFactory( 99 profile(), 100 &ProfileResetterTest::CreateTemplateURLService); 101 resetter_.reset(new ProfileResetter(profile())); 102 } 103 104 // static 105 BrowserContextKeyedService* ProfileResetterTest::CreateTemplateURLService( 106 content::BrowserContext* context) { 107 return new TemplateURLService(static_cast<Profile*>(context)); 108 } 109 110 111 // PinnedTabsResetTest -------------------------------------------------------- 112 113 class PinnedTabsResetTest : public BrowserWithTestWindowTest, 114 public ProfileResetterTestBase { 115 protected: 116 virtual void SetUp() OVERRIDE; 117 118 content::WebContents* CreateWebContents(); 119 }; 120 121 void PinnedTabsResetTest::SetUp() { 122 BrowserWithTestWindowTest::SetUp(); 123 resetter_.reset(new ProfileResetter(profile())); 124 } 125 126 content::WebContents* PinnedTabsResetTest::CreateWebContents() { 127 return content::WebContents::Create( 128 content::WebContents::CreateParams(profile())); 129 } 130 131 132 // ConfigParserTest ----------------------------------------------------------- 133 134 // URLFetcher delegate that simply records the upload data. 135 struct URLFetcherRequestListener : net::URLFetcherDelegate { 136 URLFetcherRequestListener(); 137 virtual ~URLFetcherRequestListener(); 138 139 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 140 141 std::string upload_data; 142 net::URLFetcherDelegate* real_delegate; 143 }; 144 145 URLFetcherRequestListener::URLFetcherRequestListener() 146 : real_delegate(NULL) { 147 } 148 149 URLFetcherRequestListener::~URLFetcherRequestListener() { 150 } 151 152 void URLFetcherRequestListener::OnURLFetchComplete( 153 const net::URLFetcher* source) { 154 const net::TestURLFetcher* test_fetcher = 155 static_cast<const net::TestURLFetcher*>(source); 156 upload_data = test_fetcher->upload_data(); 157 DCHECK(real_delegate); 158 real_delegate->OnURLFetchComplete(source); 159 } 160 161 class ConfigParserTest : public testing::Test { 162 protected: 163 ConfigParserTest(); 164 virtual ~ConfigParserTest(); 165 166 scoped_ptr<BrandcodeConfigFetcher> WaitForRequest(const GURL& url); 167 168 net::FakeURLFetcherFactory& factory() { return factory_; } 169 170 private: 171 scoped_ptr<net::FakeURLFetcher> CreateFakeURLFetcher( 172 const GURL& url, 173 net::URLFetcherDelegate* fetcher_delegate, 174 const std::string& response_data, 175 bool success); 176 177 MOCK_METHOD0(Callback, void(void)); 178 179 base::MessageLoop loop_; 180 content::TestBrowserThread ui_thread_; 181 content::TestBrowserThread io_thread_; 182 URLFetcherRequestListener request_listener_; 183 net::FakeURLFetcherFactory factory_; 184 }; 185 186 ConfigParserTest::ConfigParserTest() 187 : loop_(base::MessageLoop::TYPE_IO), 188 ui_thread_(content::BrowserThread::UI, &loop_), 189 io_thread_(content::BrowserThread::IO, &loop_), 190 factory_(NULL, base::Bind(&ConfigParserTest::CreateFakeURLFetcher, 191 base::Unretained(this))) { 192 } 193 194 ConfigParserTest::~ConfigParserTest() {} 195 196 scoped_ptr<BrandcodeConfigFetcher> ConfigParserTest::WaitForRequest( 197 const GURL& url) { 198 EXPECT_CALL(*this, Callback()); 199 scoped_ptr<BrandcodeConfigFetcher> fetcher( 200 new BrandcodeConfigFetcher(base::Bind(&ConfigParserTest::Callback, 201 base::Unretained(this)), 202 url, 203 "ABCD")); 204 base::MessageLoop::current()->RunUntilIdle(); 205 EXPECT_FALSE(fetcher->IsActive()); 206 // Look for the brand code in the request. 207 EXPECT_NE(std::string::npos, request_listener_.upload_data.find("ABCD")); 208 return fetcher.Pass(); 209 } 210 211 scoped_ptr<net::FakeURLFetcher> ConfigParserTest::CreateFakeURLFetcher( 212 const GURL& url, 213 net::URLFetcherDelegate* fetcher_delegate, 214 const std::string& response_data, 215 bool success) { 216 request_listener_.real_delegate = fetcher_delegate; 217 scoped_ptr<net::FakeURLFetcher> fetcher( 218 new net::FakeURLFetcher(url, &request_listener_, response_data, success)); 219 scoped_refptr<net::HttpResponseHeaders> download_headers = 220 new net::HttpResponseHeaders(""); 221 download_headers->AddHeader("Content-Type: text/xml"); 222 fetcher->set_response_headers(download_headers); 223 return fetcher.Pass(); 224 } 225 226 227 // helper functions ----------------------------------------------------------- 228 229 scoped_refptr<Extension> CreateExtension(const std::string& name, 230 const base::FilePath& path, 231 Manifest::Location location, 232 extensions::Manifest::Type type, 233 bool installed_by_default) { 234 DictionaryValue manifest; 235 manifest.SetString(extension_manifest_keys::kVersion, "1.0.0.0"); 236 manifest.SetString(extension_manifest_keys::kName, name); 237 switch (type) { 238 case extensions::Manifest::TYPE_THEME: 239 manifest.Set(extension_manifest_keys::kTheme, new DictionaryValue); 240 break; 241 case extensions::Manifest::TYPE_HOSTED_APP: 242 manifest.SetString(extension_manifest_keys::kLaunchWebURL, 243 "http://www.google.com"); 244 manifest.SetString(extension_manifest_keys::kUpdateURL, 245 "http://clients2.google.com/service/update2/crx"); 246 break; 247 case extensions::Manifest::TYPE_EXTENSION: 248 // do nothing 249 break; 250 default: 251 NOTREACHED(); 252 } 253 manifest.SetString(extension_manifest_keys::kOmniboxKeyword, name); 254 std::string error; 255 scoped_refptr<Extension> extension = Extension::Create( 256 path, 257 location, 258 manifest, 259 installed_by_default ? Extension::WAS_INSTALLED_BY_DEFAULT 260 : Extension::NO_FLAGS, 261 &error); 262 EXPECT_TRUE(extension.get() != NULL) << error; 263 return extension; 264 } 265 266 void ReplaceString(std::string* str, 267 const std::string& placeholder, 268 const std::string& substitution) { 269 ASSERT_NE(static_cast<std::string*>(NULL), str); 270 size_t placeholder_pos = str->find(placeholder); 271 ASSERT_NE(std::string::npos, placeholder_pos); 272 str->replace(placeholder_pos, placeholder.size(), substitution); 273 } 274 275 276 /********************* Tests *********************/ 277 278 TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) { 279 // Search engine's logic is tested by 280 // TemplateURLServiceTest.ResetURLs. 281 PrefService* prefs = profile()->GetPrefs(); 282 DCHECK(prefs); 283 prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/"); 284 285 scoped_refptr<Extension> extension = CreateExtension( 286 "xxx", 287 base::FilePath(FILE_PATH_LITERAL("//nonexistent")), 288 Manifest::COMPONENT, 289 extensions::Manifest::TYPE_EXTENSION, 290 false); 291 service_->AddExtension(extension.get()); 292 293 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE); 294 295 // TemplateURLService should reset extension search engines. 296 TemplateURLService* model = 297 TemplateURLServiceFactory::GetForProfile(profile()); 298 TemplateURL* ext_url = model->GetTemplateURLForKeyword(ASCIIToUTF16("xxx")); 299 ASSERT_TRUE(ext_url); 300 EXPECT_TRUE(ext_url->IsExtensionKeyword()); 301 EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->keyword()); 302 EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->short_name()); 303 EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL)); 304 } 305 306 TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) { 307 PrefService* prefs = profile()->GetPrefs(); 308 DCHECK(prefs); 309 prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/"); 310 311 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE, kDistributionConfig); 312 313 TemplateURLService* model = 314 TemplateURLServiceFactory::GetForProfile(profile()); 315 EXPECT_EQ(1u, model->GetTemplateURLs().size()); 316 TemplateURL* default_engine = model->GetDefaultSearchProvider(); 317 ASSERT_NE(static_cast<TemplateURL*>(NULL), default_engine); 318 EXPECT_EQ(ASCIIToUTF16("first"), default_engine->short_name()); 319 EXPECT_EQ(ASCIIToUTF16("firstkey"), default_engine->keyword()); 320 EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", default_engine->url()); 321 322 EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL)); 323 } 324 325 TEST_F(ProfileResetterTest, ResetHomepage) { 326 PrefService* prefs = profile()->GetPrefs(); 327 DCHECK(prefs); 328 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false); 329 prefs->SetString(prefs::kHomePage, "http://google.com"); 330 prefs->SetBoolean(prefs::kShowHomeButton, true); 331 332 ResetAndWait(ProfileResetter::HOMEPAGE); 333 334 EXPECT_TRUE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage)); 335 EXPECT_EQ(std::string(), prefs->GetString(prefs::kHomePage)); 336 EXPECT_FALSE(prefs->GetBoolean(prefs::kShowHomeButton)); 337 } 338 339 TEST_F(ProfileResetterTest, ResetHomepageNonOrganic) { 340 PrefService* prefs = profile()->GetPrefs(); 341 DCHECK(prefs); 342 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, true); 343 prefs->SetString(prefs::kHomePage, "http://google.com"); 344 prefs->SetBoolean(prefs::kShowHomeButton, false); 345 346 ResetAndWait(ProfileResetter::HOMEPAGE, kDistributionConfig); 347 348 EXPECT_FALSE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage)); 349 EXPECT_EQ("http://www.foo.com", prefs->GetString(prefs::kHomePage)); 350 EXPECT_TRUE(prefs->GetBoolean(prefs::kShowHomeButton)); 351 } 352 353 TEST_F(ProfileResetterTest, ResetContentSettings) { 354 HostContentSettingsMap* host_content_settings_map = 355 profile()->GetHostContentSettingsMap(); 356 DesktopNotificationService* notification_service = 357 DesktopNotificationServiceFactory::GetForProfile(profile()); 358 ContentSettingsPattern pattern = 359 ContentSettingsPattern::FromString("[*.]example.org"); 360 std::map<ContentSettingsType, ContentSetting> default_settings; 361 362 for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { 363 if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 364 notification_service->SetDefaultContentSetting(CONTENT_SETTING_BLOCK); 365 notification_service->GrantPermission(GURL("http://foo.de")); 366 } else if (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE || 367 type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT || 368 type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) { 369 // These types are excluded because one can't call 370 // GetDefaultContentSetting() for them. 371 } else { 372 ContentSettingsType content_type = static_cast<ContentSettingsType>(type); 373 ContentSetting default_setting = 374 host_content_settings_map->GetDefaultContentSetting(content_type, 375 NULL); 376 default_settings[content_type] = default_setting; 377 ContentSetting wildcard_setting = 378 default_setting == CONTENT_SETTING_BLOCK ? CONTENT_SETTING_ALLOW 379 : CONTENT_SETTING_BLOCK; 380 ContentSetting site_setting = 381 default_setting == CONTENT_SETTING_ALLOW ? CONTENT_SETTING_ALLOW 382 : CONTENT_SETTING_BLOCK; 383 if (HostContentSettingsMap::IsSettingAllowedForType( 384 profile()->GetPrefs(), 385 wildcard_setting, 386 content_type)) { 387 host_content_settings_map->SetDefaultContentSetting( 388 content_type, 389 wildcard_setting); 390 } 391 if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type) && 392 HostContentSettingsMap::IsSettingAllowedForType( 393 profile()->GetPrefs(), 394 site_setting, 395 content_type)) { 396 host_content_settings_map->SetContentSetting( 397 pattern, 398 ContentSettingsPattern::Wildcard(), 399 content_type, 400 std::string(), 401 site_setting); 402 ContentSettingsForOneType host_settings; 403 host_content_settings_map->GetSettingsForOneType( 404 content_type, std::string(), &host_settings); 405 EXPECT_EQ(2U, host_settings.size()); 406 } 407 } 408 } 409 410 ResetAndWait(ProfileResetter::CONTENT_SETTINGS); 411 412 for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { 413 if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 414 EXPECT_EQ(CONTENT_SETTING_ASK, 415 notification_service->GetDefaultContentSetting(NULL)); 416 EXPECT_EQ(CONTENT_SETTING_ASK, 417 notification_service->GetContentSetting(GURL("http://foo.de"))); 418 } else { 419 ContentSettingsType content_type = static_cast<ContentSettingsType>(type); 420 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type) || 421 type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE || 422 content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT || 423 content_type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) 424 continue; 425 ContentSetting default_setting = 426 host_content_settings_map->GetDefaultContentSetting(content_type, 427 NULL); 428 EXPECT_TRUE(default_settings.count(content_type)); 429 EXPECT_EQ(default_settings[content_type], default_setting); 430 if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type)) { 431 ContentSetting site_setting = 432 host_content_settings_map->GetContentSetting( 433 GURL("example.org"), 434 GURL(), 435 content_type, 436 std::string()); 437 EXPECT_EQ(default_setting, site_setting); 438 } 439 440 ContentSettingsForOneType host_settings; 441 host_content_settings_map->GetSettingsForOneType( 442 content_type, std::string(), &host_settings); 443 EXPECT_EQ(1U, host_settings.size()); 444 } 445 } 446 } 447 448 TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) { 449 base::ScopedTempDir temp_dir; 450 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 451 452 scoped_refptr<Extension> theme = 453 CreateExtension("example1", 454 temp_dir.path(), 455 Manifest::INVALID_LOCATION, 456 extensions::Manifest::TYPE_THEME, 457 false); 458 service_->FinishInstallationForTest(theme.get()); 459 // Let ThemeService finish creating the theme pack. 460 base::MessageLoop::current()->RunUntilIdle(); 461 462 ThemeService* theme_service = 463 ThemeServiceFactory::GetForProfile(profile()); 464 EXPECT_FALSE(theme_service->UsingDefaultTheme()); 465 466 scoped_refptr<Extension> ext2 = CreateExtension( 467 "example2", 468 base::FilePath(FILE_PATH_LITERAL("//nonexistent")), 469 Manifest::INVALID_LOCATION, 470 extensions::Manifest::TYPE_EXTENSION, 471 false); 472 service_->AddExtension(ext2.get()); 473 // Components and external policy extensions shouldn't be deleted. 474 scoped_refptr<Extension> ext3 = CreateExtension( 475 "example3", 476 base::FilePath(FILE_PATH_LITERAL("//nonexistent2")), 477 Manifest::COMPONENT, 478 extensions::Manifest::TYPE_EXTENSION, 479 false); 480 service_->AddExtension(ext3.get()); 481 scoped_refptr<Extension> ext4 = 482 CreateExtension("example4", 483 base::FilePath(FILE_PATH_LITERAL("//nonexistent3")), 484 Manifest::EXTERNAL_POLICY_DOWNLOAD, 485 extensions::Manifest::TYPE_EXTENSION, 486 false); 487 service_->AddExtension(ext4.get()); 488 EXPECT_EQ(4u, service_->extensions()->size()); 489 490 ResetAndWait(ProfileResetter::EXTENSIONS); 491 EXPECT_EQ(2u, service_->extensions()->size()); 492 EXPECT_FALSE(service_->extensions()->Contains(theme->id())); 493 EXPECT_FALSE(service_->extensions()->Contains(ext2->id())); 494 EXPECT_TRUE(service_->extensions()->Contains(ext3->id())); 495 EXPECT_TRUE(service_->extensions()->Contains(ext4->id())); 496 EXPECT_TRUE(theme_service->UsingDefaultTheme()); 497 } 498 499 TEST_F(ProfileResetterTest, ResetExtensionsByDisablingNonOrganic) { 500 scoped_refptr<Extension> ext2 = CreateExtension( 501 "example2", 502 base::FilePath(FILE_PATH_LITERAL("//nonexistent")), 503 Manifest::INVALID_LOCATION, 504 extensions::Manifest::TYPE_EXTENSION, 505 false); 506 service_->AddExtension(ext2.get()); 507 // Components and external policy extensions shouldn't be deleted. 508 scoped_refptr<Extension> ext3 = CreateExtension( 509 "example3", 510 base::FilePath(FILE_PATH_LITERAL("//nonexistent2")), 511 Manifest::INVALID_LOCATION, 512 extensions::Manifest::TYPE_EXTENSION, 513 false); 514 service_->AddExtension(ext3.get()); 515 EXPECT_EQ(2u, service_->extensions()->size()); 516 517 std::string master_prefs(kDistributionConfig); 518 ReplaceString(&master_prefs, "placeholder_for_id", ext3->id()); 519 520 ResetAndWait(ProfileResetter::EXTENSIONS, master_prefs); 521 522 EXPECT_EQ(1u, service_->extensions()->size()); 523 EXPECT_TRUE(service_->extensions()->Contains(ext3->id())); 524 } 525 526 TEST_F(ProfileResetterTest, ResetExtensionsAndDefaultApps) { 527 service_->Init(); 528 529 base::ScopedTempDir temp_dir; 530 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 531 532 scoped_refptr<Extension> ext1 = 533 CreateExtension("example1", 534 temp_dir.path(), 535 Manifest::INVALID_LOCATION, 536 extensions::Manifest::TYPE_THEME, 537 false); 538 service_->FinishInstallationForTest(ext1.get()); 539 // Let ThemeService finish creating the theme pack. 540 base::MessageLoop::current()->RunUntilIdle(); 541 542 ThemeService* theme_service = 543 ThemeServiceFactory::GetForProfile(profile()); 544 EXPECT_FALSE(theme_service->UsingDefaultTheme()); 545 546 scoped_refptr<Extension> ext2 = 547 CreateExtension("example2", 548 base::FilePath(FILE_PATH_LITERAL("//nonexistent2")), 549 Manifest::INVALID_LOCATION, 550 extensions::Manifest::TYPE_EXTENSION, 551 false); 552 service_->AddExtension(ext2.get()); 553 554 scoped_refptr<Extension> ext3 = 555 CreateExtension("example2", 556 base::FilePath(FILE_PATH_LITERAL("//nonexistent3")), 557 Manifest::INVALID_LOCATION, 558 extensions::Manifest::TYPE_HOSTED_APP, 559 true); 560 service_->AddExtension(ext3.get()); 561 EXPECT_EQ(3u, service_->extensions()->size()); 562 563 ResetAndWait(ProfileResetter::EXTENSIONS); 564 565 EXPECT_EQ(1u, service_->extensions()->size()); 566 EXPECT_FALSE(service_->extensions()->Contains(ext1->id())); 567 EXPECT_FALSE(service_->extensions()->Contains(ext2->id())); 568 EXPECT_TRUE(service_->extensions()->Contains(ext3->id())); 569 EXPECT_TRUE(theme_service->UsingDefaultTheme()); 570 } 571 572 TEST_F(ProfileResetterTest, ResetStartPage) { 573 PrefService* prefs = profile()->GetPrefs(); 574 DCHECK(prefs); 575 576 SessionStartupPref startup_pref(SessionStartupPref::URLS); 577 startup_pref.urls.push_back(GURL("http://foo")); 578 startup_pref.urls.push_back(GURL("http://bar")); 579 SessionStartupPref::SetStartupPref(prefs, startup_pref); 580 581 ResetAndWait(ProfileResetter::STARTUP_PAGES); 582 583 startup_pref = SessionStartupPref::GetStartupPref(prefs); 584 EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref.type); 585 EXPECT_EQ(std::vector<GURL>(), startup_pref.urls); 586 } 587 588 TEST_F(ProfileResetterTest, ResetStartPageNonOrganic) { 589 PrefService* prefs = profile()->GetPrefs(); 590 DCHECK(prefs); 591 592 SessionStartupPref startup_pref(SessionStartupPref::LAST); 593 SessionStartupPref::SetStartupPref(prefs, startup_pref); 594 595 ResetAndWait(ProfileResetter::STARTUP_PAGES, kDistributionConfig); 596 597 startup_pref = SessionStartupPref::GetStartupPref(prefs); 598 EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type); 599 const GURL urls[] = {GURL("http://goo.gl"), GURL("http://foo.de")}; 600 EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), startup_pref.urls); 601 } 602 603 TEST_F(PinnedTabsResetTest, ResetPinnedTabs) { 604 scoped_refptr<Extension> extension_app = CreateExtension( 605 "hello!", 606 base::FilePath(FILE_PATH_LITERAL("//nonexistent")), 607 Manifest::INVALID_LOCATION, 608 extensions::Manifest::TYPE_HOSTED_APP, 609 false); 610 scoped_ptr<content::WebContents> contents1(CreateWebContents()); 611 extensions::TabHelper::CreateForWebContents(contents1.get()); 612 extensions::TabHelper::FromWebContents(contents1.get())-> 613 SetExtensionApp(extension_app.get()); 614 scoped_ptr<content::WebContents> contents2(CreateWebContents()); 615 scoped_ptr<content::WebContents> contents3(CreateWebContents()); 616 scoped_ptr<content::WebContents> contents4(CreateWebContents()); 617 TabStripModel* tab_strip_model = browser()->tab_strip_model(); 618 619 tab_strip_model->AppendWebContents(contents4.get(), true); 620 tab_strip_model->AppendWebContents(contents3.get(), true); 621 tab_strip_model->AppendWebContents(contents2.get(), true); 622 tab_strip_model->SetTabPinned(2, true); 623 tab_strip_model->AppendWebContents(contents1.get(), true); 624 tab_strip_model->SetTabPinned(3, true); 625 626 EXPECT_EQ(contents2, tab_strip_model->GetWebContentsAt(0)); 627 EXPECT_EQ(contents1, tab_strip_model->GetWebContentsAt(1)); 628 EXPECT_EQ(contents3, tab_strip_model->GetWebContentsAt(2)); 629 EXPECT_EQ(contents4, tab_strip_model->GetWebContentsAt(3)); 630 EXPECT_EQ(3, tab_strip_model->IndexOfFirstNonMiniTab()); 631 632 ResetAndWait(ProfileResetter::PINNED_TABS); 633 634 EXPECT_EQ(contents1, tab_strip_model->GetWebContentsAt(0)); 635 EXPECT_EQ(contents2, tab_strip_model->GetWebContentsAt(1)); 636 EXPECT_EQ(contents3, tab_strip_model->GetWebContentsAt(2)); 637 EXPECT_EQ(contents4, tab_strip_model->GetWebContentsAt(3)); 638 EXPECT_EQ(1, tab_strip_model->IndexOfFirstNonMiniTab()); 639 } 640 641 TEST_F(ProfileResetterTest, ResetFewFlags) { 642 // mock_object_ is a StrictMock, so we verify that it is called only once. 643 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | 644 ProfileResetter::HOMEPAGE | 645 ProfileResetter::CONTENT_SETTINGS); 646 } 647 648 // Tries to load unavailable config file. 649 TEST_F(ConfigParserTest, NoConnectivity) { 650 const std::string url("http://test"); 651 factory().SetFakeResponse(url, "", false); 652 653 scoped_ptr<BrandcodeConfigFetcher> fetcher = WaitForRequest(GURL(url)); 654 EXPECT_FALSE(fetcher->GetSettings()); 655 } 656 657 // Tries to load available config file. 658 TEST_F(ConfigParserTest, ParseConfig) { 659 const std::string url("http://test"); 660 std::string xml_config(kXmlConfig); 661 ReplaceString(&xml_config, "placeholder_for_data", kDistributionConfig); 662 ReplaceString(&xml_config, 663 "placeholder_for_id", 664 "abbaabbaabbaabbaabbaabbaabbaabba"); 665 factory().SetFakeResponse(url, xml_config, true); 666 667 scoped_ptr<BrandcodeConfigFetcher> fetcher = WaitForRequest(GURL(url)); 668 scoped_ptr<BrandcodedDefaultSettings> settings = fetcher->GetSettings(); 669 ASSERT_TRUE(settings); 670 671 std::vector<std::string> extension_ids; 672 EXPECT_TRUE(settings->GetExtensions(&extension_ids)); 673 EXPECT_EQ(1u, extension_ids.size()); 674 EXPECT_EQ("abbaabbaabbaabbaabbaabbaabbaabba", extension_ids[0]); 675 676 std::string homepage; 677 EXPECT_TRUE(settings->GetHomepage(&homepage)); 678 EXPECT_EQ("http://www.foo.com", homepage); 679 680 scoped_ptr<base::ListValue> startup_list( 681 settings->GetUrlsToRestoreOnStartup()); 682 EXPECT_TRUE(startup_list); 683 std::vector<std::string> startup_pages; 684 for (base::ListValue::iterator i = startup_list->begin(); 685 i != startup_list->end(); ++i) { 686 std::string url; 687 EXPECT_TRUE((*i)->GetAsString(&url)); 688 startup_pages.push_back(url); 689 } 690 ASSERT_EQ(2u, startup_pages.size()); 691 EXPECT_EQ("http://goo.gl", startup_pages[0]); 692 EXPECT_EQ("http://foo.de", startup_pages[1]); 693 } 694 695 TEST_F(ProfileResetterTest, CheckSnapshots) { 696 ResettableSettingsSnapshot empty_snap(profile()); 697 EXPECT_EQ(0, empty_snap.FindDifferentFields(empty_snap)); 698 699 scoped_refptr<Extension> ext = CreateExtension( 700 "example", 701 base::FilePath(FILE_PATH_LITERAL("//nonexistent")), 702 Manifest::INVALID_LOCATION, 703 extensions::Manifest::TYPE_EXTENSION, 704 false); 705 ASSERT_TRUE(ext); 706 service_->AddExtension(ext.get()); 707 708 std::string master_prefs(kDistributionConfig); 709 std::string ext_id = ext->id(); 710 ReplaceString(&master_prefs, "placeholder_for_id", ext_id); 711 712 // Reset to non organic defaults. 713 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | 714 ProfileResetter::HOMEPAGE | 715 ProfileResetter::STARTUP_PAGES, master_prefs); 716 717 ResettableSettingsSnapshot nonorganic_snap(profile()); 718 EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS, 719 empty_snap.FindDifferentFields(nonorganic_snap)); 720 empty_snap.Subtract(nonorganic_snap); 721 EXPECT_TRUE(empty_snap.startup_urls().empty()); 722 EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), 723 empty_snap.startup_type()); 724 EXPECT_TRUE(empty_snap.homepage().empty()); 725 EXPECT_TRUE(empty_snap.homepage_is_ntp()); 726 EXPECT_NE(std::string::npos, empty_snap.dse_url().find("{google:baseURL}")); 727 EXPECT_EQ(std::vector<std::string>(), empty_snap.enabled_extensions()); 728 729 // Reset to organic defaults. 730 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | 731 ProfileResetter::HOMEPAGE | 732 ProfileResetter::STARTUP_PAGES | 733 ProfileResetter::EXTENSIONS); 734 735 ResettableSettingsSnapshot organic_snap(profile()); 736 EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS, 737 nonorganic_snap.FindDifferentFields(organic_snap)); 738 nonorganic_snap.Subtract(organic_snap); 739 const GURL urls[] = {GURL("http://foo.de"), GURL("http://goo.gl")}; 740 EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), 741 nonorganic_snap.startup_urls()); 742 EXPECT_EQ(SessionStartupPref::URLS, nonorganic_snap.startup_type()); 743 EXPECT_EQ("http://www.foo.com", nonorganic_snap.homepage()); 744 EXPECT_FALSE(nonorganic_snap.homepage_is_ntp()); 745 EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", nonorganic_snap.dse_url()); 746 EXPECT_EQ(std::vector<std::string>(1, ext_id), 747 nonorganic_snap.enabled_extensions()); 748 } 749 750 TEST_F(ProfileResetterTest, FeedbackSerializtionTest) { 751 // Reset to non organic defaults. 752 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | 753 ProfileResetter::HOMEPAGE | 754 ProfileResetter::STARTUP_PAGES, kDistributionConfig); 755 756 scoped_refptr<Extension> ext = CreateExtension( 757 "example", 758 base::FilePath(FILE_PATH_LITERAL("//nonexistent")), 759 Manifest::INVALID_LOCATION, 760 extensions::Manifest::TYPE_EXTENSION, 761 false); 762 ASSERT_TRUE(ext); 763 service_->AddExtension(ext.get()); 764 765 const ResettableSettingsSnapshot nonorganic_snap(profile()); 766 767 COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63, 768 expand_this_test); 769 for (int field_mask = 0; field_mask <= ResettableSettingsSnapshot::ALL_FIELDS; 770 ++field_mask) { 771 std::string report = SerializeSettingsReport(nonorganic_snap, field_mask); 772 JSONStringValueSerializer json(report); 773 std::string error; 774 scoped_ptr<base::Value> root(json.Deserialize(NULL, &error)); 775 ASSERT_TRUE(root) << error; 776 ASSERT_TRUE(root->IsType(base::Value::TYPE_DICTIONARY)) << error; 777 778 base::DictionaryValue* dict = 779 static_cast<base::DictionaryValue*>(root.get()); 780 781 ListValue* startup_urls = NULL; 782 int startup_type = 0; 783 std::string homepage; 784 bool homepage_is_ntp = true; 785 std::string default_search_engine; 786 ListValue* extensions; 787 788 EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_URLS), 789 dict->GetList("startup_urls", &startup_urls)); 790 EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_TYPE), 791 dict->GetInteger("startup_type", &startup_type)); 792 EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE), 793 dict->GetString("homepage", &homepage)); 794 EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP), 795 dict->GetBoolean("homepage_is_ntp", &homepage_is_ntp)); 796 EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::DSE_URL), 797 dict->GetString("default_search_engine", &default_search_engine)); 798 EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::EXTENSIONS), 799 dict->GetList("enabled_extensions", &extensions)); 800 } 801 } 802 803 } // namespace 804