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

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

Powered by Google App Engine
This is Rietveld 408576698