summaryrefslogtreecommitdiffstats
path: root/chrome/browser/profile_resetter/profile_resetter_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/profile_resetter/profile_resetter_unittest.cc')
-rw-r--r--chrome/browser/profile_resetter/profile_resetter_unittest.cc281
1 files changed, 246 insertions, 35 deletions
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index 08f204a..f976ec6 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -7,6 +7,7 @@
#include "base/json/json_string_value_serializer.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_path_override.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/extensions/extension_service_unittest.h"
#include "chrome/browser/extensions/tab_helper.h"
@@ -33,7 +34,16 @@
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
-using base::ASCIIToUTF16;
+#if defined(OS_WIN)
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/process/process_handle.h"
+#include "base/rand_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/win/scoped_com_initializer.h"
+#include "base/win/shortcut.h"
+#endif
+
namespace {
@@ -85,6 +95,10 @@ using extensions::Manifest;
// ProfileResetterTest sets up the extension, WebData and TemplateURL services.
class ProfileResetterTest : public ExtensionServiceTestBase,
public ProfileResetterTestBase {
+ public:
+ ProfileResetterTest();
+ virtual ~ProfileResetterTest();
+
protected:
virtual void SetUp() OVERRIDE;
@@ -92,8 +106,29 @@ class ProfileResetterTest : public ExtensionServiceTestBase,
static BrowserContextKeyedService* CreateTemplateURLService(
content::BrowserContext* context);
+
+ private:
+#if defined(OS_WIN)
+ base::ScopedPathOverride user_desktop_override_;
+ base::ScopedPathOverride app_dir_override_;
+ base::ScopedPathOverride start_menu_override_;
+ base::ScopedPathOverride taskbar_pins_override_;
+ base::win::ScopedCOMInitializer com_init_;
+#endif
};
+ProfileResetterTest::ProfileResetterTest()
+#if defined(OS_WIN)
+ : user_desktop_override_(base::DIR_USER_DESKTOP),
+ app_dir_override_(base::DIR_APP_DATA),
+ start_menu_override_(base::DIR_START_MENU),
+ taskbar_pins_override_(base::DIR_TASKBAR_PINS)
+#endif
+{}
+
+ProfileResetterTest::~ProfileResetterTest() {
+}
+
void ProfileResetterTest::SetUp() {
ExtensionServiceTestBase::SetUp();
InitializeEmptyExtensionService();
@@ -230,6 +265,99 @@ scoped_ptr<net::FakeURLFetcher> ConfigParserTest::CreateFakeURLFetcher(
return fetcher.Pass();
}
+// A helper class to create/delete/check a Chrome desktop shortcut on Windows.
+class ShortcutHandler {
+ public:
+ ShortcutHandler();
+ ~ShortcutHandler();
+
+ static bool IsSupported();
+ ShortcutCommand CreateWithArguments(const base::string16& name,
+ const base::string16& args);
+ void CheckShortcutHasArguments(const base::string16& desired_args) const;
+ void Delete();
+
+ private:
+#if defined(OS_WIN)
+ base::FilePath shortcut_path_;
+#endif
+ DISALLOW_COPY_AND_ASSIGN(ShortcutHandler);
+};
+
+#if defined(OS_WIN)
+ShortcutHandler::ShortcutHandler() {
+}
+
+ShortcutHandler::~ShortcutHandler() {
+ if (!shortcut_path_.empty())
+ Delete();
+}
+
+// static
+bool ShortcutHandler::IsSupported() {
+ return true;
+}
+
+ShortcutCommand ShortcutHandler::CreateWithArguments(
+ const base::string16& name,
+ const base::string16& args) {
+ EXPECT_TRUE(shortcut_path_.empty());
+ base::FilePath path_to_create;
+ EXPECT_TRUE(PathService::Get(base::DIR_USER_DESKTOP, &path_to_create));
+ path_to_create = path_to_create.Append(name);
+ EXPECT_FALSE(base::PathExists(path_to_create)) << path_to_create.value();
+
+ base::FilePath path_exe;
+ EXPECT_TRUE(PathService::Get(base::FILE_EXE, &path_exe));
+ base::win::ShortcutProperties shortcut_properties;
+ shortcut_properties.set_target(path_exe);
+ shortcut_properties.set_arguments(args);
+ EXPECT_TRUE(base::win::CreateOrUpdateShortcutLink(
+ path_to_create, shortcut_properties,
+ base::win::SHORTCUT_CREATE_ALWAYS)) << path_to_create.value();
+ shortcut_path_ = path_to_create;
+ return ShortcutCommand(shortcut_path_,
+ args);
+}
+
+void ShortcutHandler::CheckShortcutHasArguments(
+ const base::string16& desired_args) const {
+ EXPECT_FALSE(shortcut_path_.empty());
+ base::FilePath target_path;
+ base::string16 args;
+ EXPECT_TRUE(base::win::ResolveShortcut(shortcut_path_, &target_path, &args));
+ EXPECT_EQ(desired_args, args);
+}
+
+void ShortcutHandler::Delete() {
+ EXPECT_FALSE(shortcut_path_.empty());
+ EXPECT_TRUE(base::DeleteFile(shortcut_path_, false));
+ shortcut_path_.clear();
+}
+#else
+ShortcutHandler::ShortcutHandler() {}
+
+ShortcutHandler::~ShortcutHandler() {}
+
+// static
+bool ShortcutHandler::IsSupported() {
+ return false;
+}
+
+ShortcutCommand ShortcutHandler::CreateWithArguments(
+ const base::string16& name,
+ const base::string16& args) {
+ return ShortcutCommand();
+}
+
+void ShortcutHandler::CheckShortcutHasArguments(
+ const base::string16& desired_args) const {
+}
+
+void ShortcutHandler::Delete() {
+}
+#endif // defined(OS_WIN)
+
// helper functions -----------------------------------------------------------
@@ -299,8 +427,8 @@ TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
TemplateURLServiceFactory::GetForProfile(profile());
TemplateURL* default_engine = model->GetDefaultSearchProvider();
ASSERT_NE(static_cast<TemplateURL*>(NULL), default_engine);
- EXPECT_EQ(ASCIIToUTF16("first"), default_engine->short_name());
- EXPECT_EQ(ASCIIToUTF16("firstkey"), default_engine->keyword());
+ EXPECT_EQ(base::ASCIIToUTF16("first"), default_engine->short_name());
+ EXPECT_EQ(base::ASCIIToUTF16("firstkey"), default_engine->keyword());
EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", default_engine->url());
EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
@@ -457,7 +585,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) {
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<Extension> theme =
- CreateExtension(ASCIIToUTF16("example1"),
+ CreateExtension(base::ASCIIToUTF16("example1"),
temp_dir.path(),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_THEME,
@@ -471,7 +599,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) {
EXPECT_FALSE(theme_service->UsingDefaultTheme());
scoped_refptr<Extension> ext2 = CreateExtension(
- ASCIIToUTF16("example2"),
+ base::ASCIIToUTF16("example2"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_EXTENSION,
@@ -479,28 +607,28 @@ TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) {
service_->AddExtension(ext2.get());
// Component extensions and policy-managed extensions shouldn't be disabled.
scoped_refptr<Extension> ext3 = CreateExtension(
- ASCIIToUTF16("example3"),
+ base::ASCIIToUTF16("example3"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
Manifest::COMPONENT,
extensions::Manifest::TYPE_EXTENSION,
false);
service_->AddExtension(ext3.get());
- scoped_refptr<Extension> ext4 = CreateExtension(
- ASCIIToUTF16("example4"),
- base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
- Manifest::EXTERNAL_POLICY_DOWNLOAD,
- extensions::Manifest::TYPE_EXTENSION,
- false);
+ scoped_refptr<Extension> ext4 =
+ CreateExtension(base::ASCIIToUTF16("example4"),
+ base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
+ Manifest::EXTERNAL_POLICY_DOWNLOAD,
+ extensions::Manifest::TYPE_EXTENSION,
+ false);
service_->AddExtension(ext4.get());
scoped_refptr<Extension> ext5 = CreateExtension(
- ASCIIToUTF16("example5"),
+ base::ASCIIToUTF16("example5"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent4")),
Manifest::EXTERNAL_COMPONENT,
extensions::Manifest::TYPE_EXTENSION,
false);
service_->AddExtension(ext5.get());
scoped_refptr<Extension> ext6 = CreateExtension(
- ASCIIToUTF16("example6"),
+ base::ASCIIToUTF16("example6"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent5")),
Manifest::EXTERNAL_POLICY,
extensions::Manifest::TYPE_EXTENSION,
@@ -521,7 +649,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) {
TEST_F(ProfileResetterTest, ResetExtensionsByDisablingNonOrganic) {
scoped_refptr<Extension> ext2 = CreateExtension(
- ASCIIToUTF16("example2"),
+ base::ASCIIToUTF16("example2"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_EXTENSION,
@@ -529,7 +657,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsByDisablingNonOrganic) {
service_->AddExtension(ext2.get());
// Components and external policy extensions shouldn't be deleted.
scoped_refptr<Extension> ext3 = CreateExtension(
- ASCIIToUTF16("example3"),
+ base::ASCIIToUTF16("example3"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_EXTENSION,
@@ -553,7 +681,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsAndDefaultApps) {
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<Extension> ext1 =
- CreateExtension(ASCIIToUTF16("example1"),
+ CreateExtension(base::ASCIIToUTF16("example1"),
temp_dir.path(),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_THEME,
@@ -567,7 +695,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsAndDefaultApps) {
EXPECT_FALSE(theme_service->UsingDefaultTheme());
scoped_refptr<Extension> ext2 =
- CreateExtension(ASCIIToUTF16("example2"),
+ CreateExtension(base::ASCIIToUTF16("example2"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_EXTENSION,
@@ -575,7 +703,7 @@ TEST_F(ProfileResetterTest, ResetExtensionsAndDefaultApps) {
service_->AddExtension(ext2.get());
scoped_refptr<Extension> ext3 =
- CreateExtension(ASCIIToUTF16("example2"),
+ CreateExtension(base::ASCIIToUTF16("example2"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_HOSTED_APP,
@@ -626,7 +754,7 @@ TEST_F(ProfileResetterTest, ResetStartPagePartially) {
TEST_F(PinnedTabsResetTest, ResetPinnedTabs) {
scoped_refptr<Extension> extension_app = CreateExtension(
- ASCIIToUTF16("hello!"),
+ base::ASCIIToUTF16("hello!"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_HOSTED_APP,
@@ -662,6 +790,20 @@ TEST_F(PinnedTabsResetTest, ResetPinnedTabs) {
EXPECT_EQ(1, tab_strip_model->IndexOfFirstNonMiniTab());
}
+TEST_F(ProfileResetterTest, ResetShortcuts) {
+ ShortcutHandler shortcut;
+ ShortcutCommand command_line = shortcut.CreateWithArguments(
+ base::ASCIIToUTF16("chrome.lnk"),
+ base::ASCIIToUTF16("--profile-directory=Default foo.com"));
+ shortcut.CheckShortcutHasArguments(base::ASCIIToUTF16(
+ "--profile-directory=Default foo.com"));
+
+ ResetAndWait(ProfileResetter::SHORTCUTS);
+
+ shortcut.CheckShortcutHasArguments(base::ASCIIToUTF16(
+ "--profile-directory=Default"));
+}
+
TEST_F(ProfileResetterTest, ResetFewFlags) {
// mock_object_ is a StrictMock, so we verify that it is called only once.
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
@@ -719,11 +861,11 @@ TEST_F(ConfigParserTest, ParseConfig) {
}
TEST_F(ProfileResetterTest, CheckSnapshots) {
- ResettableSettingsSnapshot empty_snap(profile());
+ ResettableSettingsSnapshot empty_snap(profile(), false);
EXPECT_EQ(0, empty_snap.FindDifferentFields(empty_snap));
scoped_refptr<Extension> ext = CreateExtension(
- ASCIIToUTF16("example"),
+ base::ASCIIToUTF16("example"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_EXTENSION,
@@ -740,9 +882,24 @@ TEST_F(ProfileResetterTest, CheckSnapshots) {
ProfileResetter::HOMEPAGE |
ProfileResetter::STARTUP_PAGES,
master_prefs);
-
- ResettableSettingsSnapshot nonorganic_snap(profile());
- EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS,
+ ShortcutHandler shortcut_hijacked;
+ ShortcutCommand command_line = shortcut_hijacked.CreateWithArguments(
+ base::ASCIIToUTF16("chrome1.lnk"),
+ base::ASCIIToUTF16("--profile-directory=Default foo.com"));
+ shortcut_hijacked.CheckShortcutHasArguments(
+ base::ASCIIToUTF16("--profile-directory=Default foo.com"));
+ ShortcutHandler shortcut_ok;
+ shortcut_ok.CreateWithArguments(
+ base::ASCIIToUTF16("chrome2.lnk"),
+ base::ASCIIToUTF16("--profile-directory=Default1"));
+
+ ResettableSettingsSnapshot nonorganic_snap(profile(), true);
+ // Let it enumerate shortcuts on the FILE thread.
+ base::MessageLoop::current()->RunUntilIdle();
+ int diff_fields = ResettableSettingsSnapshot::ALL_FIELDS;
+ if (!ShortcutHandler::IsSupported())
+ diff_fields &= ~ResettableSettingsSnapshot::SHORTCUTS;
+ EXPECT_EQ(diff_fields,
empty_snap.FindDifferentFields(nonorganic_snap));
empty_snap.Subtract(nonorganic_snap);
EXPECT_TRUE(empty_snap.startup_urls().empty());
@@ -753,16 +910,19 @@ TEST_F(ProfileResetterTest, CheckSnapshots) {
EXPECT_NE(std::string::npos, empty_snap.dse_url().find("{google:baseURL}"));
EXPECT_EQ(ResettableSettingsSnapshot::ExtensionList(),
empty_snap.enabled_extensions());
+ EXPECT_EQ(std::vector<ShortcutCommand>(), empty_snap.shortcuts());
// Reset to organic defaults.
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
ProfileResetter::HOMEPAGE |
ProfileResetter::STARTUP_PAGES |
- ProfileResetter::EXTENSIONS);
+ ProfileResetter::EXTENSIONS |
+ ProfileResetter::SHORTCUTS);
- ResettableSettingsSnapshot organic_snap(profile());
- EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS,
- nonorganic_snap.FindDifferentFields(organic_snap));
+ ResettableSettingsSnapshot organic_snap(profile(), true);
+ // Let it enumerate shortcuts on the FILE thread.
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_EQ(diff_fields, nonorganic_snap.FindDifferentFields(organic_snap));
nonorganic_snap.Subtract(organic_snap);
const GURL urls[] = {GURL("http://foo.de"), GURL("http://goo.gl")};
EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)),
@@ -774,9 +934,15 @@ TEST_F(ProfileResetterTest, CheckSnapshots) {
EXPECT_EQ(ResettableSettingsSnapshot::ExtensionList(
1, std::make_pair(ext_id, "example")),
nonorganic_snap.enabled_extensions());
+ if (ShortcutHandler::IsSupported()) {
+ std::vector<ShortcutCommand> shortcuts = nonorganic_snap.shortcuts();
+ ASSERT_EQ(1u, shortcuts.size());
+ EXPECT_EQ(command_line.first.value(), shortcuts[0].first.value());
+ EXPECT_EQ(command_line.second, shortcuts[0].second);
+ }
}
-TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
+TEST_F(ProfileResetterTest, FeedbackSerializationTest) {
// Reset to non organic defaults.
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
ProfileResetter::HOMEPAGE |
@@ -784,7 +950,7 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
kDistributionConfig);
scoped_refptr<Extension> ext = CreateExtension(
- ASCIIToUTF16("example"),
+ base::ASCIIToUTF16("example"),
base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
Manifest::INVALID_LOCATION,
extensions::Manifest::TYPE_EXTENSION,
@@ -792,9 +958,16 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
ASSERT_TRUE(ext);
service_->AddExtension(ext.get());
- const ResettableSettingsSnapshot nonorganic_snap(profile());
+ ShortcutHandler shortcut;
+ ShortcutCommand command_line = shortcut.CreateWithArguments(
+ base::ASCIIToUTF16("chrome.lnk"),
+ base::ASCIIToUTF16("--profile-directory=Default foo.com"));
- COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 15,
+ const ResettableSettingsSnapshot nonorganic_snap(profile(), true);
+ // Let it enumerate shortcuts on the FILE thread.
+ base::MessageLoop::current()->RunUntilIdle();
+
+ COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 31,
expand_this_test);
for (int field_mask = 0; field_mask <= ResettableSettingsSnapshot::ALL_FIELDS;
++field_mask) {
@@ -813,7 +986,8 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
std::string homepage;
bool homepage_is_ntp = true;
std::string default_search_engine;
- base::ListValue* extensions;
+ base::ListValue* extensions = NULL;
+ base::ListValue* shortcuts = NULL;
EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_MODE),
dict->GetList("startup_urls", &startup_urls));
@@ -827,9 +1001,22 @@ TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
dict->GetString("default_search_engine", &default_search_engine));
EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::EXTENSIONS),
dict->GetList("enabled_extensions", &extensions));
+ EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::SHORTCUTS),
+ dict->GetList("shortcuts", &shortcuts));
}
}
+struct FeedbackCapture {
+ void SetList(scoped_ptr<base::ListValue> list) {
+ list_ = list.Pass();
+ OnUpdatedList();
+ }
+
+ MOCK_METHOD0(OnUpdatedList, void(void));
+
+ scoped_ptr<base::ListValue> list_;
+};
+
// Make sure GetReadableFeedback handles non-ascii letters.
TEST_F(ProfileResetterTest, GetReadableFeedback) {
scoped_refptr<Extension> ext = CreateExtension(
@@ -853,10 +1040,25 @@ TEST_F(ProfileResetterTest, GetReadableFeedback) {
startup_pref.urls.push_back(GURL(base::WideToUTF8(url)));
SessionStartupPref::SetStartupPref(prefs, startup_pref);
+ ShortcutHandler shortcut;
+ ShortcutCommand command_line = shortcut.CreateWithArguments(
+ base::ASCIIToUTF16("chrome.lnk"),
+ base::ASCIIToUTF16("--profile-directory=Default foo.com"));
+
+ FeedbackCapture capture;
+ EXPECT_CALL(capture, OnUpdatedList());
+ ResettableSettingsSnapshot::GetReadableFeedback(
+ profile(),
+ base::Bind(&FeedbackCapture::SetList, base::Unretained(&capture)));
+ // Let it enumerate shortcuts on the FILE thread.
+ base::MessageLoop::current()->RunUntilIdle();
+ ::testing::Mock::VerifyAndClearExpectations(&capture);
// The homepage and the startup page are in punycode. They are unreadable.
// Trying to find the extension name.
- scoped_ptr<base::ListValue> list(GetReadableFeedback(profile()));
+ scoped_ptr<base::ListValue> list = capture.list_.Pass();
ASSERT_TRUE(list);
+ bool checked_extensions = false;
+ bool checked_shortcuts = false;
for (size_t i = 0; i < list->GetSize(); ++i) {
base::DictionaryValue* dict = NULL;
ASSERT_TRUE(list->GetDictionary(i, &dict));
@@ -866,8 +1068,17 @@ TEST_F(ProfileResetterTest, GetReadableFeedback) {
base::string16 extensions;
EXPECT_TRUE(dict->GetString("value", &extensions));
EXPECT_EQ(base::WideToUTF16(L"Tiƫsto"), extensions);
+ checked_extensions = true;
+ } else if (value == "Shortcut targets") {
+ base::string16 targets;
+ EXPECT_TRUE(dict->GetString("value", &targets));
+ EXPECT_NE(base::string16::npos,
+ targets.find(base::ASCIIToUTF16("foo.com"))) << targets;
+ checked_shortcuts = true;
}
}
+ EXPECT_TRUE(checked_extensions);
+ EXPECT_EQ(ShortcutHandler::IsSupported(), checked_shortcuts);
}
} // namespace