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