summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-08 18:33:30 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-08 18:33:30 +0000
commit5bfb1eb0a729e8d1adb448b0a84580564a883d2e (patch)
treebdac0bcedc000d43f2b65fedac764bfdfa4b7c60 /chrome/browser
parentd8cc3a679233604df94571b882ac912614cb2bbe (diff)
downloadchromium_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.cc36
-rw-r--r--chrome/browser/extensions/extension.h8
-rwxr-xr-xchrome/browser/extensions/extension_content_script_inject_unittest.cc62
-rw-r--r--chrome/browser/extensions/extension_ui_unittest.cc2
-rw-r--r--chrome/browser/extensions/extension_unittest.cc61
-rwxr-xr-xchrome/browser/extensions/extension_view_unittest.cc63
-rw-r--r--chrome/browser/extensions/extensions_service.cc24
-rw-r--r--chrome/browser/extensions/extensions_service.h2
-rwxr-xr-xchrome/browser/extensions/test_extension_loader.cc63
-rwxr-xr-xchrome/browser/extensions/test_extension_loader.h35
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_