OLD | NEW |
| (Empty) |
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 "chrome/browser/notifications/desktop_notifications_unittest.h" | |
6 | |
7 #include "base/prefs/testing_pref_service.h" | |
8 #include "base/strings/string_util.h" | |
9 #include "base/strings/utf_string_conversions.h" | |
10 #include "chrome/browser/notifications/balloon_notification_ui_manager.h" | |
11 #include "chrome/browser/notifications/fake_balloon_view.h" | |
12 #include "chrome/browser/prefs/browser_prefs.h" | |
13 #include "chrome/common/pref_names.h" | |
14 #include "chrome/test/base/chrome_unit_test_suite.h" | |
15 #include "chrome/test/base/testing_browser_process.h" | |
16 #include "chrome/test/base/testing_profile.h" | |
17 #include "chrome/test/base/testing_profile_manager.h" | |
18 #include "content/public/common/show_desktop_notification_params.h" | |
19 #include "ui/base/ime/input_method_initializer.h" | |
20 #include "ui/gl/gl_surface.h" | |
21 #include "ui/message_center/message_center.h" | |
22 | |
23 #if defined(USE_ASH) | |
24 #include "ash/shell.h" | |
25 #include "ash/test/test_shell_delegate.h" | |
26 #include "ui/aura/env.h" | |
27 #include "ui/aura/window_event_dispatcher.h" | |
28 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | |
29 #include "ui/compositor/test/context_factories_for_test.h" | |
30 #endif | |
31 | |
32 #if defined(USE_AURA) | |
33 #include "ui/wm/core/wm_state.h" | |
34 #endif | |
35 | |
36 | |
37 using content::BrowserThread; | |
38 | |
39 // static | |
40 const int MockBalloonCollection::kMockBalloonSpace = 5; | |
41 | |
42 // static | |
43 std::string DesktopNotificationsTest::log_output_; | |
44 | |
45 MockBalloonCollection::MockBalloonCollection() {} | |
46 | |
47 MockBalloonCollection::~MockBalloonCollection() {} | |
48 | |
49 void MockBalloonCollection::Add(const Notification& notification, | |
50 Profile* profile) { | |
51 // Swap in a logging proxy for the purpose of logging calls that | |
52 // would be made into javascript, then pass this down to the | |
53 // balloon collection. | |
54 Notification test_notification( | |
55 notification.origin_url(), | |
56 notification.content_url(), | |
57 notification.display_source(), | |
58 notification.replace_id(), | |
59 new LoggingNotificationProxy(notification.notification_id())); | |
60 BalloonCollectionImpl::Add(test_notification, profile); | |
61 } | |
62 | |
63 bool MockBalloonCollection::HasSpace() const { | |
64 return count() < kMockBalloonSpace; | |
65 } | |
66 | |
67 Balloon* MockBalloonCollection::MakeBalloon(const Notification& notification, | |
68 Profile* profile) { | |
69 // Start with a normal balloon but mock out the view. | |
70 Balloon* balloon = BalloonCollectionImpl::MakeBalloon(notification, profile); | |
71 balloon->set_view(new FakeBalloonView(balloon)); | |
72 balloons_.push_back(balloon); | |
73 return balloon; | |
74 } | |
75 | |
76 void MockBalloonCollection::OnBalloonClosed(Balloon* source) { | |
77 std::deque<Balloon*>::iterator it; | |
78 for (it = balloons_.begin(); it != balloons_.end(); ++it) { | |
79 if (*it == source) { | |
80 balloons_.erase(it); | |
81 BalloonCollectionImpl::OnBalloonClosed(source); | |
82 break; | |
83 } | |
84 } | |
85 } | |
86 | |
87 const BalloonCollection::Balloons& MockBalloonCollection::GetActiveBalloons() { | |
88 return balloons_; | |
89 } | |
90 | |
91 int MockBalloonCollection::UppermostVerticalPosition() { | |
92 int min = 0; | |
93 std::deque<Balloon*>::iterator iter; | |
94 for (iter = balloons_.begin(); iter != balloons_.end(); ++iter) { | |
95 int pos = (*iter)->GetPosition().y(); | |
96 if (iter == balloons_.begin() || pos < min) | |
97 min = pos; | |
98 } | |
99 return min; | |
100 } | |
101 | |
102 DesktopNotificationsTest::DesktopNotificationsTest() | |
103 : ui_thread_(BrowserThread::UI, &message_loop_), | |
104 balloon_collection_(NULL) { | |
105 } | |
106 | |
107 DesktopNotificationsTest::~DesktopNotificationsTest() { | |
108 } | |
109 | |
110 void DesktopNotificationsTest::SetUp() { | |
111 ChromeUnitTestSuite::InitializeProviders(); | |
112 ChromeUnitTestSuite::InitializeResourceBundle(); | |
113 ui::InitializeInputMethodForTesting(); | |
114 #if defined(USE_AURA) | |
115 wm_state_.reset(new wm::WMState); | |
116 #endif | |
117 #if defined(USE_ASH) | |
118 ui::ScopedAnimationDurationScaleMode normal_duration_mode( | |
119 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); | |
120 // The message center is notmally initialized on |g_browser_process| which | |
121 // is not created for these tests. | |
122 message_center::MessageCenter::Initialize(); | |
123 // The ContextFactory must exist before any Compositors are created. | |
124 bool enable_pixel_output = false; | |
125 ui::InitializeContextFactoryForTests(enable_pixel_output); | |
126 // MockBalloonCollection retrieves information about the screen on creation. | |
127 // So it is necessary to make sure the desktop gets created first. | |
128 ash::Shell::CreateInstance(new ash::test::TestShellDelegate); | |
129 #endif | |
130 chrome::RegisterLocalState(local_state_.registry()); | |
131 profile_.reset(new TestingProfile()); | |
132 ui_manager_.reset(new BalloonNotificationUIManager(&local_state_)); | |
133 balloon_collection_ = new MockBalloonCollection(); | |
134 ui_manager_->SetBalloonCollection(balloon_collection_); | |
135 service_.reset(new DesktopNotificationService(profile(), ui_manager_.get())); | |
136 log_output_.clear(); | |
137 } | |
138 | |
139 void DesktopNotificationsTest::TearDown() { | |
140 service_.reset(NULL); | |
141 ui_manager_.reset(NULL); | |
142 profile_.reset(NULL); | |
143 #if defined(USE_ASH) | |
144 ash::Shell::DeleteInstance(); | |
145 // The message center is notmally shutdown on |g_browser_process| which | |
146 // is not created for these tests. | |
147 message_center::MessageCenter::Shutdown(); | |
148 aura::Env::DeleteInstance(); | |
149 ui::TerminateContextFactoryForTests(); | |
150 #endif | |
151 #if defined(USE_AURA) | |
152 wm_state_.reset(); | |
153 #endif | |
154 ui::ShutdownInputMethodForTesting(); | |
155 } | |
156 | |
157 content::ShowDesktopNotificationHostMsgParams | |
158 DesktopNotificationsTest::StandardTestNotification() { | |
159 content::ShowDesktopNotificationHostMsgParams params; | |
160 params.notification_id = 0; | |
161 params.origin = GURL("http://www.google.com"); | |
162 params.icon_url = GURL("/icon.png"); | |
163 params.title = base::ASCIIToUTF16("Title"); | |
164 params.body = base::ASCIIToUTF16("Text"); | |
165 params.direction = blink::WebTextDirectionDefault; | |
166 return params; | |
167 } | |
168 | |
169 TEST_F(DesktopNotificationsTest, TestShow) { | |
170 content::ShowDesktopNotificationHostMsgParams params = | |
171 StandardTestNotification(); | |
172 params.notification_id = 1; | |
173 | |
174 EXPECT_TRUE(service_->ShowDesktopNotification( | |
175 params, 0, 0, DesktopNotificationService::PageNotification)); | |
176 base::MessageLoopForUI::current()->RunUntilIdle(); | |
177 EXPECT_EQ(1, balloon_collection_->count()); | |
178 | |
179 content::ShowDesktopNotificationHostMsgParams params2 = | |
180 StandardTestNotification(); | |
181 params2.notification_id = 2; | |
182 params2.origin = GURL("http://www.google.com"); | |
183 params2.body = base::ASCIIToUTF16("Text"); | |
184 | |
185 EXPECT_TRUE(service_->ShowDesktopNotification( | |
186 params2, 0, 0, DesktopNotificationService::PageNotification)); | |
187 base::MessageLoopForUI::current()->RunUntilIdle(); | |
188 EXPECT_EQ(2, balloon_collection_->count()); | |
189 | |
190 EXPECT_EQ("notification displayed\n" | |
191 "notification displayed\n", | |
192 log_output_); | |
193 } | |
194 | |
195 TEST_F(DesktopNotificationsTest, TestClose) { | |
196 content::ShowDesktopNotificationHostMsgParams params = | |
197 StandardTestNotification(); | |
198 params.notification_id = 1; | |
199 | |
200 // Request a notification; should open a balloon. | |
201 EXPECT_TRUE(service_->ShowDesktopNotification( | |
202 params, 0, 0, DesktopNotificationService::PageNotification)); | |
203 base::MessageLoopForUI::current()->RunUntilIdle(); | |
204 EXPECT_EQ(1, balloon_collection_->count()); | |
205 | |
206 // Close all the open balloons. | |
207 while (balloon_collection_->count() > 0) { | |
208 (*(balloon_collection_->GetActiveBalloons().begin()))->OnClose(true); | |
209 } | |
210 | |
211 EXPECT_EQ("notification displayed\n" | |
212 "notification closed by user\n", | |
213 log_output_); | |
214 } | |
215 | |
216 TEST_F(DesktopNotificationsTest, TestCancel) { | |
217 int process_id = 0; | |
218 int route_id = 0; | |
219 int notification_id = 1; | |
220 | |
221 content::ShowDesktopNotificationHostMsgParams params = | |
222 StandardTestNotification(); | |
223 params.notification_id = notification_id; | |
224 | |
225 // Request a notification; should open a balloon. | |
226 EXPECT_TRUE(service_->ShowDesktopNotification( | |
227 params, process_id, route_id, | |
228 DesktopNotificationService::PageNotification)); | |
229 base::MessageLoopForUI::current()->RunUntilIdle(); | |
230 EXPECT_EQ(1, balloon_collection_->count()); | |
231 | |
232 // Cancel the same notification | |
233 service_->CancelDesktopNotification(process_id, | |
234 route_id, | |
235 notification_id); | |
236 base::MessageLoopForUI::current()->RunUntilIdle(); | |
237 // Verify that the balloon collection is now empty. | |
238 EXPECT_EQ(0, balloon_collection_->count()); | |
239 | |
240 EXPECT_EQ("notification displayed\n" | |
241 "notification closed by script\n", | |
242 log_output_); | |
243 } | |
244 | |
245 #if defined(OS_WIN) || defined(TOOLKIT_VIEWS) | |
246 TEST_F(DesktopNotificationsTest, TestPositioning) { | |
247 content::ShowDesktopNotificationHostMsgParams params = | |
248 StandardTestNotification(); | |
249 std::string expected_log; | |
250 // Create some toasts. After each but the first, make sure there | |
251 // is a minimum separation between the toasts. | |
252 int last_top = 0; | |
253 for (int id = 0; id <= 3; ++id) { | |
254 params.notification_id = id; | |
255 EXPECT_TRUE(service_->ShowDesktopNotification( | |
256 params, 0, 0, DesktopNotificationService::PageNotification)); | |
257 expected_log.append("notification displayed\n"); | |
258 int top = balloon_collection_->UppermostVerticalPosition(); | |
259 if (id > 0) | |
260 EXPECT_LE(top, last_top - balloon_collection_->MinHeight()); | |
261 last_top = top; | |
262 } | |
263 | |
264 EXPECT_EQ(expected_log, log_output_); | |
265 } | |
266 | |
267 TEST_F(DesktopNotificationsTest, TestVariableSize) { | |
268 content::ShowDesktopNotificationHostMsgParams params; | |
269 params.origin = GURL("http://long.google.com"); | |
270 params.icon_url = GURL("/icon.png"); | |
271 params.title = base::ASCIIToUTF16("Really Really Really Really Really Really " | |
272 "Really Really Really Really Really Really " | |
273 "Really Really Really Really Really Really " | |
274 "Really Long Title"), | |
275 params.body = base::ASCIIToUTF16("Text"); | |
276 params.notification_id = 0; | |
277 | |
278 std::string expected_log; | |
279 // Create some toasts. After each but the first, make sure there | |
280 // is a minimum separation between the toasts. | |
281 EXPECT_TRUE(service_->ShowDesktopNotification( | |
282 params, 0, 0, DesktopNotificationService::PageNotification)); | |
283 expected_log.append("notification displayed\n"); | |
284 | |
285 params.origin = GURL("http://short.google.com"); | |
286 params.title = base::ASCIIToUTF16("Short title"); | |
287 params.notification_id = 1; | |
288 EXPECT_TRUE(service_->ShowDesktopNotification( | |
289 params, 0, 0, DesktopNotificationService::PageNotification)); | |
290 expected_log.append("notification displayed\n"); | |
291 | |
292 std::deque<Balloon*>& balloons = balloon_collection_->balloons(); | |
293 std::deque<Balloon*>::iterator iter; | |
294 for (iter = balloons.begin(); iter != balloons.end(); ++iter) { | |
295 if ((*iter)->notification().origin_url().host() == "long.google.com") { | |
296 EXPECT_GE((*iter)->GetViewSize().height(), | |
297 balloon_collection_->MinHeight()); | |
298 EXPECT_LE((*iter)->GetViewSize().height(), | |
299 balloon_collection_->MaxHeight()); | |
300 } else { | |
301 EXPECT_EQ((*iter)->GetViewSize().height(), | |
302 balloon_collection_->MinHeight()); | |
303 } | |
304 } | |
305 EXPECT_EQ(expected_log, log_output_); | |
306 } | |
307 #endif | |
308 | |
309 TEST_F(DesktopNotificationsTest, TestCancelByProfile) { | |
310 int process_id = 0; | |
311 int route_id = 0; | |
312 | |
313 TestingBrowserProcess* browser_process = | |
314 TestingBrowserProcess::GetGlobal(); | |
315 TestingProfileManager profile_manager(browser_process); | |
316 ASSERT_TRUE(profile_manager.SetUp()); | |
317 | |
318 TestingProfile* second_profile = | |
319 profile_manager.CreateTestingProfile("SecondTestingProfile"); | |
320 | |
321 scoped_ptr<DesktopNotificationService> second_service( | |
322 new DesktopNotificationService(second_profile, ui_manager_.get())); | |
323 | |
324 // Request lots of identical notifications. | |
325 content::ShowDesktopNotificationHostMsgParams params = | |
326 StandardTestNotification(); | |
327 params.notification_id = 1; | |
328 // Notice that the first one is the only one that doesn't use | |
329 // the second profile. | |
330 EXPECT_TRUE(service_->ShowDesktopNotification( | |
331 params, process_id, route_id, | |
332 DesktopNotificationService::PageNotification)); | |
333 | |
334 // |kLotsOfToasts| must be large enough to trigger a resize of the underlying | |
335 // std::deque while we're clearing it. | |
336 const int kLotsOfToasts = 20; | |
337 for (int id = 2; id <= kLotsOfToasts; ++id) { | |
338 params.notification_id = id; | |
339 EXPECT_TRUE(second_service->ShowDesktopNotification( | |
340 params, process_id, route_id, | |
341 DesktopNotificationService::PageNotification)); | |
342 } | |
343 base::MessageLoopForUI::current()->RunUntilIdle(); | |
344 | |
345 ui_manager_->CancelAllByProfile(second_profile); | |
346 | |
347 // Verify that the balloon collection only contains the single | |
348 // notification from the first profile. | |
349 EXPECT_EQ(1, balloon_collection_->count()); | |
350 } | |
351 | |
352 TEST_F(DesktopNotificationsTest, TestCancelBySourceOrigin) { | |
353 int process_id = 0; | |
354 int route_id = 0; | |
355 | |
356 // Request lots of identical notifications. | |
357 content::ShowDesktopNotificationHostMsgParams params = | |
358 StandardTestNotification(); | |
359 | |
360 // After the first, all the notifications are from attacker.com. | |
361 content::ShowDesktopNotificationHostMsgParams odd_params = | |
362 StandardTestNotification(); | |
363 odd_params.origin = GURL("attacker.com"); | |
364 | |
365 // Show the only non-attacker.com notification. | |
366 params.notification_id = 1; | |
367 EXPECT_TRUE(service_->ShowDesktopNotification( | |
368 params, process_id, route_id, | |
369 DesktopNotificationService::PageNotification)); | |
370 | |
371 // |kLotsOfToasts| must be large enough to trigger a resize of the underlying | |
372 // std::deque while we're clearing it. | |
373 const int kLotsOfToasts = 20; | |
374 for (int id = 2; id <= kLotsOfToasts; ++id) { | |
375 odd_params.notification_id = id; | |
376 EXPECT_TRUE(service_->ShowDesktopNotification( | |
377 odd_params, process_id, route_id, | |
378 DesktopNotificationService::PageNotification)); | |
379 } | |
380 base::MessageLoopForUI::current()->RunUntilIdle(); | |
381 | |
382 ui_manager_->CancelAllBySourceOrigin(odd_params.origin); | |
383 | |
384 // Verify that the balloon collection only contains the single | |
385 // notification which is not from the canceled origin. | |
386 EXPECT_EQ(1, balloon_collection_->count()); | |
387 } | |
388 | |
389 TEST_F(DesktopNotificationsTest, TestQueueing) { | |
390 int process_id = 0; | |
391 int route_id = 0; | |
392 | |
393 // Request lots of identical notifications. | |
394 content::ShowDesktopNotificationHostMsgParams params = | |
395 StandardTestNotification(); | |
396 const int kLotsOfToasts = 20; | |
397 for (int id = 1; id <= kLotsOfToasts; ++id) { | |
398 params.notification_id = id; | |
399 EXPECT_TRUE(service_->ShowDesktopNotification( | |
400 params, process_id, route_id, | |
401 DesktopNotificationService::PageNotification)); | |
402 } | |
403 base::MessageLoopForUI::current()->RunUntilIdle(); | |
404 | |
405 // Build up an expected log of what should be happening. | |
406 std::string expected_log; | |
407 for (int i = 0; i < balloon_collection_->max_balloon_count(); ++i) { | |
408 expected_log.append("notification displayed\n"); | |
409 } | |
410 | |
411 // The max number that our balloon collection can hold should be | |
412 // shown. | |
413 EXPECT_EQ(balloon_collection_->max_balloon_count(), | |
414 balloon_collection_->count()); | |
415 EXPECT_EQ(expected_log, log_output_); | |
416 | |
417 // Cancel the notifications from the start; the balloon space should | |
418 // remain full. | |
419 { | |
420 int id; | |
421 for (id = 1; | |
422 id <= kLotsOfToasts - balloon_collection_->max_balloon_count(); | |
423 ++id) { | |
424 service_->CancelDesktopNotification(process_id, route_id, id); | |
425 base::MessageLoopForUI::current()->RunUntilIdle(); | |
426 expected_log.append("notification closed by script\n"); | |
427 expected_log.append("notification displayed\n"); | |
428 EXPECT_EQ(balloon_collection_->max_balloon_count(), | |
429 balloon_collection_->count()); | |
430 EXPECT_EQ(expected_log, log_output_); | |
431 } | |
432 | |
433 // Now cancel the rest. It should empty the balloon space. | |
434 for (; id <= kLotsOfToasts; ++id) { | |
435 service_->CancelDesktopNotification(process_id, route_id, id); | |
436 expected_log.append("notification closed by script\n"); | |
437 base::MessageLoopForUI::current()->RunUntilIdle(); | |
438 EXPECT_EQ(expected_log, log_output_); | |
439 } | |
440 } | |
441 | |
442 // Verify that the balloon collection is now empty. | |
443 EXPECT_EQ(0, balloon_collection_->count()); | |
444 } | |
445 | |
446 TEST_F(DesktopNotificationsTest, TestEarlyDestruction) { | |
447 // Create some toasts and then prematurely delete the notification service, | |
448 // just to make sure nothing crashes/leaks. | |
449 content::ShowDesktopNotificationHostMsgParams params = | |
450 StandardTestNotification(); | |
451 for (int id = 0; id <= 3; ++id) { | |
452 params.notification_id = id; | |
453 EXPECT_TRUE(service_->ShowDesktopNotification( | |
454 params, 0, 0, DesktopNotificationService::PageNotification)); | |
455 } | |
456 service_.reset(NULL); | |
457 } | |
458 | |
459 TEST_F(DesktopNotificationsTest, TestUserInputEscaping) { | |
460 // Create a test script with some HTML; assert that it doesn't get into the | |
461 // data:// URL that's produced for the balloon. | |
462 content::ShowDesktopNotificationHostMsgParams params = | |
463 StandardTestNotification(); | |
464 params.title = base::ASCIIToUTF16("<script>window.alert('uh oh');</script>"); | |
465 params.body = base::ASCIIToUTF16("<i>this text is in italics</i>"); | |
466 params.notification_id = 1; | |
467 EXPECT_TRUE(service_->ShowDesktopNotification( | |
468 params, 0, 0, DesktopNotificationService::PageNotification)); | |
469 | |
470 base::MessageLoopForUI::current()->RunUntilIdle(); | |
471 EXPECT_EQ(1, balloon_collection_->count()); | |
472 Balloon* balloon = (*balloon_collection_->balloons().begin()); | |
473 GURL data_url = balloon->notification().content_url(); | |
474 EXPECT_EQ(std::string::npos, data_url.spec().find("<script>")); | |
475 EXPECT_EQ(std::string::npos, data_url.spec().find("<i>")); | |
476 // URL-encoded versions of tags should also not be found. | |
477 EXPECT_EQ(std::string::npos, data_url.spec().find("%3cscript%3e")); | |
478 EXPECT_EQ(std::string::npos, data_url.spec().find("%3ci%3e")); | |
479 } | |
480 | |
481 TEST_F(DesktopNotificationsTest, TestBoundingBox) { | |
482 // Create some notifications. | |
483 content::ShowDesktopNotificationHostMsgParams params = | |
484 StandardTestNotification(); | |
485 for (int id = 0; id <= 3; ++id) { | |
486 params.notification_id = id; | |
487 EXPECT_TRUE(service_->ShowDesktopNotification( | |
488 params, 0, 0, DesktopNotificationService::PageNotification)); | |
489 } | |
490 | |
491 gfx::Rect box = balloon_collection_->GetBalloonsBoundingBox(); | |
492 | |
493 // Try this for all positions. | |
494 BalloonCollection::PositionPreference pref; | |
495 for (pref = BalloonCollection::UPPER_RIGHT; | |
496 pref <= BalloonCollection::LOWER_LEFT; | |
497 pref = static_cast<BalloonCollection::PositionPreference>(pref + 1)) { | |
498 // Make sure each balloon's 4 corners are inside the box. | |
499 std::deque<Balloon*>& balloons = balloon_collection_->balloons(); | |
500 std::deque<Balloon*>::iterator iter; | |
501 for (iter = balloons.begin(); iter != balloons.end(); ++iter) { | |
502 int min_x = (*iter)->GetPosition().x(); | |
503 int max_x = min_x + (*iter)->GetViewSize().width() - 1; | |
504 int min_y = (*iter)->GetPosition().y(); | |
505 int max_y = min_y + (*iter)->GetViewSize().height() - 1; | |
506 | |
507 EXPECT_TRUE(box.Contains(gfx::Point(min_x, min_y))); | |
508 EXPECT_TRUE(box.Contains(gfx::Point(min_x, max_y))); | |
509 EXPECT_TRUE(box.Contains(gfx::Point(max_x, min_y))); | |
510 EXPECT_TRUE(box.Contains(gfx::Point(max_x, max_y))); | |
511 } | |
512 } | |
513 } | |
514 | |
515 TEST_F(DesktopNotificationsTest, TestPositionPreference) { | |
516 // Set position preference to lower right. | |
517 local_state_.SetInteger(prefs::kDesktopNotificationPosition, | |
518 BalloonCollection::LOWER_RIGHT); | |
519 | |
520 // Create some notifications. | |
521 content::ShowDesktopNotificationHostMsgParams params = | |
522 StandardTestNotification(); | |
523 for (int id = 0; id <= 3; ++id) { | |
524 params.notification_id = id; | |
525 EXPECT_TRUE(service_->ShowDesktopNotification( | |
526 params, 0, 0, DesktopNotificationService::PageNotification)); | |
527 } | |
528 | |
529 std::deque<Balloon*>& balloons = balloon_collection_->balloons(); | |
530 std::deque<Balloon*>::iterator iter; | |
531 | |
532 // Check that they decrease in y-position (for MAC, with reversed | |
533 // coordinates, they should increase). | |
534 int last_y = -1; | |
535 int last_x = -1; | |
536 | |
537 for (iter = balloons.begin(); iter != balloons.end(); ++iter) { | |
538 int current_x = (*iter)->GetPosition().x(); | |
539 int current_y = (*iter)->GetPosition().y(); | |
540 if (last_x > 0) | |
541 EXPECT_EQ(last_x, current_x); | |
542 | |
543 if (last_y > 0) { | |
544 #if defined(OS_MACOSX) | |
545 EXPECT_GT(current_y, last_y); | |
546 #else | |
547 EXPECT_LT(current_y, last_y); | |
548 #endif | |
549 } | |
550 | |
551 last_x = current_x; | |
552 last_y = current_y; | |
553 } | |
554 | |
555 // Now change the position to upper right. This should cause an immediate | |
556 // repositioning, and we check for the reverse ordering. | |
557 local_state_.SetInteger(prefs::kDesktopNotificationPosition, | |
558 BalloonCollection::UPPER_RIGHT); | |
559 last_x = -1; | |
560 last_y = -1; | |
561 | |
562 for (iter = balloons.begin(); iter != balloons.end(); ++iter) { | |
563 int current_x = (*iter)->GetPosition().x(); | |
564 int current_y = (*iter)->GetPosition().y(); | |
565 | |
566 if (last_x > 0) | |
567 EXPECT_EQ(last_x, current_x); | |
568 | |
569 if (last_y > 0) { | |
570 #if defined(OS_MACOSX) | |
571 EXPECT_LT(current_y, last_y); | |
572 #else | |
573 EXPECT_GT(current_y, last_y); | |
574 #endif | |
575 } | |
576 | |
577 last_x = current_x; | |
578 last_y = current_y; | |
579 } | |
580 | |
581 // Now change the position to upper left. Confirm that the X value for the | |
582 // balloons gets smaller. | |
583 local_state_.SetInteger(prefs::kDesktopNotificationPosition, | |
584 BalloonCollection::UPPER_LEFT); | |
585 | |
586 int current_x = (*balloons.begin())->GetPosition().x(); | |
587 EXPECT_LT(current_x, last_x); | |
588 } | |
OLD | NEW |