- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / script_badge_controller_unittest.cc
1 // Copyright (c) 2012 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 <string>
6
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/extension_action_manager.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/script_badge_controller.h"
15 #include "chrome/browser/extensions/tab_helper.h"
16 #include "chrome/browser/extensions/test_extension_system.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/chrome_version_info.h"
19 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/extensions/extension_builder.h"
21 #include "chrome/common/extensions/feature_switch.h"
22 #include "chrome/common/extensions/features/feature_channel.h"
23 #include "chrome/common/extensions/value_builder.h"
24 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
25 #include "chrome/test/base/testing_profile.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/navigation_entry.h"
28 #include "content/public/browser/notification_registrar.h"
29 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/test/test_browser_thread.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33
34 #if defined(OS_CHROMEOS)
35 #include "chrome/browser/chromeos/login/user_manager.h"
36 #include "chrome/browser/chromeos/settings/cros_settings.h"
37 #include "chrome/browser/chromeos/settings/device_settings_service.h"
38 #endif
39
40 namespace extensions {
41 namespace {
42
43 class ScriptBadgeControllerTest : public ChromeRenderViewHostTestHarness {
44  public:
45   ScriptBadgeControllerTest()
46       : feature_override_(FeatureSwitch::script_badges(), true),
47         current_channel_(chrome::VersionInfo::CHANNEL_DEV) {}
48
49   virtual void SetUp() OVERRIDE {
50     // Note that this sets a PageActionController into the
51     // extensions::TabHelper's location_bar_controller field.  Do
52     // not use that for testing.
53     ChromeRenderViewHostTestHarness::SetUp();
54
55 #if defined OS_CHROMEOS
56   test_user_manager_.reset(new chromeos::ScopedTestUserManager());
57 #endif
58
59     Profile* profile =
60         Profile::FromBrowserContext(web_contents()->GetBrowserContext());
61     TestExtensionSystem* extension_system =
62         static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile));
63
64     // Create an ExtensionService so the ScriptBadgeController can find its
65     // extensions.
66     CommandLine command_line(CommandLine::NO_PROGRAM);
67     extension_service_ = extension_system->CreateExtensionService(
68         &command_line, base::FilePath(), false);
69
70     TabHelper::CreateForWebContents(web_contents());
71     script_badge_controller_ = static_cast<ScriptBadgeController*>(
72         TabHelper::FromWebContents(web_contents())->location_bar_controller());
73   }
74
75   virtual void TearDown() OVERRIDE {
76 #if defined OS_CHROMEOS
77     test_user_manager_.reset();
78 #endif
79     ChromeRenderViewHostTestHarness::TearDown();
80   }
81
82  protected:
83   // Creates a test extension and adds it to |extension_service_|.
84   scoped_refptr<const Extension> AddTestExtension() {
85     scoped_refptr<const Extension> extension = ExtensionBuilder()
86         .SetManifest(DictionaryBuilder()
87             .Set("name", "Extension with page action")
88             .Set("version", "1.0.0")
89             .Set("manifest_version", 2)
90             .Set("permissions", ListBuilder()
91                 .Append("tabs"))
92             .Set("page_action", DictionaryBuilder()
93                 .Set("default_title", "Hello")))
94         .Build();
95     extension_service_->AddExtension(extension.get());
96     return extension;
97   }
98
99   ExtensionAction* GetScriptBadge(const Extension& extension) {
100     return ExtensionActionManager::Get(profile())->GetScriptBadge(extension);
101   }
102
103   ExtensionService* extension_service_;
104   ScriptBadgeController* script_badge_controller_;
105
106  private:
107   FeatureSwitch::ScopedOverride feature_override_;
108   ScopedCurrentChannel current_channel_;
109
110 #if defined OS_CHROMEOS
111   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
112   chromeos::ScopedTestCrosSettings test_cros_settings_;
113   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
114 #endif
115 };
116
117 struct CountingNotificationObserver : public content::NotificationObserver {
118   CountingNotificationObserver() : events(0) {}
119
120   virtual void Observe(int type,
121                        const content::NotificationSource& source,
122                        const content::NotificationDetails& details) OVERRIDE {
123     events++;
124   }
125
126   int events;
127 };
128
129 TEST_F(ScriptBadgeControllerTest, ExecutionMakesBadgeVisible) {
130   content::NotificationRegistrar notification_registrar;
131
132   EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
133               testing::ElementsAre());
134
135   scoped_refptr<const Extension> extension = AddTestExtension();
136
137   // Establish a page id.
138   NavigateAndCommit(GURL("http://www.google.com"));
139
140   CountingNotificationObserver location_bar_updated;
141   Profile* profile =
142       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
143   notification_registrar.Add(
144       &location_bar_updated,
145       chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
146       content::Source<Profile>(profile));
147
148   // Initially, no script badges.
149   EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
150               testing::ElementsAre());
151
152   TabHelper::ScriptExecutionObserver::ExecutingScriptsMap id_map;
153   id_map[extension->id()] = std::set<std::string>();
154   script_badge_controller_->OnScriptsExecuted(
155       web_contents(),
156       id_map,
157       web_contents()->GetController().GetVisibleEntry()->GetPageID(),
158       GURL(std::string()));
159   EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
160               testing::ElementsAre(GetScriptBadge(*extension.get())));
161   EXPECT_THAT(location_bar_updated.events, testing::Gt(0));
162 };
163
164 TEST_F(ScriptBadgeControllerTest, FragmentNavigation) {
165   scoped_refptr<const Extension> extension = AddTestExtension();
166   Profile* profile =
167       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
168
169   // Establish a page id.
170   NavigateAndCommit(GURL("http://www.google.com"));
171
172   // Run script. Should be a notification and a script badge.
173   {
174     content::NotificationRegistrar notification_registrar;
175     CountingNotificationObserver location_bar_updated;
176     notification_registrar.Add(
177         &location_bar_updated,
178         chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
179         content::Source<Profile>(profile));
180
181     TabHelper::ScriptExecutionObserver::ExecutingScriptsMap id_map;
182     id_map[extension->id()] = std::set<std::string>();
183     script_badge_controller_->OnScriptsExecuted(
184         web_contents(),
185         id_map,
186         web_contents()->GetController().GetVisibleEntry()->GetPageID(),
187         GURL(std::string()));
188
189     EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
190                 testing::ElementsAre(GetScriptBadge(*extension.get())));
191     EXPECT_EQ(1, location_bar_updated.events);
192   }
193
194   // Navigate to a hash fragment. Shouldn't change.
195   {
196     content::NotificationRegistrar notification_registrar;
197     CountingNotificationObserver location_bar_updated;
198     notification_registrar.Add(
199         &location_bar_updated,
200         chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
201         content::Source<Profile>(profile));
202
203     NavigateAndCommit(GURL("http://www.google.com#hash"));
204
205     EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
206                 testing::ElementsAre(GetScriptBadge(*extension.get())));
207     EXPECT_EQ(0, location_bar_updated.events);
208   }
209
210   // Refreshing the page should reset the badges.
211   {
212     content::NotificationRegistrar notification_registrar;
213     CountingNotificationObserver location_bar_updated;
214     notification_registrar.Add(
215         &location_bar_updated,
216         chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
217         content::Source<Profile>(profile));
218
219     Reload();
220
221     EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
222                 testing::ElementsAre());
223   }
224 }
225
226 TEST_F(ScriptBadgeControllerTest, GetAttentionMakesBadgeVisible) {
227   content::NotificationRegistrar notification_registrar;
228
229   scoped_refptr<const Extension> extension =
230       ExtensionBuilder()
231       .SetManifest(DictionaryBuilder()
232                    .Set("name", "Extension")
233                    .Set("version", "1.0.0")
234                    .Set("manifest_version", 2)
235                    .Set("permissions", ListBuilder()
236                         .Append("tabs")))
237       .Build();
238   extension_service_->AddExtension(extension.get());
239
240   // Establish a page id.
241   NavigateAndCommit(GURL("http://www.google.com"));
242
243   CountingNotificationObserver initial_badge_display;
244   Profile* profile =
245       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
246   notification_registrar.Add(
247       &initial_badge_display,
248       chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
249       content::Source<Profile>(profile));
250
251   // Initially, no script badges.
252   EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
253               testing::ElementsAre());
254
255   // Getting attention the first time should display the badge.
256   script_badge_controller_->GetAttentionFor(extension->id());
257
258   EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
259               testing::ElementsAre(GetScriptBadge(*extension.get())));
260   EXPECT_THAT(initial_badge_display.events, testing::Gt(0));
261
262   CountingNotificationObserver subsequent_get_attention_call;
263   notification_registrar.Add(
264       &subsequent_get_attention_call,
265       chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
266       content::Source<Profile>(profile));
267
268   // Getting attention a second time should have no effect.
269   script_badge_controller_->GetAttentionFor(extension->id());
270
271   EXPECT_THAT(script_badge_controller_->GetCurrentActions(),
272               testing::ElementsAre(GetScriptBadge(*extension.get())));
273   EXPECT_EQ(0, subsequent_get_attention_call.events);
274 };
275
276 }  // namespace
277 }  // namespace extensions