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

Side by Side Diff: chrome/browser/extensions/extension_message_bubble_controller_unittest.cc

Issue 95133002: Add an extension bubble explaining which extensions are in dev mode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head Created 7 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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 "base/command_line.h"
6 #include "base/strings/string_util.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/dev_mode_bubble_controller.h"
9 #include "chrome/browser/extensions/extension_function_test_utils.h"
10 #include "chrome/browser/extensions/extension_message_bubble.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
13 #include "chrome/browser/extensions/test_extension_system.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "extensions/common/extension.h"
17
18 namespace extensions {
19
20 class TestDelegate {
21 public:
22 TestDelegate()
23 : action_button_callback_count_(0),
24 dismiss_button_callback_count_(0),
25 link_click_callback_count_(0) {
26 }
27
28 // Returns how often the dismiss button has been called.
29 size_t action_click_count() {
30 return action_button_callback_count_;
31 }
32
33 // Returns how often the dismiss button has been called.
34 size_t dismiss_click_count() {
35 return dismiss_button_callback_count_;
36 }
37
38 // Returns how often the link has been clicked.
39 size_t link_click_count() {
40 return link_click_callback_count_;
41 }
42
43 protected:
44 size_t action_button_callback_count_;
45 size_t dismiss_button_callback_count_;
46 size_t link_click_callback_count_;
47 };
48
49 // A test class for the SuspiciousExtensionBubbleController.
50 class TestSuspiciousExtensionBubbleController
51 : public SuspiciousExtensionBubbleController,
52 public TestDelegate {
53 public:
54 explicit TestSuspiciousExtensionBubbleController(Profile* profile)
55 : SuspiciousExtensionBubbleController(profile) {
56 }
57
58 virtual void OnBubbleAction() OVERRIDE {
59 ++action_button_callback_count_;
60 SuspiciousExtensionBubbleController::OnBubbleAction();
61 }
62
63 virtual void OnBubbleDismiss() OVERRIDE {
64 ++dismiss_button_callback_count_;
65 SuspiciousExtensionBubbleController::OnBubbleDismiss();
66 }
67
68 virtual void OnLinkClicked() OVERRIDE {
69 ++link_click_callback_count_;
70 SuspiciousExtensionBubbleController::OnLinkClicked();
71 }
72 };
73
74 // A test class for the DevModeBubbleController.
75 class TestDevModeBubbleController
76 : public DevModeBubbleController,
77 public TestDelegate {
78 public:
79 explicit TestDevModeBubbleController(Profile* profile)
80 : DevModeBubbleController(profile) {
81 }
82
83 virtual void OnBubbleAction() OVERRIDE {
84 ++action_button_callback_count_;
85 DevModeBubbleController::OnBubbleAction();
86 }
87
88 virtual void OnBubbleDismiss() OVERRIDE {
89 ++dismiss_button_callback_count_;
90 DevModeBubbleController::OnBubbleDismiss();
91 }
92
93 virtual void OnLinkClicked() OVERRIDE {
94 ++link_click_callback_count_;
95 DevModeBubbleController::OnLinkClicked();
96 }
97 };
98
99 // A fake bubble used for testing the controller. Takes an action that specifies
100 // what should happen when the bubble is "shown" (the bubble is actually not
101 // shown, the corresponding action is taken immediately).
102 class FakeExtensionMessageBubble : public ExtensionMessageBubble {
103 public:
104 enum ExtensionBubbleAction {
105 BUBBLE_ACTION_CLICK_ACTION_BUTTON = 0,
106 BUBBLE_ACTION_CLICK_DISMISS_BUTTON,
107 BUBBLE_ACTION_CLICK_LINK,
108 };
109
110 FakeExtensionMessageBubble() {}
111
112 void set_action_on_show(ExtensionBubbleAction action) {
113 action_ = action;
114 }
115
116 virtual void Show() OVERRIDE {
117 if (action_ == BUBBLE_ACTION_CLICK_ACTION_BUTTON)
118 action_callback_.Run();
119 else if (action_ == BUBBLE_ACTION_CLICK_DISMISS_BUTTON)
120 dismiss_callback_.Run();
121 else if (action_ == BUBBLE_ACTION_CLICK_LINK)
122 link_callback_.Run();
123 }
124
125 virtual void OnActionButtonClicked(const base::Closure& callback) OVERRIDE {
126 action_callback_ = callback;
127 }
128
129 virtual void OnDismissButtonClicked(const base::Closure& callback) OVERRIDE {
130 dismiss_callback_ = callback;
131 }
132
133 virtual void OnLinkClicked(const base::Closure& callback) OVERRIDE {
134 link_callback_ = callback;
135 }
136
137 private:
138 ExtensionBubbleAction action_;
139
140 base::Closure action_callback_;
141 base::Closure dismiss_callback_;
142 base::Closure link_callback_;
143 };
144
145 class ExtensionMessageBubbleTest : public testing::Test {
146 public:
147 ExtensionMessageBubbleTest() {
148 // The two lines of magical incantation required to get the extension
149 // service to work inside a unit test and access the extension prefs.
150 thread_bundle_.reset(new content::TestBrowserThreadBundle);
151 profile_.reset(new TestingProfile);
152
153 static_cast<TestExtensionSystem*>(
154 ExtensionSystem::Get(profile()))->CreateExtensionService(
155 CommandLine::ForCurrentProcess(),
156 base::FilePath(),
157 false);
158 service_ = profile_->GetExtensionService();
159 service_->Init();
160
161 std::string basic_extension =
162 "{\"name\": \"Extension #\","
163 "\"version\": \"1.0\","
164 "\"manifest_version\": 2}";
165 std::string basic_extension_with_action =
166 "{\"name\": \"Extension #\","
167 "\"version\": \"1.0\","
168 "\"browser_action\": {"
169 " \"default_title\": \"Default title\""
170 "},"
171 "\"manifest_version\": 2}";
172
173 std::string extension_data;
174 base::ReplaceChars(basic_extension_with_action, "#", "1", &extension_data);
175 scoped_refptr<Extension> my_test_extension1(
176 CreateExtension(
177 Manifest::COMMAND_LINE,
178 extension_data,
179 "Autogenerated 1"));
180
181 base::ReplaceChars(basic_extension, "#", "2", &extension_data);
182 scoped_refptr<Extension> my_test_extension2(
183 CreateExtension(
184 Manifest::UNPACKED,
185 extension_data,
186 "Autogenerated 2"));
187
188 base::ReplaceChars(basic_extension, "#", "3", &extension_data);
189 scoped_refptr<Extension> regular_extension(
190 CreateExtension(
191 Manifest::EXTERNAL_POLICY,
192 extension_data,
193 "Autogenerated 3"));
194
195 extension_id1_ = my_test_extension1->id();
196 extension_id2_ = my_test_extension2->id();
197 extension_id3_ = regular_extension->id();
198
199 service_->AddExtension(regular_extension);
200 service_->AddExtension(my_test_extension1);
201 service_->AddExtension(my_test_extension2);
202 }
203 virtual ~ExtensionMessageBubbleTest() {
204 // Make sure the profile is destroyed before the thread bundle.
205 profile_.reset(NULL);
206 }
207
208 virtual void SetUp() {
209 command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
210 }
211
212 protected:
213 Profile* profile() { return profile_.get(); }
214
215 scoped_refptr<Extension> CreateExtension(
216 Manifest::Location location,
217 const std::string& data,
218 const std::string& id) {
219 scoped_ptr<base::DictionaryValue> parsed_manifest(
220 extension_function_test_utils::ParseDictionary(data));
221 return extension_function_test_utils::CreateExtension(
222 location,
223 parsed_manifest.get(),
224 id);
225 }
226
227 ExtensionService* service_;
228 std::string extension_id1_;
229 std::string extension_id2_;
230 std::string extension_id3_;
231
232 private:
233 scoped_ptr<CommandLine> command_line_;
234 scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_;
235 scoped_ptr<TestingProfile> profile_;
236
237 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleTest);
238 };
239
240 // The feature this is meant to test is only implemented on Windows.
241 #if defined(OS_WIN)
242 #define MAYBE_WipeoutControllerTest WipeoutControllerTest
243 #else
244 #define MAYBE_WipeoutControllerTest DISABLED_WipeoutControllerTest
245 #endif
246
247 TEST_F(ExtensionMessageBubbleTest, MAYBE_WipeoutControllerTest) {
248 // The test base class adds three extensions, and we control two of them in
249 // this test (ids are: extension_id1_ and extension_id2_).
250 scoped_ptr<TestSuspiciousExtensionBubbleController> controller(
251 new TestSuspiciousExtensionBubbleController(profile()));
252 FakeExtensionMessageBubble bubble;
253 bubble.set_action_on_show(
254 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
255
256 // Validate that we don't have a suppress value for the extensions.
257 ExtensionPrefs* prefs = service_->extension_prefs();
258 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(extension_id1_));
259 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(extension_id2_));
260
261 EXPECT_FALSE(controller->ShouldShow());
262 std::vector<string16> suspicious_extensions = controller->GetExtensionList();
263 EXPECT_EQ(0U, suspicious_extensions.size());
264 EXPECT_EQ(0U, controller->link_click_count());
265 EXPECT_EQ(0U, controller->dismiss_click_count());
266
267 // Now disable an extension, specifying the wipeout flag.
268 service_->DisableExtension(extension_id1_,
269 Extension::DISABLE_NOT_VERIFIED);
270
271 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(extension_id1_));
272 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(extension_id2_));
273 controller.reset(new TestSuspiciousExtensionBubbleController(
274 profile()));
275 EXPECT_TRUE(controller->ShouldShow());
276 suspicious_extensions = controller->GetExtensionList();
277 ASSERT_EQ(1U, suspicious_extensions.size());
278 EXPECT_TRUE(ASCIIToUTF16("Extension 1") == suspicious_extensions[0]);
279 controller->Show(&bubble); // Simulate showing the bubble.
280 EXPECT_EQ(0U, controller->link_click_count());
281 EXPECT_EQ(1U, controller->dismiss_click_count());
282 // Now the acknowledge flag should be set only for the first extension.
283 EXPECT_TRUE(prefs->HasWipeoutBeenAcknowledged(extension_id1_));
284 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(extension_id2_));
285 // Clear the flag.
286 prefs->SetWipeoutAcknowledged(extension_id1_, false);
287 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(extension_id1_));
288
289 // Now disable the other extension and exercise the link click code path.
290 service_->DisableExtension(extension_id2_,
291 Extension::DISABLE_NOT_VERIFIED);
292
293 bubble.set_action_on_show(
294 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
295 controller.reset(new TestSuspiciousExtensionBubbleController(
296 profile()));
297 EXPECT_TRUE(controller->ShouldShow());
298 suspicious_extensions = controller->GetExtensionList();
299 ASSERT_EQ(2U, suspicious_extensions.size());
300 EXPECT_TRUE(ASCIIToUTF16("Extension 1") == suspicious_extensions[1]);
301 EXPECT_TRUE(ASCIIToUTF16("Extension 2") == suspicious_extensions[0]);
302 controller->Show(&bubble); // Simulate showing the bubble.
303 EXPECT_EQ(1U, controller->link_click_count());
304 EXPECT_EQ(0U, controller->dismiss_click_count());
305 EXPECT_TRUE(prefs->HasWipeoutBeenAcknowledged(extension_id1_));
306 }
307
308 // The feature this is meant to test is only implemented on Windows.
309 #if defined(OS_WIN)
310 #define MAYBE_DevModeControllerTest DevModeControllerTest
311 #else
312 #define MAYBE_DevModeControllerTest DISABLED_DevModeControllerTest
313 #endif
314
315 TEST_F(ExtensionMessageBubbleTest, MAYBE_DevModeControllerTest) {
316 // The test base class adds three extensions, and we control two of them in
317 // this test (ids are: extension_id1_ and extension_id2_). Extension 1 is a
318 // regular extension, Extension 2 is UNPACKED so it counts as a DevMode
319 // extension.
320 scoped_ptr<TestDevModeBubbleController> controller(
321 new TestDevModeBubbleController(profile()));
322
323 // The list will contain one enabled unpacked extension.
324 EXPECT_TRUE(controller->ShouldShow());
325 std::vector<string16> dev_mode_extensions = controller->GetExtensionList();
326 ASSERT_EQ(2U, dev_mode_extensions.size());
327 EXPECT_TRUE(ASCIIToUTF16("Extension 2") == dev_mode_extensions[0]);
328 EXPECT_TRUE(ASCIIToUTF16("Extension 1") == dev_mode_extensions[1]);
329 EXPECT_EQ(0U, controller->link_click_count());
330 EXPECT_EQ(0U, controller->dismiss_click_count());
331 EXPECT_EQ(0U, controller->action_click_count());
332
333 // Simulate showing the bubble.
334 FakeExtensionMessageBubble bubble;
335 bubble.set_action_on_show(
336 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
337 controller->Show(&bubble);
338 EXPECT_EQ(0U, controller->link_click_count());
339 EXPECT_EQ(0U, controller->action_click_count());
340 EXPECT_EQ(1U, controller->dismiss_click_count());
341 EXPECT_TRUE(service_->GetExtensionById(extension_id1_, false) != NULL);
342 EXPECT_TRUE(service_->GetExtensionById(extension_id2_, false) != NULL);
343
344 // Do it again, but now press different button (Disable).
345 bubble.set_action_on_show(
346 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
347 controller.reset(new TestDevModeBubbleController(
348 profile()));
349 EXPECT_TRUE(controller->ShouldShow());
350 dev_mode_extensions = controller->GetExtensionList();
351 EXPECT_EQ(2U, dev_mode_extensions.size());
352 controller->Show(&bubble); // Simulate showing the bubble.
353 EXPECT_EQ(0U, controller->link_click_count());
354 EXPECT_EQ(1U, controller->action_click_count());
355 EXPECT_EQ(0U, controller->dismiss_click_count());
356 EXPECT_TRUE(service_->GetExtensionById(extension_id1_, false) == NULL);
357 EXPECT_TRUE(service_->GetExtensionById(extension_id2_, false) == NULL);
358
359 // Re-enable the extensions (disabled by the action button above).
360 service_->EnableExtension(extension_id1_);
361 service_->EnableExtension(extension_id2_);
362
363 // Show the dialog a third time, but now press the learn more link.
364 bubble.set_action_on_show(
365 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
366 controller.reset(new TestDevModeBubbleController(
367 profile()));
368 EXPECT_TRUE(controller->ShouldShow());
369 dev_mode_extensions = controller->GetExtensionList();
370 EXPECT_EQ(2U, dev_mode_extensions.size());
371 controller->Show(&bubble); // Simulate showing the bubble.
372 EXPECT_EQ(1U, controller->link_click_count());
373 EXPECT_EQ(0U, controller->action_click_count());
374 EXPECT_EQ(0U, controller->dismiss_click_count());
375 EXPECT_TRUE(service_->GetExtensionById(extension_id1_, false) != NULL);
376 EXPECT_TRUE(service_->GetExtensionById(extension_id2_, false) != NULL);
377
378 // Now disable the unpacked extension.
379 service_->DisableExtension(extension_id1_, Extension::DISABLE_USER_ACTION);
380 service_->DisableExtension(extension_id2_, Extension::DISABLE_USER_ACTION);
381
382 controller.reset(new TestDevModeBubbleController(
383 profile()));
384 EXPECT_FALSE(controller->ShouldShow());
385 dev_mode_extensions = controller->GetExtensionList();
386 EXPECT_EQ(0U, dev_mode_extensions.size());
387 }
388
389 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_message_bubble_controller.cc ('k') | chrome/browser/extensions/extension_prefs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698