Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(437)

Unified Diff: chrome/browser/extensions/error_console/error_console_browsertest.cc

Issue 22938005: Add ErrorConsole UI for Extension Install Warnings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dc_ec_install_warnings
Patch Set: Rebase to Master Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/error_console/error_console_browsertest.cc
diff --git a/chrome/browser/extensions/error_console/error_console_browsertest.cc b/chrome/browser/extensions/error_console/error_console_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..40bd87cc810d1fab3774828dbe4da2e9d7df3376
--- /dev/null
+++ b/chrome/browser/extensions/error_console/error_console_browsertest.cc
@@ -0,0 +1,251 @@
+// Copyright 2013 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/error_console/error_console.h"
+
+#include "base/files/file_path.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "extensions/browser/extension_error.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+using base::string16;
+using base::UTF8ToUTF16;
+
+namespace errors = extension_manifest_errors;
+
+namespace extensions {
+
+namespace {
+
+base::string16 GetManifestFilename() {
+ return base::FilePath(kManifestFilename).AsUTF16Unsafe();
+}
+
+// Verify that all properites of a given |error| are correct.
Yoyo Zhou 2013/08/16 00:17:26 typo: properties
Devlin 2013/08/16 18:07:49 Done.
+void CheckError(const ExtensionError* error,
+ ExtensionError::Type type,
+ const std::string& id,
+ const string16& source,
+ bool from_incognito,
+ const string16& message) {
+ ASSERT_TRUE(error);
+ EXPECT_EQ(type, error->type());
+ EXPECT_EQ(id, error->extension_id());
+ EXPECT_EQ(source, error->source());
+ EXPECT_EQ(from_incognito, error->from_incognito());
+ EXPECT_EQ(message, error->message());
+}
+
+void CheckManifestError(const ExtensionError* error,
+ const std::string& id,
+ const string16& message,
+ const string16& manifest_key,
+ const string16& manifest_specific) {
+ CheckError(error,
+ ExtensionError::MANIFEST_PARSING_ERROR,
+ id,
+ GetManifestFilename(), // source is always the manifest.
+ false, // manifest errors are never from incognito.
+ message);
+
+ const ManifestParsingError* manifest_error =
+ static_cast<const ManifestParsingError*>(error);
+ EXPECT_EQ(manifest_key, manifest_error->manifest_key());
+ EXPECT_EQ(manifest_specific, manifest_error->manifest_specific());
+}
+
+} // namespace
+
+class ErrorConsoleBrowserTest : public ExtensionBrowserTest {
+ public:
+ ErrorConsoleBrowserTest() : error_console_(NULL) { }
+ virtual ~ErrorConsoleBrowserTest() { }
+
+ protected:
+ // A helper class in order to wait for the proper number of errors to be
+ // caught by the ErrorConsole. This will run the MessageLoop until a given
+ // number of errors are observed.
+ // Usage:
+ // ...
+ // ErrorObserver observer(3, error_console);
+ // <Cause three errors...>
+ // observer.WaitForErrors();
+ // <Perform any additional checks...>
+ class ErrorObserver : public ErrorConsole::Observer {
+ public:
+ ErrorObserver(size_t errors_expected, ErrorConsole* error_console)
+ : errors_observed_(0),
+ errors_expected_(errors_expected),
+ waiting_(false),
+ error_console_(error_console) {
+ error_console_->AddObserver(this);
+ }
+ virtual ~ErrorObserver() {
+ if (error_console_)
+ error_console_->RemoveObserver(this);
+ }
+
+ // ErrorConsole::Observer implementation.
+ virtual void OnErrorAdded(const ExtensionError* error) OVERRIDE {
+ ++errors_observed_;
+ if (errors_observed_ >= errors_expected_) {
+ if (waiting_)
+ base::MessageLoopForUI::current()->Quit();
+ }
+ }
+
+ virtual void OnErrorConsoleDestroyed() OVERRIDE {
+ error_console_ = NULL;
+ }
+
+ // Spin until the appropriate number of errors have been observed.
+ void WaitForErrors() {
+ if (errors_observed_ < errors_expected_) {
+ waiting_ = true;
+ content::RunMessageLoop();
+ waiting_ = false;
+ }
+ }
+
+ private:
+ size_t errors_observed_;
+ size_t errors_expected_;
+ bool waiting_;
+
+ ErrorConsole* error_console_;
+
+ DISALLOW_COPY_AND_ASSIGN(ErrorObserver);
+ };
+
+ virtual void SetUpOnMainThread() OVERRIDE {
+ ExtensionBrowserTest::SetUpOnMainThread();
+
+ // Errors are only kept if we have Developer Mode enabled.
+ profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
+
+ error_console_ = ErrorConsole::Get(profile());
+ CHECK(error_console_);
+
+ test_data_dir_ = test_data_dir_.AppendASCII("error_console");
+ }
+
+ // Load the extension at |path| wait for |expected_errors| errors.
Yoyo Zhou 2013/08/16 00:17:26 nit: missing an and
Devlin 2013/08/16 18:07:49 Done.
+ // Populates |extension| with a pointer to the loaded extension.
Yoyo Zhou 2013/08/16 00:17:26 This could return Extension*.
Devlin 2013/08/16 18:07:49 Unfortunately, it can't. Use of ASSERT* in a func
+ void LoadExtensionAndCheckErrors(
+ const std::string& path,
+ int flags,
+ size_t errors_expected,
+ const Extension** extension) {
+ ErrorObserver observer(errors_expected, error_console_);
+ *extension =
+ LoadExtensionWithFlags(test_data_dir_.AppendASCII(path), flags);
+ ASSERT_TRUE(extension);
+ observer.WaitForErrors();
+
+ // We should only have errors for a single extension, or should have no
+ // entries, if no errors were expected.
+ ASSERT_EQ(errors_expected > 0 ? 1u : 0u, error_console()->errors().size());
+ ASSERT_EQ(
+ errors_expected,
+ error_console()->GetErrorsForExtension((*extension)->id()).size());
+ }
+
+ ErrorConsole* error_console() { return error_console_; }
+ private:
+ // Weak reference to the ErrorConsole object.
+ ErrorConsole* error_console_;
+};
+
+// Test to ensure that we are successfully reporting manifest errors as an
+// extension is installed.
+IN_PROC_BROWSER_TEST_F(ErrorConsoleBrowserTest, ReportManifestErrors) {
+ const Extension* extension = NULL;
+ // We expect two errors - one for an invalid permission, and a second for
+ // an unknown key.
+ LoadExtensionAndCheckErrors("manifest_warnings",
+ ExtensionBrowserTest::kFlagIgnoreManifestWarnings,
+ 2,
+ &extension);
+
+ const ErrorConsole::ErrorList& errors =
+ error_console()->GetErrorsForExtension(extension->id());
+
+ // Unfortunately, there's not always a hard guarantee of order in parsing the
+ // manifest, so there's not a definitive order in which these errors may
+ // occur. As such, we need to determine which error corresponds to which
+ // expected error.
+ ASSERT_EQ(ExtensionError::MANIFEST_PARSING_ERROR, errors[0]->type());
+ const ManifestParsingError* temp_error =
+ static_cast<const ManifestParsingError*>(errors[0]);
+
+ const ExtensionError* permissions_error = NULL;
+ const ExtensionError* unknown_key_error = NULL;
+ if (temp_error->manifest_key() == base::UTF8ToUTF16("permissions")) {
Yoyo Zhou 2013/08/16 00:17:26 This is more extensible if you write it like: for
Devlin 2013/08/16 18:07:49 Done.
+ permissions_error = errors[0];
+ unknown_key_error = errors[1];
+ } else {
+ permissions_error = errors[1];
+ unknown_key_error = errors[0];
+ }
+
+ const char kFakePermission[] = "not_a_real_permission";
+ CheckManifestError(permissions_error,
+ extension->id(),
+ base::UTF8ToUTF16(
+ ErrorUtils::FormatErrorMessage(
+ errors::kPermissionUnknownOrMalformed,
+ kFakePermission)),
+ base::UTF8ToUTF16(manifest_keys::kPermissions),
+ base::UTF8ToUTF16(kFakePermission));
+
+ const char kFakeKey[] = "not_a_real_key";
+ CheckManifestError(unknown_key_error,
+ extension->id(),
+ base::UTF8ToUTF16(
+ ErrorUtils::FormatErrorMessage(
+ errors::kUnrecognizedManifestKey,
+ kFakeKey)),
+ base::UTF8ToUTF16(kFakeKey),
+ EmptyString16());
+}
+
+// Test that we do not store any errors unless the Developer Mode switch is
+// toggled on the profile.
+IN_PROC_BROWSER_TEST_F(ErrorConsoleBrowserTest,
+ DontStoreErrorsWithoutDeveloperMode) {
+ profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
+
+ const Extension* extension = NULL;
+ // Same test as ReportManifestErrors, except we don't expect any errors since
+ // we disable Developer Mode.
+ LoadExtensionAndCheckErrors("manifest_warnings",
+ ExtensionBrowserTest::kFlagIgnoreManifestWarnings,
+ 0,
+ &extension);
+
+ // Now if we enable developer mode, the errors should be reported...
+ profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
+ EXPECT_EQ(2u, error_console()->GetErrorsForExtension(extension->id()).size());
+
+ // ... and if we disable it again, all errors which we were holding should be
+ // removed.
+ profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
+ EXPECT_EQ(0u, error_console()->GetErrorsForExtension(extension->id()).size());
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698