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 "base/base64.h" 6 #include "base/base_paths.h" 7 #include "base/command_line.h" 8 #include "base/file_util.h" 9 #include "base/files/file_path.h" 10 #include "base/files/scoped_temp_dir.h" 11 #include "base/json/json_reader.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/path_service.h" 14 #include "base/strings/string_split.h" 15 #include "base/values.h" 16 #include "chrome/test/chromedriver/chrome/status.h" 17 #include "chrome/test/chromedriver/chrome_launcher.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 TEST(ProcessExtensions, NoExtension) { 21 Switches switches; 22 std::vector<std::string> extensions; 23 base::FilePath extension_dir; 24 std::vector<std::string> bg_pages; 25 Status status = internal::ProcessExtensions(extensions, extension_dir, 26 false, &switches, &bg_pages); 27 ASSERT_TRUE(status.IsOk()); 28 ASSERT_FALSE(switches.HasSwitch("load-extension")); 29 ASSERT_EQ(0u, bg_pages.size()); 30 } 31 32 bool AddExtensionForInstall(const std::string& relative_path, 33 std::vector<std::string>* extensions) { 34 base::FilePath source_root; 35 PathService::Get(base::DIR_SOURCE_ROOT, &source_root); 36 base::FilePath crx_file_path = source_root.AppendASCII( 37 "chrome/test/data/chromedriver/" + relative_path); 38 std::string crx_contents; 39 if (!base::ReadFileToString(crx_file_path, &crx_contents)) 40 return false; 41 42 std::string crx_encoded; 43 base::Base64Encode(crx_contents, &crx_encoded); 44 extensions->push_back(crx_encoded); 45 return true; 46 } 47 48 TEST(ProcessExtensions, GenerateIds) { 49 std::vector<std::string> extensions; 50 base::ScopedTempDir extension_dir; 51 Switches switches; 52 std::vector<std::string> bg_pages; 53 54 ASSERT_TRUE(AddExtensionForInstall("no_key_in_manifest.crx", &extensions)); 55 ASSERT_TRUE(AddExtensionForInstall("same_key_as_header.crx", &extensions)); 56 ASSERT_TRUE(AddExtensionForInstall("diff_key_from_header.crx", &extensions)); 57 58 ASSERT_TRUE(extension_dir.CreateUniqueTempDir()); 59 60 Status status = internal::ProcessExtensions(extensions, extension_dir.path(), 61 false, &switches, &bg_pages); 62 63 ASSERT_EQ(kOk, status.code()) << status.message(); 64 ASSERT_EQ(3u, bg_pages.size()); 65 ASSERT_EQ("chrome-extension://llphabdmknikmpmkioimgdfbohinlekl/" 66 "_generated_background_page.html", bg_pages[0]); 67 ASSERT_EQ("chrome-extension://dfdeoklpcichfcnoaomfpagfiibhomnh/" 68 "_generated_background_page.html", bg_pages[1]); 69 ASSERT_EQ("chrome-extension://ioccpomhcpklobebcbeohnmffkmcokbm/" 70 "_generated_background_page.html", bg_pages[2]); 71 } 72 73 TEST(ProcessExtensions, SingleExtensionWithBgPage) { 74 std::vector<std::string> extensions; 75 ASSERT_TRUE(AddExtensionForInstall("ext_slow_loader.crx", &extensions)); 76 77 base::ScopedTempDir extension_dir; 78 ASSERT_TRUE(extension_dir.CreateUniqueTempDir()); 79 80 Switches switches; 81 std::vector<std::string> bg_pages; 82 Status status = internal::ProcessExtensions(extensions, extension_dir.path(), 83 false, &switches, &bg_pages); 84 ASSERT_TRUE(status.IsOk()); 85 ASSERT_TRUE(switches.HasSwitch("load-extension")); 86 base::FilePath temp_ext_path(switches.GetSwitchValueNative("load-extension")); 87 ASSERT_TRUE(base::PathExists(temp_ext_path)); 88 std::string manifest_txt; 89 ASSERT_TRUE(base::ReadFileToString( 90 temp_ext_path.AppendASCII("manifest.json"), &manifest_txt)); 91 scoped_ptr<base::Value> manifest(base::JSONReader::Read(manifest_txt)); 92 ASSERT_TRUE(manifest); 93 base::DictionaryValue* manifest_dict = NULL; 94 ASSERT_TRUE(manifest->GetAsDictionary(&manifest_dict)); 95 std::string key; 96 ASSERT_TRUE(manifest_dict->GetString("key", &key)); 97 ASSERT_EQ( 98 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8qhZthEHjTIA3IYMzi79s2KFepVziY0du" 99 "JzHcqRUB/YHSGseIUqcYXGazJhDz/" 100 "4FbRg8ef9fQazL1UbMMGBIf4za1kJ2os2MsRrNXzHslkbtcLVj2VfofhuHJmu+" 101 "CnKJ77UWamJiNAaQSiclu4duwnEWrkx+g/8ChQfhZzC4jvQIDAQAB", 102 key); 103 ASSERT_EQ(1u, bg_pages.size()); 104 ASSERT_EQ( 105 "chrome-extension://jijhlkpcmmeckhlgdipjhnchhoabdjae/" 106 "_generated_background_page.html", 107 bg_pages[0]); 108 } 109 110 TEST(ProcessExtensions, MultipleExtensionsNoBgPages) { 111 std::vector<std::string> extensions; 112 ASSERT_TRUE(AddExtensionForInstall("ext_test_1.crx", &extensions)); 113 ASSERT_TRUE(AddExtensionForInstall("ext_test_2.crx", &extensions)); 114 115 base::ScopedTempDir extension_dir; 116 ASSERT_TRUE(extension_dir.CreateUniqueTempDir()); 117 118 Switches switches; 119 std::vector<std::string> bg_pages; 120 Status status = internal::ProcessExtensions(extensions, extension_dir.path(), 121 false, &switches, &bg_pages); 122 ASSERT_TRUE(status.IsOk()); 123 ASSERT_TRUE(switches.HasSwitch("load-extension")); 124 CommandLine::StringType ext_paths = switches.GetSwitchValueNative( 125 "load-extension"); 126 std::vector<CommandLine::StringType> ext_path_list; 127 base::SplitString(ext_paths, FILE_PATH_LITERAL(','), &ext_path_list); 128 ASSERT_EQ(2u, ext_path_list.size()); 129 ASSERT_TRUE(base::PathExists(base::FilePath(ext_path_list[0]))); 130 ASSERT_TRUE(base::PathExists(base::FilePath(ext_path_list[1]))); 131 ASSERT_EQ(0u, bg_pages.size()); 132 } 133 134 TEST(ProcessExtensions, CommandLineExtensions) { 135 std::vector<std::string> extensions; 136 ASSERT_TRUE(AddExtensionForInstall("ext_test_1.crx", &extensions)); 137 base::ScopedTempDir extension_dir; 138 ASSERT_TRUE(extension_dir.CreateUniqueTempDir()); 139 140 Switches switches; 141 switches.SetSwitch("load-extension", "/a"); 142 std::vector<std::string> bg_pages; 143 Status status = internal::ProcessExtensions(extensions, extension_dir.path(), 144 false, &switches, &bg_pages); 145 ASSERT_EQ(kOk, status.code()); 146 base::FilePath::StringType load = switches.GetSwitchValueNative( 147 "load-extension"); 148 ASSERT_EQ(FILE_PATH_LITERAL("/a,"), load.substr(0, 3)); 149 ASSERT_TRUE(base::PathExists(base::FilePath(load.substr(3)))); 150 } 151 152 namespace { 153 154 void AssertEQ(const base::DictionaryValue& dict, const std::string& key, 155 const char* expected_value) { 156 std::string value; 157 ASSERT_TRUE(dict.GetString(key, &value)); 158 ASSERT_STREQ(value.c_str(), expected_value); 159 } 160 161 } // namespace 162 163 TEST(PrepareUserDataDir, CustomPrefs) { 164 base::ScopedTempDir temp_dir; 165 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 166 167 base::DictionaryValue prefs; 168 prefs.SetString("myPrefsKey", "ok"); 169 prefs.SetStringWithoutPathExpansion("pref.sub", "1"); 170 base::DictionaryValue local_state; 171 local_state.SetString("myLocalKey", "ok"); 172 local_state.SetStringWithoutPathExpansion("local.state.sub", "2"); 173 Status status = internal::PrepareUserDataDir( 174 temp_dir.path(), &prefs, &local_state); 175 ASSERT_EQ(kOk, status.code()); 176 177 base::FilePath prefs_file = 178 temp_dir.path().AppendASCII("Default").AppendASCII("Preferences"); 179 std::string prefs_str; 180 ASSERT_TRUE(base::ReadFileToString(prefs_file, &prefs_str)); 181 scoped_ptr<base::Value> prefs_value(base::JSONReader::Read(prefs_str)); 182 const base::DictionaryValue* prefs_dict = NULL; 183 ASSERT_TRUE(prefs_value->GetAsDictionary(&prefs_dict)); 184 AssertEQ(*prefs_dict, "myPrefsKey", "ok"); 185 AssertEQ(*prefs_dict, "pref.sub", "1"); 186 187 base::FilePath local_state_file = temp_dir.path().AppendASCII("Local State"); 188 std::string local_state_str; 189 ASSERT_TRUE(base::ReadFileToString(local_state_file, &local_state_str)); 190 scoped_ptr<base::Value> local_state_value( 191 base::JSONReader::Read(local_state_str)); 192 const base::DictionaryValue* local_state_dict = NULL; 193 ASSERT_TRUE(local_state_value->GetAsDictionary(&local_state_dict)); 194 AssertEQ(*local_state_dict, "myLocalKey", "ok"); 195 AssertEQ(*local_state_dict, "local.state.sub", "2"); 196 } 197