Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_message_bubble_controller_unittest.cc
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/ntp_overridden_bubble_controller.h"
13 #include "chrome/browser/extensions/settings_api_bubble_controller.h"
14 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
15 #include "chrome/browser/extensions/test_extension_system.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_builder.h"
21 #include "extensions/common/feature_switch.h"
22
23 namespace {
24
25 const char kId1[] = "iccfkkhkfiphcjdakkmcjmkfboccmndk";
26 const char kId2[] = "ajjhifimiemdpmophmkkkcijegphclbl";
27 const char kId3[] = "ioibbbfddncmmabjmpokikkeiofalaek";
28
29 }  // namespace
30
31 namespace extensions {
32
33 class TestDelegate {
34  public:
35   TestDelegate()
36       : action_button_callback_count_(0),
37         dismiss_button_callback_count_(0),
38         link_click_callback_count_(0) {
39   }
40
41   // Returns how often the dismiss button has been called.
42   size_t action_click_count() {
43     return action_button_callback_count_;
44   }
45
46   // Returns how often the dismiss button has been called.
47   size_t dismiss_click_count() {
48     return dismiss_button_callback_count_;
49   }
50
51   // Returns how often the link has been clicked.
52   size_t link_click_count() {
53     return link_click_callback_count_;
54   }
55
56  protected:
57   size_t action_button_callback_count_;
58   size_t dismiss_button_callback_count_;
59   size_t link_click_callback_count_;
60 };
61
62 // A test class for the SuspiciousExtensionBubbleController.
63 class TestSuspiciousExtensionBubbleController
64     : public SuspiciousExtensionBubbleController,
65       public TestDelegate {
66  public:
67   explicit TestSuspiciousExtensionBubbleController(Profile* profile)
68       : SuspiciousExtensionBubbleController(profile) {
69   }
70
71   virtual void OnBubbleAction() OVERRIDE {
72     ++action_button_callback_count_;
73     SuspiciousExtensionBubbleController::OnBubbleAction();
74   }
75
76   virtual void OnBubbleDismiss() OVERRIDE {
77     ++dismiss_button_callback_count_;
78     SuspiciousExtensionBubbleController::OnBubbleDismiss();
79   }
80
81   virtual void OnLinkClicked() OVERRIDE {
82     ++link_click_callback_count_;
83     SuspiciousExtensionBubbleController::OnLinkClicked();
84   }
85 };
86
87 // A test class for the DevModeBubbleController.
88 class TestDevModeBubbleController
89     : public DevModeBubbleController,
90       public TestDelegate {
91  public:
92   explicit TestDevModeBubbleController(Profile* profile)
93       : DevModeBubbleController(profile) {
94   }
95
96   virtual void OnBubbleAction() OVERRIDE {
97     ++action_button_callback_count_;
98     DevModeBubbleController::OnBubbleAction();
99   }
100
101   virtual void OnBubbleDismiss() OVERRIDE {
102     ++dismiss_button_callback_count_;
103     DevModeBubbleController::OnBubbleDismiss();
104   }
105
106   virtual void OnLinkClicked() OVERRIDE {
107     ++link_click_callback_count_;
108     DevModeBubbleController::OnLinkClicked();
109   }
110 };
111
112 // A test class for the SettingsApiBubbleController.
113 class TestSettingsApiBubbleController : public SettingsApiBubbleController,
114                                         public TestDelegate {
115  public:
116   TestSettingsApiBubbleController(Profile* profile,
117                                   SettingsApiOverrideType type)
118       : SettingsApiBubbleController(profile, type) {}
119
120   virtual void OnBubbleAction() OVERRIDE {
121     ++action_button_callback_count_;
122     SettingsApiBubbleController::OnBubbleAction();
123   }
124
125   virtual void OnBubbleDismiss() OVERRIDE {
126     ++dismiss_button_callback_count_;
127     SettingsApiBubbleController::OnBubbleDismiss();
128   }
129
130   virtual void OnLinkClicked() OVERRIDE {
131     ++link_click_callback_count_;
132     SettingsApiBubbleController::OnLinkClicked();
133   }
134 };
135
136 // A test class for the NtpOverriddenBubbleController.
137 class TestNtpOverriddenBubbleController
138     : public NtpOverriddenBubbleController,
139       public TestDelegate {
140  public:
141   explicit TestNtpOverriddenBubbleController(Profile* profile)
142       : NtpOverriddenBubbleController(profile) {
143   }
144
145   virtual void OnBubbleAction() OVERRIDE {
146     ++action_button_callback_count_;
147     NtpOverriddenBubbleController::OnBubbleAction();
148   }
149
150   virtual void OnBubbleDismiss() OVERRIDE {
151     ++dismiss_button_callback_count_;
152     NtpOverriddenBubbleController::OnBubbleDismiss();
153   }
154
155   virtual void OnLinkClicked() OVERRIDE {
156     ++link_click_callback_count_;
157     NtpOverriddenBubbleController::OnLinkClicked();
158   }
159 };
160
161 // A fake bubble used for testing the controller. Takes an action that specifies
162 // what should happen when the bubble is "shown" (the bubble is actually not
163 // shown, the corresponding action is taken immediately).
164 class FakeExtensionMessageBubble : public ExtensionMessageBubble {
165  public:
166   enum ExtensionBubbleAction {
167     BUBBLE_ACTION_CLICK_ACTION_BUTTON = 0,
168     BUBBLE_ACTION_CLICK_DISMISS_BUTTON,
169     BUBBLE_ACTION_CLICK_LINK,
170   };
171
172   FakeExtensionMessageBubble() {}
173
174   void set_action_on_show(ExtensionBubbleAction action) {
175     action_ = action;
176   }
177
178   virtual void Show() OVERRIDE {
179     if (action_ == BUBBLE_ACTION_CLICK_ACTION_BUTTON)
180       action_callback_.Run();
181     else if (action_ == BUBBLE_ACTION_CLICK_DISMISS_BUTTON)
182       dismiss_callback_.Run();
183     else if (action_ == BUBBLE_ACTION_CLICK_LINK)
184       link_callback_.Run();
185   }
186
187   virtual void OnActionButtonClicked(const base::Closure& callback) OVERRIDE {
188     action_callback_ = callback;
189   }
190
191   virtual void OnDismissButtonClicked(const base::Closure& callback) OVERRIDE {
192     dismiss_callback_ = callback;
193   }
194
195   virtual void OnLinkClicked(const base::Closure& callback) OVERRIDE {
196     link_callback_ = callback;
197   }
198
199  private:
200   ExtensionBubbleAction action_;
201
202   base::Closure action_callback_;
203   base::Closure dismiss_callback_;
204   base::Closure link_callback_;
205 };
206
207 class ExtensionMessageBubbleTest : public testing::Test {
208  public:
209   ExtensionMessageBubbleTest() {}
210
211   void LoadGenericExtension(const std::string& index,
212                             const std::string& id,
213                             Manifest::Location location) {
214     extensions::ExtensionBuilder builder;
215     builder.SetManifest(extensions::DictionaryBuilder()
216                             .Set("name", std::string("Extension " + index))
217                             .Set("version", "1.0")
218                             .Set("manifest_version", 2));
219     builder.SetLocation(location);
220     builder.SetID(id);
221     service_->AddExtension(builder.Build().get());
222   }
223
224   void LoadExtensionWithAction(const std::string& index,
225                                const std::string& id,
226                                Manifest::Location location) {
227     extensions::ExtensionBuilder builder;
228     builder.SetManifest(extensions::DictionaryBuilder()
229                             .Set("name", std::string("Extension " + index))
230                             .Set("version", "1.0")
231                             .Set("manifest_version", 2)
232                             .Set("browser_action",
233                                  extensions::DictionaryBuilder().Set(
234                                      "default_title", "Default title")));
235     builder.SetLocation(location);
236     builder.SetID(id);
237     service_->AddExtension(builder.Build().get());
238   }
239
240   void LoadExtensionOverridingHome(const std::string& index,
241                                    const std::string& id,
242                                    Manifest::Location location) {
243     extensions::ExtensionBuilder builder;
244     builder.SetManifest(extensions::DictionaryBuilder()
245                             .Set("name", std::string("Extension " + index))
246                             .Set("version", "1.0")
247                             .Set("manifest_version", 2)
248                             .Set("chrome_settings_overrides",
249                                  extensions::DictionaryBuilder().Set(
250                                      "homepage", "http://www.google.com")));
251     builder.SetLocation(location);
252     builder.SetID(id);
253     service_->AddExtension(builder.Build().get());
254   }
255
256   void LoadExtensionOverridingStart(const std::string& index,
257                                     const std::string& id,
258                                     Manifest::Location location) {
259     extensions::ExtensionBuilder builder;
260     builder.SetManifest(extensions::DictionaryBuilder()
261                             .Set("name", std::string("Extension " + index))
262                             .Set("version", "1.0")
263                             .Set("manifest_version", 2)
264                             .Set("chrome_settings_overrides",
265                                  extensions::DictionaryBuilder().Set(
266                                      "startup_pages",
267                                      extensions::ListBuilder().Append(
268                                          "http://www.google.com"))));
269     builder.SetLocation(location);
270     builder.SetID(id);
271     service_->AddExtension(builder.Build().get());
272   }
273
274   void LoadExtensionOverridingNtp(const std::string& index,
275                                   const std::string& id,
276                                   Manifest::Location location) {
277     extensions::ExtensionBuilder builder;
278     builder.SetManifest(extensions::DictionaryBuilder()
279                             .Set("name", std::string("Extension " + index))
280                             .Set("version", "1.0")
281                             .Set("manifest_version", 2)
282                             .Set("chrome_url_overrides",
283                                  extensions::DictionaryBuilder().Set(
284                                      "newtab", "Default.html")));
285
286     builder.SetLocation(location);
287     builder.SetID(id);
288     service_->AddExtension(builder.Build().get());
289   }
290
291   void Init() {
292     // The two lines of magical incantation required to get the extension
293     // service to work inside a unit test and access the extension prefs.
294     thread_bundle_.reset(new content::TestBrowserThreadBundle);
295     profile_.reset(new TestingProfile);
296     static_cast<TestExtensionSystem*>(
297         ExtensionSystem::Get(profile()))->CreateExtensionService(
298             CommandLine::ForCurrentProcess(),
299             base::FilePath(),
300             false);
301     service_ = profile_->GetExtensionService();
302     service_->Init();
303   }
304
305   virtual ~ExtensionMessageBubbleTest() {
306     // Make sure the profile is destroyed before the thread bundle.
307     profile_.reset(NULL);
308   }
309
310   virtual void SetUp() {
311     command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
312   }
313
314  protected:
315   Profile* profile() { return profile_.get(); }
316
317   scoped_refptr<Extension> CreateExtension(
318       Manifest::Location location,
319       const std::string& data,
320       const std::string& id) {
321     scoped_ptr<base::DictionaryValue> parsed_manifest(
322         extension_function_test_utils::ParseDictionary(data));
323     return extension_function_test_utils::CreateExtension(
324         location,
325         parsed_manifest.get(),
326         id);
327   }
328
329   ExtensionService* service_;
330
331  private:
332   scoped_ptr<CommandLine> command_line_;
333   scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_;
334   scoped_ptr<TestingProfile> profile_;
335
336   DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleTest);
337 };
338
339 // The feature this is meant to test is only implemented on Windows.
340 #if defined(OS_WIN)
341 #define MAYBE_WipeoutControllerTest WipeoutControllerTest
342 #else
343 #define MAYBE_WipeoutControllerTest DISABLED_WipeoutControllerTest
344 #endif
345
346 TEST_F(ExtensionMessageBubbleTest, MAYBE_WipeoutControllerTest) {
347   Init();
348   // Add three extensions, and control two of them in this test (extension 1
349   // and 2).
350   LoadExtensionWithAction("1", kId1, Manifest::COMMAND_LINE);
351   LoadGenericExtension("2", kId2, Manifest::UNPACKED);
352   LoadGenericExtension("3", kId3, Manifest::EXTERNAL_POLICY);
353
354   scoped_ptr<TestSuspiciousExtensionBubbleController> controller(
355       new TestSuspiciousExtensionBubbleController(profile()));
356   FakeExtensionMessageBubble bubble;
357   bubble.set_action_on_show(
358       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
359
360   // Validate that we don't have a suppress value for the extensions.
361   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
362   EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId1));
363   EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId2));
364
365   EXPECT_FALSE(controller->ShouldShow());
366   std::vector<base::string16> suspicious_extensions =
367       controller->GetExtensionList();
368   EXPECT_EQ(0U, suspicious_extensions.size());
369   EXPECT_EQ(0U, controller->link_click_count());
370   EXPECT_EQ(0U, controller->dismiss_click_count());
371
372   // Now disable an extension, specifying the wipeout flag.
373   service_->DisableExtension(kId1, Extension::DISABLE_NOT_VERIFIED);
374
375   EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId1));
376   EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId2));
377   controller.reset(new TestSuspiciousExtensionBubbleController(
378       profile()));
379   SuspiciousExtensionBubbleController::ClearProfileListForTesting();
380   EXPECT_TRUE(controller->ShouldShow());
381   suspicious_extensions = controller->GetExtensionList();
382   ASSERT_EQ(1U, suspicious_extensions.size());
383   EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions[0]);
384   controller->Show(&bubble);  // Simulate showing the bubble.
385   EXPECT_EQ(0U, controller->link_click_count());
386   EXPECT_EQ(1U, controller->dismiss_click_count());
387   // Now the acknowledge flag should be set only for the first extension.
388   EXPECT_TRUE(prefs->HasWipeoutBeenAcknowledged(kId1));
389   EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId2));
390   // Clear the flag.
391   prefs->SetWipeoutAcknowledged(kId1, false);
392   EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId1));
393
394   // Now disable the other extension and exercise the link click code path.
395   service_->DisableExtension(kId2, Extension::DISABLE_NOT_VERIFIED);
396
397   bubble.set_action_on_show(
398       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
399   controller.reset(new TestSuspiciousExtensionBubbleController(
400       profile()));
401   SuspiciousExtensionBubbleController::ClearProfileListForTesting();
402   EXPECT_TRUE(controller->ShouldShow());
403   suspicious_extensions = controller->GetExtensionList();
404   ASSERT_EQ(2U, suspicious_extensions.size());
405   EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions[1]);
406   EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == suspicious_extensions[0]);
407   controller->Show(&bubble);  // Simulate showing the bubble.
408   EXPECT_EQ(1U, controller->link_click_count());
409   EXPECT_EQ(0U, controller->dismiss_click_count());
410   EXPECT_TRUE(prefs->HasWipeoutBeenAcknowledged(kId1));
411 }
412
413 // The feature this is meant to test is only implemented on Windows.
414 #if defined(OS_WIN)
415 #define MAYBE_DevModeControllerTest DevModeControllerTest
416 #else
417 #define MAYBE_DevModeControllerTest DISABLED_DevModeControllerTest
418 #endif
419
420 TEST_F(ExtensionMessageBubbleTest, MAYBE_DevModeControllerTest) {
421   FeatureSwitch::ScopedOverride force_dev_mode_highlighting(
422       FeatureSwitch::force_dev_mode_highlighting(), true);
423   Init();
424   // Add three extensions, and control two of them in this test (extension 1
425   // and 2). Extension 1 is a regular extension, Extension 2 is UNPACKED so it
426   // counts as a DevMode extension.
427   LoadExtensionWithAction("1", kId1, Manifest::COMMAND_LINE);
428   LoadGenericExtension("2", kId2, Manifest::UNPACKED);
429   LoadGenericExtension("3", kId3, Manifest::EXTERNAL_POLICY);
430
431   scoped_ptr<TestDevModeBubbleController> controller(
432       new TestDevModeBubbleController(profile()));
433
434   // The list will contain one enabled unpacked extension.
435   EXPECT_TRUE(controller->ShouldShow());
436   std::vector<base::string16> dev_mode_extensions =
437       controller->GetExtensionList();
438   ASSERT_EQ(2U, dev_mode_extensions.size());
439   EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == dev_mode_extensions[0]);
440   EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == dev_mode_extensions[1]);
441   EXPECT_EQ(0U, controller->link_click_count());
442   EXPECT_EQ(0U, controller->dismiss_click_count());
443   EXPECT_EQ(0U, controller->action_click_count());
444
445   // Simulate showing the bubble.
446   FakeExtensionMessageBubble bubble;
447   bubble.set_action_on_show(
448       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
449   controller->Show(&bubble);
450   EXPECT_EQ(0U, controller->link_click_count());
451   EXPECT_EQ(0U, controller->action_click_count());
452   EXPECT_EQ(1U, controller->dismiss_click_count());
453   EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
454   EXPECT_TRUE(service_->GetExtensionById(kId2, false) != NULL);
455
456   // Do it again, but now press different button (Disable).
457   bubble.set_action_on_show(
458       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
459   controller.reset(new TestDevModeBubbleController(
460       profile()));
461   DevModeBubbleController::ClearProfileListForTesting();
462   EXPECT_TRUE(controller->ShouldShow());
463   dev_mode_extensions = controller->GetExtensionList();
464   EXPECT_EQ(2U, dev_mode_extensions.size());
465   controller->Show(&bubble);  // Simulate showing the bubble.
466   EXPECT_EQ(0U, controller->link_click_count());
467   EXPECT_EQ(1U, controller->action_click_count());
468   EXPECT_EQ(0U, controller->dismiss_click_count());
469   EXPECT_TRUE(service_->GetExtensionById(kId1, false) == NULL);
470   EXPECT_TRUE(service_->GetExtensionById(kId2, false) == NULL);
471
472   // Re-enable the extensions (disabled by the action button above).
473   service_->EnableExtension(kId1);
474   service_->EnableExtension(kId2);
475
476   // Show the dialog a third time, but now press the learn more link.
477   bubble.set_action_on_show(
478       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
479   controller.reset(new TestDevModeBubbleController(
480       profile()));
481   DevModeBubbleController::ClearProfileListForTesting();
482   EXPECT_TRUE(controller->ShouldShow());
483   dev_mode_extensions = controller->GetExtensionList();
484   EXPECT_EQ(2U, dev_mode_extensions.size());
485   controller->Show(&bubble);  // Simulate showing the bubble.
486   EXPECT_EQ(1U, controller->link_click_count());
487   EXPECT_EQ(0U, controller->action_click_count());
488   EXPECT_EQ(0U, controller->dismiss_click_count());
489   EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
490   EXPECT_TRUE(service_->GetExtensionById(kId2, false) != NULL);
491
492   // Now disable the unpacked extension.
493   service_->DisableExtension(kId1, Extension::DISABLE_USER_ACTION);
494   service_->DisableExtension(kId2, Extension::DISABLE_USER_ACTION);
495
496   controller.reset(new TestDevModeBubbleController(
497       profile()));
498   DevModeBubbleController::ClearProfileListForTesting();
499   EXPECT_FALSE(controller->ShouldShow());
500   dev_mode_extensions = controller->GetExtensionList();
501   EXPECT_EQ(0U, dev_mode_extensions.size());
502 }
503
504 // The feature this is meant to test is only implemented on Windows.
505 #if defined(OS_WIN)
506 #define MAYBE_SettingsApiControllerTest SettingsApiControllerTest
507 #else
508 #define MAYBE_SettingsApiControllerTest DISABLED_SettingsApiControllerTest
509 #endif
510
511 TEST_F(ExtensionMessageBubbleTest, MAYBE_SettingsApiControllerTest) {
512   Init();
513   extensions::ExtensionPrefs* prefs =
514       extensions::ExtensionPrefs::Get(profile());
515
516   for (int i = 0; i < 3; ++i) {
517     switch (static_cast<SettingsApiOverrideType>(i)) {
518       case BUBBLE_TYPE_HOME_PAGE:
519         // Load two extensions overriding home page and one overriding something
520         // unrelated (to check for interference). Extension 2 should still win
521         // on the home page setting.
522         LoadExtensionOverridingHome("1", kId1, Manifest::UNPACKED);
523         LoadExtensionOverridingHome("2", kId2, Manifest::UNPACKED);
524         LoadExtensionOverridingStart("3", kId3, Manifest::UNPACKED);
525         break;
526       case BUBBLE_TYPE_SEARCH_ENGINE:
527         // We deliberately skip testing the search engine since it relies on
528         // TemplateURLServiceFactory that isn't available while unit testing.
529         // This test is only simulating the bubble interaction with the user and
530         // that is more or less the same for the search engine as it is for the
531         // others.
532         continue;
533       case BUBBLE_TYPE_STARTUP_PAGES:
534         // Load two extensions overriding start page and one overriding
535         // something unrelated (to check for interference). Extension 2 should
536         // still win on the startup page setting.
537         LoadExtensionOverridingStart("1", kId1, Manifest::UNPACKED);
538         LoadExtensionOverridingStart("2", kId2, Manifest::UNPACKED);
539         LoadExtensionOverridingHome("3", kId3, Manifest::UNPACKED);
540         break;
541       default:
542         NOTREACHED();
543         break;
544     }
545
546     scoped_ptr<TestSettingsApiBubbleController> controller(
547         new TestSettingsApiBubbleController(
548             profile(), static_cast<SettingsApiOverrideType>(i)));
549
550     // The list will contain one enabled unpacked extension (ext 2).
551     EXPECT_TRUE(controller->ShouldShow(kId2));
552     std::vector<base::string16> override_extensions =
553         controller->GetExtensionList();
554     ASSERT_EQ(1U, override_extensions.size());
555     EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
556                 override_extensions[0].c_str());
557     EXPECT_EQ(0U, controller->link_click_count());
558     EXPECT_EQ(0U, controller->dismiss_click_count());
559     EXPECT_EQ(0U, controller->action_click_count());
560
561     // Simulate showing the bubble and dismissing it.
562     FakeExtensionMessageBubble bubble;
563     bubble.set_action_on_show(
564         FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
565     controller->Show(&bubble);
566     EXPECT_EQ(0U, controller->link_click_count());
567     EXPECT_EQ(0U, controller->action_click_count());
568     EXPECT_EQ(1U, controller->dismiss_click_count());
569     // No extension should have become disabled.
570     EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
571     EXPECT_TRUE(service_->GetExtensionById(kId2, false) != NULL);
572     EXPECT_TRUE(service_->GetExtensionById(kId3, false) != NULL);
573     // Only extension 2 should have been acknowledged.
574     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId1));
575     EXPECT_TRUE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId2));
576     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId3));
577     // Clean up after ourselves.
578     prefs->SetSettingsApiBubbleBeenAcknowledged(kId2, false);
579
580     // Simulate clicking the learn more link to dismiss it.
581     bubble.set_action_on_show(
582         FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
583     controller.reset(new TestSettingsApiBubbleController(
584         profile(), static_cast<SettingsApiOverrideType>(i)));
585     controller->Show(&bubble);
586     EXPECT_EQ(1U, controller->link_click_count());
587     EXPECT_EQ(0U, controller->action_click_count());
588     EXPECT_EQ(0U, controller->dismiss_click_count());
589     // No extension should have become disabled.
590     EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
591     EXPECT_TRUE(service_->GetExtensionById(kId2, false) != NULL);
592     EXPECT_TRUE(service_->GetExtensionById(kId3, false) != NULL);
593     // Only extension 2 should have been acknowledged.
594     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId1));
595     EXPECT_TRUE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId2));
596     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId3));
597     // Clean up after ourselves.
598     prefs->SetSettingsApiBubbleBeenAcknowledged(kId2, false);
599
600     // Do it again, but now opt to disable the extension.
601     bubble.set_action_on_show(
602         FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
603     controller.reset(new TestSettingsApiBubbleController(
604         profile(), static_cast<SettingsApiOverrideType>(i)));
605     EXPECT_TRUE(controller->ShouldShow(kId2));
606     override_extensions = controller->GetExtensionList();
607     EXPECT_EQ(1U, override_extensions.size());
608     controller->Show(&bubble);  // Simulate showing the bubble.
609     EXPECT_EQ(0U, controller->link_click_count());
610     EXPECT_EQ(1U, controller->action_click_count());
611     EXPECT_EQ(0U, controller->dismiss_click_count());
612     // Only extension 2 should have become disabled.
613     EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
614     EXPECT_TRUE(service_->GetExtensionById(kId2, false) == NULL);
615     EXPECT_TRUE(service_->GetExtensionById(kId3, false) != NULL);
616     // No extension should have been acknowledged (it got disabled).
617     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId1));
618     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId2));
619     EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId3));
620
621     // Clean up after ourselves.
622     service_->UninstallExtension(kId1, false, NULL);
623     service_->UninstallExtension(kId2, false, NULL);
624     service_->UninstallExtension(kId3, false, NULL);
625   }
626 }
627
628 // The feature this is meant to test is only implemented on Windows.
629 #if defined(OS_WIN)
630 #define MAYBE_NtpOverriddenControllerTest NtpOverriddenControllerTest
631 #else
632 #define MAYBE_NtpOverriddenControllerTest DISABLED_NtpOverriddenControllerTest
633 #endif
634
635 TEST_F(ExtensionMessageBubbleTest, MAYBE_NtpOverriddenControllerTest) {
636   Init();
637   extensions::ExtensionPrefs* prefs =
638       extensions::ExtensionPrefs::Get(profile());
639   // Load two extensions overriding new tab page and one overriding something
640   // unrelated (to check for interference). Extension 2 should still win
641   // on the new tab page setting.
642   LoadExtensionOverridingNtp("1", kId1, Manifest::UNPACKED);
643   LoadExtensionOverridingNtp("2", kId2, Manifest::UNPACKED);
644   LoadExtensionOverridingStart("3", kId3, Manifest::UNPACKED);
645
646   scoped_ptr<TestNtpOverriddenBubbleController> controller(
647       new TestNtpOverriddenBubbleController(profile()));
648
649   // The list will contain one enabled unpacked extension (ext 2).
650   EXPECT_TRUE(controller->ShouldShow(kId2));
651   std::vector<base::string16> override_extensions =
652       controller->GetExtensionList();
653   ASSERT_EQ(1U, override_extensions.size());
654   EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
655               override_extensions[0].c_str());
656   EXPECT_EQ(0U, controller->link_click_count());
657   EXPECT_EQ(0U, controller->dismiss_click_count());
658   EXPECT_EQ(0U, controller->action_click_count());
659
660   // Simulate showing the bubble and dismissing it.
661   FakeExtensionMessageBubble bubble;
662   bubble.set_action_on_show(
663       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
664   EXPECT_TRUE(controller->ShouldShow(kId2));
665   controller->Show(&bubble);
666   EXPECT_EQ(0U, controller->link_click_count());
667   EXPECT_EQ(0U, controller->action_click_count());
668   EXPECT_EQ(1U, controller->dismiss_click_count());
669   // No extension should have become disabled.
670   EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
671   EXPECT_TRUE(service_->GetExtensionById(kId2, false) != NULL);
672   EXPECT_TRUE(service_->GetExtensionById(kId3, false) != NULL);
673   // Only extension 2 should have been acknowledged.
674   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId1));
675   EXPECT_TRUE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId2));
676   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId3));
677   // Clean up after ourselves.
678   prefs->SetNtpOverriddenBubbleBeenAcknowledged(kId2, false);
679
680   // Simulate clicking the learn more link to dismiss it.
681   bubble.set_action_on_show(
682       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
683   controller.reset(new TestNtpOverriddenBubbleController(profile()));
684   EXPECT_TRUE(controller->ShouldShow(kId2));
685   controller->Show(&bubble);
686   EXPECT_EQ(1U, controller->link_click_count());
687   EXPECT_EQ(0U, controller->action_click_count());
688   EXPECT_EQ(0U, controller->dismiss_click_count());
689   // No extension should have become disabled.
690   EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
691   EXPECT_TRUE(service_->GetExtensionById(kId2, false) != NULL);
692   EXPECT_TRUE(service_->GetExtensionById(kId3, false) != NULL);
693   // Only extension 2 should have been acknowledged.
694   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId1));
695   EXPECT_TRUE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId2));
696   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId3));
697   // Clean up after ourselves.
698   prefs->SetNtpOverriddenBubbleBeenAcknowledged(kId2, false);
699
700   // Do it again, but now opt to disable the extension.
701   bubble.set_action_on_show(
702       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
703   controller.reset(new TestNtpOverriddenBubbleController(profile()));
704   EXPECT_TRUE(controller->ShouldShow(kId2));
705   override_extensions = controller->GetExtensionList();
706   EXPECT_EQ(1U, override_extensions.size());
707   controller->Show(&bubble);  // Simulate showing the bubble.
708   EXPECT_EQ(0U, controller->link_click_count());
709   EXPECT_EQ(1U, controller->action_click_count());
710   EXPECT_EQ(0U, controller->dismiss_click_count());
711   // Only extension 2 should have become disabled.
712   EXPECT_TRUE(service_->GetExtensionById(kId1, false) != NULL);
713   EXPECT_TRUE(service_->GetExtensionById(kId2, false) == NULL);
714   EXPECT_TRUE(service_->GetExtensionById(kId3, false) != NULL);
715   // No extension should have been acknowledged (it got disabled).
716   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId1));
717   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId2));
718   EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId3));
719
720   // Clean up after ourselves.
721   service_->UninstallExtension(kId1, false, NULL);
722   service_->UninstallExtension(kId2, false, NULL);
723   service_->UninstallExtension(kId3, false, NULL);
724 }
725
726 }  // namespace extensions