• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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