| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 #if defined(TOOLKIT_GTK) | 7 #if defined(TOOLKIT_GTK) |
| 8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 } | 41 } |
| 42 | 42 |
| 43 namespace errors = extension_manifest_errors; | 43 namespace errors = extension_manifest_errors; |
| 44 namespace keys = extension_manifest_keys; | 44 namespace keys = extension_manifest_keys; |
| 45 | 45 |
| 46 class ExtensionManifestTest : public testing::Test { | 46 class ExtensionManifestTest : public testing::Test { |
| 47 public: | 47 public: |
| 48 ExtensionManifestTest() : enable_apps_(true) {} | 48 ExtensionManifestTest() : enable_apps_(true) {} |
| 49 | 49 |
| 50 protected: | 50 protected: |
| 51 DictionaryValue* LoadManifestFile(const std::string& filename, | 51 static DictionaryValue* LoadManifestFile(const std::string& filename, |
| 52 std::string* error) { | 52 std::string* error) { |
| 53 FilePath path; | 53 FilePath path; |
| 54 PathService::Get(chrome::DIR_TEST_DATA, &path); | 54 PathService::Get(chrome::DIR_TEST_DATA, &path); |
| 55 path = path.AppendASCII("extensions") | 55 path = path.AppendASCII("extensions") |
| 56 .AppendASCII("manifest_tests") | 56 .AppendASCII("manifest_tests") |
| 57 .AppendASCII(filename.c_str()); | 57 .AppendASCII(filename.c_str()); |
| 58 EXPECT_TRUE(file_util::PathExists(path)); | 58 EXPECT_TRUE(file_util::PathExists(path)); |
| 59 | 59 |
| 60 JSONFileValueSerializer serializer(path); | 60 JSONFileValueSerializer serializer(path); |
| 61 return static_cast<DictionaryValue*>(serializer.Deserialize(NULL, error)); | 61 return static_cast<DictionaryValue*>(serializer.Deserialize(NULL, error)); |
| 62 } | 62 } |
| 63 | 63 |
| 64 scoped_refptr<Extension> LoadExtensionWithLocation( | 64 // Helper class that simplifies creating methods that take either a filename |
| 65 DictionaryValue* value, | 65 // to a manifest or the manifest itself. |
| 66 Extension::Location location, | 66 class Manifest { |
| 67 bool strict_error_checks, | 67 public: |
| 68 std::string* error) { | 68 // Purposely not marked explicit for convenience. The vast majority of |
| 69 // callers pass string literal. |
| 70 Manifest(const char* name) |
| 71 : name_(name), manifest_(NULL) { |
| 72 } |
| 73 Manifest(DictionaryValue* manifest, const char* name) |
| 74 : name_(name), manifest_(manifest) { |
| 75 } |
| 76 |
| 77 const std::string& name() const { return name_; } |
| 78 |
| 79 DictionaryValue* GetManifest(std::string* error) const { |
| 80 if (manifest_) |
| 81 return manifest_; |
| 82 |
| 83 manifest_ = LoadManifestFile(name_, error); |
| 84 manifest_holder_.reset(manifest_); |
| 85 return manifest_; |
| 86 } |
| 87 |
| 88 private: |
| 89 std::string name_; |
| 90 mutable DictionaryValue* manifest_; |
| 91 mutable scoped_ptr<DictionaryValue> manifest_holder_; |
| 92 }; |
| 93 |
| 94 scoped_refptr<Extension> LoadExtension( |
| 95 const Manifest& manifest, |
| 96 std::string* error, |
| 97 Extension::Location location = Extension::INTERNAL, |
| 98 int flags = Extension::NO_FLAGS) { |
| 99 DictionaryValue* value = manifest.GetManifest(error); |
| 100 if (!value) |
| 101 return NULL; |
| 69 FilePath path; | 102 FilePath path; |
| 70 PathService::Get(chrome::DIR_TEST_DATA, &path); | 103 PathService::Get(chrome::DIR_TEST_DATA, &path); |
| 71 path = path.AppendASCII("extensions").AppendASCII("manifest_tests"); | 104 path = path.AppendASCII("extensions").AppendASCII("manifest_tests"); |
| 72 int flags = Extension::NO_FLAGS; | |
| 73 if (strict_error_checks) | |
| 74 flags |= Extension::STRICT_ERROR_CHECKS; | |
| 75 return Extension::Create(path.DirName(), location, *value, flags, error); | 105 return Extension::Create(path.DirName(), location, *value, flags, error); |
| 76 } | 106 } |
| 77 | 107 |
| 78 scoped_refptr<Extension> LoadExtension(const std::string& name, | 108 scoped_refptr<Extension> LoadAndExpectSuccess( |
| 79 std::string* error) { | 109 const Manifest& manifest, |
| 80 return LoadExtensionWithLocation(name, Extension::INTERNAL, false, error); | 110 Extension::Location location = Extension::INTERNAL, |
| 81 } | 111 int flags = Extension::NO_FLAGS) { |
| 82 | |
| 83 scoped_refptr<Extension> LoadExtensionStrict(const std::string& name, | |
| 84 std::string* error) { | |
| 85 return LoadExtensionWithLocation(name, Extension::INTERNAL, true, error); | |
| 86 } | |
| 87 | |
| 88 scoped_refptr<Extension> LoadExtension(DictionaryValue* value, | |
| 89 std::string* error) { | |
| 90 // Loading as an installed extension disables strict error checks. | |
| 91 return LoadExtensionWithLocation(value, Extension::INTERNAL, false, error); | |
| 92 } | |
| 93 | |
| 94 scoped_refptr<Extension> LoadExtensionWithLocation( | |
| 95 const std::string& name, | |
| 96 Extension::Location location, | |
| 97 bool strict_error_checks, | |
| 98 std::string* error) { | |
| 99 scoped_ptr<DictionaryValue> value(LoadManifestFile(name, error)); | |
| 100 if (!value.get()) | |
| 101 return NULL; | |
| 102 return LoadExtensionWithLocation(value.get(), location, | |
| 103 strict_error_checks, error); | |
| 104 } | |
| 105 | |
| 106 scoped_refptr<Extension> LoadAndExpectSuccess(const std::string& name) { | |
| 107 std::string error; | 112 std::string error; |
| 108 scoped_refptr<Extension> extension = LoadExtension(name, &error); | 113 scoped_refptr<Extension> extension = |
| 109 EXPECT_TRUE(extension) << name; | 114 LoadExtension(manifest, &error, location, flags); |
| 110 EXPECT_EQ("", error) << name; | 115 EXPECT_TRUE(extension) << manifest.name(); |
| 116 EXPECT_EQ("", error) << manifest.name(); |
| 111 return extension; | 117 return extension; |
| 112 } | 118 } |
| 113 | 119 |
| 114 scoped_refptr<Extension> LoadStrictAndExpectSuccess(const std::string& name) { | |
| 115 std::string error; | |
| 116 scoped_refptr<Extension> extension = LoadExtensionStrict(name, &error); | |
| 117 EXPECT_TRUE(extension) << name; | |
| 118 EXPECT_EQ("", error) << name; | |
| 119 return extension; | |
| 120 } | |
| 121 | |
| 122 scoped_refptr<Extension> LoadAndExpectSuccess(DictionaryValue* manifest, | |
| 123 const std::string& name) { | |
| 124 std::string error; | |
| 125 scoped_refptr<Extension> extension = LoadExtension(manifest, &error); | |
| 126 EXPECT_TRUE(extension) << "Unexpected failure for " << name; | |
| 127 EXPECT_EQ("", error) << "Unexpected error for " << name; | |
| 128 return extension; | |
| 129 } | |
| 130 | |
| 131 void VerifyExpectedError(Extension* extension, | 120 void VerifyExpectedError(Extension* extension, |
| 132 const std::string& name, | 121 const std::string& name, |
| 133 const std::string& error, | 122 const std::string& error, |
| 134 const std::string& expected_error) { | 123 const std::string& expected_error) { |
| 135 EXPECT_FALSE(extension) << | 124 EXPECT_FALSE(extension) << |
| 136 "Expected failure loading extension '" << name << | 125 "Expected failure loading extension '" << name << |
| 137 "', but didn't get one."; | 126 "', but didn't get one."; |
| 138 EXPECT_TRUE(MatchPattern(error, expected_error)) << name << | 127 EXPECT_TRUE(MatchPattern(error, expected_error)) << name << |
| 139 " expected '" << expected_error << "' but got '" << error << "'"; | 128 " expected '" << expected_error << "' but got '" << error << "'"; |
| 140 } | 129 } |
| 141 | 130 |
| 142 void LoadAndExpectError(const std::string& name, | 131 void LoadAndExpectError(const Manifest& manifest, |
| 143 const std::string& expected_error) { | 132 const std::string& expected_error, |
| 133 Extension::Location location = Extension::INTERNAL, |
| 134 int flags = Extension::NO_FLAGS) { |
| 144 std::string error; | 135 std::string error; |
| 145 scoped_refptr<Extension> extension(LoadExtension(name, &error)); | 136 scoped_refptr<Extension> extension( |
| 146 VerifyExpectedError(extension.get(), name, error, expected_error); | 137 LoadExtension(manifest, &error, location, flags)); |
| 147 } | 138 VerifyExpectedError(extension.get(), manifest.name(), error, |
| 148 | 139 expected_error); |
| 149 void LoadAndExpectErrorStrict(const std::string& name, | |
| 150 const std::string& expected_error) { | |
| 151 std::string error; | |
| 152 scoped_refptr<Extension> extension(LoadExtensionStrict(name, &error)); | |
| 153 VerifyExpectedError(extension.get(), name, error, expected_error); | |
| 154 } | |
| 155 | |
| 156 void LoadAndExpectError(DictionaryValue* manifest, | |
| 157 const std::string& name, | |
| 158 const std::string& expected_error) { | |
| 159 std::string error; | |
| 160 scoped_refptr<Extension> extension(LoadExtension(manifest, &error)); | |
| 161 VerifyExpectedError(extension.get(), name, error, expected_error); | |
| 162 } | 140 } |
| 163 | 141 |
| 164 struct Testcase { | 142 struct Testcase { |
| 165 std::string manifest; | 143 std::string manifest; |
| 166 std::string expected_error; | 144 std::string expected_error; |
| 167 }; | 145 }; |
| 168 | 146 |
| 169 void RunTestcases(const Testcase* testcases, size_t num_testcases) { | 147 void RunTestcases(const Testcase* testcases, size_t num_testcases) { |
| 170 for (size_t i = 0; i < num_testcases; ++i) { | 148 for (size_t i = 0; i < num_testcases; ++i) { |
| 171 LoadAndExpectError(testcases[i].manifest, testcases[i].expected_error); | 149 LoadAndExpectError(testcases[i].manifest.c_str(), |
| 150 testcases[i].expected_error); |
| 172 } | 151 } |
| 173 } | 152 } |
| 174 | 153 |
| 175 bool enable_apps_; | 154 bool enable_apps_; |
| 176 }; | 155 }; |
| 177 | 156 |
| 178 TEST_F(ExtensionManifestTest, InitFromValueInvalid) { | 157 TEST_F(ExtensionManifestTest, InitFromValueInvalid) { |
| 179 Testcase testcases[] = { | 158 Testcase testcases[] = { |
| 180 {"init_invalid_version_missing.json", errors::kInvalidVersion}, | 159 {"init_invalid_version_missing.json", errors::kInvalidVersion}, |
| 181 {"init_invalid_version_invalid.json", errors::kInvalidVersion}, | 160 {"init_invalid_version_invalid.json", errors::kInvalidVersion}, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 // Reset locale. | 267 // Reset locale. |
| 289 #if defined(TOOLKIT_GTK) | 268 #if defined(TOOLKIT_GTK) |
| 290 gtk_widget_set_default_direction(gtk_dir); | 269 gtk_widget_set_default_direction(gtk_dir); |
| 291 #else | 270 #else |
| 292 base::i18n::SetICUDefaultLocale(locale); | 271 base::i18n::SetICUDefaultLocale(locale); |
| 293 #endif | 272 #endif |
| 294 } | 273 } |
| 295 | 274 |
| 296 TEST_F(ExtensionManifestTest, UpdateUrls) { | 275 TEST_F(ExtensionManifestTest, UpdateUrls) { |
| 297 // Test several valid update urls | 276 // Test several valid update urls |
| 298 LoadStrictAndExpectSuccess("update_url_valid_1.json"); | 277 LoadAndExpectSuccess("update_url_valid_1.json", Extension::INTERNAL, |
| 299 LoadStrictAndExpectSuccess("update_url_valid_2.json"); | 278 Extension::STRICT_ERROR_CHECKS); |
| 300 LoadStrictAndExpectSuccess("update_url_valid_3.json"); | 279 LoadAndExpectSuccess("update_url_valid_2.json", Extension::INTERNAL, |
| 301 LoadStrictAndExpectSuccess("update_url_valid_4.json"); | 280 Extension::STRICT_ERROR_CHECKS); |
| 281 LoadAndExpectSuccess("update_url_valid_3.json", Extension::INTERNAL, |
| 282 Extension::STRICT_ERROR_CHECKS); |
| 283 LoadAndExpectSuccess("update_url_valid_4.json", Extension::INTERNAL, |
| 284 Extension::STRICT_ERROR_CHECKS); |
| 302 | 285 |
| 303 // Test some invalid update urls | 286 // Test some invalid update urls |
| 304 LoadAndExpectErrorStrict("update_url_invalid_1.json", | 287 LoadAndExpectError("update_url_invalid_1.json", errors::kInvalidUpdateURL, |
| 305 errors::kInvalidUpdateURL); | 288 Extension::INTERNAL, Extension::STRICT_ERROR_CHECKS); |
| 306 LoadAndExpectErrorStrict("update_url_invalid_2.json", | 289 LoadAndExpectError("update_url_invalid_2.json", errors::kInvalidUpdateURL, |
| 307 errors::kInvalidUpdateURL); | 290 Extension::INTERNAL, Extension::STRICT_ERROR_CHECKS); |
| 308 LoadAndExpectErrorStrict("update_url_invalid_3.json", | 291 LoadAndExpectError("update_url_invalid_3.json", errors::kInvalidUpdateURL, |
| 309 errors::kInvalidUpdateURL); | 292 Extension::INTERNAL, Extension::STRICT_ERROR_CHECKS); |
| 310 } | 293 } |
| 311 | 294 |
| 312 // Tests that the old permission name "unlimited_storage" still works for | 295 // Tests that the old permission name "unlimited_storage" still works for |
| 313 // backwards compatibility (we renamed it to "unlimitedStorage"). | 296 // backwards compatibility (we renamed it to "unlimitedStorage"). |
| 314 TEST_F(ExtensionManifestTest, OldUnlimitedStoragePermission) { | 297 TEST_F(ExtensionManifestTest, OldUnlimitedStoragePermission) { |
| 315 scoped_refptr<Extension> extension = LoadStrictAndExpectSuccess( | 298 scoped_refptr<Extension> extension = LoadAndExpectSuccess( |
| 316 "old_unlimited_storage.json"); | 299 "old_unlimited_storage.json", Extension::INTERNAL, |
| 300 Extension::STRICT_ERROR_CHECKS); |
| 317 EXPECT_TRUE(extension->HasAPIPermission( | 301 EXPECT_TRUE(extension->HasAPIPermission( |
| 318 ExtensionAPIPermission::kUnlimitedStorage)); | 302 ExtensionAPIPermission::kUnlimitedStorage)); |
| 319 } | 303 } |
| 320 | 304 |
| 321 TEST_F(ExtensionManifestTest, ValidApp) { | 305 TEST_F(ExtensionManifestTest, ValidApp) { |
| 322 scoped_refptr<Extension> extension(LoadAndExpectSuccess("valid_app.json")); | 306 scoped_refptr<Extension> extension(LoadAndExpectSuccess("valid_app.json")); |
| 323 URLPatternSet expected_patterns; | 307 URLPatternSet expected_patterns; |
| 324 AddPattern(&expected_patterns, "http://www.google.com/mail/*"); | 308 AddPattern(&expected_patterns, "http://www.google.com/mail/*"); |
| 325 AddPattern(&expected_patterns, "http://www.google.com/foobar/*"); | 309 AddPattern(&expected_patterns, "http://www.google.com/foobar/*"); |
| 326 EXPECT_EQ(expected_patterns, extension->web_extent()); | 310 EXPECT_EQ(expected_patterns, extension->web_extent()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 LoadAndExpectError( | 347 LoadAndExpectError( |
| 364 "web_urls_invalid_5.json", | 348 "web_urls_invalid_5.json", |
| 365 ExtensionErrorUtils::FormatErrorMessage( | 349 ExtensionErrorUtils::FormatErrorMessage( |
| 366 errors::kInvalidWebURL, | 350 errors::kInvalidWebURL, |
| 367 base::IntToString(1), | 351 base::IntToString(1), |
| 368 errors::kCannotClaimAllHostsInExtent)); | 352 errors::kCannotClaimAllHostsInExtent)); |
| 369 | 353 |
| 370 // Ports in app.urls only raise an error when loading as a | 354 // Ports in app.urls only raise an error when loading as a |
| 371 // developer would. | 355 // developer would. |
| 372 LoadAndExpectSuccess("web_urls_invalid_has_port.json"); | 356 LoadAndExpectSuccess("web_urls_invalid_has_port.json"); |
| 373 LoadAndExpectErrorStrict( | 357 LoadAndExpectError( |
| 374 "web_urls_invalid_has_port.json", | 358 "web_urls_invalid_has_port.json", |
| 375 ExtensionErrorUtils::FormatErrorMessage( | 359 ExtensionErrorUtils::FormatErrorMessage( |
| 376 errors::kInvalidWebURL, | 360 errors::kInvalidWebURL, |
| 377 base::IntToString(1), | 361 base::IntToString(1), |
| 378 URLPattern::GetParseResultString(URLPattern::PARSE_ERROR_HAS_COLON))); | 362 URLPattern::GetParseResultString(URLPattern::PARSE_ERROR_HAS_COLON)), |
| 379 | 363 Extension::INTERNAL, |
| 364 Extension::STRICT_ERROR_CHECKS); |
| 380 | 365 |
| 381 scoped_refptr<Extension> extension( | 366 scoped_refptr<Extension> extension( |
| 382 LoadAndExpectSuccess("web_urls_default.json")); | 367 LoadAndExpectSuccess("web_urls_default.json")); |
| 383 ASSERT_EQ(1u, extension->web_extent().patterns().size()); | 368 ASSERT_EQ(1u, extension->web_extent().patterns().size()); |
| 384 EXPECT_EQ("*://www.google.com/*", | 369 EXPECT_EQ("*://www.google.com/*", |
| 385 extension->web_extent().patterns().begin()->GetAsString()); | 370 extension->web_extent().patterns().begin()->GetAsString()); |
| 386 } | 371 } |
| 387 | 372 |
| 388 TEST_F(ExtensionManifestTest, AppLaunchContainer) { | 373 TEST_F(ExtensionManifestTest, AppLaunchContainer) { |
| 389 scoped_refptr<Extension> extension; | 374 scoped_refptr<Extension> extension; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 TEST_F(ExtensionManifestTest, ChromeURLPermissionInvalid) { | 455 TEST_F(ExtensionManifestTest, ChromeURLPermissionInvalid) { |
| 471 LoadAndExpectError("permission_chrome_url_invalid.json", | 456 LoadAndExpectError("permission_chrome_url_invalid.json", |
| 472 errors::kInvalidPermissionScheme); | 457 errors::kInvalidPermissionScheme); |
| 473 } | 458 } |
| 474 | 459 |
| 475 TEST_F(ExtensionManifestTest, ChromeResourcesPermissionValidOnlyForComponents) { | 460 TEST_F(ExtensionManifestTest, ChromeResourcesPermissionValidOnlyForComponents) { |
| 476 LoadAndExpectError("permission_chrome_resources_url.json", | 461 LoadAndExpectError("permission_chrome_resources_url.json", |
| 477 errors::kInvalidPermissionScheme); | 462 errors::kInvalidPermissionScheme); |
| 478 std::string error; | 463 std::string error; |
| 479 scoped_refptr<Extension> extension; | 464 scoped_refptr<Extension> extension; |
| 480 extension = LoadExtensionWithLocation( | 465 extension = LoadExtension( |
| 481 "permission_chrome_resources_url.json", | 466 "permission_chrome_resources_url.json", |
| 467 &error, |
| 482 Extension::COMPONENT, | 468 Extension::COMPONENT, |
| 483 true, // Strict error checking | 469 Extension::STRICT_ERROR_CHECKS); |
| 484 &error); | |
| 485 EXPECT_EQ("", error); | 470 EXPECT_EQ("", error); |
| 486 } | 471 } |
| 487 | 472 |
| 488 TEST_F(ExtensionManifestTest, InvalidContentScriptMatchPattern) { | 473 TEST_F(ExtensionManifestTest, InvalidContentScriptMatchPattern) { |
| 489 | 474 |
| 490 // chrome:// urls are not allowed. | 475 // chrome:// urls are not allowed. |
| 491 LoadAndExpectError( | 476 LoadAndExpectError( |
| 492 "content_script_chrome_url_invalid.json", | 477 "content_script_chrome_url_invalid.json", |
| 493 ExtensionErrorUtils::FormatErrorMessage( | 478 ExtensionErrorUtils::FormatErrorMessage( |
| 494 errors::kInvalidMatch, | 479 errors::kInvalidMatch, |
| 495 base::IntToString(0), | 480 base::IntToString(0), |
| 496 base::IntToString(0), | 481 base::IntToString(0), |
| 497 URLPattern::GetParseResultString( | 482 URLPattern::GetParseResultString( |
| 498 URLPattern::PARSE_ERROR_INVALID_SCHEME))); | 483 URLPattern::PARSE_ERROR_INVALID_SCHEME))); |
| 499 | 484 |
| 500 // Match paterns must be strings. | 485 // Match paterns must be strings. |
| 501 LoadAndExpectError( | 486 LoadAndExpectError( |
| 502 "content_script_match_pattern_not_string.json", | 487 "content_script_match_pattern_not_string.json", |
| 503 ExtensionErrorUtils::FormatErrorMessage( | 488 ExtensionErrorUtils::FormatErrorMessage( |
| 504 errors::kInvalidMatch, | 489 errors::kInvalidMatch, |
| 505 base::IntToString(0), | 490 base::IntToString(0), |
| 506 base::IntToString(0), | 491 base::IntToString(0), |
| 507 errors::kExpectString)); | 492 errors::kExpectString)); |
| 508 | 493 |
| 509 // Ports in match patterns cause an error, but only when loading | 494 // Ports in match patterns cause an error, but only when loading |
| 510 // in developer mode. | 495 // in developer mode. |
| 511 LoadAndExpectSuccess("forbid_ports_in_content_scripts.json"); | 496 LoadAndExpectSuccess("forbid_ports_in_content_scripts.json"); |
| 512 | 497 |
| 513 // Loading as a developer would should give an error. | 498 // Loading as a developer would should give an error. |
| 514 LoadAndExpectErrorStrict( | 499 LoadAndExpectError( |
| 515 "forbid_ports_in_content_scripts.json", | 500 "forbid_ports_in_content_scripts.json", |
| 516 ExtensionErrorUtils::FormatErrorMessage( | 501 ExtensionErrorUtils::FormatErrorMessage( |
| 517 errors::kInvalidMatch, | 502 errors::kInvalidMatch, |
| 518 base::IntToString(1), | 503 base::IntToString(1), |
| 519 base::IntToString(0), | 504 base::IntToString(0), |
| 520 URLPattern::GetParseResultString( | 505 URLPattern::GetParseResultString( |
| 521 URLPattern::PARSE_ERROR_HAS_COLON))); | 506 URLPattern::PARSE_ERROR_HAS_COLON)), |
| 507 Extension::INTERNAL, |
| 508 Extension::STRICT_ERROR_CHECKS); |
| 522 } | 509 } |
| 523 | 510 |
| 524 TEST_F(ExtensionManifestTest, ExcludeMatchPatterns) { | 511 TEST_F(ExtensionManifestTest, ExcludeMatchPatterns) { |
| 525 LoadAndExpectSuccess("exclude_matches.json"); | 512 LoadAndExpectSuccess("exclude_matches.json"); |
| 526 LoadAndExpectSuccess("exclude_matches_empty.json"); | 513 LoadAndExpectSuccess("exclude_matches_empty.json"); |
| 527 | 514 |
| 528 LoadAndExpectError("exclude_matches_not_list.json", | 515 LoadAndExpectError("exclude_matches_not_list.json", |
| 529 "Invalid value for 'content_scripts[0].exclude_matches'."); | 516 "Invalid value for 'content_scripts[0].exclude_matches'."); |
| 530 | 517 |
| 531 LoadAndExpectError("exclude_matches_invalid_host.json", | 518 LoadAndExpectError("exclude_matches_invalid_host.json", |
| 532 "Invalid value for " | 519 "Invalid value for " |
| 533 "'content_scripts[0].exclude_matches[0]': " | 520 "'content_scripts[0].exclude_matches[0]': " |
| 534 "Invalid host wildcard."); | 521 "Invalid host wildcard."); |
| 535 } | 522 } |
| 536 | 523 |
| 537 TEST_F(ExtensionManifestTest, ExperimentalPermission) { | 524 TEST_F(ExtensionManifestTest, ExperimentalPermission) { |
| 538 LoadAndExpectError("experimental.json", errors::kExperimentalFlagRequired); | 525 LoadAndExpectError("experimental.json", errors::kExperimentalFlagRequired); |
| 526 LoadAndExpectSuccess("experimental.json", Extension::COMPONENT); |
| 527 LoadAndExpectSuccess("experimental.json", Extension::INTERNAL, |
| 528 Extension::FROM_WEBSTORE); |
| 539 CommandLine old_command_line = *CommandLine::ForCurrentProcess(); | 529 CommandLine old_command_line = *CommandLine::ForCurrentProcess(); |
| 540 CommandLine::ForCurrentProcess()->AppendSwitch( | 530 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 541 switches::kEnableExperimentalExtensionApis); | 531 switches::kEnableExperimentalExtensionApis); |
| 542 LoadAndExpectSuccess("experimental.json"); | 532 LoadAndExpectSuccess("experimental.json"); |
| 543 *CommandLine::ForCurrentProcess() = old_command_line; | 533 *CommandLine::ForCurrentProcess() = old_command_line; |
| 544 } | 534 } |
| 545 | 535 |
| 546 TEST_F(ExtensionManifestTest, DevToolsExtensions) { | 536 TEST_F(ExtensionManifestTest, DevToolsExtensions) { |
| 547 LoadAndExpectError("devtools_extension_no_permissions.json", | 537 LoadAndExpectError("devtools_extension_no_permissions.json", |
| 548 errors::kDevToolsExperimental); | 538 errors::kDevToolsExperimental); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 | 642 |
| 653 if (*i == ExtensionAPIPermission::kExperimental) { | 643 if (*i == ExtensionAPIPermission::kExperimental) { |
| 654 // Experimental permission is allowed, but requires this switch. | 644 // Experimental permission is allowed, but requires this switch. |
| 655 CommandLine::ForCurrentProcess()->AppendSwitch( | 645 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 656 switches::kEnableExperimentalExtensionApis); | 646 switches::kEnableExperimentalExtensionApis); |
| 657 } | 647 } |
| 658 | 648 |
| 659 // Extensions are allowed to contain unrecognized API permissions, | 649 // Extensions are allowed to contain unrecognized API permissions, |
| 660 // so there shouldn't be any errors. | 650 // so there shouldn't be any errors. |
| 661 scoped_refptr<Extension> extension; | 651 scoped_refptr<Extension> extension; |
| 662 extension = LoadAndExpectSuccess(manifest.get(), message_name); | 652 extension = LoadAndExpectSuccess( |
| 653 Manifest(manifest.get(), message_name.c_str())); |
| 663 } | 654 } |
| 664 *CommandLine::ForCurrentProcess() = old_command_line; | 655 *CommandLine::ForCurrentProcess() = old_command_line; |
| 665 } | 656 } |
| 666 | 657 |
| 667 TEST_F(ExtensionManifestTest, NormalizeIconPaths) { | 658 TEST_F(ExtensionManifestTest, NormalizeIconPaths) { |
| 668 scoped_refptr<Extension> extension( | 659 scoped_refptr<Extension> extension( |
| 669 LoadAndExpectSuccess("normalize_icon_paths.json")); | 660 LoadAndExpectSuccess("normalize_icon_paths.json")); |
| 670 EXPECT_EQ("16.png", | 661 EXPECT_EQ("16.png", |
| 671 extension->icons().Get(16, ExtensionIconSet::MATCH_EXACTLY)); | 662 extension->icons().Get(16, ExtensionIconSet::MATCH_EXACTLY)); |
| 672 EXPECT_EQ("48.png", | 663 EXPECT_EQ("48.png", |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 } | 792 } |
| 802 | 793 |
| 803 TEST_F(ExtensionManifestTest, ForbidPortsInPermissions) { | 794 TEST_F(ExtensionManifestTest, ForbidPortsInPermissions) { |
| 804 // Loading as a user would shoud not trigger an error. | 795 // Loading as a user would shoud not trigger an error. |
| 805 LoadAndExpectSuccess("forbid_ports_in_permissions.json"); | 796 LoadAndExpectSuccess("forbid_ports_in_permissions.json"); |
| 806 | 797 |
| 807 // Ideally, loading as a developer would give an error. | 798 // Ideally, loading as a developer would give an error. |
| 808 // To ensure that we do not error out on a valid permission | 799 // To ensure that we do not error out on a valid permission |
| 809 // in a future version of chrome, validation is to loose | 800 // in a future version of chrome, validation is to loose |
| 810 // to flag this case. | 801 // to flag this case. |
| 811 LoadStrictAndExpectSuccess("forbid_ports_in_permissions.json"); | 802 LoadAndExpectSuccess("forbid_ports_in_permissions.json", |
| 803 Extension::INTERNAL, Extension::STRICT_ERROR_CHECKS); |
| 812 } | 804 } |
| 813 | 805 |
| 814 TEST_F(ExtensionManifestTest, IsolatedApps) { | 806 TEST_F(ExtensionManifestTest, IsolatedApps) { |
| 815 // Requires --enable-experimental-extension-apis | 807 // Requires --enable-experimental-extension-apis |
| 816 LoadAndExpectError("isolated_app_valid.json", | 808 LoadAndExpectError("isolated_app_valid.json", |
| 817 errors::kExperimentalFlagRequired); | 809 errors::kExperimentalFlagRequired); |
| 818 | 810 |
| 819 CommandLine old_command_line = *CommandLine::ForCurrentProcess(); | 811 CommandLine old_command_line = *CommandLine::ForCurrentProcess(); |
| 820 CommandLine::ForCurrentProcess()->AppendSwitch( | 812 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 821 switches::kEnableExperimentalExtensionApis); | 813 switches::kEnableExperimentalExtensionApis); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 const URLPatternSet& patterns = action->file_url_patterns(); | 849 const URLPatternSet& patterns = action->file_url_patterns(); |
| 858 ASSERT_EQ(patterns.patterns().size(), 1U); | 850 ASSERT_EQ(patterns.patterns().size(), 1U); |
| 859 ASSERT_TRUE(action->MatchesURL( | 851 ASSERT_TRUE(action->MatchesURL( |
| 860 GURL("filesystem:chrome-extension://foo/local/test.txt"))); | 852 GURL("filesystem:chrome-extension://foo/local/test.txt"))); |
| 861 } | 853 } |
| 862 | 854 |
| 863 TEST_F(ExtensionManifestTest, FileManagerURLOverride) { | 855 TEST_F(ExtensionManifestTest, FileManagerURLOverride) { |
| 864 // A component extention can override chrome://files/ URL. | 856 // A component extention can override chrome://files/ URL. |
| 865 std::string error; | 857 std::string error; |
| 866 scoped_refptr<Extension> extension; | 858 scoped_refptr<Extension> extension; |
| 867 extension = LoadExtensionWithLocation( | 859 extension = LoadExtension( |
| 868 "filebrowser_url_override.json", | 860 "filebrowser_url_override.json", |
| 861 &error, |
| 869 Extension::COMPONENT, | 862 Extension::COMPONENT, |
| 870 true, // Strict error checking | 863 Extension::STRICT_ERROR_CHECKS); |
| 871 &error); | |
| 872 #if defined(FILE_MANAGER_EXTENSION) | 864 #if defined(FILE_MANAGER_EXTENSION) |
| 873 EXPECT_EQ("", error); | 865 EXPECT_EQ("", error); |
| 874 #else | 866 #else |
| 875 EXPECT_EQ(errors::kInvalidChromeURLOverrides, error); | 867 EXPECT_EQ(errors::kInvalidChromeURLOverrides, error); |
| 876 #endif | 868 #endif |
| 877 | 869 |
| 878 // Extensions of other types can't ovverride chrome://files/ URL. | 870 // Extensions of other types can't ovverride chrome://files/ URL. |
| 879 LoadAndExpectError("filebrowser_url_override.json", | 871 LoadAndExpectError("filebrowser_url_override.json", |
| 880 errors::kInvalidChromeURLOverrides); | 872 errors::kInvalidChromeURLOverrides); |
| 881 } | 873 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 892 scoped_refptr<Extension> extension_2( | 884 scoped_refptr<Extension> extension_2( |
| 893 LoadAndExpectSuccess("offline_disabled_packaged_app.json")); | 885 LoadAndExpectSuccess("offline_disabled_packaged_app.json")); |
| 894 EXPECT_FALSE(extension_2->offline_enabled()); | 886 EXPECT_FALSE(extension_2->offline_enabled()); |
| 895 scoped_refptr<Extension> extension_3( | 887 scoped_refptr<Extension> extension_3( |
| 896 LoadAndExpectSuccess("offline_default_packaged_app.json")); | 888 LoadAndExpectSuccess("offline_default_packaged_app.json")); |
| 897 EXPECT_FALSE(extension_3->offline_enabled()); | 889 EXPECT_FALSE(extension_3->offline_enabled()); |
| 898 scoped_refptr<Extension> extension_4( | 890 scoped_refptr<Extension> extension_4( |
| 899 LoadAndExpectSuccess("offline_enabled_hosted_app.json")); | 891 LoadAndExpectSuccess("offline_enabled_hosted_app.json")); |
| 900 EXPECT_TRUE(extension_4->offline_enabled()); | 892 EXPECT_TRUE(extension_4->offline_enabled()); |
| 901 } | 893 } |
| OLD | NEW |