| 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 |