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
TEST(ProcessExtensions,NoExtension)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
AddExtensionForInstall(const std::string & relative_path,std::vector<std::string> * extensions)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
TEST(ProcessExtensions,GenerateIds)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
TEST(ProcessExtensions,SingleExtensionWithBgPage)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
TEST(ProcessExtensions,MultipleExtensionsNoBgPages)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
TEST(ProcessExtensions,CommandLineExtensions)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
AssertEQ(const base::DictionaryValue & dict,const std::string & key,const char * expected_value)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
TEST(PrepareUserDataDir,CustomPrefs)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