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