OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
11 #include "chrome/browser/extensions/extension_service.h" | 11 #include "chrome/browser/extensions/extension_service.h" |
12 #include "chrome/browser/extensions/script_badge_controller.h" | 12 #include "chrome/browser/extensions/script_badge_controller.h" |
13 #include "chrome/browser/extensions/tab_helper.h" | 13 #include "chrome/browser/extensions/tab_helper.h" |
14 #include "chrome/browser/extensions/test_extension_system.h" | 14 #include "chrome/browser/extensions/test_extension_system.h" |
15 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 15 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
16 #include "chrome/browser/ui/tab_contents/test_tab_contents.h" | 16 #include "chrome/browser/ui/tab_contents/test_tab_contents.h" |
17 #include "chrome/common/chrome_notification_types.h" | 17 #include "chrome/common/chrome_notification_types.h" |
18 #include "chrome/common/extensions/extension.h" | 18 #include "chrome/common/extensions/extension.h" |
19 #include "chrome/common/extensions/extension_builder.h" | 19 #include "chrome/common/extensions/extension_builder.h" |
20 #include "chrome/common/extensions/value_builder.h" | 20 #include "chrome/common/extensions/value_builder.h" |
21 #include "chrome/test/base/testing_profile.h" | 21 #include "chrome/test/base/testing_profile.h" |
22 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
23 #include "content/public/browser/navigation_entry.h" | 23 #include "content/public/browser/navigation_entry.h" |
24 #include "content/public/browser/notification_registrar.h" | 24 #include "content/public/browser/notification_registrar.h" |
25 #include "content/public/browser/notification_source.h" | 25 #include "content/public/browser/notification_source.h" |
26 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
27 #include "content/public/test/test_browser_thread.h" | 27 #include "content/public/test/test_browser_thread.h" |
28 #include "content/public/test/test_notification_tracker.h" | |
28 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
29 | 30 |
30 using content::BrowserThread; | 31 using content::BrowserThread; |
31 | 32 |
32 namespace extensions { | 33 namespace extensions { |
33 namespace { | 34 namespace { |
34 | 35 |
35 class ScriptBadgeControllerTest : public TabContentsTestHarness { | 36 class ScriptBadgeControllerTest : public TabContentsTestHarness { |
36 public: | 37 public: |
37 ScriptBadgeControllerTest() | 38 ScriptBadgeControllerTest() |
(...skipping 15 matching lines...) Expand all Loading... | |
53 CommandLine command_line(CommandLine::NO_PROGRAM); | 54 CommandLine command_line(CommandLine::NO_PROGRAM); |
54 extension_service_ = extension_system->CreateExtensionService( | 55 extension_service_ = extension_system->CreateExtensionService( |
55 &command_line, FilePath(), false); | 56 &command_line, FilePath(), false); |
56 | 57 |
57 script_executor_.reset(new ScriptExecutor(web_contents())); | 58 script_executor_.reset(new ScriptExecutor(web_contents())); |
58 script_badge_controller_.reset(new ScriptBadgeController( | 59 script_badge_controller_.reset(new ScriptBadgeController( |
59 tab_contents(), script_executor_.get())); | 60 tab_contents(), script_executor_.get())); |
60 } | 61 } |
61 | 62 |
62 protected: | 63 protected: |
64 // Gets the current page ID, or -1 if there isn't one yet. | |
65 int32 GetPageID() { | |
66 content::NavigationEntry* active_entry = | |
67 tab_contents()->web_contents()->GetController().GetActiveEntry(); | |
68 return active_entry ? active_entry->GetPageID() : -1; | |
69 } | |
70 | |
63 // Creates a test extension and adds it to |extension_service_|. | 71 // Creates a test extension and adds it to |extension_service_|. |
64 scoped_refptr<const Extension> AddTestExtension() { | 72 scoped_refptr<const Extension> AddTestExtension() { |
73 return AddTestExtension(""); | |
74 } | |
75 | |
76 // Creates a test extension with a specific ID and adds it to | |
77 // |extension_service_|. | |
78 scoped_refptr<const Extension> AddTestExtension(const std::string& id) { | |
65 scoped_refptr<const Extension> extension = ExtensionBuilder() | 79 scoped_refptr<const Extension> extension = ExtensionBuilder() |
80 .SetID(id) | |
66 .SetManifest(DictionaryBuilder() | 81 .SetManifest(DictionaryBuilder() |
67 .Set("name", "Extension with page action") | 82 .Set("name", "Test extension") |
68 .Set("version", "1.0.0") | 83 .Set("version", "1.0.0") |
69 .Set("manifest_version", 2) | 84 .Set("manifest_version", 2) |
70 .Set("permissions", ListBuilder() | 85 .Set("permissions", ListBuilder() |
71 .Append("tabs")) | 86 .Append("tabs")) |
72 .Set("page_action", DictionaryBuilder() | 87 .Set("page_action", DictionaryBuilder() |
73 .Set("default_title", "Hello"))) | 88 .Set("default_title", "Hello"))) |
74 .Build(); | 89 .Build(); |
75 extension_service_->AddExtension(extension); | 90 extension_service_->AddExtension(extension); |
76 return extension; | 91 return extension; |
77 } | 92 } |
78 | 93 |
79 ExtensionService* extension_service_; | 94 ExtensionService* extension_service_; |
80 scoped_ptr<ScriptExecutor> script_executor_; | 95 scoped_ptr<ScriptExecutor> script_executor_; |
81 scoped_ptr<ScriptBadgeController> script_badge_controller_; | 96 scoped_ptr<ScriptBadgeController> script_badge_controller_; |
82 | 97 |
83 private: | 98 private: |
84 content::TestBrowserThread ui_thread_; | 99 content::TestBrowserThread ui_thread_; |
85 content::TestBrowserThread file_thread_; | 100 content::TestBrowserThread file_thread_; |
86 }; | 101 }; |
87 | 102 |
88 struct CountingNotificationObserver : public content::NotificationObserver { | 103 TEST_F(ScriptBadgeControllerTest, ExecutionMakesBadgeVisible) { |
89 CountingNotificationObserver() : events(0) {} | 104 content::TestNotificationTracker notification_tracker; |
105 notification_tracker.ListenFor( | |
Jeffrey Yasskin
2012/07/25 22:22:39
Hey cool, that's better than my class. :)
not at google - send to devlin
2012/07/26 08:52:46
:) a lucky find. I was looking for where yours was
| |
106 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
107 content::Source<Profile>(tab_contents()->profile())); | |
90 | 108 |
91 virtual void Observe(int type, | 109 scoped_refptr<const Extension> extension = AddTestExtension(); |
92 const content::NotificationSource& source, | |
93 const content::NotificationDetails& details) OVERRIDE { | |
94 events++; | |
95 } | |
96 | |
97 int events; | |
98 }; | |
99 | |
100 TEST_F(ScriptBadgeControllerTest, ExecutionMakesBadgeVisible) { | |
101 content::NotificationRegistrar notification_registrar; | |
102 | 110 |
103 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 111 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
104 testing::ElementsAre()); | 112 testing::ElementsAre()); |
105 | 113 |
106 scoped_refptr<const Extension> extension = AddTestExtension(); | |
107 | |
108 // Establish a page id. | 114 // Establish a page id. |
109 NavigateAndCommit(GURL("http://www.google.com")); | 115 NavigateAndCommit(GURL("http://www.google.com")); |
110 | 116 |
111 CountingNotificationObserver location_bar_updated; | |
112 notification_registrar.Add( | |
113 &location_bar_updated, | |
114 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
115 content::Source<Profile>(tab_contents()->profile())); | |
116 | |
117 // Initially, no script badges. | 117 // Initially, no script badges. |
118 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 118 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
119 testing::ElementsAre()); | 119 testing::ElementsAre()); |
120 | 120 |
121 ListValue val; | 121 // Extension calls executeScript(), should be a script badge for that. |
122 script_badge_controller_->OnExecuteScriptFinished( | 122 { |
123 extension->id(), true, | 123 ListValue val; |
124 tab_contents()->web_contents()->GetController().GetActiveEntry()-> | 124 script_badge_controller_->OnExecuteScriptFinished(extension->id(), |
125 GetPageID(), | 125 true, |
126 "", | 126 GetPageID(), |
127 val); | 127 "", |
128 val); | |
129 } | |
130 | |
128 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 131 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
129 testing::ElementsAre(extension->script_badge())); | 132 testing::ElementsAre(extension->script_badge())); |
130 EXPECT_THAT(location_bar_updated.events, testing::Gt(0)); | 133 EXPECT_TRUE(notification_tracker.Check1AndReset( |
134 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); | |
135 | |
136 | |
137 // Should clear on navigate. | |
138 NavigateAndCommit(GURL("http://www.chromium.org")); | |
139 | |
140 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
141 testing::ElementsAre()); | |
142 EXPECT_EQ(0u, notification_tracker.size()); | |
143 | |
144 // Extension calls executeScript() on a page that the browser doesn't | |
Jeffrey Yasskin
2012/07/25 22:22:39
This seems redundant with the ContentScripts test.
| |
145 // know about yet. | |
146 { | |
147 ListValue val; | |
148 script_badge_controller_->OnExecuteScriptFinished(extension->id(), | |
149 true, | |
150 GetPageID() + 1, | |
151 "", | |
152 val); | |
153 } | |
154 | |
155 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
156 testing::ElementsAre()); | |
157 EXPECT_EQ(0u, notification_tracker.size()); | |
158 | |
159 // On navigating to that page, should run script badges then. | |
160 NavigateAndCommit(GURL("http://www.google.com")); | |
161 | |
162 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
163 testing::ElementsAre(extension->script_badge())); | |
164 EXPECT_TRUE(notification_tracker.Check1AndReset( | |
165 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); | |
131 }; | 166 }; |
132 | 167 |
133 TEST_F(ScriptBadgeControllerTest, FragmentNavigation) { | 168 TEST_F(ScriptBadgeControllerTest, FragmentNavigation) { |
169 content::TestNotificationTracker notification_tracker; | |
170 notification_tracker.ListenFor( | |
171 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
172 content::Source<Profile>(tab_contents()->profile())); | |
173 | |
134 scoped_refptr<const Extension> extension = AddTestExtension(); | 174 scoped_refptr<const Extension> extension = AddTestExtension(); |
135 | 175 |
136 // Establish a page id. | 176 // Establish a page id. |
137 NavigateAndCommit(GURL("http://www.google.com")); | 177 NavigateAndCommit(GURL("http://www.google.com")); |
138 | 178 |
139 // Run script. Should be a notification and a script badge. | 179 // Run script. Should be a notification and a script badge. |
140 { | 180 { |
141 content::NotificationRegistrar notification_registrar; | |
142 CountingNotificationObserver location_bar_updated; | |
143 notification_registrar.Add( | |
144 &location_bar_updated, | |
145 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
146 content::Source<Profile>(tab_contents()->profile())); | |
147 | |
148 ListValue val; | 181 ListValue val; |
149 script_badge_controller_->OnExecuteScriptFinished( | 182 script_badge_controller_->OnExecuteScriptFinished(extension->id(), |
150 extension->id(), true, | 183 true, |
151 tab_contents()->web_contents()->GetController().GetActiveEntry()-> | 184 GetPageID(), |
152 GetPageID(), | 185 "", |
153 "", | 186 val); |
154 val); | |
155 | 187 |
156 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 188 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
157 testing::ElementsAre(extension->script_badge())); | 189 testing::ElementsAre(extension->script_badge())); |
158 EXPECT_EQ(1, location_bar_updated.events); | 190 EXPECT_TRUE(notification_tracker.Check1AndReset( |
191 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); | |
159 } | 192 } |
160 | 193 |
161 // Navigate to a hash fragment. Shouldn't change. | 194 // Navigate to a hash fragment. Shouldn't change. |
162 { | 195 { |
163 content::NotificationRegistrar notification_registrar; | |
164 CountingNotificationObserver location_bar_updated; | |
165 notification_registrar.Add( | |
166 &location_bar_updated, | |
167 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
168 content::Source<Profile>(tab_contents()->profile())); | |
169 | |
170 NavigateAndCommit(GURL("http://www.google.com#hash")); | 196 NavigateAndCommit(GURL("http://www.google.com#hash")); |
171 | 197 |
172 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 198 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
173 testing::ElementsAre(extension->script_badge())); | 199 testing::ElementsAre(extension->script_badge())); |
174 EXPECT_EQ(0, location_bar_updated.events); | 200 EXPECT_EQ(0u, notification_tracker.size()); |
175 } | 201 } |
176 | 202 |
177 // Refreshing the page should reset the badges. | 203 // Refreshing the page should reset the badges. |
178 { | 204 { |
179 content::NotificationRegistrar notification_registrar; | |
180 CountingNotificationObserver location_bar_updated; | |
181 notification_registrar.Add( | |
182 &location_bar_updated, | |
183 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
184 content::Source<Profile>(tab_contents()->profile())); | |
185 | |
186 Reload(); | 205 Reload(); |
187 | 206 |
188 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 207 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
189 testing::ElementsAre()); | 208 testing::ElementsAre()); |
190 EXPECT_EQ(0, location_bar_updated.events); | 209 EXPECT_EQ(0u, notification_tracker.size()); |
191 } | 210 } |
192 } | 211 } |
193 | 212 |
194 TEST_F(ScriptBadgeControllerTest, GetAttentionMakesBadgeVisible) { | 213 TEST_F(ScriptBadgeControllerTest, GetAttentionMakesBadgeVisible) { |
195 content::NotificationRegistrar notification_registrar; | 214 content::TestNotificationTracker notification_tracker; |
215 notification_tracker.ListenFor( | |
216 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
217 content::Source<Profile>(tab_contents()->profile())); | |
196 | 218 |
197 scoped_refptr<const Extension> extension = | 219 scoped_refptr<const Extension> extension = AddTestExtension(); |
198 ExtensionBuilder() | |
199 .SetManifest(DictionaryBuilder() | |
200 .Set("name", "Extension") | |
Jeffrey Yasskin
2012/07/25 22:22:39
I'm not a fan of moving all of the extension creat
| |
201 .Set("version", "1.0.0") | |
202 .Set("manifest_version", 2) | |
203 .Set("permissions", ListBuilder() | |
204 .Append("tabs"))) | |
205 .Build(); | |
206 extension_service_->AddExtension(extension); | |
207 | 220 |
208 // Establish a page id. | 221 // Establish a page id. |
209 NavigateAndCommit(GURL("http://www.google.com")); | 222 NavigateAndCommit(GURL("http://www.google.com")); |
210 | 223 |
211 CountingNotificationObserver initial_badge_display; | |
212 notification_registrar.Add( | |
213 &initial_badge_display, | |
214 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
215 content::Source<Profile>(tab_contents()->profile())); | |
216 | |
217 // Initially, no script badges. | 224 // Initially, no script badges. |
218 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 225 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
219 testing::ElementsAre()); | 226 testing::ElementsAre()); |
220 | 227 |
221 // Getting attention the first time should display the badge. | 228 // Getting attention the first time should display the badge. |
222 script_badge_controller_->GetAttentionFor(extension->id()); | 229 script_badge_controller_->GetAttentionFor(extension->id()); |
223 | 230 |
224 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 231 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
225 testing::ElementsAre(extension->script_badge())); | 232 testing::ElementsAre(extension->script_badge())); |
226 EXPECT_THAT(initial_badge_display.events, testing::Gt(0)); | 233 EXPECT_TRUE(notification_tracker.Check1AndReset( |
227 | 234 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); |
228 CountingNotificationObserver subsequent_get_attention_call; | |
229 notification_registrar.Add( | |
230 &subsequent_get_attention_call, | |
231 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
232 content::Source<Profile>(tab_contents()->profile())); | |
233 | 235 |
234 // Getting attention a second time should have no effect. | 236 // Getting attention a second time should have no effect. |
235 script_badge_controller_->GetAttentionFor(extension->id()); | 237 script_badge_controller_->GetAttentionFor(extension->id()); |
236 | 238 |
237 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | 239 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), |
238 testing::ElementsAre(extension->script_badge())); | 240 testing::ElementsAre(extension->script_badge())); |
239 EXPECT_EQ(0, subsequent_get_attention_call.events); | 241 EXPECT_EQ(0u, notification_tracker.size()); |
240 }; | 242 }; |
241 | 243 |
244 TEST_F(ScriptBadgeControllerTest, ContentScripts) { | |
245 content::TestNotificationTracker notification_tracker; | |
246 notification_tracker.ListenFor( | |
247 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, | |
248 content::Source<Profile>(tab_contents()->profile())); | |
249 | |
250 scoped_refptr<const Extension> extension_a = | |
251 AddTestExtension("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); | |
252 scoped_refptr<const Extension> extension_b = | |
253 AddTestExtension("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); | |
254 scoped_refptr<const Extension> extension_c = | |
255 AddTestExtension("cccccccccccccccccccccccccccccccc"); | |
256 | |
257 // Sometimes notifications for content scripts appear earlier than the page | |
258 // load has happened in the browser. | |
259 { | |
260 std::set<std::string> ids; | |
261 ids.insert(extension_a->id()); | |
262 | |
263 script_badge_controller_->OnContentScriptsExecuting(ids, 0); | |
264 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
265 testing::ElementsAre()); | |
266 EXPECT_EQ(0u, notification_tracker.size()); | |
267 } | |
268 | |
269 // Establish a page id. | |
270 NavigateAndCommit(GURL("http://www.google.com")); | |
271 | |
272 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
273 testing::ElementsAre(extension_a->script_badge())); | |
274 EXPECT_TRUE(notification_tracker.Check1AndReset( | |
275 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); | |
276 | |
277 // Next page should clear the content-script script badge. | |
278 NavigateAndCommit(GURL("http://www.chromium.org")); | |
279 | |
280 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
281 testing::ElementsAre()); | |
282 | |
283 // Executing a content script on the current page should work. | |
284 { | |
285 std::set<std::string> ids; | |
286 ids.insert(extension_a->id()); | |
287 ids.insert(extension_b->id()); | |
288 script_badge_controller_->OnContentScriptsExecuting(ids, GetPageID()); | |
289 | |
290 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
291 testing::ElementsAre(extension_a->script_badge(), | |
292 extension_b->script_badge())); | |
293 EXPECT_TRUE(notification_tracker.Check1AndReset( | |
294 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); | |
295 } | |
296 | |
297 // Executing a content script on the next page should show up when that | |
298 // page is navigated to. | |
299 { | |
300 std::set<std::string> ids; | |
301 ids.insert(extension_c->id()); | |
302 script_badge_controller_->OnContentScriptsExecuting(ids, GetPageID() + 1); | |
303 | |
304 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
305 testing::ElementsAre(extension_a->script_badge(), | |
306 extension_b->script_badge())); | |
307 EXPECT_EQ(0u, notification_tracker.size()); | |
308 } | |
309 | |
310 NavigateAndCommit(GURL("http://www.google.com")); | |
311 EXPECT_THAT(script_badge_controller_->GetCurrentActions(), | |
312 testing::ElementsAre(extension_c->script_badge())); | |
313 EXPECT_TRUE(notification_tracker.Check1AndReset( | |
314 chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED)); | |
315 } | |
316 | |
242 } // namespace | 317 } // namespace |
243 } // namespace extensions | 318 } // namespace extensions |
OLD | NEW |