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

Side by Side 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: Requested UI Changes 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/error_console/error_console.h"
6
7 #include "base/files/file_path.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/strings/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/extensions/extension_browsertest.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/extensions/extension_system.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/extensions/extension.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "extensions/browser/extension_error.h"
19 #include "extensions/common/constants.h"
20 #include "extensions/common/error_utils.h"
21 #include "extensions/common/manifest_constants.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "url/gurl.h"
24
25 using base::string16;
26 using base::UTF8ToUTF16;
27
28 namespace extensions {
29
30 namespace {
31
32 base::string16 GetManifestFilename() {
33 return base::FilePath(kManifestFilename).AsUTF16Unsafe();
34 }
35
36 // Verify that all properties of a given |error| are correct.
37 void CheckError(const ExtensionError* error,
38 ExtensionError::Type type,
39 const std::string& id,
40 const string16& source,
41 bool from_incognito,
42 const string16& message) {
43 ASSERT_TRUE(error);
44 EXPECT_EQ(type, error->type());
45 EXPECT_EQ(id, error->extension_id());
46 EXPECT_EQ(source, error->source());
47 EXPECT_EQ(from_incognito, error->from_incognito());
48 EXPECT_EQ(message, error->message());
49 }
50
51 void CheckManifestError(const ExtensionError* error,
52 const std::string& id,
53 const string16& message,
54 const string16& manifest_key,
55 const string16& manifest_specific) {
56 CheckError(error,
57 ExtensionError::MANIFEST_ERROR,
58 id,
59 GetManifestFilename(), // source is always the manifest.
60 false, // manifest errors are never from incognito.
61 message);
62
63 const ManifestError* manifest_error =
64 static_cast<const ManifestError*>(error);
65 EXPECT_EQ(manifest_key, manifest_error->manifest_key());
66 EXPECT_EQ(manifest_specific, manifest_error->manifest_specific());
67 }
68
69 } // namespace
70
71 class ErrorConsoleBrowserTest : public ExtensionBrowserTest {
72 public:
73 ErrorConsoleBrowserTest() : error_console_(NULL) { }
74 virtual ~ErrorConsoleBrowserTest() { }
75
76 protected:
77 // A helper class in order to wait for the proper number of errors to be
78 // caught by the ErrorConsole. This will run the MessageLoop until a given
79 // number of errors are observed.
80 // Usage:
81 // ...
82 // ErrorObserver observer(3, error_console);
83 // <Cause three errors...>
84 // observer.WaitForErrors();
85 // <Perform any additional checks...>
86 class ErrorObserver : public ErrorConsole::Observer {
87 public:
88 ErrorObserver(size_t errors_expected, ErrorConsole* error_console)
89 : errors_observed_(0),
90 errors_expected_(errors_expected),
91 waiting_(false),
92 error_console_(error_console) {
93 error_console_->AddObserver(this);
94 }
95 virtual ~ErrorObserver() {
96 if (error_console_)
97 error_console_->RemoveObserver(this);
98 }
99
100 // ErrorConsole::Observer implementation.
101 virtual void OnErrorAdded(const ExtensionError* error) OVERRIDE {
102 ++errors_observed_;
103 if (errors_observed_ >= errors_expected_) {
104 if (waiting_)
105 base::MessageLoopForUI::current()->Quit();
106 }
107 }
108
109 virtual void OnErrorConsoleDestroyed() OVERRIDE {
110 error_console_ = NULL;
111 }
112
113 // Spin until the appropriate number of errors have been observed.
114 void WaitForErrors() {
115 if (errors_observed_ < errors_expected_) {
116 waiting_ = true;
117 content::RunMessageLoop();
118 waiting_ = false;
119 }
120 }
121
122 private:
123 size_t errors_observed_;
124 size_t errors_expected_;
125 bool waiting_;
126
127 ErrorConsole* error_console_;
128
129 DISALLOW_COPY_AND_ASSIGN(ErrorObserver);
130 };
131
132 virtual void SetUpOnMainThread() OVERRIDE {
133 ExtensionBrowserTest::SetUpOnMainThread();
134
135 // Errors are only kept if we have Developer Mode enabled.
136 profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
137
138 error_console_ = ErrorConsole::Get(profile());
139 CHECK(error_console_);
140
141 test_data_dir_ = test_data_dir_.AppendASCII("error_console");
142 }
143
144 // Load the extension at |path| and wait for |expected_errors| errors.
145 // Populates |extension| with a pointer to the loaded extension.
146 void LoadExtensionAndCheckErrors(
147 const std::string& path,
148 int flags,
149 size_t errors_expected,
150 const Extension** extension) {
151 ErrorObserver observer(errors_expected, error_console_);
152 *extension =
153 LoadExtensionWithFlags(test_data_dir_.AppendASCII(path), flags);
154 ASSERT_TRUE(*extension);
155 observer.WaitForErrors();
156
157 // We should only have errors for a single extension, or should have no
158 // entries, if no errors were expected.
159 ASSERT_EQ(errors_expected > 0 ? 1u : 0u, error_console()->errors().size());
160 ASSERT_EQ(
161 errors_expected,
162 error_console()->GetErrorsForExtension((*extension)->id()).size());
163 }
164
165 ErrorConsole* error_console() { return error_console_; }
166 private:
167 // Weak reference to the ErrorConsole object.
168 ErrorConsole* error_console_;
169 };
170
171 // Test to ensure that we are successfully reporting manifest errors as an
172 // extension is installed.
173 IN_PROC_BROWSER_TEST_F(ErrorConsoleBrowserTest, ReportManifestErrors) {
174 const Extension* extension = NULL;
175 // We expect two errors - one for an invalid permission, and a second for
176 // an unknown key.
177 LoadExtensionAndCheckErrors("manifest_warnings",
178 ExtensionBrowserTest::kFlagIgnoreManifestWarnings,
179 2,
180 &extension);
181
182 const ErrorConsole::ErrorList& errors =
183 error_console()->GetErrorsForExtension(extension->id());
184
185 // Unfortunately, there's not always a hard guarantee of order in parsing the
186 // manifest, so there's not a definitive order in which these errors may
187 // occur. As such, we need to determine which error corresponds to which
188 // expected error.
189 const ExtensionError* permissions_error = NULL;
190 const ExtensionError* unknown_key_error = NULL;
191 const char kFakeKey[] = "not_a_real_key";
192 for (size_t i = 0; i < errors.size(); ++i) {
193 ASSERT_EQ(ExtensionError::MANIFEST_ERROR, errors[i]->type());
194 std::string utf8_key = UTF16ToUTF8(
195 (static_cast<const ManifestError*>(errors[i]))->manifest_key());
196 if (utf8_key == manifest_keys::kPermissions)
197 permissions_error = errors[i];
198 else if (utf8_key == kFakeKey)
199 unknown_key_error = errors[i];
200 }
201 ASSERT_TRUE(permissions_error);
202 ASSERT_TRUE(unknown_key_error);
203
204 const char kFakePermission[] = "not_a_real_permission";
205 CheckManifestError(permissions_error,
206 extension->id(),
207 base::UTF8ToUTF16(
208 ErrorUtils::FormatErrorMessage(
209 manifest_errors::kPermissionUnknownOrMalformed,
210 kFakePermission)),
211 base::UTF8ToUTF16(manifest_keys::kPermissions),
212 base::UTF8ToUTF16(kFakePermission));
213
214 CheckManifestError(unknown_key_error,
215 extension->id(),
216 base::UTF8ToUTF16(
217 ErrorUtils::FormatErrorMessage(
218 manifest_errors::kUnrecognizedManifestKey,
219 kFakeKey)),
220 base::UTF8ToUTF16(kFakeKey),
221 EmptyString16());
222 }
223
224 // Test that we do not store any errors unless the Developer Mode switch is
225 // toggled on the profile.
226 IN_PROC_BROWSER_TEST_F(ErrorConsoleBrowserTest,
227 DontStoreErrorsWithoutDeveloperMode) {
228 profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
229
230 const Extension* extension = NULL;
231 // Same test as ReportManifestErrors, except we don't expect any errors since
232 // we disable Developer Mode.
233 LoadExtensionAndCheckErrors("manifest_warnings",
234 ExtensionBrowserTest::kFlagIgnoreManifestWarnings,
235 0,
236 &extension);
237
238 // Now if we enable developer mode, the errors should be reported...
239 profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
240 EXPECT_EQ(2u, error_console()->GetErrorsForExtension(extension->id()).size());
241
242 // ... and if we disable it again, all errors which we were holding should be
243 // removed.
244 profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, false);
245 EXPECT_EQ(0u, error_console()->GetErrorsForExtension(extension->id()).size());
246 }
247
248 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698