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.
5 #include "chrome/browser/profile_resetter/profile_resetter.h"
7 #include "base/json/json_string_value_serializer.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/test/scoped_path_override.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/extension_service_test_base.h"
14 #include "chrome/browser/extensions/tab_helper.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_factory.h"
20 #include "chrome/browser/search_engines/ui_thread_search_terms_data.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/browser/web_data_service_factory.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/test/base/browser_with_test_window_test.h"
27 #include "components/content_settings/core/browser/host_content_settings_map.h"
28 #include "components/search_engines/template_url_service.h"
29 #include "components/search_engines/template_url_service_client.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/test/test_browser_thread.h"
32 #include "extensions/browser/extension_registry.h"
33 #include "extensions/common/extension.h"
34 #include "extensions/common/manifest_constants.h"
35 #include "net/http/http_response_headers.h"
36 #include "net/http/http_status_code.h"
37 #include "net/url_request/test_url_fetcher_factory.h"
38 #include "net/url_request/url_request_status.h"
42 #include "base/files/file_util.h"
43 #include "base/path_service.h"
44 #include "base/process/process_handle.h"
45 #include "base/rand_util.h"
46 #include "base/strings/string_number_conversions.h"
47 #include "base/win/scoped_com_initializer.h"
48 #include "base/win/shortcut.h"
54 const char kDistributionConfig
[] = "{"
55 " \"homepage\" : \"http://www.foo.com\","
56 " \"homepage_is_newtabpage\" : false,"
58 " \"show_home_button\" : true"
61 " \"restore_on_startup\" : 4,"
62 " \"startup_urls\" : [\"http://goo.gl\", \"http://foo.de\"]"
64 " \"search_provider_overrides\" : ["
66 " \"name\" : \"first\","
67 " \"keyword\" : \"firstkey\","
68 " \"search_url\" : \"http://www.foo.com/s?q={searchTerms}\","
69 " \"favicon_url\" : \"http://www.foo.com/favicon.ico\","
70 " \"suggest_url\" : \"http://www.foo.com/s?q={searchTerms}\","
71 " \"encoding\" : \"UTF-8\","
77 " \"placeholder_for_id\": {"
83 const char kXmlConfig
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
84 "<response protocol=\"3.0\" server=\"prod\">"
85 "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
86 "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" "
87 "name=\"install\" status=\"ok\">"
88 "placeholder_for_data"
93 using extensions::Extension
;
94 using extensions::Manifest
;
97 // ProfileResetterTest --------------------------------------------------------
99 // ProfileResetterTest sets up the extension, WebData and TemplateURL services.
100 class ProfileResetterTest
: public extensions::ExtensionServiceTestBase
,
101 public ProfileResetterTestBase
{
103 ProfileResetterTest();
104 ~ProfileResetterTest() override
;
107 void SetUp() override
;
109 TestingProfile
* profile() { return profile_
.get(); }
111 static scoped_ptr
<KeyedService
> CreateTemplateURLService(
112 content::BrowserContext
* context
);
116 base::ScopedPathOverride user_desktop_override_
;
117 base::ScopedPathOverride app_dir_override_
;
118 base::ScopedPathOverride start_menu_override_
;
119 base::ScopedPathOverride taskbar_pins_override_
;
120 base::win::ScopedCOMInitializer com_init_
;
124 ProfileResetterTest::ProfileResetterTest()
126 : user_desktop_override_(base::DIR_USER_DESKTOP
),
127 app_dir_override_(base::DIR_APP_DATA
),
128 start_menu_override_(base::DIR_START_MENU
),
129 taskbar_pins_override_(base::DIR_TASKBAR_PINS
)
133 ProfileResetterTest::~ProfileResetterTest() {
136 void ProfileResetterTest::SetUp() {
137 extensions::ExtensionServiceTestBase::SetUp();
138 InitializeEmptyExtensionService();
140 profile()->CreateWebDataService();
141 TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
143 &ProfileResetterTest::CreateTemplateURLService
);
144 resetter_
.reset(new ProfileResetter(profile()));
148 scoped_ptr
<KeyedService
> ProfileResetterTest::CreateTemplateURLService(
149 content::BrowserContext
* context
) {
150 Profile
* profile
= static_cast<Profile
*>(context
);
151 return make_scoped_ptr(new TemplateURLService(
153 scoped_ptr
<SearchTermsData
>(new UIThreadSearchTermsData(profile
)),
154 WebDataServiceFactory::GetKeywordWebDataForProfile(
155 profile
, ServiceAccessType::EXPLICIT_ACCESS
),
156 scoped_ptr
<TemplateURLServiceClient
>(), NULL
, NULL
, base::Closure()));
160 // PinnedTabsResetTest --------------------------------------------------------
162 class PinnedTabsResetTest
: public BrowserWithTestWindowTest
,
163 public ProfileResetterTestBase
{
165 void SetUp() override
;
167 content::WebContents
* CreateWebContents();
170 void PinnedTabsResetTest::SetUp() {
171 BrowserWithTestWindowTest::SetUp();
172 resetter_
.reset(new ProfileResetter(profile()));
175 content::WebContents
* PinnedTabsResetTest::CreateWebContents() {
176 return content::WebContents::Create(
177 content::WebContents::CreateParams(profile()));
181 // ConfigParserTest -----------------------------------------------------------
183 // URLFetcher delegate that simply records the upload data.
184 struct URLFetcherRequestListener
: net::URLFetcherDelegate
{
185 URLFetcherRequestListener();
186 ~URLFetcherRequestListener() override
;
188 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
190 std::string upload_data
;
191 net::URLFetcherDelegate
* real_delegate
;
194 URLFetcherRequestListener::URLFetcherRequestListener()
195 : real_delegate(NULL
) {
198 URLFetcherRequestListener::~URLFetcherRequestListener() {
201 void URLFetcherRequestListener::OnURLFetchComplete(
202 const net::URLFetcher
* source
) {
203 const net::TestURLFetcher
* test_fetcher
=
204 static_cast<const net::TestURLFetcher
*>(source
);
205 upload_data
= test_fetcher
->upload_data();
206 DCHECK(real_delegate
);
207 real_delegate
->OnURLFetchComplete(source
);
210 class ConfigParserTest
: public testing::Test
{
213 virtual ~ConfigParserTest();
215 scoped_ptr
<BrandcodeConfigFetcher
> WaitForRequest(const GURL
& url
);
217 net::FakeURLFetcherFactory
& factory() { return factory_
; }
220 scoped_ptr
<net::FakeURLFetcher
> CreateFakeURLFetcher(
222 net::URLFetcherDelegate
* fetcher_delegate
,
223 const std::string
& response_data
,
224 net::HttpStatusCode response_code
,
225 net::URLRequestStatus::Status status
);
227 MOCK_METHOD0(Callback
, void(void));
229 base::MessageLoopForIO loop_
;
230 content::TestBrowserThread ui_thread_
;
231 content::TestBrowserThread io_thread_
;
232 URLFetcherRequestListener request_listener_
;
233 net::FakeURLFetcherFactory factory_
;
236 ConfigParserTest::ConfigParserTest()
237 : ui_thread_(content::BrowserThread::UI
, &loop_
),
238 io_thread_(content::BrowserThread::IO
, &loop_
),
239 factory_(NULL
, base::Bind(&ConfigParserTest::CreateFakeURLFetcher
,
240 base::Unretained(this))) {
243 ConfigParserTest::~ConfigParserTest() {}
245 scoped_ptr
<BrandcodeConfigFetcher
> ConfigParserTest::WaitForRequest(
247 EXPECT_CALL(*this, Callback());
248 scoped_ptr
<BrandcodeConfigFetcher
> fetcher(
249 new BrandcodeConfigFetcher(base::Bind(&ConfigParserTest::Callback
,
250 base::Unretained(this)),
253 base::MessageLoop::current()->RunUntilIdle();
254 EXPECT_FALSE(fetcher
->IsActive());
255 // Look for the brand code in the request.
256 EXPECT_NE(std::string::npos
, request_listener_
.upload_data
.find("ABCD"));
257 return fetcher
.Pass();
260 scoped_ptr
<net::FakeURLFetcher
> ConfigParserTest::CreateFakeURLFetcher(
262 net::URLFetcherDelegate
* fetcher_delegate
,
263 const std::string
& response_data
,
264 net::HttpStatusCode response_code
,
265 net::URLRequestStatus::Status status
) {
266 request_listener_
.real_delegate
= fetcher_delegate
;
267 scoped_ptr
<net::FakeURLFetcher
> fetcher(
268 new net::FakeURLFetcher(
269 url
, &request_listener_
, response_data
, response_code
, status
));
270 scoped_refptr
<net::HttpResponseHeaders
> download_headers
=
271 new net::HttpResponseHeaders("");
272 download_headers
->AddHeader("Content-Type: text/xml");
273 fetcher
->set_response_headers(download_headers
);
274 return fetcher
.Pass();
277 // A helper class to create/delete/check a Chrome desktop shortcut on Windows.
278 class ShortcutHandler
{
283 static bool IsSupported();
284 ShortcutCommand
CreateWithArguments(const base::string16
& name
,
285 const base::string16
& args
);
286 void CheckShortcutHasArguments(const base::string16
& desired_args
) const;
291 base::FilePath shortcut_path_
;
293 DISALLOW_COPY_AND_ASSIGN(ShortcutHandler
);
297 ShortcutHandler::ShortcutHandler() {
300 ShortcutHandler::~ShortcutHandler() {
301 if (!shortcut_path_
.empty())
306 bool ShortcutHandler::IsSupported() {
310 ShortcutCommand
ShortcutHandler::CreateWithArguments(
311 const base::string16
& name
,
312 const base::string16
& args
) {
313 EXPECT_TRUE(shortcut_path_
.empty());
314 base::FilePath path_to_create
;
315 EXPECT_TRUE(PathService::Get(base::DIR_USER_DESKTOP
, &path_to_create
));
316 path_to_create
= path_to_create
.Append(name
);
317 EXPECT_FALSE(base::PathExists(path_to_create
)) << path_to_create
.value();
319 base::FilePath path_exe
;
320 EXPECT_TRUE(PathService::Get(base::FILE_EXE
, &path_exe
));
321 base::win::ShortcutProperties shortcut_properties
;
322 shortcut_properties
.set_target(path_exe
);
323 shortcut_properties
.set_arguments(args
);
324 EXPECT_TRUE(base::win::CreateOrUpdateShortcutLink(
325 path_to_create
, shortcut_properties
,
326 base::win::SHORTCUT_CREATE_ALWAYS
)) << path_to_create
.value();
327 shortcut_path_
= path_to_create
;
328 return ShortcutCommand(shortcut_path_
, args
);
331 void ShortcutHandler::CheckShortcutHasArguments(
332 const base::string16
& desired_args
) const {
333 EXPECT_FALSE(shortcut_path_
.empty());
335 EXPECT_TRUE(base::win::ResolveShortcut(shortcut_path_
, NULL
, &args
));
336 EXPECT_EQ(desired_args
, args
);
339 void ShortcutHandler::Delete() {
340 EXPECT_FALSE(shortcut_path_
.empty());
341 EXPECT_TRUE(base::DeleteFile(shortcut_path_
, false));
342 shortcut_path_
.clear();
345 ShortcutHandler::ShortcutHandler() {}
347 ShortcutHandler::~ShortcutHandler() {}
350 bool ShortcutHandler::IsSupported() {
354 ShortcutCommand
ShortcutHandler::CreateWithArguments(
355 const base::string16
& name
,
356 const base::string16
& args
) {
357 return ShortcutCommand();
360 void ShortcutHandler::CheckShortcutHasArguments(
361 const base::string16
& desired_args
) const {
364 void ShortcutHandler::Delete() {
366 #endif // defined(OS_WIN)
369 // helper functions -----------------------------------------------------------
371 scoped_refptr
<Extension
> CreateExtension(const base::string16
& name
,
372 const base::FilePath
& path
,
373 Manifest::Location location
,
374 extensions::Manifest::Type type
,
375 bool installed_by_default
) {
376 base::DictionaryValue manifest
;
377 manifest
.SetString(extensions::manifest_keys::kVersion
, "1.0.0.0");
378 manifest
.SetString(extensions::manifest_keys::kName
, name
);
380 case extensions::Manifest::TYPE_THEME
:
381 manifest
.Set(extensions::manifest_keys::kTheme
,
382 new base::DictionaryValue
);
384 case extensions::Manifest::TYPE_HOSTED_APP
:
385 manifest
.SetString(extensions::manifest_keys::kLaunchWebURL
,
386 "http://www.google.com");
387 manifest
.SetString(extensions::manifest_keys::kUpdateURL
,
388 "http://clients2.google.com/service/update2/crx");
390 case extensions::Manifest::TYPE_EXTENSION
:
396 manifest
.SetString(extensions::manifest_keys::kOmniboxKeyword
, name
);
398 scoped_refptr
<Extension
> extension
= Extension::Create(
402 installed_by_default
? Extension::WAS_INSTALLED_BY_DEFAULT
403 : Extension::NO_FLAGS
,
405 EXPECT_TRUE(extension
.get() != NULL
) << error
;
409 void ReplaceString(std::string
* str
,
410 const std::string
& placeholder
,
411 const std::string
& substitution
) {
412 ASSERT_NE(static_cast<std::string
*>(NULL
), str
);
413 size_t placeholder_pos
= str
->find(placeholder
);
414 ASSERT_NE(std::string::npos
, placeholder_pos
);
415 str
->replace(placeholder_pos
, placeholder
.size(), substitution
);
419 /********************* Tests *********************/
421 TEST_F(ProfileResetterTest
, ResetNothing
) {
422 // The callback should be called even if there is nothing to reset.
426 TEST_F(ProfileResetterTest
, ResetDefaultSearchEngineNonOrganic
) {
427 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
, kDistributionConfig
);
429 TemplateURLService
* model
=
430 TemplateURLServiceFactory::GetForProfile(profile());
431 TemplateURL
* default_engine
= model
->GetDefaultSearchProvider();
432 ASSERT_NE(static_cast<TemplateURL
*>(NULL
), default_engine
);
433 EXPECT_EQ(base::ASCIIToUTF16("first"), default_engine
->short_name());
434 EXPECT_EQ(base::ASCIIToUTF16("firstkey"), default_engine
->keyword());
435 EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", default_engine
->url());
438 TEST_F(ProfileResetterTest
, ResetDefaultSearchEnginePartially
) {
439 // Search engine's logic is tested by
440 // TemplateURLServiceTest.RepairPrepopulatedSearchEngines.
441 // Make sure TemplateURLService has loaded.
442 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
);
444 TemplateURLService
* model
=
445 TemplateURLServiceFactory::GetForProfile(profile());
446 TemplateURLService::TemplateURLVector urls
= model
->GetTemplateURLs();
448 // The second call should produce no effect.
449 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
);
451 EXPECT_EQ(urls
, model
->GetTemplateURLs());
454 TEST_F(ProfileResetterTest
, ResetHomepageNonOrganic
) {
455 PrefService
* prefs
= profile()->GetPrefs();
457 prefs
->SetBoolean(prefs::kHomePageIsNewTabPage
, true);
458 prefs
->SetString(prefs::kHomePage
, "http://google.com");
459 prefs
->SetBoolean(prefs::kShowHomeButton
, false);
461 ResetAndWait(ProfileResetter::HOMEPAGE
, kDistributionConfig
);
463 EXPECT_FALSE(prefs
->GetBoolean(prefs::kHomePageIsNewTabPage
));
464 EXPECT_EQ("http://www.foo.com", prefs
->GetString(prefs::kHomePage
));
465 EXPECT_TRUE(prefs
->GetBoolean(prefs::kShowHomeButton
));
468 TEST_F(ProfileResetterTest
, ResetHomepagePartially
) {
469 PrefService
* prefs
= profile()->GetPrefs();
471 prefs
->SetBoolean(prefs::kHomePageIsNewTabPage
, false);
472 prefs
->SetString(prefs::kHomePage
, "http://www.foo.com");
473 prefs
->SetBoolean(prefs::kShowHomeButton
, true);
475 ResetAndWait(ProfileResetter::HOMEPAGE
);
477 EXPECT_TRUE(prefs
->GetBoolean(prefs::kHomePageIsNewTabPage
));
478 EXPECT_EQ("http://www.foo.com", prefs
->GetString(prefs::kHomePage
));
479 EXPECT_FALSE(prefs
->GetBoolean(prefs::kShowHomeButton
));
482 TEST_F(ProfileResetterTest
, ResetContentSettings
) {
483 HostContentSettingsMap
* host_content_settings_map
=
484 profile()->GetHostContentSettingsMap();
485 ContentSettingsPattern pattern
=
486 ContentSettingsPattern::FromString("[*.]example.org");
487 std::map
<ContentSettingsType
, ContentSetting
> default_settings
;
489 for (int type
= 0; type
< CONTENT_SETTINGS_NUM_TYPES
; ++type
) {
490 ContentSettingsType content_type
= static_cast<ContentSettingsType
>(type
);
491 if (content_type
== CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
||
492 content_type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
||
493 content_type
== CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
) {
494 // These types are excluded because one can't call
495 // GetDefaultContentSetting() for them.
498 if (content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
) {
499 // This has been deprecated so we can neither set nor get it's value.
502 ContentSetting default_setting
=
503 host_content_settings_map
->GetDefaultContentSetting(content_type
, NULL
);
504 default_settings
[content_type
] = default_setting
;
505 ContentSetting wildcard_setting
= default_setting
== CONTENT_SETTING_BLOCK
506 ? CONTENT_SETTING_ALLOW
507 : CONTENT_SETTING_BLOCK
;
508 ContentSetting site_setting
= default_setting
== CONTENT_SETTING_ALLOW
509 ? CONTENT_SETTING_ALLOW
510 : CONTENT_SETTING_BLOCK
;
511 if (HostContentSettingsMap::IsSettingAllowedForType(
512 profile()->GetPrefs(), wildcard_setting
, content_type
)) {
513 host_content_settings_map
->SetDefaultContentSetting(content_type
,
516 if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type
) &&
517 HostContentSettingsMap::IsSettingAllowedForType(
518 profile()->GetPrefs(), site_setting
, content_type
)) {
519 host_content_settings_map
->SetContentSetting(
520 pattern
, ContentSettingsPattern::Wildcard(), content_type
,
521 std::string(), site_setting
);
522 ContentSettingsForOneType host_settings
;
523 host_content_settings_map
->GetSettingsForOneType(
524 content_type
, std::string(), &host_settings
);
525 EXPECT_EQ(2U, host_settings
.size());
529 ResetAndWait(ProfileResetter::CONTENT_SETTINGS
);
531 for (int type
= 0; type
< CONTENT_SETTINGS_NUM_TYPES
; ++type
) {
532 ContentSettingsType content_type
= static_cast<ContentSettingsType
>(type
);
533 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type
) ||
534 content_type
== CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
||
535 content_type
== CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
||
536 content_type
== CONTENT_SETTINGS_TYPE_MEDIASTREAM
||
537 content_type
== CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
)
539 ContentSetting default_setting
=
540 host_content_settings_map
->GetDefaultContentSetting(content_type
,
542 EXPECT_TRUE(default_settings
.count(content_type
));
543 EXPECT_EQ(default_settings
[content_type
], default_setting
);
544 if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type
)) {
545 ContentSetting site_setting
=
546 host_content_settings_map
->GetContentSetting(
551 EXPECT_EQ(default_setting
, site_setting
);
554 ContentSettingsForOneType host_settings
;
555 host_content_settings_map
->GetSettingsForOneType(
556 content_type
, std::string(), &host_settings
);
557 EXPECT_EQ(1U, host_settings
.size());
561 TEST_F(ProfileResetterTest
, ResetExtensionsByDisabling
) {
564 base::ScopedTempDir temp_dir
;
565 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
567 scoped_refptr
<Extension
> theme
=
568 CreateExtension(base::ASCIIToUTF16("example1"),
570 Manifest::INVALID_LOCATION
,
571 extensions::Manifest::TYPE_THEME
,
573 service_
->FinishInstallationForTest(theme
.get());
574 // Let ThemeService finish creating the theme pack.
575 base::MessageLoop::current()->RunUntilIdle();
577 ThemeService
* theme_service
=
578 ThemeServiceFactory::GetForProfile(profile());
579 EXPECT_FALSE(theme_service
->UsingDefaultTheme());
581 scoped_refptr
<Extension
> ext2
= CreateExtension(
582 base::ASCIIToUTF16("example2"),
583 base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
584 Manifest::INVALID_LOCATION
,
585 extensions::Manifest::TYPE_EXTENSION
,
587 service_
->AddExtension(ext2
.get());
588 // Component extensions and policy-managed extensions shouldn't be disabled.
589 scoped_refptr
<Extension
> ext3
= CreateExtension(
590 base::ASCIIToUTF16("example3"),
591 base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
593 extensions::Manifest::TYPE_EXTENSION
,
595 service_
->AddExtension(ext3
.get());
596 scoped_refptr
<Extension
> ext4
=
597 CreateExtension(base::ASCIIToUTF16("example4"),
598 base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
599 Manifest::EXTERNAL_POLICY_DOWNLOAD
,
600 extensions::Manifest::TYPE_EXTENSION
,
602 service_
->AddExtension(ext4
.get());
603 scoped_refptr
<Extension
> ext5
= CreateExtension(
604 base::ASCIIToUTF16("example5"),
605 base::FilePath(FILE_PATH_LITERAL("//nonexistent4")),
606 Manifest::EXTERNAL_COMPONENT
,
607 extensions::Manifest::TYPE_EXTENSION
,
609 service_
->AddExtension(ext5
.get());
610 scoped_refptr
<Extension
> ext6
= CreateExtension(
611 base::ASCIIToUTF16("example6"),
612 base::FilePath(FILE_PATH_LITERAL("//nonexistent5")),
613 Manifest::EXTERNAL_POLICY
,
614 extensions::Manifest::TYPE_EXTENSION
,
616 service_
->AddExtension(ext6
.get());
617 EXPECT_EQ(6u, registry()->enabled_extensions().size());
619 ResetAndWait(ProfileResetter::EXTENSIONS
);
620 EXPECT_EQ(4u, registry()->enabled_extensions().size());
621 EXPECT_FALSE(registry()->enabled_extensions().Contains(theme
->id()));
622 EXPECT_FALSE(registry()->enabled_extensions().Contains(ext2
->id()));
623 EXPECT_TRUE(registry()->enabled_extensions().Contains(ext3
->id()));
624 EXPECT_TRUE(registry()->enabled_extensions().Contains(ext4
->id()));
625 EXPECT_TRUE(registry()->enabled_extensions().Contains(ext5
->id()));
626 EXPECT_TRUE(registry()->enabled_extensions().Contains(ext6
->id()));
627 EXPECT_TRUE(theme_service
->UsingDefaultTheme());
630 TEST_F(ProfileResetterTest
, ResetExtensionsByDisablingNonOrganic
) {
631 scoped_refptr
<Extension
> ext2
= CreateExtension(
632 base::ASCIIToUTF16("example2"),
633 base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
634 Manifest::INVALID_LOCATION
,
635 extensions::Manifest::TYPE_EXTENSION
,
637 service_
->AddExtension(ext2
.get());
638 // Components and external policy extensions shouldn't be deleted.
639 scoped_refptr
<Extension
> ext3
= CreateExtension(
640 base::ASCIIToUTF16("example3"),
641 base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
642 Manifest::INVALID_LOCATION
,
643 extensions::Manifest::TYPE_EXTENSION
,
645 service_
->AddExtension(ext3
.get());
646 EXPECT_EQ(2u, registry()->enabled_extensions().size());
648 std::string
master_prefs(kDistributionConfig
);
649 ReplaceString(&master_prefs
, "placeholder_for_id", ext3
->id());
651 ResetAndWait(ProfileResetter::EXTENSIONS
, master_prefs
);
653 EXPECT_EQ(1u, registry()->enabled_extensions().size());
654 EXPECT_TRUE(registry()->enabled_extensions().Contains(ext3
->id()));
657 TEST_F(ProfileResetterTest
, ResetExtensionsAndDefaultApps
) {
660 base::ScopedTempDir temp_dir
;
661 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
663 scoped_refptr
<Extension
> ext1
=
664 CreateExtension(base::ASCIIToUTF16("example1"),
666 Manifest::INVALID_LOCATION
,
667 extensions::Manifest::TYPE_THEME
,
669 service_
->FinishInstallationForTest(ext1
.get());
670 // Let ThemeService finish creating the theme pack.
671 base::MessageLoop::current()->RunUntilIdle();
673 ThemeService
* theme_service
=
674 ThemeServiceFactory::GetForProfile(profile());
675 EXPECT_FALSE(theme_service
->UsingDefaultTheme());
677 scoped_refptr
<Extension
> ext2
=
678 CreateExtension(base::ASCIIToUTF16("example2"),
679 base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
680 Manifest::INVALID_LOCATION
,
681 extensions::Manifest::TYPE_EXTENSION
,
683 service_
->AddExtension(ext2
.get());
685 scoped_refptr
<Extension
> ext3
=
686 CreateExtension(base::ASCIIToUTF16("example2"),
687 base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
688 Manifest::INVALID_LOCATION
,
689 extensions::Manifest::TYPE_HOSTED_APP
,
691 service_
->AddExtension(ext3
.get());
692 EXPECT_EQ(3u, registry()->enabled_extensions().size());
694 ResetAndWait(ProfileResetter::EXTENSIONS
);
696 EXPECT_EQ(1u, registry()->enabled_extensions().size());
697 EXPECT_FALSE(registry()->enabled_extensions().Contains(ext1
->id()));
698 EXPECT_FALSE(registry()->enabled_extensions().Contains(ext2
->id()));
699 EXPECT_TRUE(registry()->enabled_extensions().Contains(ext3
->id()));
700 EXPECT_TRUE(theme_service
->UsingDefaultTheme());
703 TEST_F(ProfileResetterTest
, ResetStartPageNonOrganic
) {
704 PrefService
* prefs
= profile()->GetPrefs();
707 SessionStartupPref
startup_pref(SessionStartupPref::LAST
);
708 SessionStartupPref::SetStartupPref(prefs
, startup_pref
);
710 ResetAndWait(ProfileResetter::STARTUP_PAGES
, kDistributionConfig
);
712 startup_pref
= SessionStartupPref::GetStartupPref(prefs
);
713 EXPECT_EQ(SessionStartupPref::URLS
, startup_pref
.type
);
714 const GURL urls
[] = {GURL("http://goo.gl"), GURL("http://foo.de")};
715 EXPECT_EQ(std::vector
<GURL
>(urls
, urls
+ arraysize(urls
)), startup_pref
.urls
);
719 TEST_F(ProfileResetterTest
, ResetStartPagePartially
) {
720 PrefService
* prefs
= profile()->GetPrefs();
723 const GURL urls
[] = {GURL("http://foo"), GURL("http://bar")};
724 SessionStartupPref
startup_pref(SessionStartupPref::URLS
);
725 startup_pref
.urls
.assign(urls
, urls
+ arraysize(urls
));
726 SessionStartupPref::SetStartupPref(prefs
, startup_pref
);
728 ResetAndWait(ProfileResetter::STARTUP_PAGES
, std::string());
730 startup_pref
= SessionStartupPref::GetStartupPref(prefs
);
731 EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref
.type
);
732 EXPECT_EQ(std::vector
<GURL
>(urls
, urls
+ arraysize(urls
)), startup_pref
.urls
);
735 TEST_F(PinnedTabsResetTest
, ResetPinnedTabs
) {
736 scoped_ptr
<content::WebContents
> contents1(CreateWebContents());
737 scoped_ptr
<content::WebContents
> contents2(CreateWebContents());
738 scoped_ptr
<content::WebContents
> contents3(CreateWebContents());
739 scoped_ptr
<content::WebContents
> contents4(CreateWebContents());
740 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
742 tab_strip_model
->AppendWebContents(contents4
.get(), true);
743 tab_strip_model
->AppendWebContents(contents3
.get(), true);
744 tab_strip_model
->AppendWebContents(contents2
.get(), true);
745 tab_strip_model
->SetTabPinned(2, true);
746 tab_strip_model
->AppendWebContents(contents1
.get(), true);
747 tab_strip_model
->SetTabPinned(3, true);
749 EXPECT_EQ(contents2
, tab_strip_model
->GetWebContentsAt(0));
750 EXPECT_EQ(contents1
, tab_strip_model
->GetWebContentsAt(1));
751 EXPECT_EQ(contents4
, tab_strip_model
->GetWebContentsAt(2));
752 EXPECT_EQ(contents3
, tab_strip_model
->GetWebContentsAt(3));
753 EXPECT_EQ(2, tab_strip_model
->IndexOfFirstNonPinnedTab());
755 ResetAndWait(ProfileResetter::PINNED_TABS
);
757 EXPECT_EQ(contents2
, tab_strip_model
->GetWebContentsAt(0));
758 EXPECT_EQ(contents1
, tab_strip_model
->GetWebContentsAt(1));
759 EXPECT_EQ(contents4
, tab_strip_model
->GetWebContentsAt(2));
760 EXPECT_EQ(contents3
, tab_strip_model
->GetWebContentsAt(3));
761 EXPECT_EQ(0, tab_strip_model
->IndexOfFirstNonPinnedTab());
764 TEST_F(ProfileResetterTest
, ResetShortcuts
) {
765 ShortcutHandler shortcut
;
766 ShortcutCommand command_line
= shortcut
.CreateWithArguments(
767 base::ASCIIToUTF16("chrome.lnk"),
768 base::ASCIIToUTF16("--profile-directory=Default foo.com"));
769 shortcut
.CheckShortcutHasArguments(base::ASCIIToUTF16(
770 "--profile-directory=Default foo.com"));
772 ResetAndWait(ProfileResetter::SHORTCUTS
);
774 shortcut
.CheckShortcutHasArguments(base::ASCIIToUTF16(
775 "--profile-directory=Default"));
778 TEST_F(ProfileResetterTest
, ResetFewFlags
) {
779 // mock_object_ is a StrictMock, so we verify that it is called only once.
780 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
|
781 ProfileResetter::HOMEPAGE
|
782 ProfileResetter::CONTENT_SETTINGS
);
785 // Tries to load unavailable config file.
786 TEST_F(ConfigParserTest
, NoConnectivity
) {
787 const GURL
url("http://test");
788 factory().SetFakeResponse(url
, "", net::HTTP_INTERNAL_SERVER_ERROR
,
789 net::URLRequestStatus::FAILED
);
791 scoped_ptr
<BrandcodeConfigFetcher
> fetcher
= WaitForRequest(GURL(url
));
792 EXPECT_FALSE(fetcher
->GetSettings());
795 // Tries to load available config file.
796 TEST_F(ConfigParserTest
, ParseConfig
) {
797 const GURL
url("http://test");
798 std::string
xml_config(kXmlConfig
);
799 ReplaceString(&xml_config
, "placeholder_for_data", kDistributionConfig
);
800 ReplaceString(&xml_config
,
801 "placeholder_for_id",
802 "abbaabbaabbaabbaabbaabbaabbaabba");
803 factory().SetFakeResponse(url
, xml_config
, net::HTTP_OK
,
804 net::URLRequestStatus::SUCCESS
);
806 scoped_ptr
<BrandcodeConfigFetcher
> fetcher
= WaitForRequest(GURL(url
));
807 scoped_ptr
<BrandcodedDefaultSettings
> settings
= fetcher
->GetSettings();
808 ASSERT_TRUE(settings
);
810 std::vector
<std::string
> extension_ids
;
811 EXPECT_TRUE(settings
->GetExtensions(&extension_ids
));
812 EXPECT_EQ(1u, extension_ids
.size());
813 EXPECT_EQ("abbaabbaabbaabbaabbaabbaabbaabba", extension_ids
[0]);
815 std::string homepage
;
816 EXPECT_TRUE(settings
->GetHomepage(&homepage
));
817 EXPECT_EQ("http://www.foo.com", homepage
);
819 scoped_ptr
<base::ListValue
> startup_list(
820 settings
->GetUrlsToRestoreOnStartup());
821 EXPECT_TRUE(startup_list
);
822 std::vector
<std::string
> startup_pages
;
823 for (base::ListValue::iterator i
= startup_list
->begin();
824 i
!= startup_list
->end(); ++i
) {
826 EXPECT_TRUE((*i
)->GetAsString(&url
));
827 startup_pages
.push_back(url
);
829 ASSERT_EQ(2u, startup_pages
.size());
830 EXPECT_EQ("http://goo.gl", startup_pages
[0]);
831 EXPECT_EQ("http://foo.de", startup_pages
[1]);
834 TEST_F(ProfileResetterTest
, CheckSnapshots
) {
835 ResettableSettingsSnapshot
empty_snap(profile());
836 EXPECT_EQ(0, empty_snap
.FindDifferentFields(empty_snap
));
838 scoped_refptr
<Extension
> ext
= CreateExtension(
839 base::ASCIIToUTF16("example"),
840 base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
841 Manifest::INVALID_LOCATION
,
842 extensions::Manifest::TYPE_EXTENSION
,
844 ASSERT_TRUE(ext
.get());
845 service_
->AddExtension(ext
.get());
847 std::string
master_prefs(kDistributionConfig
);
848 std::string ext_id
= ext
->id();
849 ReplaceString(&master_prefs
, "placeholder_for_id", ext_id
);
851 // Reset to non organic defaults.
852 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
|
853 ProfileResetter::HOMEPAGE
|
854 ProfileResetter::STARTUP_PAGES
,
856 ShortcutHandler shortcut_hijacked
;
857 ShortcutCommand command_line
= shortcut_hijacked
.CreateWithArguments(
858 base::ASCIIToUTF16("chrome1.lnk"),
859 base::ASCIIToUTF16("--profile-directory=Default foo.com"));
860 shortcut_hijacked
.CheckShortcutHasArguments(
861 base::ASCIIToUTF16("--profile-directory=Default foo.com"));
862 ShortcutHandler shortcut_ok
;
863 shortcut_ok
.CreateWithArguments(
864 base::ASCIIToUTF16("chrome2.lnk"),
865 base::ASCIIToUTF16("--profile-directory=Default1"));
867 ResettableSettingsSnapshot
nonorganic_snap(profile());
868 nonorganic_snap
.RequestShortcuts(base::Closure());
869 // Let it enumerate shortcuts on the FILE thread.
870 base::MessageLoop::current()->RunUntilIdle();
871 int diff_fields
= ResettableSettingsSnapshot::ALL_FIELDS
;
872 if (!ShortcutHandler::IsSupported())
873 diff_fields
&= ~ResettableSettingsSnapshot::SHORTCUTS
;
874 EXPECT_EQ(diff_fields
,
875 empty_snap
.FindDifferentFields(nonorganic_snap
));
876 empty_snap
.Subtract(nonorganic_snap
);
877 EXPECT_TRUE(empty_snap
.startup_urls().empty());
878 EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(),
879 empty_snap
.startup_type());
880 EXPECT_TRUE(empty_snap
.homepage().empty());
881 EXPECT_TRUE(empty_snap
.homepage_is_ntp());
882 EXPECT_FALSE(empty_snap
.show_home_button());
883 EXPECT_NE(std::string::npos
, empty_snap
.dse_url().find("{google:baseURL}"));
884 EXPECT_EQ(ResettableSettingsSnapshot::ExtensionList(),
885 empty_snap
.enabled_extensions());
886 EXPECT_EQ(std::vector
<ShortcutCommand
>(), empty_snap
.shortcuts());
888 // Reset to organic defaults.
889 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
|
890 ProfileResetter::HOMEPAGE
|
891 ProfileResetter::STARTUP_PAGES
|
892 ProfileResetter::EXTENSIONS
|
893 ProfileResetter::SHORTCUTS
);
895 ResettableSettingsSnapshot
organic_snap(profile());
896 organic_snap
.RequestShortcuts(base::Closure());
897 // Let it enumerate shortcuts on the FILE thread.
898 base::MessageLoop::current()->RunUntilIdle();
899 EXPECT_EQ(diff_fields
, nonorganic_snap
.FindDifferentFields(organic_snap
));
900 nonorganic_snap
.Subtract(organic_snap
);
901 const GURL urls
[] = {GURL("http://foo.de"), GURL("http://goo.gl")};
902 EXPECT_EQ(std::vector
<GURL
>(urls
, urls
+ arraysize(urls
)),
903 nonorganic_snap
.startup_urls());
904 EXPECT_EQ(SessionStartupPref::URLS
, nonorganic_snap
.startup_type());
905 EXPECT_EQ("http://www.foo.com", nonorganic_snap
.homepage());
906 EXPECT_FALSE(nonorganic_snap
.homepage_is_ntp());
907 EXPECT_TRUE(nonorganic_snap
.show_home_button());
908 EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", nonorganic_snap
.dse_url());
909 EXPECT_EQ(ResettableSettingsSnapshot::ExtensionList(
910 1, std::make_pair(ext_id
, "example")),
911 nonorganic_snap
.enabled_extensions());
912 if (ShortcutHandler::IsSupported()) {
913 std::vector
<ShortcutCommand
> shortcuts
= nonorganic_snap
.shortcuts();
914 ASSERT_EQ(1u, shortcuts
.size());
915 EXPECT_EQ(command_line
.first
.value(), shortcuts
[0].first
.value());
916 EXPECT_EQ(command_line
.second
, shortcuts
[0].second
);
920 TEST_F(ProfileResetterTest
, FeedbackSerializationTest
) {
921 // Reset to non organic defaults.
922 ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE
|
923 ProfileResetter::HOMEPAGE
|
924 ProfileResetter::STARTUP_PAGES
,
925 kDistributionConfig
);
927 scoped_refptr
<Extension
> ext
= CreateExtension(
928 base::ASCIIToUTF16("example"),
929 base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
930 Manifest::INVALID_LOCATION
,
931 extensions::Manifest::TYPE_EXTENSION
,
933 ASSERT_TRUE(ext
.get());
934 service_
->AddExtension(ext
.get());
936 ShortcutHandler shortcut
;
937 ShortcutCommand command_line
= shortcut
.CreateWithArguments(
938 base::ASCIIToUTF16("chrome.lnk"),
939 base::ASCIIToUTF16("--profile-directory=Default foo.com"));
941 ResettableSettingsSnapshot
nonorganic_snap(profile());
942 nonorganic_snap
.RequestShortcuts(base::Closure());
943 // Let it enumerate shortcuts on the FILE thread.
944 base::MessageLoop::current()->RunUntilIdle();
946 static_assert(ResettableSettingsSnapshot::ALL_FIELDS
== 31,
947 "this test needs to be expanded");
948 for (int field_mask
= 0; field_mask
<= ResettableSettingsSnapshot::ALL_FIELDS
;
950 std::string report
= SerializeSettingsReport(nonorganic_snap
, field_mask
);
951 JSONStringValueDeserializer
json(report
);
953 scoped_ptr
<base::Value
> root(json
.Deserialize(NULL
, &error
));
954 ASSERT_TRUE(root
) << error
;
955 ASSERT_TRUE(root
->IsType(base::Value::TYPE_DICTIONARY
)) << error
;
957 base::DictionaryValue
* dict
=
958 static_cast<base::DictionaryValue
*>(root
.get());
960 base::ListValue
* startup_urls
= NULL
;
961 int startup_type
= 0;
962 std::string homepage
;
963 bool homepage_is_ntp
= true;
964 bool show_home_button
= true;
965 std::string default_search_engine
;
966 base::ListValue
* extensions
= NULL
;
967 base::ListValue
* shortcuts
= NULL
;
969 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::STARTUP_MODE
),
970 dict
->GetList("startup_urls", &startup_urls
));
971 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::STARTUP_MODE
),
972 dict
->GetInteger("startup_type", &startup_type
));
973 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::HOMEPAGE
),
974 dict
->GetString("homepage", &homepage
));
975 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::HOMEPAGE
),
976 dict
->GetBoolean("homepage_is_ntp", &homepage_is_ntp
));
977 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::HOMEPAGE
),
978 dict
->GetBoolean("show_home_button", &show_home_button
));
979 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::DSE_URL
),
980 dict
->GetString("default_search_engine", &default_search_engine
));
981 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::EXTENSIONS
),
982 dict
->GetList("enabled_extensions", &extensions
));
983 EXPECT_EQ(!!(field_mask
& ResettableSettingsSnapshot::SHORTCUTS
),
984 dict
->GetList("shortcuts", &shortcuts
));
988 struct FeedbackCapture
{
989 void SetFeedback(Profile
* profile
,
990 const ResettableSettingsSnapshot
& snapshot
) {
991 list_
= GetReadableFeedbackForSnapshot(profile
, snapshot
).Pass();
996 ADD_FAILURE() << "This method shouldn't be called.";
999 MOCK_METHOD0(OnUpdatedList
, void(void));
1001 scoped_ptr
<base::ListValue
> list_
;
1004 // Make sure GetReadableFeedback handles non-ascii letters.
1005 TEST_F(ProfileResetterTest
, GetReadableFeedback
) {
1006 scoped_refptr
<Extension
> ext
= CreateExtension(
1007 base::WideToUTF16(L
"Tiësto"),
1008 base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
1009 Manifest::INVALID_LOCATION
,
1010 extensions::Manifest::TYPE_EXTENSION
,
1012 ASSERT_TRUE(ext
.get());
1013 service_
->AddExtension(ext
.get());
1015 PrefService
* prefs
= profile()->GetPrefs();
1017 // The URL is "http://россия.рф".
1018 std::wstring
url(L
"http://"
1019 L
"\u0440\u043e\u0441\u0441\u0438\u044f.\u0440\u0444");
1020 prefs
->SetBoolean(prefs::kHomePageIsNewTabPage
, false);
1021 prefs
->SetString(prefs::kHomePage
, base::WideToUTF8(url
));
1023 SessionStartupPref
startup_pref(SessionStartupPref::URLS
);
1024 startup_pref
.urls
.push_back(GURL(base::WideToUTF8(url
)));
1025 SessionStartupPref::SetStartupPref(prefs
, startup_pref
);
1027 ShortcutHandler shortcut
;
1028 ShortcutCommand command_line
= shortcut
.CreateWithArguments(
1029 base::ASCIIToUTF16("chrome.lnk"),
1030 base::ASCIIToUTF16("--profile-directory=Default foo.com"));
1032 FeedbackCapture capture
;
1033 EXPECT_CALL(capture
, OnUpdatedList());
1034 ResettableSettingsSnapshot
snapshot(profile());
1035 snapshot
.RequestShortcuts(base::Bind(&FeedbackCapture::SetFeedback
,
1036 base::Unretained(&capture
),
1038 base::ConstRef(snapshot
)));
1039 // Let it enumerate shortcuts on the FILE thread.
1040 base::MessageLoop::current()->RunUntilIdle();
1041 ::testing::Mock::VerifyAndClearExpectations(&capture
);
1042 // The homepage and the startup page are in punycode. They are unreadable.
1043 // Trying to find the extension name.
1044 scoped_ptr
<base::ListValue
> list
= capture
.list_
.Pass();
1046 bool checked_extensions
= false;
1047 bool checked_shortcuts
= false;
1048 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
1049 base::DictionaryValue
* dict
= NULL
;
1050 ASSERT_TRUE(list
->GetDictionary(i
, &dict
));
1052 ASSERT_TRUE(dict
->GetString("key", &value
));
1053 if (value
== "Extensions") {
1054 base::string16 extensions
;
1055 EXPECT_TRUE(dict
->GetString("value", &extensions
));
1056 EXPECT_EQ(base::WideToUTF16(L
"Tiësto"), extensions
);
1057 checked_extensions
= true;
1058 } else if (value
== "Shortcut targets") {
1059 base::string16 targets
;
1060 EXPECT_TRUE(dict
->GetString("value", &targets
));
1061 EXPECT_NE(base::string16::npos
,
1062 targets
.find(base::ASCIIToUTF16("foo.com"))) << targets
;
1063 checked_shortcuts
= true;
1066 EXPECT_TRUE(checked_extensions
);
1067 EXPECT_EQ(ShortcutHandler::IsSupported(), checked_shortcuts
);
1070 TEST_F(ProfileResetterTest
, DestroySnapshotFast
) {
1071 FeedbackCapture capture
;
1072 scoped_ptr
<ResettableSettingsSnapshot
> deleted_snapshot(
1073 new ResettableSettingsSnapshot(profile()));
1074 deleted_snapshot
->RequestShortcuts(base::Bind(&FeedbackCapture::Fail
,
1075 base::Unretained(&capture
)));
1076 deleted_snapshot
.reset();
1077 // Running remaining tasks shouldn't trigger the callback to be called as
1078 // |deleted_snapshot| was deleted before it could run.
1079 base::MessageLoop::current()->RunUntilIdle();