| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 <gmock/gmock.h> | 5 #include "chrome/browser/chromeos/extensions/file_browser_notifications.h" |
| 6 |
| 6 #include <gtest/gtest.h> | 7 #include <gtest/gtest.h> |
| 7 #include <string> | 8 #include <string> |
| 8 | 9 |
| 9 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| 10 #include "chrome/browser/ui/browser.h" | 11 #include "chrome/browser/ui/browser.h" |
| 11 #include "chrome/browser/chromeos/extensions/file_browser_notifications.h" | |
| 12 #include "chrome/browser/chromeos/notifications/balloon_collection_impl.h" | |
| 13 #include "chrome/browser/notifications/balloon.h" | 12 #include "chrome/browser/notifications/balloon.h" |
| 13 #include "chrome/browser/notifications/balloon_collection.h" |
| 14 #include "chrome/browser/notifications/notification.h" | 14 #include "chrome/browser/notifications/notification.h" |
| 15 #include "chrome/browser/notifications/notification_ui_manager.h" | 15 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 16 #include "chrome/test/base/in_process_browser_test.h" | 16 #include "chrome/test/base/in_process_browser_test.h" |
| 17 #include "chrome/test/base/ui_test_utils.h" | 17 #include "chrome/test/base/ui_test_utils.h" |
| 18 | 18 |
| 19 using ::testing::_; | |
| 20 using ::testing::InSequence; | |
| 21 using ::testing::Return; | |
| 22 using ::testing::StrEq; | |
| 23 | |
| 24 namespace chromeos { | 19 namespace chromeos { |
| 25 | 20 |
| 26 class MockNotificationUI : public BalloonCollectionImpl::NotificationUI { | |
| 27 public: | |
| 28 virtual ~MockNotificationUI() {} | |
| 29 | |
| 30 MOCK_METHOD1(Add, void(Balloon* balloon)); | |
| 31 MOCK_METHOD1(Update, bool(Balloon* balloon)); | |
| 32 MOCK_METHOD1(Remove, void(Balloon* balloon)); | |
| 33 MOCK_METHOD1(Show, void(Balloon* balloon)); | |
| 34 | |
| 35 virtual void ResizeNotification(Balloon* balloon, const gfx::Size& size) | |
| 36 OVERRIDE { | |
| 37 } | |
| 38 virtual void SetActiveView(BalloonViewImpl* view) OVERRIDE {} | |
| 39 }; | |
| 40 | |
| 41 class MockFileBrowserNotifications : public FileBrowserNotifications { | 21 class MockFileBrowserNotifications : public FileBrowserNotifications { |
| 42 public: | 22 public: |
| 43 explicit MockFileBrowserNotifications(Profile* profile) | 23 explicit MockFileBrowserNotifications(Profile* profile) |
| 44 : FileBrowserNotifications(profile) { | 24 : FileBrowserNotifications(profile) { |
| 45 } | 25 } |
| 46 virtual ~MockFileBrowserNotifications() {} | 26 virtual ~MockFileBrowserNotifications() {} |
| 47 | 27 |
| 28 // Records the notification so we can force it to show later. |
| 48 virtual void PostDelayedShowNotificationTask( | 29 virtual void PostDelayedShowNotificationTask( |
| 49 const std::string& notification_id, | 30 const std::string& notification_id, |
| 50 NotificationType type, | 31 NotificationType type, |
| 51 const string16& message, | 32 const string16& message, |
| 52 size_t delay_ms) { | 33 size_t delay_ms) OVERRIDE { |
| 53 show_callback_data_.id = notification_id; | 34 show_callback_data_.id = notification_id; |
| 54 show_callback_data_.type = type; | 35 show_callback_data_.type = type; |
| 55 show_callback_data_.message = message; | 36 show_callback_data_.message = message; |
| 56 } | 37 } |
| 57 | 38 |
| 39 // Records the notification so we can force it to hide later. |
| 58 virtual void PostDelayedHideNotificationTask(NotificationType type, | 40 virtual void PostDelayedHideNotificationTask(NotificationType type, |
| 59 const std::string path, | 41 const std::string path, |
| 60 size_t delay_ms) { | 42 size_t delay_ms) OVERRIDE { |
| 61 hide_callback_data_.type = type; | 43 hide_callback_data_.type = type; |
| 62 hide_callback_data_.path = path; | 44 hide_callback_data_.path = path; |
| 63 } | 45 } |
| 64 | 46 |
| 65 void ExecuteShow() { | 47 void ExecuteShow() { |
| 66 FileBrowserNotifications::ShowNotificationDelayedTask( | 48 FileBrowserNotifications::ShowNotificationDelayedTask( |
| 67 show_callback_data_.id, show_callback_data_.type, | 49 show_callback_data_.id, show_callback_data_.type, |
| 68 show_callback_data_.message, AsWeakPtr()); | 50 show_callback_data_.message, AsWeakPtr()); |
| 69 } | 51 } |
| 70 | 52 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 85 struct HideCallbackData { | 67 struct HideCallbackData { |
| 86 NotificationType type; | 68 NotificationType type; |
| 87 std::string path; | 69 std::string path; |
| 88 }; | 70 }; |
| 89 | 71 |
| 90 HideCallbackData hide_callback_data_; | 72 HideCallbackData hide_callback_data_; |
| 91 }; | 73 }; |
| 92 | 74 |
| 93 class FileBrowserNotificationsTest : public InProcessBrowserTest { | 75 class FileBrowserNotificationsTest : public InProcessBrowserTest { |
| 94 public: | 76 public: |
| 95 FileBrowserNotificationsTest() {} | 77 FileBrowserNotificationsTest() : collection_(NULL) {} |
| 96 | 78 |
| 97 protected: | 79 protected: |
| 98 void ChangeNotificationUIMock() { | 80 // This must be initialized late in test startup. |
| 99 // collection will take ownership of the mock. | 81 void InitNotifications() { |
| 100 mock_notification_ui_ = new MockNotificationUI(); | 82 Profile* profile = browser()->profile(); |
| 101 collection_->set_notification_ui(mock_notification_ui_); | 83 notifications_.reset(new MockFileBrowserNotifications(profile)); |
| 102 } | 84 collection_ = |
| 103 | 85 g_browser_process->notification_ui_manager()->balloon_collection(); |
| 104 void InitNotificationUIMock() { | |
| 105 collection_ = static_cast<BalloonCollectionImpl*>( | |
| 106 g_browser_process->notification_ui_manager()->balloon_collection()); | |
| 107 ChangeNotificationUIMock(); | |
| 108 } | 86 } |
| 109 | 87 |
| 110 bool FindNotification(const std::string& id) { | 88 bool FindNotification(const std::string& id) { |
| 111 return notifications_->notifications().find(id) != | 89 return notifications_->notifications().find(id) != |
| 112 notifications_->notifications().end(); | 90 notifications_->notifications().end(); |
| 113 } | 91 } |
| 114 | 92 |
| 115 BalloonCollectionImpl* collection_; | 93 bool FindBalloon(const std::string& id) { |
| 116 MockNotificationUI* mock_notification_ui_; | 94 const std::deque<Balloon*>& balloons = collection_->GetActiveBalloons(); |
| 117 scoped_ptr<FileBrowserNotifications> notifications_; | 95 for (std::deque<Balloon*>::const_iterator it = balloons.begin(); |
| 96 it != balloons.end(); |
| 97 ++it) { |
| 98 Balloon* balloon = *it; |
| 99 if (balloon->notification().notification_id() == id) |
| 100 return true; |
| 101 } |
| 102 return false; |
| 103 } |
| 104 |
| 105 BalloonCollection* collection_; |
| 106 scoped_ptr<MockFileBrowserNotifications> notifications_; |
| 118 }; | 107 }; |
| 119 | 108 |
| 120 MATCHER_P(BalloonNotificationMatcher, expected_id, "") { | 109 #if defined(USE_AURA) |
| 121 return arg->notification().notification_id() == expected_id; | 110 // TODO(jamescook): Fails on linux_chromeos_aura because we haven't implemented |
| 122 } | 111 // chromeos::SystemNotification yet. http://crbug.com/104471 |
| 112 #define MAYBE_TestBasic FAILS_TestBasic |
| 113 #else |
| 114 #define MAYBE_TestBasic TestBasic |
| 115 #endif |
| 116 IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, MAYBE_TestBasic) { |
| 117 InitNotifications(); |
| 118 // We start with no balloons. |
| 119 EXPECT_EQ(0u, collection_->GetActiveBalloons().size()); |
| 123 | 120 |
| 124 IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, TestBasic) { | 121 // Showing a notification both updates our data and shows a balloon. |
| 125 InitNotificationUIMock(); | |
| 126 notifications_.reset(new MockFileBrowserNotifications(browser()->profile())); | |
| 127 | |
| 128 EXPECT_CALL(*mock_notification_ui_, | |
| 129 Add(BalloonNotificationMatcher("Dpath"))); | |
| 130 notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path"); | 122 notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path"); |
| 131 | |
| 132 EXPECT_CALL(*mock_notification_ui_, | |
| 133 Update(BalloonNotificationMatcher("Dpath"))) | |
| 134 .WillOnce(Return(true)); | |
| 135 notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path"); | |
| 136 | |
| 137 EXPECT_EQ(1u, notifications_->notifications().size()); | 123 EXPECT_EQ(1u, notifications_->notifications().size()); |
| 138 EXPECT_TRUE(FindNotification("Dpath")); | 124 EXPECT_TRUE(FindNotification("Dpath")); |
| 125 EXPECT_EQ(1u, collection_->GetActiveBalloons().size()); |
| 126 EXPECT_TRUE(FindBalloon("Dpath")); |
| 139 | 127 |
| 140 EXPECT_CALL(*mock_notification_ui_, | 128 // Updating the same notification maintains the same balloon. |
| 141 Add(BalloonNotificationMatcher("DFpath"))); | 129 notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path"); |
| 130 EXPECT_EQ(1u, notifications_->notifications().size()); |
| 131 EXPECT_TRUE(FindNotification("Dpath")); |
| 132 EXPECT_EQ(1u, collection_->GetActiveBalloons().size()); |
| 133 EXPECT_TRUE(FindBalloon("Dpath")); |
| 134 |
| 135 // A new notification adds a new balloon. |
| 142 notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL, | 136 notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL, |
| 143 "path"); | 137 "path"); |
| 144 EXPECT_EQ(2u, notifications_->notifications().size()); | 138 EXPECT_EQ(2u, notifications_->notifications().size()); |
| 145 EXPECT_TRUE(FindNotification("DFpath")); | 139 EXPECT_TRUE(FindNotification("DFpath")); |
| 140 EXPECT_TRUE(FindNotification("Dpath")); |
| 141 EXPECT_EQ(2u, collection_->GetActiveBalloons().size()); |
| 142 EXPECT_TRUE(FindBalloon("DFpath")); |
| 143 EXPECT_TRUE(FindBalloon("Dpath")); |
| 146 | 144 |
| 147 EXPECT_CALL(*mock_notification_ui_, | 145 // Hiding a notification removes it from our data. |
| 148 Remove(BalloonNotificationMatcher("DFpath"))); | |
| 149 notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL, | 146 notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL, |
| 150 "path"); | 147 "path"); |
| 151 | |
| 152 EXPECT_EQ(1u, notifications_->notifications().size()); | 148 EXPECT_EQ(1u, notifications_->notifications().size()); |
| 153 EXPECT_FALSE(FindNotification("DFpath")); | 149 EXPECT_FALSE(FindNotification("DFpath")); |
| 150 EXPECT_TRUE(FindNotification("Dpath")); |
| 154 | 151 |
| 152 // Balloons don't go away until we run the message loop. |
| 153 EXPECT_EQ(2u, collection_->GetActiveBalloons().size()); |
| 154 EXPECT_TRUE(FindBalloon("DFpath")); |
| 155 EXPECT_TRUE(FindBalloon("Dpath")); |
| 156 |
| 157 // Running the message loop allows the balloon to disappear. |
| 155 ui_test_utils::RunAllPendingInMessageLoop(); | 158 ui_test_utils::RunAllPendingInMessageLoop(); |
| 156 | 159 EXPECT_EQ(1u, collection_->GetActiveBalloons().size()); |
| 157 ChangeNotificationUIMock(); | 160 EXPECT_FALSE(FindBalloon("DFpath")); |
| 158 | 161 EXPECT_TRUE(FindBalloon("Dpath")); |
| 159 EXPECT_CALL(*mock_notification_ui_, Remove(_)) | |
| 160 .Times(1); | |
| 161 }; | 162 }; |
| 162 | 163 |
| 163 IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, ShowDelayedTest) { | 164 #if defined(USE_AURA) |
| 164 InitNotificationUIMock(); | 165 // TODO(jamescook): Fails on linux_chromeos_aura because we haven't implemented |
| 165 MockFileBrowserNotifications* mocked_notifications = | 166 // chromeos::SystemNotification yet. http://crbug.com/104471 |
| 166 new MockFileBrowserNotifications(browser()->profile()); | 167 #define MAYBE_ShowDelayedTest FAILS_ShowDelayedTest |
| 167 notifications_.reset(mocked_notifications); | 168 #else |
| 168 | 169 // TODO(jamescook): This test is flaky on linux_chromeos, occasionally causing |
| 169 EXPECT_CALL(*mock_notification_ui_, | 170 // this assertion failure inside Gtk: |
| 170 Add(BalloonNotificationMatcher("Dpath"))); | 171 // "murrine_style_draw_box: assertion `height >= -1' failed" |
| 172 // There may be an underlying bug in the ChromeOS notification code. |
| 173 // I'm not marking it as FLAKY because this doesn't happen on the bots. |
| 174 #define MAYBE_ShowDelayedTest ShowDelayedTest |
| 175 #endif |
| 176 IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, MAYBE_ShowDelayedTest) { |
| 177 InitNotifications(); |
| 178 // Adding a delayed notification does not show a balloon. |
| 171 notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE, | 179 notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE, |
| 172 "path", 3000); | 180 "path", 3000); |
| 173 mocked_notifications->ExecuteShow(); | 181 EXPECT_EQ(0u, collection_->GetActiveBalloons().size()); |
| 174 | 182 |
| 175 EXPECT_CALL(*mock_notification_ui_, | 183 // Forcing the show to happen makes the balloon appear. |
| 176 Add(BalloonNotificationMatcher("DFpath"))); | 184 notifications_->ExecuteShow(); |
| 185 ui_test_utils::RunAllPendingInMessageLoop(); |
| 186 EXPECT_EQ(1u, collection_->GetActiveBalloons().size()); |
| 187 EXPECT_TRUE(FindBalloon("Dpath")); |
| 188 |
| 189 // Showing a notification both immediately and delayed results in one |
| 190 // additional balloon. |
| 177 notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL, | 191 notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL, |
| 178 "path", 3000); | 192 "path", 3000); |
| 179 notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL, | 193 notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL, |
| 180 "path"); | 194 "path"); |
| 195 EXPECT_EQ(2u, collection_->GetActiveBalloons().size()); |
| 196 EXPECT_TRUE(FindBalloon("Dpath")); |
| 197 EXPECT_TRUE(FindBalloon("DFpath")); |
| 181 | 198 |
| 182 ChangeNotificationUIMock(); | 199 // When the delayed notification arrives, it's an update, so we still only |
| 183 EXPECT_CALL(*mock_notification_ui_, | 200 // have two balloons. |
| 184 Update(BalloonNotificationMatcher("DFpath"))); | 201 notifications_->ExecuteShow(); |
| 185 mocked_notifications->ExecuteShow(); | 202 ui_test_utils::RunAllPendingInMessageLoop(); |
| 203 EXPECT_EQ(2u, collection_->GetActiveBalloons().size()); |
| 204 EXPECT_TRUE(FindBalloon("Dpath")); |
| 205 EXPECT_TRUE(FindBalloon("DFpath")); |
| 186 | 206 |
| 187 EXPECT_CALL(*mock_notification_ui_, | 207 // If we schedule a show for later, then hide before it becomes visible, |
| 188 Remove(BalloonNotificationMatcher("Fpath"))) | 208 // the balloon should not be added. |
| 189 .Times(0); | |
| 190 EXPECT_CALL(*mock_notification_ui_, | |
| 191 Add(BalloonNotificationMatcher("Fpath"))) | |
| 192 .Times(0); | |
| 193 notifications_->ShowNotificationDelayed( | 209 notifications_->ShowNotificationDelayed( |
| 194 FileBrowserNotifications::FORMAT_FAIL, "path", 3000); | 210 FileBrowserNotifications::FORMAT_FAIL, "path", 3000); |
| 195 notifications_->HideNotification(FileBrowserNotifications::FORMAT_FAIL, | 211 notifications_->HideNotification(FileBrowserNotifications::FORMAT_FAIL, |
| 196 "path"); | 212 "path"); |
| 213 EXPECT_EQ(2u, collection_->GetActiveBalloons().size()); |
| 214 EXPECT_TRUE(FindBalloon("Dpath")); |
| 215 EXPECT_TRUE(FindBalloon("DFpath")); |
| 216 EXPECT_FALSE(FindBalloon("Fpath")); |
| 217 |
| 218 // Even when we try to force the show, nothing appears, because the balloon |
| 219 // was explicitly hidden. |
| 220 notifications_->ExecuteShow(); |
| 197 ui_test_utils::RunAllPendingInMessageLoop(); | 221 ui_test_utils::RunAllPendingInMessageLoop(); |
| 198 | 222 EXPECT_EQ(2u, collection_->GetActiveBalloons().size()); |
| 199 mocked_notifications->ExecuteShow(); | 223 EXPECT_TRUE(FindBalloon("Dpath")); |
| 200 | 224 EXPECT_TRUE(FindBalloon("DFpath")); |
| 201 ChangeNotificationUIMock(); | 225 EXPECT_FALSE(FindBalloon("Fpath")); |
| 202 EXPECT_CALL(*mock_notification_ui_, Remove(_)) | |
| 203 .Times(2); | |
| 204 | |
| 205 ui_test_utils::RunAllPendingInMessageLoop(); | |
| 206 } | 226 } |
| 207 | 227 |
| 208 IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, HideDelayedTest) { | 228 #if defined(USE_AURA) |
| 209 InitNotificationUIMock(); | 229 // TODO(jamescook): Fails on linux_chromeos_aura because we haven't implemented |
| 210 MockFileBrowserNotifications* mocked_notifications = | 230 // chromeos::SystemNotification yet. http://crbug.com/104471 |
| 211 new MockFileBrowserNotifications(browser()->profile()); | 231 #define MAYBE_HideDelayedTest FAILS_HideDelayedTest |
| 212 notifications_.reset(mocked_notifications); | 232 #else |
| 213 | 233 #define MAYBE_HideDelayedTest HideDelayedTest |
| 214 EXPECT_CALL(*mock_notification_ui_, | 234 #endif |
| 215 Add(BalloonNotificationMatcher("Dpath"))); | 235 IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, MAYBE_HideDelayedTest) { |
| 236 InitNotifications(); |
| 237 // Showing now, and scheduling a hide for later, results in one balloon. |
| 216 notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path"); | 238 notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path"); |
| 217 | |
| 218 notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE, | 239 notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE, |
| 219 "path", 3000); | 240 "path", 3000); |
| 220 ChangeNotificationUIMock(); | 241 EXPECT_EQ(1u, collection_->GetActiveBalloons().size()); |
| 221 EXPECT_CALL(*mock_notification_ui_, | 242 EXPECT_TRUE(FindBalloon("Dpath")); |
| 222 Remove(BalloonNotificationMatcher("Dpath"))); | |
| 223 mocked_notifications->ExecuteHide(); | |
| 224 | 243 |
| 244 // Forcing the hide removes the balloon. |
| 245 notifications_->ExecuteHide(); |
| 225 ui_test_utils::RunAllPendingInMessageLoop(); | 246 ui_test_utils::RunAllPendingInMessageLoop(); |
| 247 EXPECT_EQ(0u, collection_->GetActiveBalloons().size()); |
| 226 | 248 |
| 227 EXPECT_CALL(*mock_notification_ui_, | 249 // Immediate show then hide results in no balloons. |
| 228 Add(BalloonNotificationMatcher("DFpath"))); | |
| 229 EXPECT_CALL(*mock_notification_ui_, | |
| 230 Remove(BalloonNotificationMatcher("DFpath"))); | |
| 231 notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL, | 250 notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL, |
| 232 "path"); | 251 "path"); |
| 233 notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL, | 252 notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL, |
| 234 "path"); | 253 "path"); |
| 235 ui_test_utils::RunAllPendingInMessageLoop(); | 254 ui_test_utils::RunAllPendingInMessageLoop(); |
| 255 EXPECT_EQ(0u, collection_->GetActiveBalloons().size()); |
| 236 | 256 |
| 257 // Delayed hide for a notification that doesn't exist does nothing. |
| 237 notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL, | 258 notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL, |
| 238 "path", 3000); | 259 "path", 3000); |
| 239 ChangeNotificationUIMock(); | 260 notifications_->ExecuteHide(); |
| 240 EXPECT_CALL(*mock_notification_ui_, | |
| 241 Remove(BalloonNotificationMatcher("DFpath"))) | |
| 242 .Times(0); | |
| 243 mocked_notifications->ExecuteHide(); | |
| 244 | |
| 245 ui_test_utils::RunAllPendingInMessageLoop(); | 261 ui_test_utils::RunAllPendingInMessageLoop(); |
| 262 EXPECT_EQ(0u, collection_->GetActiveBalloons().size()); |
| 246 } | 263 } |
| 247 | 264 |
| 248 } // namespace chromeos. | 265 } // namespace chromeos. |
| 249 | |
| OLD | NEW |