diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-08 18:33:30 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-08 18:33:30 +0000 |
commit | 5bfb1eb0a729e8d1adb448b0a84580564a883d2e (patch) | |
tree | bdac0bcedc000d43f2b65fedac764bfdfa4b7c60 /chrome/browser | |
parent | d8cc3a679233604df94571b882ac912614cb2bbe (diff) | |
download | chromium_src-5bfb1eb0a729e8d1adb448b0a84580564a883d2e.zip chromium_src-5bfb1eb0a729e8d1adb448b0a84580564a883d2e.tar.gz chromium_src-5bfb1eb0a729e8d1adb448b0a84580564a883d2e.tar.bz2 |
Try one more time to check in http://codereview.chromium.org/60112
Added this test to the list of skipped purify tests as it is
experience the same issue as ExtensionView test.
I also found an unrelated memory leak and created a patch
separately: http://codereview.chromium.org/63073
Review URL: http://codereview.chromium.org/63075
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13369 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/extensions/extension.cc | 36 | ||||
-rw-r--r-- | chrome/browser/extensions/extension.h | 8 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_content_script_inject_unittest.cc | 62 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_ui_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_unittest.cc | 61 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_view_unittest.cc | 63 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 24 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 2 | ||||
-rwxr-xr-x | chrome/browser/extensions/test_extension_loader.cc | 63 | ||||
-rwxr-xr-x | chrome/browser/extensions/test_extension_loader.h | 35 |
10 files changed, 234 insertions, 122 deletions
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc index d8ab403..1aeaeaa 100644 --- a/chrome/browser/extensions/extension.cc +++ b/chrome/browser/extensions/extension.cc @@ -103,21 +103,6 @@ Extension::Extension(const Extension& rhs) theme_paths_(rhs.theme_paths_) { } -const GURL& Extension::url() { - if (!extension_url_.is_valid()) - extension_url_ = GURL(std::string(chrome::kExtensionScheme) + - chrome::kStandardSchemeSeparator + id_ + "/"); - - return extension_url_; -} - -void Extension::set_id(const std::string& id) { - id_ = id; - - // Reset url_ so that it gets reinitialized next time. - extension_url_ = GURL(); -} - const std::string Extension::VersionString() const { return version_->GetString(); } @@ -335,10 +320,9 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, return true; } -bool Extension::InitFromValue(const DictionaryValue& source, +bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, std::string* error) { - // Initialize id. The ID is not required here because we don't require IDs for - // extensions used with --load-extension. + // Initialize id. if (source.HasKey(kIdKey)) { if (!source.GetString(kIdKey, &id_)) { *error = kInvalidIdError; @@ -356,8 +340,23 @@ bool Extension::InitFromValue(const DictionaryValue& source, *error = kInvalidIdError; return false; } + } else if (require_id) { + *error = kInvalidIdError; + return false; + } else { + // Generate a random ID + static int counter = 0; + id_ = StringPrintf("%x", counter); + ++counter; + + // pad the string out to 40 chars with zeroes. + id_.insert(0, 40 - id_.length(), '0'); } + // Initialize the URL. + extension_url_ = GURL(std::string(chrome::kExtensionScheme) + + chrome::kStandardSchemeSeparator + id_ + "/"); + // Initialize version. std::string version_str; if (!source.GetString(kVersionKey, &version_str)) { @@ -457,6 +456,7 @@ bool Extension::InitFromValue(const DictionaryValue& source, UserScript script; if (!LoadUserScriptHelper(content_script, i, error, &script)) return false; // Failed to parse script context definition + script.set_extension_id(id()); content_scripts_.push_back(script); } } diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h index 5c3d9b8f..2f59115 100644 --- a/chrome/browser/extensions/extension.h +++ b/chrome/browser/extensions/extension.h @@ -100,7 +100,10 @@ class Extension { } // Initialize the extension from a parsed manifest. - bool InitFromValue(const DictionaryValue& value, std::string* error); + // If |require_id| is true, will return an error if the "id" key is missing + // from the value. + bool InitFromValue(const DictionaryValue& value, bool require_id, + std::string* error); // Returns an absolute path to a resource inside of an extension if the // extension has a theme defined with the given |resource_id|. Otherwise @@ -110,9 +113,8 @@ class Extension { FilePath GetThemeResourcePath(const int resource_id); const FilePath& path() const { return path_; } - const GURL& url(); + const GURL& url() const { return extension_url_; } const std::string& id() const { return id_; } - void set_id(const std::string& id); const Version* version() const { return version_.get(); } // String representation of the version number. const std::string VersionString() const; diff --git a/chrome/browser/extensions/extension_content_script_inject_unittest.cc b/chrome/browser/extensions/extension_content_script_inject_unittest.cc new file mode 100755 index 0000000..750176b --- /dev/null +++ b/chrome/browser/extensions/extension_content_script_inject_unittest.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/browser.h" +#include "chrome/browser/extensions/extension_error_reporter.h" +#include "chrome/browser/extensions/test_extension_loader.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" +#include "net/base/net_util.h" + +namespace { + +// The extension we're using as our test case. +const char* kExtensionId = "00123456789abcdef0123456789abcdef0123456"; + +} // namespace + +class ExtensionContentScriptInjectTest : public InProcessBrowserTest { + public: + virtual void SetUp() { + // Initialize the error reporter here, otherwise BrowserMain will create it + // with the wrong MessageLoop. + ExtensionErrorReporter::Init(false); + + InProcessBrowserTest::SetUp(); + } +}; + +// Tests that an extension's user script gets injected into content. +IN_PROC_BROWSER_TEST_F(ExtensionContentScriptInjectTest, Simple) { + // Get the path to our extension. + FilePath extension_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extension_path)); + extension_path = extension_path.AppendASCII("extensions"). + AppendASCII("content_script_inject"); + ASSERT_TRUE(file_util::DirectoryExists(extension_path)); // sanity check + + // Load it. + TestExtensionLoader loader(browser()->profile()); + Extension* extension = loader.Load(kExtensionId, extension_path); + ASSERT_TRUE(extension); + + // Get the file URL to our test page. + FilePath test_page_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_page_path)); + test_page_path = test_page_path.AppendASCII("extensions"). + AppendASCII("content_script_inject_page.html"); + ASSERT_TRUE(file_util::PathExists(test_page_path)); // sanity check + GURL test_page_url = net::FilePathToFileURL(test_page_path); + + ui_test_utils::NavigateToURL(browser(), test_page_url); + TabContents* tabContents = browser()->GetSelectedTabContents(); + + // The injected user script will set the page title upon execution. + const char kExpectedTitle[] = + "testScriptFilesRunInSameContext,testContentInteraction," + "testCSSWasInjected,testCannotSeeOtherContentScriptGlobals," + "testRunAtDocumentStart,testGotLoadEvents,"; + EXPECT_EQ(ASCIIToUTF16(kExpectedTitle), tabContents->GetTitle()); +} diff --git a/chrome/browser/extensions/extension_ui_unittest.cc b/chrome/browser/extensions/extension_ui_unittest.cc index 0e24832..c3dbbb0 100644 --- a/chrome/browser/extensions/extension_ui_unittest.cc +++ b/chrome/browser/extensions/extension_ui_unittest.cc @@ -39,7 +39,7 @@ namespace { scoped_ptr<DictionaryValue> extension_data(DeserializeJSONTestData( manifest_path, &error)); EXPECT_EQ("", error); - EXPECT_TRUE(extension.InitFromValue(*extension_data, &error)); + EXPECT_TRUE(extension.InitFromValue(*extension_data, true, &error)); EXPECT_EQ("", error); scoped_ptr<DictionaryValue>expected_output_data(DeserializeJSONTestData( diff --git a/chrome/browser/extensions/extension_unittest.cc b/chrome/browser/extensions/extension_unittest.cc index 5cde5ca..f160117 100644 --- a/chrome/browser/extensions/extension_unittest.cc +++ b/chrome/browser/extensions/extension_unittest.cc @@ -38,47 +38,52 @@ TEST(ExtensionTest, InitFromValueInvalid) { static_cast<DictionaryValue*>(serializer.Deserialize(&error))); ASSERT_TRUE(valid_value.get()); ASSERT_EQ("", error); - ASSERT_TRUE(extension.InitFromValue(*valid_value, &error)); + ASSERT_TRUE(extension.InitFromValue(*valid_value, true, &error)); ASSERT_EQ("", error); scoped_ptr<DictionaryValue> input_value; // Test missing and invalid ids input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); + input_value->Remove(Extension::kIdKey, NULL); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(Extension::kInvalidIdError, error); + + input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->SetInteger(Extension::kIdKey, 42); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidIdError, error); // Test missing and invalid versions input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->Remove(Extension::kVersionKey, NULL); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidVersionError, error); input_value->SetInteger(Extension::kVersionKey, 42); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidVersionError, error); // Test missing and invalid names input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->Remove(Extension::kNameKey, NULL); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidNameError, error); input_value->SetInteger(Extension::kNameKey, 42); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidNameError, error); // Test invalid description input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->SetInteger(Extension::kDescriptionKey, 42); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidDescriptionError, error); // Test invalid user scripts list input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->SetInteger(Extension::kContentScriptsKey, 42); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_EQ(Extension::kInvalidContentScriptsListError, error); // Test invalid user script item @@ -87,7 +92,7 @@ TEST(ExtensionTest, InitFromValueInvalid) { input_value->GetList(Extension::kContentScriptsKey, &content_scripts); ASSERT_FALSE(NULL == content_scripts); content_scripts->Set(0, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidContentScriptError)); // Test missing and invalid matches array @@ -96,21 +101,21 @@ TEST(ExtensionTest, InitFromValueInvalid) { DictionaryValue* user_script = NULL; content_scripts->GetDictionary(0, &user_script); user_script->Remove(Extension::kMatchesKey, NULL); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError)); user_script->Set(Extension::kMatchesKey, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError)); ListValue* matches = new ListValue; user_script->Set(Extension::kMatchesKey, matches); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchCountError)); // Test invalid match element matches->Set(0, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchError)); // Test missing and invalid files array @@ -119,52 +124,52 @@ TEST(ExtensionTest, InitFromValueInvalid) { content_scripts->GetDictionary(0, &user_script); user_script->Remove(Extension::kJsKey, NULL); user_script->Remove(Extension::kCssKey, NULL); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kMissingFileError)); user_script->Set(Extension::kJsKey, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsListError)); user_script->Set(Extension::kCssKey, new ListValue); user_script->Set(Extension::kJsKey, new ListValue); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kMissingFileError)); user_script->Remove(Extension::kCssKey, NULL); ListValue* files = new ListValue; user_script->Set(Extension::kJsKey, files); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kMissingFileError)); // Test invalid file element files->Set(0, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsError)); user_script->Remove(Extension::kJsKey, NULL); // Test the css element user_script->Set(Extension::kCssKey, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidCssListError)); // Test invalid file element ListValue* css_files = new ListValue; user_script->Set(Extension::kCssKey, css_files); css_files->Set(0, Value::CreateIntegerValue(42)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidCssError)); // Test missing and invalid permissions array input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); - EXPECT_TRUE(extension.InitFromValue(*input_value, &error)); + EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error)); ListValue* permissions = NULL; input_value->GetList(Extension::kPermissionsKey, &permissions); ASSERT_FALSE(NULL == permissions); permissions = new ListValue; input_value->Set(Extension::kPermissionsKey, permissions); - EXPECT_TRUE(extension.InitFromValue(*input_value, &error)); + EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error)); const std::vector<std::string>* error_vector = ExtensionErrorReporter::GetInstance()->GetErrors(); const std::string log_error = error_vector->at(error_vector->size() - 1); @@ -172,24 +177,24 @@ TEST(ExtensionTest, InitFromValueInvalid) { Extension::kInvalidPermissionCountWarning)); input_value->Set(Extension::kPermissionsKey, Value::CreateIntegerValue(9)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionsError)); input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->GetList(Extension::kPermissionsKey, &permissions); permissions->Set(0, Value::CreateIntegerValue(24)); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionError)); permissions->Set(0, Value::CreateStringValue("www.google.com")); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionError)); // Test permissions scheme. input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); input_value->GetList(Extension::kPermissionsKey, &permissions); permissions->Set(0, Value::CreateStringValue("file:///C:/foo.txt")); - EXPECT_FALSE(extension.InitFromValue(*input_value, &error)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionSchemeError)); } @@ -209,7 +214,7 @@ TEST(ExtensionTest, InitFromValueValid) { input_value.SetString(Extension::kVersionKey, "1.0.0.0"); input_value.SetString(Extension::kNameKey, "my extension"); - EXPECT_TRUE(extension.InitFromValue(input_value, &error)); + EXPECT_TRUE(extension.InitFromValue(input_value, true, &error)); EXPECT_EQ("", error); EXPECT_EQ("00123456789abcdef0123456789abcdef0123456", extension.id()); EXPECT_EQ("1.0.0.0", extension.VersionString()); @@ -231,7 +236,7 @@ TEST(ExtensionTest, GetResourceURLAndPath) { "00123456789ABCDEF0123456789ABCDEF0123456"); input_value.SetString(Extension::kVersionKey, "1.0.0.0"); input_value.SetString(Extension::kNameKey, "my extension"); - EXPECT_TRUE(extension.InitFromValue(input_value, NULL)); + EXPECT_TRUE(extension.InitFromValue(input_value, true, NULL)); EXPECT_EQ(extension.url().spec() + "bar/baz.js", Extension::GetResourceURL(extension.url(), "bar/baz.js").spec()); diff --git a/chrome/browser/extensions/extension_view_unittest.cc b/chrome/browser/extensions/extension_view_unittest.cc index 4cdb91c..69a1fb9 100755 --- a/chrome/browser/extensions/extension_view_unittest.cc +++ b/chrome/browser/extensions/extension_view_unittest.cc @@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/message_loop.h" #include "base/ref_counted.h" #include "chrome/browser/browser.h" #include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/profile.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_view.h" #include "chrome/browser/extensions/extensions_service.h" +#include "chrome/browser/extensions/test_extension_loader.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/notification_service.h" #include "chrome/test/in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" @@ -21,12 +19,11 @@ namespace { // up. const int kAlertTimeoutMs = 20000; -// How long to wait for the extension to load before giving up. -const int kLoadTimeoutMs = 10000; - // The extension we're using as our test case. const char* kExtensionId = "00123456789abcdef0123456789abcdef0123456"; +}; // namespace + // This class starts up an extension process and waits until it tries to put // up a javascript alert. class MockExtensionView : public ExtensionView { @@ -60,44 +57,6 @@ class MockExtensionView : public ExtensionView { bool got_message_; }; -// This class waits for a specific extension to be loaded. -class ExtensionLoadedObserver : public NotificationObserver { - public: - explicit ExtensionLoadedObserver() : extension_(NULL) { - registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, - NotificationService::AllSources()); - } - - Extension* WaitForExtension() { - MessageLoop::current()->PostDelayedTask(FROM_HERE, - new MessageLoop::QuitTask, kLoadTimeoutMs); - ui_test_utils::RunMessageLoop(); - return extension_; - } - - private: - virtual void Observe(NotificationType type, const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::EXTENSIONS_LOADED) { - ExtensionList* extensions = Details<ExtensionList>(details).ptr(); - for (size_t i = 0; i < (*extensions).size(); i++) { - if ((*extensions)[i]->id() == kExtensionId) { - extension_ = (*extensions)[i]; - MessageLoopForUI::current()->Quit(); - break; - } - } - } else { - NOTREACHED(); - } - } - - NotificationRegistrar registrar_; - Extension* extension_; -}; - -} // namespace - class ExtensionViewTest : public InProcessBrowserTest { public: virtual void SetUp() { @@ -115,10 +74,6 @@ class ExtensionViewTest : public InProcessBrowserTest { // Tests that ExtensionView starts an extension process and runs the script // contained in the extension's "index.html" file. IN_PROC_BROWSER_TEST_F(ExtensionViewTest, Index) { - // Create an observer first to be sure we have the notification registered - // before it's sent. - ExtensionLoadedObserver observer; - // Get the path to our extension. FilePath path; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); @@ -126,17 +81,13 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, Index) { AppendASCII("good").AppendASCII("extension1").AppendASCII("1"); ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check - // Load it. - Profile* profile = browser()->profile(); - profile->GetExtensionsService()->Init(); - profile->GetExtensionsService()->LoadExtension(path); - - // Now wait for it to load, and grab a pointer to it. - Extension* extension = observer.WaitForExtension(); + // Wait for the extension to load and grab a pointer to it. + TestExtensionLoader loader(browser()->profile()); + Extension* extension = loader.Load(kExtensionId, path); ASSERT_TRUE(extension); GURL url = Extension::GetResourceURL(extension->url(), "toolstrip1.html"); // Start the extension process and wait for it to show a javascript alert. - MockExtensionView view(extension, url, profile); + MockExtensionView view(extension, url, browser()->profile()); EXPECT_TRUE(view.got_message()); } diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 5c836d0..942d23c 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -258,18 +258,9 @@ void ExtensionsServiceBackend::LoadSingleExtension( LOG(INFO) << "Loading single extension from " << WideToASCII(extension_path.BaseName().ToWStringHack()); - Extension* extension = LoadExtension(extension_path); + Extension* extension = LoadExtension(extension_path, + false); // don't require ID if (extension) { - if (extension->id().empty()) { - // Generate an ID - static int counter = 0; - std::string id = StringPrintf("%x", counter); - ++counter; - - // pad the string out to 40 chars with zeroes. - id.insert(0, 40 - id.length(), '0'); - extension->set_id(id); - } ExtensionList* extensions = new ExtensionList; extensions->push_back(extension); ReportExtensionsLoaded(extensions); @@ -290,11 +281,12 @@ Extension* ExtensionsServiceBackend::LoadExtensionCurrentVersion( WideToASCII(extension_path.BaseName().ToWStringHack()) << " version: " << version_str; - return LoadExtension(extension_path.AppendASCII(version_str)); + return LoadExtension(extension_path.AppendASCII(version_str), + true); // require id } Extension* ExtensionsServiceBackend::LoadExtension( - const FilePath& extension_path) { + const FilePath& extension_path, bool require_id) { FilePath manifest_path = extension_path.AppendASCII(Extension::kManifestFilename); if (!file_util::PathExists(manifest_path)) { @@ -317,7 +309,7 @@ Extension* ExtensionsServiceBackend::LoadExtension( scoped_ptr<Extension> extension(new Extension(extension_path)); if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()), - &error)) { + require_id, &error)) { ReportExtensionLoadError(extension_path, error); return NULL; } @@ -638,7 +630,9 @@ bool ExtensionsServiceBackend::InstallOrUpdateExtension( DictionaryValue* dict = manifest.get(); Extension extension; std::string error; - if (!extension.InitFromValue(*dict, &error)) { + if (!extension.InitFromValue(*dict, + true, // require ID + &error)) { ReportExtensionInstallError(source_file, "Invalid extension manifest."); return false; diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index 5c08685..64d2e55 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -141,7 +141,7 @@ class ExtensionsServiceBackend private: // Load a single extension from |extension_path|, the top directory of // a specific extension where its manifest file lives. - Extension* LoadExtension(const FilePath& extension_path); + Extension* LoadExtension(const FilePath& extension_path, bool require_id); // Load a single extension from |extension_path|, the top directory of // a versioned extension where its Current Version file lives. diff --git a/chrome/browser/extensions/test_extension_loader.cc b/chrome/browser/extensions/test_extension_loader.cc new file mode 100755 index 0000000..d8bacb7 --- /dev/null +++ b/chrome/browser/extensions/test_extension_loader.cc @@ -0,0 +1,63 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/test_extension_loader.h" + +#include "base/file_path.h" +#include "base/message_loop.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/common/notification_service.h" +#include "chrome/test/ui_test_utils.h" + +namespace { + +// How long to wait for the extension to load before giving up. +const int kLoadTimeoutMs = 5000; + +} // namespace + +TestExtensionLoader::TestExtensionLoader(Profile* profile) + : profile_(profile), + extension_(NULL) { + registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, + NotificationService::AllSources()); + + profile_->GetExtensionsService()->Init(); + DCHECK(profile_->GetExtensionsService()->extensions()->empty()); +} + +Extension* TestExtensionLoader::Load(const char* extension_id, + const FilePath& path) { + loading_extension_id_ = extension_id; + + // Load the extension. + profile_->GetExtensionsService()->LoadExtension(path); + + // Wait for the load to complete. Stick a QuitTask into the message loop + // with the timeout so it will exit if the extension never loads. + extension_ = NULL; + MessageLoop::current()->PostDelayedTask(FROM_HERE, + new MessageLoop::QuitTask, kLoadTimeoutMs); + ui_test_utils::RunMessageLoop(); + + return extension_; +} + +void TestExtensionLoader::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::EXTENSIONS_LOADED) { + ExtensionList* extensions = Details<ExtensionList>(details).ptr(); + for (size_t i = 0; i < (*extensions).size(); ++i) { + if ((*extensions)[i]->id() == loading_extension_id_) { + extension_ = (*extensions)[i]; + MessageLoopForUI::current()->Quit(); + break; + } + } + } else { + NOTREACHED(); + } +} diff --git a/chrome/browser/extensions/test_extension_loader.h b/chrome/browser/extensions/test_extension_loader.h new file mode 100755 index 0000000..4fb74d9 --- /dev/null +++ b/chrome/browser/extensions/test_extension_loader.h @@ -0,0 +1,35 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_LOADER_H_ +#define CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_LOADER_H_ + +#include "chrome/browser/extensions/extension.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" + +class Extension; +class FilePath; +class Profile; + +class TestExtensionLoader : public NotificationObserver { + public: + explicit TestExtensionLoader(Profile* profile); + + Extension* Load(const char* extension_id, const FilePath& path); + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + private: + Profile* profile_; + Extension* extension_; + NotificationRegistrar registrar_; + std::string loading_extension_id_; + + DISALLOW_COPY_AND_ASSIGN(TestExtensionLoader); +}; + +#endif // CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_LOADER_H_ |