| 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/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.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/commands/commands_handler.h" | 16 #include "chrome/common/extensions/api/commands/commands_handler.h" |
| 17 #include "chrome/common/extensions/api/extension_action/action_info.h" | |
| 18 #include "chrome/common/extensions/command.h" | 17 #include "chrome/common/extensions/command.h" |
| 19 #include "chrome/common/extensions/extension_file_util.h" | 18 #include "chrome/common/extensions/extension_file_util.h" |
| 20 #include "chrome/common/extensions/extension_manifest_constants.h" | 19 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 21 #include "chrome/common/extensions/extension_resource.h" | 20 #include "chrome/common/extensions/extension_resource.h" |
| 22 #include "chrome/common/extensions/features/feature.h" | 21 #include "chrome/common/extensions/features/feature.h" |
| 23 #include "chrome/common/extensions/manifest.h" | 22 #include "chrome/common/extensions/manifest.h" |
| 24 #include "chrome/common/extensions/manifest_handler.h" | 23 #include "chrome/common/extensions/manifest_handler.h" |
| 25 #include "chrome/common/extensions/permissions/api_permission.h" | 24 #include "chrome/common/extensions/permissions/api_permission.h" |
| 26 #include "chrome/common/extensions/permissions/permission_set.h" | 25 #include "chrome/common/extensions/permissions/permission_set.h" |
| 27 #include "chrome/common/extensions/permissions/socket_permission.h" | 26 #include "chrome/common/extensions/permissions/socket_permission.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 const std::string& test_file) { | 89 const std::string& test_file) { |
| 91 return LoadManifest(dir, test_file, Extension::NO_FLAGS); | 90 return LoadManifest(dir, test_file, Extension::NO_FLAGS); |
| 92 } | 91 } |
| 93 | 92 |
| 94 static scoped_refptr<Extension> LoadManifestStrict( | 93 static scoped_refptr<Extension> LoadManifestStrict( |
| 95 const std::string& dir, | 94 const std::string& dir, |
| 96 const std::string& test_file) { | 95 const std::string& test_file) { |
| 97 return LoadManifest(dir, test_file, Extension::NO_FLAGS); | 96 return LoadManifest(dir, test_file, Extension::NO_FLAGS); |
| 98 } | 97 } |
| 99 | 98 |
| 100 static scoped_ptr<ActionInfo> LoadAction( | 99 } // namespace |
| 101 const std::string& manifest) { | |
| 102 scoped_refptr<Extension> extension = LoadManifest("page_action", | |
| 103 manifest); | |
| 104 EXPECT_TRUE(extension->page_action_info()); | |
| 105 if (extension->page_action_info()) { | |
| 106 return make_scoped_ptr(new ActionInfo( | |
| 107 *extension->page_action_info())); | |
| 108 } | |
| 109 ADD_FAILURE() << "Expected manifest in " << manifest | |
| 110 << " to include a page_action section."; | |
| 111 return scoped_ptr<ActionInfo>(); | |
| 112 } | |
| 113 | |
| 114 static void LoadActionAndExpectError(const std::string& manifest, | |
| 115 const std::string& expected_error) { | |
| 116 std::string error; | |
| 117 scoped_refptr<Extension> extension = LoadManifestUnchecked("page_action", | |
| 118 manifest, Manifest::INTERNAL, Extension::NO_FLAGS, &error); | |
| 119 EXPECT_FALSE(extension); | |
| 120 EXPECT_EQ(expected_error, error); | |
| 121 } | |
| 122 | |
| 123 } | |
| 124 | 100 |
| 125 class ExtensionTest : public testing::Test { | 101 class ExtensionTest : public testing::Test { |
| 126 protected: | 102 protected: |
| 127 virtual void SetUp() OVERRIDE { | 103 virtual void SetUp() OVERRIDE { |
| 128 ManifestHandler::Register(extension_manifest_keys::kCommands, | 104 ManifestHandler::Register(extension_manifest_keys::kCommands, |
| 129 make_linked_ptr(new CommandsHandler)); | 105 make_linked_ptr(new CommandsHandler)); |
| 130 } | 106 } |
| 131 }; | 107 }; |
| 132 | 108 |
| 133 // We persist location values in the preferences, so this is a sanity test that | 109 // We persist location values in the preferences, so this is a sanity test that |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 EXPECT_TRUE(extension_file_util::ValidateExtension(extension.get(), | 183 EXPECT_TRUE(extension_file_util::ValidateExtension(extension.get(), |
| 208 &err, &warnings)); | 184 &err, &warnings)); |
| 209 EXPECT_EQ(0U, warnings.size()); | 185 EXPECT_EQ(0U, warnings.size()); |
| 210 | 186 |
| 211 EXPECT_EQ(extension->path().AppendASCII("test.html").value(), | 187 EXPECT_EQ(extension->path().AppendASCII("test.html").value(), |
| 212 extension->GetResource("test.html").GetFilePath().value()); | 188 extension->GetResource("test.html").GetFilePath().value()); |
| 213 EXPECT_EQ(extension->path().AppendASCII("test.js").value(), | 189 EXPECT_EQ(extension->path().AppendASCII("test.js").value(), |
| 214 extension->GetResource("test.js").GetFilePath().value()); | 190 extension->GetResource("test.js").GetFilePath().value()); |
| 215 } | 191 } |
| 216 | 192 |
| 217 TEST_F(ExtensionTest, LoadPageActionHelper) { | |
| 218 scoped_ptr<ActionInfo> action; | |
| 219 | |
| 220 // First try with an empty dictionary. | |
| 221 action = LoadAction("page_action_empty.json"); | |
| 222 ASSERT_TRUE(action != NULL); | |
| 223 | |
| 224 // Now setup some values to use in the action. | |
| 225 const std::string id("MyExtensionActionId"); | |
| 226 const std::string name("MyExtensionActionName"); | |
| 227 std::string img1("image1.png"); | |
| 228 | |
| 229 action = LoadAction("page_action.json"); | |
| 230 ASSERT_TRUE(NULL != action.get()); | |
| 231 ASSERT_EQ(id, action->id); | |
| 232 | |
| 233 // No title, so fall back to name. | |
| 234 ASSERT_EQ(name, action->default_title); | |
| 235 ASSERT_EQ(img1, | |
| 236 action->default_icon.Get(extension_misc::EXTENSION_ICON_ACTION, | |
| 237 ExtensionIconSet::MATCH_EXACTLY)); | |
| 238 | |
| 239 // Same test with explicitly set type. | |
| 240 action = LoadAction("page_action_type.json"); | |
| 241 ASSERT_TRUE(NULL != action.get()); | |
| 242 | |
| 243 // Try an action without id key. | |
| 244 action = LoadAction("page_action_no_id.json"); | |
| 245 ASSERT_TRUE(NULL != action.get()); | |
| 246 | |
| 247 // Then try without the name key. It's optional, so no error. | |
| 248 action = LoadAction("page_action_no_name.json"); | |
| 249 ASSERT_TRUE(NULL != action.get()); | |
| 250 ASSERT_TRUE(action->default_title.empty()); | |
| 251 | |
| 252 // Then try without the icon paths key. | |
| 253 action = LoadAction("page_action_no_icon.json"); | |
| 254 ASSERT_TRUE(NULL != action.get()); | |
| 255 | |
| 256 // Now test that we can parse the new format for page actions. | |
| 257 const std::string kTitle("MyExtensionActionTitle"); | |
| 258 const std::string kIcon("image1.png"); | |
| 259 const std::string kPopupHtmlFile("a_popup.html"); | |
| 260 | |
| 261 action = LoadAction("page_action_new_format.json"); | |
| 262 ASSERT_TRUE(action.get()); | |
| 263 ASSERT_EQ(kTitle, action->default_title); | |
| 264 ASSERT_FALSE(action->default_icon.empty()); | |
| 265 | |
| 266 // Invalid title should give an error even with a valid name. | |
| 267 LoadActionAndExpectError("page_action_invalid_title.json", | |
| 268 errors::kInvalidPageActionDefaultTitle); | |
| 269 | |
| 270 // Invalid name should give an error only with no title. | |
| 271 action = LoadAction("page_action_invalid_name.json"); | |
| 272 ASSERT_TRUE(NULL != action.get()); | |
| 273 ASSERT_EQ(kTitle, action->default_title); | |
| 274 | |
| 275 LoadActionAndExpectError("page_action_invalid_name_no_title.json", | |
| 276 errors::kInvalidPageActionName); | |
| 277 | |
| 278 // Test that keys "popup" and "default_popup" both work, but can not | |
| 279 // be used at the same time. | |
| 280 // These tests require an extension_url, so we also load the manifest. | |
| 281 | |
| 282 // Only use "popup", expect success. | |
| 283 scoped_refptr<Extension> extension = LoadManifest("page_action", | |
| 284 "page_action_popup.json"); | |
| 285 action = LoadAction("page_action_popup.json"); | |
| 286 ASSERT_TRUE(NULL != action.get()); | |
| 287 ASSERT_STREQ( | |
| 288 extension->url().Resolve(kPopupHtmlFile).spec().c_str(), | |
| 289 action->default_popup_url.spec().c_str()); | |
| 290 | |
| 291 // Use both "popup" and "default_popup", expect failure. | |
| 292 LoadActionAndExpectError("page_action_popup_and_default_popup.json", | |
| 293 ErrorUtils::FormatErrorMessage( | |
| 294 errors::kInvalidPageActionOldAndNewKeys, | |
| 295 keys::kPageActionDefaultPopup, | |
| 296 keys::kPageActionPopup)); | |
| 297 | |
| 298 // Use only "default_popup", expect success. | |
| 299 extension = LoadManifest("page_action", "page_action_popup.json"); | |
| 300 action = LoadAction("page_action_default_popup.json"); | |
| 301 ASSERT_TRUE(NULL != action.get()); | |
| 302 ASSERT_STREQ( | |
| 303 extension->url().Resolve(kPopupHtmlFile).spec().c_str(), | |
| 304 action->default_popup_url.spec().c_str()); | |
| 305 | |
| 306 // Setting default_popup to "" is the same as having no popup. | |
| 307 action = LoadAction("page_action_empty_default_popup.json"); | |
| 308 ASSERT_TRUE(NULL != action.get()); | |
| 309 EXPECT_TRUE(action->default_popup_url.is_empty()); | |
| 310 ASSERT_STREQ( | |
| 311 "", | |
| 312 action->default_popup_url.spec().c_str()); | |
| 313 | |
| 314 // Setting popup to "" is the same as having no popup. | |
| 315 action = LoadAction("page_action_empty_popup.json"); | |
| 316 | |
| 317 ASSERT_TRUE(NULL != action.get()); | |
| 318 EXPECT_TRUE(action->default_popup_url.is_empty()); | |
| 319 ASSERT_STREQ( | |
| 320 "", | |
| 321 action->default_popup_url.spec().c_str()); | |
| 322 } | |
| 323 | 193 |
| 324 TEST_F(ExtensionTest, IdIsValid) { | 194 TEST_F(ExtensionTest, IdIsValid) { |
| 325 EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); | 195 EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); |
| 326 EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp")); | 196 EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp")); |
| 327 EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop")); | 197 EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop")); |
| 328 EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")); | 198 EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")); |
| 329 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno")); | 199 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno")); |
| 330 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa")); | 200 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa")); |
| 331 EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef")); | 201 EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef")); |
| 332 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq")); | 202 EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq")); |
| (...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 scoped_refptr<Extension> extension( | 1079 scoped_refptr<Extension> extension( |
| 1210 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), | 1080 MakeSyncTestExtension(EXTENSION, GURL(), GURL(), |
| 1211 Manifest::INTERNAL, 2, base::FilePath(), | 1081 Manifest::INTERNAL, 2, base::FilePath(), |
| 1212 Extension::NO_FLAGS)); | 1082 Extension::NO_FLAGS)); |
| 1213 if (extension) | 1083 if (extension) |
| 1214 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); | 1084 EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE); |
| 1215 } | 1085 } |
| 1216 #endif // !defined(OS_CHROMEOS) | 1086 #endif // !defined(OS_CHROMEOS) |
| 1217 | 1087 |
| 1218 } // namespace extensions | 1088 } // namespace extensions |
| OLD | NEW |