OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/json/json_file_value_serializer.h" | 10 #include "base/json/json_file_value_serializer.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
12 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "chrome/common/chrome_paths.h" | 15 #include "chrome/common/chrome_paths.h" |
16 #include "chrome/common/extensions/api/extension_action/action_info.h" | |
17 #include "chrome/common/extensions/command.h" | 16 #include "chrome/common/extensions/command.h" |
18 #include "chrome/common/extensions/extension_file_util.h" | 17 #include "chrome/common/extensions/extension_file_util.h" |
19 #include "chrome/common/extensions/extension_manifest_constants.h" | 18 #include "chrome/common/extensions/extension_manifest_constants.h" |
20 #include "chrome/common/extensions/extension_resource.h" | 19 #include "chrome/common/extensions/extension_resource.h" |
21 #include "chrome/common/extensions/features/feature.h" | 20 #include "chrome/common/extensions/features/feature.h" |
| 21 #include "chrome/common/extensions/manifest_handler.h" |
22 #include "chrome/common/extensions/permissions/api_permission.h" | 22 #include "chrome/common/extensions/permissions/api_permission.h" |
23 #include "chrome/common/extensions/permissions/permission_set.h" | 23 #include "chrome/common/extensions/permissions/permission_set.h" |
24 #include "chrome/common/extensions/permissions/socket_permission.h" | 24 #include "chrome/common/extensions/permissions/socket_permission.h" |
25 #include "chrome/common/extensions/permissions/usb_device_permission.h" | 25 #include "chrome/common/extensions/permissions/usb_device_permission.h" |
26 #include "chrome/common/url_constants.h" | 26 #include "chrome/common/url_constants.h" |
27 #include "extensions/common/error_utils.h" | 27 #include "extensions/common/error_utils.h" |
28 #include "googleurl/src/gurl.h" | 28 #include "googleurl/src/gurl.h" |
29 #include "net/base/mime_sniffer.h" | 29 #include "net/base/mime_sniffer.h" |
30 #include "net/base/mock_host_resolver.h" | 30 #include "net/base/mock_host_resolver.h" |
31 #include "skia/ext/image_operations.h" | 31 #include "skia/ext/image_operations.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 const std::string& test_file) { | 87 const std::string& test_file) { |
88 return LoadManifest(dir, test_file, Extension::NO_FLAGS); | 88 return LoadManifest(dir, test_file, Extension::NO_FLAGS); |
89 } | 89 } |
90 | 90 |
91 static scoped_refptr<Extension> LoadManifestStrict( | 91 static scoped_refptr<Extension> LoadManifestStrict( |
92 const std::string& dir, | 92 const std::string& dir, |
93 const std::string& test_file) { | 93 const std::string& test_file) { |
94 return LoadManifest(dir, test_file, Extension::NO_FLAGS); | 94 return LoadManifest(dir, test_file, Extension::NO_FLAGS); |
95 } | 95 } |
96 | 96 |
97 static scoped_ptr<ActionInfo> LoadAction( | 97 } // namespace |
98 const std::string& manifest) { | |
99 scoped_refptr<Extension> extension = LoadManifest("page_action", | |
100 manifest); | |
101 EXPECT_TRUE(extension->page_action_info()); | |
102 if (extension->page_action_info()) { | |
103 return make_scoped_ptr(new ActionInfo( | |
104 *extension->page_action_info())); | |
105 } | |
106 ADD_FAILURE() << "Expected manifest in " << manifest | |
107 << " to include a page_action section."; | |
108 return scoped_ptr<ActionInfo>(); | |
109 } | |
110 | |
111 static void LoadActionAndExpectError(const std::string& manifest, | |
112 const std::string& expected_error) { | |
113 std::string error; | |
114 scoped_refptr<Extension> extension = LoadManifestUnchecked("page_action", | |
115 manifest, Extension::INTERNAL, Extension::NO_FLAGS, &error); | |
116 EXPECT_FALSE(extension); | |
117 EXPECT_EQ(expected_error, error); | |
118 } | |
119 | |
120 } | |
121 | 98 |
122 class ExtensionTest : public testing::Test { | 99 class ExtensionTest : public testing::Test { |
123 }; | 100 }; |
124 | 101 |
125 // We persist location values in the preferences, so this is a sanity test that | 102 // We persist location values in the preferences, so this is a sanity test that |
126 // someone doesn't accidentally change them. | 103 // someone doesn't accidentally change them. |
127 TEST(ExtensionTest, LocationValuesTest) { | 104 TEST(ExtensionTest, LocationValuesTest) { |
128 ASSERT_EQ(0, Extension::INVALID); | 105 ASSERT_EQ(0, Extension::INVALID); |
129 ASSERT_EQ(1, Extension::INTERNAL); | 106 ASSERT_EQ(1, Extension::INTERNAL); |
130 ASSERT_EQ(2, Extension::EXTERNAL_PREF); | 107 ASSERT_EQ(2, Extension::EXTERNAL_PREF); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 EXPECT_TRUE(extension_file_util::ValidateExtension(extension.get(), | 176 EXPECT_TRUE(extension_file_util::ValidateExtension(extension.get(), |
200 &err, &warnings)); | 177 &err, &warnings)); |
201 EXPECT_EQ(0U, warnings.size()); | 178 EXPECT_EQ(0U, warnings.size()); |
202 | 179 |
203 EXPECT_EQ(extension->path().AppendASCII("test.html").value(), | 180 EXPECT_EQ(extension->path().AppendASCII("test.html").value(), |
204 extension->GetResource("test.html").GetFilePath().value()); | 181 extension->GetResource("test.html").GetFilePath().value()); |
205 EXPECT_EQ(extension->path().AppendASCII("test.js").value(), | 182 EXPECT_EQ(extension->path().AppendASCII("test.js").value(), |
206 extension->GetResource("test.js").GetFilePath().value()); | 183 extension->GetResource("test.js").GetFilePath().value()); |
207 } | 184 } |
208 | 185 |
209 TEST(ExtensionTest, LoadPageActionHelper) { | |
210 scoped_ptr<ActionInfo> action; | |
211 | |
212 // First try with an empty dictionary. | |
213 action = LoadAction("page_action_empty.json"); | |
214 ASSERT_TRUE(action != NULL); | |
215 | |
216 // Now setup some values to use in the action. | |
217 const std::string id("MyExtensionActionId"); | |
218 const std::string name("MyExtensionActionName"); | |
219 std::string img1("image1.png"); | |
220 | |
221 action = LoadAction("page_action.json"); | |
222 ASSERT_TRUE(NULL != action.get()); | |
223 ASSERT_EQ(id, action->id); | |
224 | |
225 // No title, so fall back to name. | |
226 ASSERT_EQ(name, action->default_title); | |
227 ASSERT_EQ(img1, | |
228 action->default_icon.Get(extension_misc::EXTENSION_ICON_ACTION, | |
229 ExtensionIconSet::MATCH_EXACTLY)); | |
230 | |
231 // Same test with explicitly set type. | |
232 action = LoadAction("page_action_type.json"); | |
233 ASSERT_TRUE(NULL != action.get()); | |
234 | |
235 // Try an action without id key. | |
236 action = LoadAction("page_action_no_id.json"); | |
237 ASSERT_TRUE(NULL != action.get()); | |
238 | |
239 // Then try without the name key. It's optional, so no error. | |
240 action = LoadAction("page_action_no_name.json"); | |
241 ASSERT_TRUE(NULL != action.get()); | |
242 ASSERT_TRUE(action->default_title.empty()); | |
243 | |
244 // Then try without the icon paths key. | |
245 action = LoadAction("page_action_no_icon.json"); | |
246 ASSERT_TRUE(NULL != action.get()); | |
247 | |
248 // Now test that we can parse the new format for page actions. | |
249 const std::string kTitle("MyExtensionActionTitle"); | |
250 const std::string kIcon("image1.png"); | |
251 const std::string kPopupHtmlFile("a_popup.html"); | |
252 | |
253 action = LoadAction("page_action_new_format.json"); | |
254 ASSERT_TRUE(action.get()); | |
255 ASSERT_EQ(kTitle, action->default_title); | |
256 ASSERT_FALSE(action->default_icon.empty()); | |
257 | |
258 // Invalid title should give an error even with a valid name. | |
259 LoadActionAndExpectError("page_action_invalid_title.json", | |
260 errors::kInvalidPageActionDefaultTitle); | |
261 | |
262 // Invalid name should give an error only with no title. | |
263 action = LoadAction("page_action_invalid_name.json"); | |
264 ASSERT_TRUE(NULL != action.get()); | |
265 ASSERT_EQ(kTitle, action->default_title); | |
266 | |
267 LoadActionAndExpectError("page_action_invalid_name_no_title.json", | |
268 errors::kInvalidPageActionName); | |
269 | |
270 // Test that keys "popup" and "default_popup" both work, but can not | |
271 // be used at the same time. | |
272 // These tests require an extension_url, so we also load the manifest. | |
273 | |
274 // Only use "popup", expect success. | |
275 scoped_refptr<Extension> extension = LoadManifest("page_action", | |
276 "page_action_popup.json"); | |
277 action = LoadAction("page_action_popup.json"); | |
278 ASSERT_TRUE(NULL != action.get()); | |
279 ASSERT_STREQ( | |
280 extension->url().Resolve(kPopupHtmlFile).spec().c_str(), | |
281 action->default_popup_url.spec().c_str()); | |
282 | |
283 // Use both "popup" and "default_popup", expect failure. | |
284 LoadActionAndExpectError("page_action_popup_and_default_popup.json", | |
285 ErrorUtils::FormatErrorMessage( | |
286 errors::kInvalidPageActionOldAndNewKeys, | |
287 keys::kPageActionDefaultPopup, | |
288 keys::kPageActionPopup)); | |
289 | |
290 // Use only "default_popup", expect success. | |
291 extension = LoadManifest("page_action", "page_action_popup.json"); | |
292 action = LoadAction("page_action_default_popup.json"); | |
293 ASSERT_TRUE(NULL != action.get()); | |
294 ASSERT_STREQ( | |
295 extension->url().Resolve(kPopupHtmlFile).spec().c_str(), | |
296 action->default_popup_url.spec().c_str()); | |
297 | |
298 // Setting default_popup to "" is the same as having no popup. | |
299 action = LoadAction("page_action_empty_default_popup.json"); | |
300 ASSERT_TRUE(NULL != action.get()); | |
301 EXPECT_TRUE(action->default_popup_url.is_empty()); | |
302 ASSERT_STREQ( | |
303 "", | |
304 action->default_popup_url.spec().c_str()); | |
305 | |
306 // Setting popup to "" is the same as having no popup. | |
307 action = LoadAction("page_action_empty_popup.json"); | |
308 | |
309 ASSERT_TRUE(NULL != action.get()); | |
310 EXPECT_TRUE(action->default_popup_url.is_empty()); | |
311 ASSERT_STREQ( | |
312 "", | |
313 action->default_popup_url.spec().c_str()); | |
314 } | |
315 | |
316 TEST(ExtensionTest, IdIsValid) { | 186 TEST(ExtensionTest, IdIsValid) { |
317 EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); | 187 EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); |
318 EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp")); | 188 EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp")); |
319 EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop")); | 189 EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop")); |
320 EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")); | 190 EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")); |
321 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno")); | 191 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno")); |
322 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa")); | 192 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa")); |
323 EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef")); | 193 EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef")); |
324 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq")); | 194 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq")); |
325 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno0")); | 195 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno0")); |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 scoped_refptr<Extension> extension( | 1152 scoped_refptr<Extension> extension( |
1283 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), | 1153 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), |
1284 Extension::INTERNAL, 2, FilePath(), | 1154 Extension::INTERNAL, 2, FilePath(), |
1285 Extension::NO_FLAGS)); | 1155 Extension::NO_FLAGS)); |
1286 if (extension) | 1156 if (extension) |
1287 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); | 1157 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); |
1288 } | 1158 } |
1289 #endif // !defined(OS_CHROMEOS) | 1159 #endif // !defined(OS_CHROMEOS) |
1290 | 1160 |
1291 } // namespace extensions | 1161 } // namespace extensions |
OLD | NEW |