1 // Copyright (c) 2011 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/path_service.h"
6 #include "base/string_util.h"
7 #include "chrome/browser/extensions/extensions_ui.h"
8 #include "chrome/common/chrome_paths.h"
9 #include "chrome/common/extensions/extension.h"
10 #include "content/common/json_value_serializer.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace {
DeserializeJSONTestData(const FilePath & path,std::string * error)14 static DictionaryValue* DeserializeJSONTestData(const FilePath& path,
15 std::string *error) {
16 Value* value;
17
18 JSONFileValueSerializer serializer(path);
19 value = serializer.Deserialize(NULL, error);
20
21 return static_cast<DictionaryValue*>(value);
22 }
23
CreateExtensionDetailViewFromPath(const FilePath & extension_path,const std::vector<ExtensionPage> & pages,Extension::Location location)24 static DictionaryValue* CreateExtensionDetailViewFromPath(
25 const FilePath& extension_path,
26 const std::vector<ExtensionPage>& pages,
27 Extension::Location location) {
28 std::string error;
29
30 FilePath manifest_path = extension_path.Append(
31 Extension::kManifestFilename);
32 scoped_ptr<DictionaryValue> extension_data(DeserializeJSONTestData(
33 manifest_path, &error));
34 EXPECT_EQ("", error);
35
36 scoped_refptr<Extension> extension(Extension::Create(
37 extension_path, location, *extension_data,
38 Extension::REQUIRE_KEY | Extension::STRICT_ERROR_CHECKS, &error));
39 EXPECT_TRUE(extension.get());
40 EXPECT_EQ("", error);
41
42 return ExtensionsDOMHandler::CreateExtensionDetailValue(
43 NULL, extension.get(), pages, true, false);
44 }
45
46
CompareExpectedAndActualOutput(const FilePath & extension_path,const std::vector<ExtensionPage> & pages,const FilePath & expected_output_path)47 static void CompareExpectedAndActualOutput(
48 const FilePath& extension_path,
49 const std::vector<ExtensionPage>& pages,
50 const FilePath& expected_output_path) {
51 std::string error;
52
53 scoped_ptr<DictionaryValue> expected_output_data(DeserializeJSONTestData(
54 expected_output_path, &error));
55 EXPECT_EQ("", error);
56
57 // Produce test output.
58 scoped_ptr<DictionaryValue> actual_output_data(
59 CreateExtensionDetailViewFromPath(
60 extension_path, pages, Extension::INVALID));
61
62 // Compare the outputs.
63 // Ignore unknown fields in the actual output data.
64 std::string paths_details = " - expected (" +
65 expected_output_path.MaybeAsASCII() + ") vs. actual (" +
66 extension_path.MaybeAsASCII() + ")";
67 for (DictionaryValue::key_iterator key = expected_output_data->begin_keys();
68 key != expected_output_data->end_keys();
69 ++key) {
70 Value* expected_value = NULL;
71 Value* actual_value = NULL;
72 EXPECT_TRUE(expected_output_data->Get(*key, &expected_value)) <<
73 *key + " is missing" + paths_details;
74 EXPECT_TRUE(actual_output_data->Get(*key, &actual_value)) <<
75 *key + " is missing" + paths_details;
76 if (expected_value == NULL) {
77 EXPECT_EQ(NULL, actual_value) << *key + paths_details;
78 } else {
79 EXPECT_TRUE(expected_value->Equals(actual_value)) << *key +
80 paths_details;
81 }
82 }
83 }
84 } // namespace
85
TEST(ExtensionUITest,GenerateExtensionsJSONData)86 TEST(ExtensionUITest, GenerateExtensionsJSONData) {
87 FilePath data_test_dir_path, extension_path, expected_output_path;
88 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path));
89
90 // Test Extension1
91 extension_path = data_test_dir_path.AppendASCII("extensions")
92 .AppendASCII("good")
93 .AppendASCII("Extensions")
94 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
95 .AppendASCII("1.0.0.0");
96
97 std::vector<ExtensionPage> pages;
98 pages.push_back(ExtensionPage(
99 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/bar.html"),
100 42, 88, false));
101 pages.push_back(ExtensionPage(
102 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/dog.html"),
103 0, 0, false));
104
105 expected_output_path = data_test_dir_path.AppendASCII("extensions")
106 .AppendASCII("ui")
107 .AppendASCII("create_extension_detail_value_expected_output")
108 .AppendASCII("good-extension1.json");
109
110 CompareExpectedAndActualOutput(extension_path, pages, expected_output_path);
111
112 #if !defined(OS_CHROMEOS)
113 // Test Extension2
114 extension_path = data_test_dir_path.AppendASCII("extensions")
115 .AppendASCII("good")
116 .AppendASCII("Extensions")
117 .AppendASCII("hpiknbiabeeppbpihjehijgoemciehgk")
118 .AppendASCII("2");
119
120 expected_output_path = data_test_dir_path.AppendASCII("extensions")
121 .AppendASCII("ui")
122 .AppendASCII("create_extension_detail_value_expected_output")
123 .AppendASCII("good-extension2.json");
124
125 // It's OK to have duplicate URLs, so long as the IDs are different.
126 pages[1].url = pages[0].url;
127
128 CompareExpectedAndActualOutput(extension_path, pages, expected_output_path);
129 #endif
130
131 // Test Extension3
132 extension_path = data_test_dir_path.AppendASCII("extensions")
133 .AppendASCII("good")
134 .AppendASCII("Extensions")
135 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
136 .AppendASCII("1.0");
137
138 expected_output_path = data_test_dir_path.AppendASCII("extensions")
139 .AppendASCII("ui")
140 .AppendASCII("create_extension_detail_value_expected_output")
141 .AppendASCII("good-extension3.json");
142
143 pages.clear();
144
145 CompareExpectedAndActualOutput(extension_path, pages, expected_output_path);
146 }
147
148 // Test that using Extension::LOAD for the extension location triggers the
149 // correct values in the details, including location, order, and allow_reload.
TEST(ExtensionUITest,LocationLoadPropagation)150 TEST(ExtensionUITest, LocationLoadPropagation) {
151 FilePath data_test_dir_path, extension_path;
152 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path));
153
154 extension_path = data_test_dir_path.AppendASCII("extensions")
155 .AppendASCII("good")
156 .AppendASCII("Extensions")
157 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
158 .AppendASCII("1.0.0.0");
159
160 std::vector<ExtensionPage> pages;
161
162 scoped_ptr<DictionaryValue> extension_details(
163 CreateExtensionDetailViewFromPath(
164 extension_path, pages, Extension::LOAD));
165
166 bool ui_allow_reload = false;
167 bool ui_is_unpacked = false;
168 FilePath::StringType ui_path;
169
170 EXPECT_TRUE(extension_details->GetBoolean("allow_reload", &ui_allow_reload));
171 EXPECT_TRUE(extension_details->GetBoolean("isUnpacked", &ui_is_unpacked));
172 EXPECT_TRUE(extension_details->GetString("path", &ui_path));
173 EXPECT_EQ(true, ui_allow_reload);
174 EXPECT_EQ(true, ui_is_unpacked);
175 EXPECT_EQ(extension_path, FilePath(ui_path));
176 }
177
178 // Test that using Extension::EXTERNAL_PREF for the extension location triggers
179 // the correct values in the details, including location, order, and
180 // allow_reload. Contrast to Extension::LOAD, which has somewhat different
181 // values.
TEST(ExtensionUITest,LocationExternalPrefPropagation)182 TEST(ExtensionUITest, LocationExternalPrefPropagation) {
183 FilePath data_test_dir_path, extension_path;
184 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path));
185
186 extension_path = data_test_dir_path.AppendASCII("extensions")
187 .AppendASCII("good")
188 .AppendASCII("Extensions")
189 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
190 .AppendASCII("1.0.0.0");
191
192 std::vector<ExtensionPage> pages;
193
194 scoped_ptr<DictionaryValue> extension_details(
195 CreateExtensionDetailViewFromPath(
196 extension_path, pages, Extension::EXTERNAL_PREF));
197
198 bool ui_allow_reload = true;
199 bool ui_is_unpacked = true;
200 FilePath::StringType ui_path;
201
202 EXPECT_TRUE(extension_details->GetBoolean("allow_reload", &ui_allow_reload));
203 EXPECT_TRUE(extension_details->GetBoolean("isUnpacked", &ui_is_unpacked));
204 EXPECT_FALSE(extension_details->GetString("path", &ui_path));
205 EXPECT_FALSE(ui_allow_reload);
206 EXPECT_FALSE(ui_is_unpacked);
207 }
208
209 // Test that the extension path is correctly propagated into the extension
210 // details.
TEST(ExtensionUITest,PathPropagation)211 TEST(ExtensionUITest, PathPropagation) {
212 FilePath data_test_dir_path, extension_path;
213 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path));
214
215 extension_path = data_test_dir_path.AppendASCII("extensions")
216 .AppendASCII("good")
217 .AppendASCII("Extensions")
218 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
219 .AppendASCII("1.0.0.0");
220
221 std::vector<ExtensionPage> pages;
222
223 scoped_ptr<DictionaryValue> extension_details(
224 CreateExtensionDetailViewFromPath(
225 extension_path, pages, Extension::LOAD));
226
227 FilePath::StringType ui_path;
228
229 EXPECT_TRUE(extension_details->GetString("path", &ui_path));
230 EXPECT_EQ(extension_path, FilePath(ui_path));
231 }
232
233