1 // Copyright (c) 2011 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/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop.h"
8 #include "base/string16.h"
9 #include "base/string_util.h"
10 #include "base/stringprintf.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
14 #include "chrome/browser/chromeos/notifications/balloon_view.h"
15 #include "chrome/browser/chromeos/notifications/notification_panel.h"
16 #include "chrome/browser/chromeos/notifications/system_notification_factory.h"
17 #include "chrome/browser/notifications/notification_test_util.h"
18 #include "chrome/browser/notifications/notification_ui_manager.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/test/in_process_browser_test.h"
21 #include "chrome/test/ui_test_utils.h"
22 #include "content/common/notification_service.h"
23 #include "ui/base/x/x11_util.h"
24
25 namespace {
26
27 // The name of ChromeOS's window manager.
28 const char* kChromeOsWindowManagerName = "chromeos-wm";
29
30 } // namespace
31
32 namespace chromeos {
33
34 class NotificationTest : public InProcessBrowserTest,
35 public NotificationObserver {
36 public:
NotificationTest()37 NotificationTest()
38 : under_chromeos_(false),
39 state_(PanelController::INITIAL),
40 expected_(PanelController::INITIAL) {
41 }
42
HandleWebUIMessage(const ListValue * value)43 void HandleWebUIMessage(const ListValue* value) {
44 MessageLoop::current()->Quit();
45 }
46
47 protected:
SetUp()48 virtual void SetUp() {
49 // Detect if we're running under ChromeOS WindowManager. See
50 // the description for "under_chromeos_" below for why we need this.
51 std::string wm_name;
52 bool wm_name_valid = ui::GetWindowManagerName(&wm_name);
53 // NOTE: On Chrome OS the wm and Chrome are started in parallel. This
54 // means it's possible for us not to be able to get the name of the window
55 // manager. We assume that when this happens we're on Chrome OS.
56 under_chromeos_ = (!wm_name_valid ||
57 wm_name == kChromeOsWindowManagerName);
58 InProcessBrowserTest::SetUp();
59 }
60
GetBalloonCollectionImpl()61 BalloonCollectionImpl* GetBalloonCollectionImpl() {
62 return static_cast<BalloonCollectionImpl*>(
63 g_browser_process->notification_ui_manager()->balloon_collection());
64 }
65
GetNotificationPanel()66 NotificationPanel* GetNotificationPanel() {
67 return static_cast<NotificationPanel*>(
68 GetBalloonCollectionImpl()->notification_ui());
69 }
70
NewMockNotification(const std::string & id)71 Notification NewMockNotification(const std::string& id) {
72 return NewMockNotification(new MockNotificationDelegate(id));
73 }
74
NewMockNotification(NotificationDelegate * delegate)75 Notification NewMockNotification(NotificationDelegate* delegate) {
76 std::string text = delegate->id();
77 return SystemNotificationFactory::Create(
78 GURL(), ASCIIToUTF16(text.c_str()), ASCIIToUTF16(text.c_str()),
79 delegate);
80 }
81
MarkStale(const char * id)82 void MarkStale(const char* id) {
83 GetNotificationPanel()->GetTester()->MarkStale(NewMockNotification(id));
84 }
85
86 // Waits untilt the panel's state becomes the specified state.
87 // Does nothing if it's not running with ChromeOS Window Manager.
WaitForPanelState(NotificationPanelTester * tester,PanelController::State state)88 void WaitForPanelState(NotificationPanelTester* tester,
89 PanelController::State state) {
90 if (under_chromeos_ && state != state_) {
91 expected_ = state;
92 ui_test_utils::RunAllPendingInMessageLoop();
93 }
94 }
95
96 // Busy loop to wait until the view becomes visible in the panel.
WaitForVisible(BalloonViewImpl * view)97 void WaitForVisible(BalloonViewImpl* view) {
98 WaitForResize(view);
99 NotificationPanelTester* tester = GetNotificationPanel()->GetTester();
100 while (!tester->IsVisible(view)) {
101 ui_test_utils::RunAllPendingInMessageLoop();
102 }
103 }
104
105 // Busy loop to wait until the webkit give some size to the notification.
WaitForResize(BalloonViewImpl * view)106 void WaitForResize(BalloonViewImpl* view) {
107 while (view->bounds().IsEmpty()) {
108 ui_test_utils::RunAllPendingInMessageLoop();
109 }
110 }
111
112 // NotificationObserver overrides.
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)113 virtual void Observe(NotificationType type,
114 const NotificationSource& source,
115 const NotificationDetails& details) {
116 ASSERT_TRUE(NotificationType::PANEL_STATE_CHANGED == type);
117 PanelController::State* state =
118 reinterpret_cast<PanelController::State*>(details.map_key());
119 state_ = *state;
120 if (under_chromeos_ && expected_ == state_) {
121 expected_ = PanelController::INITIAL;
122 MessageLoop::current()->Quit();
123 }
124 }
125
126 private:
127 // ChromeOS build of chrome communicates with ChromeOS's
128 // WindowManager, and behaves differently if it runs under a
129 // chromeos window manager. ChromeOS WindowManager sends
130 // EXPANDED/MINIMIED state change message when the panels's state
131 // changed (regardless of who changed it), and to avoid
132 // mis-recognizing such events as user-initiated actions, we need to
133 // wait and eat them before moving to a next step.
134 bool under_chromeos_;
135 PanelController::State state_;
136 PanelController::State expected_;
137 };
138
IN_PROC_BROWSER_TEST_F(NotificationTest,TestBasic)139 IN_PROC_BROWSER_TEST_F(NotificationTest, TestBasic) {
140 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
141 NotificationPanel* panel = GetNotificationPanel();
142 NotificationPanelTester* tester = panel->GetTester();
143
144 // Using system notification as regular notification.
145 collection->Add(NewMockNotification("1"), browser()->profile());
146
147 EXPECT_EQ(1, tester->GetNewNotificationCount());
148 EXPECT_EQ(1, tester->GetNotificationCount());
149 EXPECT_EQ(0, tester->GetStickyNotificationCount());
150 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
151
152 collection->Add(NewMockNotification("2"), browser()->profile());
153
154 EXPECT_EQ(2, tester->GetNewNotificationCount());
155 EXPECT_EQ(2, tester->GetNotificationCount());
156 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
157
158 collection->RemoveById("1");
159 ui_test_utils::RunAllPendingInMessageLoop();
160
161 EXPECT_EQ(1, tester->GetNewNotificationCount());
162 EXPECT_EQ(1, tester->GetNotificationCount());
163 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
164
165 collection->RemoveById("2");
166 ui_test_utils::RunAllPendingInMessageLoop();
167 EXPECT_EQ(0, tester->GetNewNotificationCount());
168 EXPECT_EQ(0, tester->GetNotificationCount());
169 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
170
171 // CLOSE is asynchronous. Run the all pending tasks to finish closing
172 // task.
173 ui_test_utils::RunAllPendingInMessageLoop();
174 }
175
176 // [CLOSED] -add->[STICKY_AND_NEW] -mouse-> [KEEP_SIZE] -remove/add->
177 // [KEEP_SIZE] -remove-> [CLOSED] -add-> [STICKY_AND_NEW] -remove-> [CLOSED]
IN_PROC_BROWSER_TEST_F(NotificationTest,TestKeepSizeState)178 IN_PROC_BROWSER_TEST_F(NotificationTest, TestKeepSizeState) {
179 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
180 NotificationPanel* panel = GetNotificationPanel();
181 NotificationPanelTester* tester = panel->GetTester();
182
183 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
184
185 // Using system notification as regular notification.
186 collection->Add(NewMockNotification("1"), browser()->profile());
187 collection->Add(NewMockNotification("2"), browser()->profile());
188
189 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
190
191 panel->OnMouseMotion(gfx::Point(10, 10));
192 EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
193
194 collection->RemoveById("1");
195 ui_test_utils::RunAllPendingInMessageLoop();
196 EXPECT_EQ(1, tester->GetNewNotificationCount());
197 EXPECT_EQ(1, tester->GetNotificationCount());
198 EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
199
200 collection->Add(NewMockNotification("1"), browser()->profile());
201 ui_test_utils::RunAllPendingInMessageLoop();
202 EXPECT_EQ(2, tester->GetNewNotificationCount());
203 EXPECT_EQ(2, tester->GetNotificationCount());
204 EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
205
206 collection->RemoveById("1");
207 ui_test_utils::RunAllPendingInMessageLoop();
208 EXPECT_EQ(1, tester->GetNewNotificationCount());
209 EXPECT_EQ(1, tester->GetNotificationCount());
210 EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
211
212 collection->RemoveById("2");
213 ui_test_utils::RunAllPendingInMessageLoop();
214 EXPECT_EQ(0, tester->GetNotificationCount());
215 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
216
217 collection->Add(NewMockNotification("3"), browser()->profile());
218 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
219 collection->RemoveById("3");
220
221 ui_test_utils::RunAllPendingInMessageLoop();
222 EXPECT_EQ(0, tester->GetNotificationCount());
223 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
224 }
225
IN_PROC_BROWSER_TEST_F(NotificationTest,TestSystemNotification)226 IN_PROC_BROWSER_TEST_F(NotificationTest, TestSystemNotification) {
227 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
228 NotificationPanel* panel = GetNotificationPanel();
229 scoped_refptr<MockNotificationDelegate> delegate(
230 new MockNotificationDelegate("power"));
231 NotificationPanelTester* tester = panel->GetTester();
232
233 Notification notify = NewMockNotification(delegate.get());
234 collection->AddSystemNotification(notify, browser()->profile(), true, false);
235
236 EXPECT_EQ(1, tester->GetNewNotificationCount());
237 EXPECT_EQ(1, tester->GetStickyNotificationCount());
238
239 Notification update = SystemNotificationFactory::Create(
240 GURL(), ASCIIToUTF16("Title"), ASCIIToUTF16("updated"), delegate.get());
241 collection->UpdateNotification(update);
242
243 EXPECT_EQ(1, tester->GetStickyNotificationCount());
244
245 Notification update_and_show = SystemNotificationFactory::Create(
246 GURL(), ASCIIToUTF16("Title"), ASCIIToUTF16("updated and shown"),
247 delegate.get());
248 collection->UpdateAndShowNotification(update_and_show);
249
250 EXPECT_EQ(1, tester->GetStickyNotificationCount());
251
252 // Dismiss the notification.
253 collection->RemoveById(delegate->id());
254 ui_test_utils::RunAllPendingInMessageLoop();
255
256 EXPECT_EQ(0, tester->GetStickyNotificationCount());
257 EXPECT_EQ(0, tester->GetNewNotificationCount());
258 // TODO(oshima): check content, etc..
259 }
260
261 // [CLOSED] -add,add->[STICKY_AND_NEW] -stale-> [MINIMIZED] -remove->
262 // [MINIMIZED] -remove-> [CLOSED]
IN_PROC_BROWSER_TEST_F(NotificationTest,TestStateTransition1)263 IN_PROC_BROWSER_TEST_F(NotificationTest, TestStateTransition1) {
264 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
265 NotificationPanel* panel = GetNotificationPanel();
266 NotificationPanelTester* tester = panel->GetTester();
267
268 tester->SetStaleTimeout(0);
269 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
270
271 collection->Add(NewMockNotification("1"), browser()->profile());
272 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
273
274 collection->Add(NewMockNotification("2"), browser()->profile());
275 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
276
277 ui_test_utils::RunAllPendingInMessageLoop();
278 EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
279
280 collection->RemoveById("2");
281 ui_test_utils::RunAllPendingInMessageLoop();
282 EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
283
284 collection->RemoveById("1");
285 ui_test_utils::RunAllPendingInMessageLoop();
286 EXPECT_EQ(0, tester->GetNotificationCount());
287 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
288
289 ui_test_utils::RunAllPendingInMessageLoop();
290 }
291
292 // [CLOSED] -add->[STICKY_AND_NEW] -stale-> [MINIMIZED] -add->
293 // [STICKY_AND_NEW] -stale-> [MINIMIZED] -add sys-> [STICKY_NEW]
294 // -stale-> [STICKY_NEW] -remove-> [STICKY_NEW] -remove sys->
295 // [MINIMIZED] -remove-> [CLOSED]
296 //
297 // This test depends on the fact that the panel state change occurs
298 // quicker than stale timeout, thus the stale timeout cannot be set to
299 // 0. This test explicitly controls the stale state instead.
IN_PROC_BROWSER_TEST_F(NotificationTest,TestStateTransition2)300 IN_PROC_BROWSER_TEST_F(NotificationTest, TestStateTransition2) {
301 // Register observer here as the registration does not work in SetUp().
302 NotificationRegistrar registrar;
303 registrar.Add(this,
304 NotificationType::PANEL_STATE_CHANGED,
305 NotificationService::AllSources());
306
307 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
308 NotificationPanel* panel = GetNotificationPanel();
309 NotificationPanelTester* tester = panel->GetTester();
310
311 // See description above.
312 tester->SetStaleTimeout(100000);
313
314 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
315
316 collection->Add(NewMockNotification("1"), browser()->profile());
317 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
318 ui_test_utils::RunAllPendingInMessageLoop();
319
320 // Make the notification stale and make sure panel is minimized state.
321 MarkStale("1");
322 ui_test_utils::RunAllPendingInMessageLoop();
323 EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
324 WaitForPanelState(tester, PanelController::MINIMIZED);
325
326 // Adding new notification expands the panel.
327 collection->Add(NewMockNotification("2"), browser()->profile());
328 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
329 WaitForPanelState(tester, PanelController::EXPANDED);
330
331 // The panel must be minimzied when the new notification becomes stale.
332 MarkStale("2");
333 ui_test_utils::RunAllPendingInMessageLoop();
334 EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
335 WaitForPanelState(tester, PanelController::MINIMIZED);
336
337 // The panel must be expanded again when a new system notification is added.
338 collection->AddSystemNotification(
339 NewMockNotification("3"), browser()->profile(), true, false);
340 EXPECT_EQ(3, tester->GetNotificationCount());
341 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
342 WaitForPanelState(tester, PanelController::EXPANDED);
343
344 // Running all events nor removing non sticky should not change the state.
345 ui_test_utils::RunAllPendingInMessageLoop();
346 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
347
348 collection->RemoveById("1");
349 ui_test_utils::RunAllPendingInMessageLoop();
350 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
351
352 // Removing the system notification should minimize the panel.
353 collection->RemoveById("3");
354 ui_test_utils::RunAllPendingInMessageLoop();
355 EXPECT_EQ(1, tester->GetNotificationCount());
356 EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
357 WaitForPanelState(tester, PanelController::MINIMIZED);
358
359 // Removing the last notification. Should close the panel.
360 collection->RemoveById("2");
361 ui_test_utils::RunAllPendingInMessageLoop();
362 EXPECT_EQ(0, tester->GetNotificationCount());
363 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
364
365 ui_test_utils::RunAllPendingInMessageLoop();
366 }
367
IN_PROC_BROWSER_TEST_F(NotificationTest,TestCleanupOnExit)368 IN_PROC_BROWSER_TEST_F(NotificationTest, TestCleanupOnExit) {
369 NotificationRegistrar registrar;
370 registrar.Add(this,
371 NotificationType::PANEL_STATE_CHANGED,
372 NotificationService::AllSources());
373
374 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
375 NotificationPanel* panel = GetNotificationPanel();
376 NotificationPanelTester* tester = panel->GetTester();
377
378 // Don't become stale.
379 tester->SetStaleTimeout(100000);
380
381 collection->Add(NewMockNotification("1"), browser()->profile());
382 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
383 WaitForPanelState(tester, PanelController::EXPANDED);
384 // end without closing.
385 }
386
IN_PROC_BROWSER_TEST_F(NotificationTest,TestCloseOpen)387 IN_PROC_BROWSER_TEST_F(NotificationTest, TestCloseOpen) {
388 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
389 NotificationPanel* panel = GetNotificationPanel();
390 NotificationPanelTester* tester = panel->GetTester();
391 Profile* profile = browser()->profile();
392
393 collection->Add(NewMockNotification("1"), profile);
394 collection->Add(NewMockNotification("2"), profile);
395 ui_test_utils::RunAllPendingInMessageLoop();
396 WaitForPanelState(tester, PanelController::EXPANDED);
397 PanelController* controller = tester->GetPanelController();
398 // close now
399 panel->ClosePanel();
400 controller->Close();
401 ui_test_utils::RunAllPendingInMessageLoop();
402 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
403 // open again
404 collection->Add(NewMockNotification("3"), profile);
405 WaitForPanelState(tester, PanelController::EXPANDED);
406 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
407
408 // close again
409 controller = tester->GetPanelController();
410 panel->ClosePanel();
411 controller->Close();
412 ui_test_utils::RunAllPendingInMessageLoop();
413 EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
414 }
415
IN_PROC_BROWSER_TEST_F(NotificationTest,TestScrollBalloonToVisible)416 IN_PROC_BROWSER_TEST_F(NotificationTest, TestScrollBalloonToVisible) {
417 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
418 NotificationPanel* panel = GetNotificationPanel();
419 NotificationPanelTester* tester = panel->GetTester();
420 Profile* profile = browser()->profile();
421
422 // Create notifications enough to overflow the panel size.
423 const int create_count = 15;
424
425 // new notification is always visible
426 for (int i = 0; i < create_count; i++) {
427 {
428 SCOPED_TRACE(base::StringPrintf("new normal %d", i));
429 std::string id = base::StringPrintf("n%d", i);
430 collection->Add(NewMockNotification(id), profile);
431 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
432 BalloonViewImpl* view =
433 tester->GetBalloonView(collection, NewMockNotification(id));
434 WaitForVisible(view);
435 }
436 {
437 SCOPED_TRACE(base::StringPrintf("new system %d", i));
438 std::string id = base::StringPrintf("s%d", i);
439 collection->AddSystemNotification(
440 NewMockNotification(id), browser()->profile(), true, false);
441 BalloonViewImpl* view =
442 tester->GetBalloonView(collection, NewMockNotification(id));
443 WaitForVisible(view);
444 }
445 }
446
447 // Update should not change the visibility
448 for (int i = 0; i < create_count; i++) {
449 {
450 SCOPED_TRACE(base::StringPrintf("update n%d", i));
451 Notification notify = NewMockNotification(base::StringPrintf("n%d", i));
452 // The last shown notification is sticky, which makes all non sticky
453 // invisible.
454 EXPECT_TRUE(collection->UpdateNotification(notify));
455 ui_test_utils::RunAllPendingInMessageLoop();
456 BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
457 EXPECT_FALSE(tester->IsVisible(view));
458 }
459 {
460 SCOPED_TRACE(base::StringPrintf("update s%d", i));
461 Notification notify = NewMockNotification(base::StringPrintf("s%d", i));
462 BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
463 bool currently_visible = tester->IsVisible(view);
464 EXPECT_TRUE(collection->UpdateNotification(notify));
465 ui_test_utils::RunAllPendingInMessageLoop();
466 EXPECT_EQ(view, tester->GetBalloonView(collection, notify));
467 EXPECT_EQ(currently_visible, tester->IsVisible(view));
468 }
469 }
470 // UpdateAndShowNotification makes notification visible
471 for (int i = 0; i < create_count; i++) {
472 {
473 SCOPED_TRACE(base::StringPrintf("update and show n%d", i));
474 Notification notify = NewMockNotification(base::StringPrintf("n%d", i));
475 EXPECT_TRUE(collection->UpdateAndShowNotification(notify));
476 ui_test_utils::RunAllPendingInMessageLoop();
477 BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
478 EXPECT_TRUE(tester->IsVisible(view));
479 }
480 {
481 SCOPED_TRACE(base::StringPrintf("update and show s%d", i));
482 Notification notify = NewMockNotification(base::StringPrintf("s%d", i));
483 EXPECT_TRUE(collection->UpdateAndShowNotification(notify));
484 ui_test_utils::RunAllPendingInMessageLoop();
485 BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
486 EXPECT_TRUE(tester->IsVisible(view));
487 }
488 }
489 }
490
IN_PROC_BROWSER_TEST_F(NotificationTest,TestActivateDeactivate)491 IN_PROC_BROWSER_TEST_F(NotificationTest, TestActivateDeactivate) {
492 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
493 NotificationPanel* panel = GetNotificationPanel();
494 NotificationPanelTester* tester = panel->GetTester();
495 Profile* profile = browser()->profile();
496
497 collection->Add(NewMockNotification("1"), profile);
498 collection->AddSystemNotification(
499 NewMockNotification("2"), profile, true, false);
500 ui_test_utils::RunAllPendingInMessageLoop();
501 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
502 BalloonViewImpl* view1 =
503 tester->GetBalloonView(collection, NewMockNotification("1"));
504 BalloonViewImpl* view2 =
505 tester->GetBalloonView(collection, NewMockNotification("2"));
506 // Wait until all renderers get size.
507 WaitForResize(view1);
508 WaitForResize(view2);
509 EXPECT_LT(view2->size().height(), 50) << "view size is bigger than expected";
510
511 panel->OnMouseMotion(gfx::Point(10, 50));
512 EXPECT_TRUE(tester->IsActive(view1));
513 EXPECT_FALSE(tester->IsActive(view2));
514
515 panel->OnMouseMotion(gfx::Point(10, 10));
516 EXPECT_FALSE(tester->IsActive(view1));
517 EXPECT_TRUE(tester->IsActive(view2));
518
519 panel->OnMouseMotion(gfx::Point(500, 500));
520 EXPECT_FALSE(tester->IsActive(view1));
521 EXPECT_FALSE(tester->IsActive(view2));
522 }
523
IN_PROC_BROWSER_TEST_F(NotificationTest,TestCloseDismissAllNonSticky)524 IN_PROC_BROWSER_TEST_F(NotificationTest, TestCloseDismissAllNonSticky) {
525 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
526 NotificationPanel* panel = GetNotificationPanel();
527 NotificationPanelTester* tester = panel->GetTester();
528 Profile* profile = browser()->profile();
529
530 collection->Add(NewMockNotification("1"), profile);
531 collection->AddSystemNotification(
532 NewMockNotification("2"), profile, true, false);
533 collection->Add(NewMockNotification("3"), profile);
534
535 ui_test_utils::RunAllPendingInMessageLoop();
536 EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
537 EXPECT_EQ(3, tester->GetNotificationCount());
538 EXPECT_EQ(1, tester->GetStickyNotificationCount());
539
540 // Hide
541 panel->Hide();
542 ui_test_utils::RunAllPendingInMessageLoop();
543 EXPECT_EQ(1, tester->GetNotificationCount());
544 EXPECT_EQ(1, tester->GetStickyNotificationCount());
545 }
546
IN_PROC_BROWSER_TEST_F(NotificationTest,TestAddWebUIMessageCallback)547 IN_PROC_BROWSER_TEST_F(NotificationTest, TestAddWebUIMessageCallback) {
548 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
549 Profile* profile = browser()->profile();
550
551 collection->AddSystemNotification(
552 NewMockNotification("1"), profile, false, false);
553
554 EXPECT_TRUE(collection->AddWebUIMessageCallback(
555 NewMockNotification("1"),
556 "test",
557 NewCallback(
558 static_cast<NotificationTest*>(this),
559 &NotificationTest::HandleWebUIMessage)));
560
561 // Adding callback for the same message twice should fail.
562 EXPECT_FALSE(collection->AddWebUIMessageCallback(
563 NewMockNotification("1"),
564 "test",
565 NewCallback(
566 static_cast<NotificationTest*>(this),
567 &NotificationTest::HandleWebUIMessage)));
568
569 // Adding callback to nonexistent notification should fail.
570 EXPECT_FALSE(collection->AddWebUIMessageCallback(
571 NewMockNotification("2"),
572 "test1",
573 NewCallback(
574 static_cast<NotificationTest*>(this),
575 &NotificationTest::HandleWebUIMessage)));
576 }
577
IN_PROC_BROWSER_TEST_F(NotificationTest,TestWebUIMessageCallback)578 IN_PROC_BROWSER_TEST_F(NotificationTest, TestWebUIMessageCallback) {
579 BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
580 Profile* profile = browser()->profile();
581 // A notification that sends 'test' WebUI message back to chrome.
582 const GURL content_url(
583 "data:text/html;charset=utf-8,"
584 "<html><script>function send() { chrome.send('test', ['']); }</script>"
585 "<body onload='send()'></body></html>");
586 collection->AddSystemNotification(
587 Notification(GURL(), content_url, string16(), string16(),
588 new MockNotificationDelegate("1")),
589 profile,
590 false,
591 false);
592 EXPECT_TRUE(collection->AddWebUIMessageCallback(
593 NewMockNotification("1"),
594 "test",
595 NewCallback(
596 static_cast<NotificationTest*>(this),
597 &NotificationTest::HandleWebUIMessage)));
598 MessageLoop::current()->Run();
599 }
600
601 } // namespace chromeos
602