| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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/strings/string_split.h" |
| 6 #include "chrome/browser/chromeos/hats/hats_notification_controller.h" |
| 7 #include "chrome/browser/notifications/message_center_notification_manager.h" |
| 8 #include "chrome/browser/notifications/notification.h" |
| 9 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 10 #include "chrome/common/pref_names.h" |
| 11 #include "chrome/test/base/browser_with_test_window_test.h" |
| 12 #include "chrome/test/base/testing_browser_process.h" |
| 13 #include "chrome/test/base/testing_profile.h" |
| 14 #include "chrome/test/base/testing_profile_manager.h" |
| 15 #include "chromeos/network/network_state.h" |
| 16 #include "chromeos/network/portal_detector/network_portal_detector.h" |
| 17 #include "components/prefs/pref_service.h" |
| 18 #include "content/public/test/test_browser_thread_bundle.h" |
| 19 #include "content/public/test/test_utils.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #include "ui/message_center/fake_message_center_tray_delegate.h" |
| 23 #include "ui/message_center/message_center.h" |
| 24 |
| 25 using testing::_; |
| 26 using testing::AtLeast; |
| 27 using testing::Invoke; |
| 28 using testing::Return; |
| 29 using testing::SaveArg; |
| 30 using testing::StrictMock; |
| 31 |
| 32 namespace chromeos { |
| 33 |
| 34 namespace { |
| 35 |
| 36 class MockNetworkPortalDetector : public NetworkPortalDetector { |
| 37 public: |
| 38 MockNetworkPortalDetector() {} |
| 39 ~MockNetworkPortalDetector() override {} |
| 40 |
| 41 MOCK_METHOD1(AddObserver, |
| 42 void(chromeos::NetworkPortalDetector::Observer* observer)); |
| 43 MOCK_METHOD1(RemoveObserver, |
| 44 void(chromeos::NetworkPortalDetector::Observer* observer)); |
| 45 MOCK_METHOD1(AddAndFireObserver, |
| 46 void(chromeos::NetworkPortalDetector::Observer* observer)); |
| 47 MOCK_METHOD1(GetCaptivePortalState, |
| 48 chromeos::NetworkPortalDetector::CaptivePortalState( |
| 49 const std::string& service_path)); |
| 50 MOCK_METHOD0(IsEnabled, bool()); |
| 51 MOCK_METHOD1(Enable, void(bool start_detection)); |
| 52 MOCK_METHOD0(StartDetectionIfIdle, bool()); |
| 53 MOCK_METHOD1(SetStrategy, |
| 54 void(chromeos::PortalDetectorStrategy::StrategyId id)); |
| 55 MOCK_METHOD0(OnLockScreenRequest, void()); |
| 56 |
| 57 private: |
| 58 DISALLOW_COPY_AND_ASSIGN(MockNetworkPortalDetector); |
| 59 }; |
| 60 |
| 61 } // namespace |
| 62 |
| 63 class HatsNotificationControllerTest : public BrowserWithTestWindowTest { |
| 64 public: |
| 65 HatsNotificationControllerTest() {} |
| 66 ~HatsNotificationControllerTest() override {} |
| 67 |
| 68 void SetUp() override { |
| 69 BrowserWithTestWindowTest::SetUp(); |
| 70 |
| 71 profile_manager_.reset( |
| 72 new TestingProfileManager(TestingBrowserProcess::GetGlobal())); |
| 73 ASSERT_TRUE(profile_manager_->SetUp()); |
| 74 |
| 75 MessageCenterNotificationManager* manager = |
| 76 static_cast<MessageCenterNotificationManager*>( |
| 77 g_browser_process->notification_ui_manager()); |
| 78 manager->SetMessageCenterTrayDelegateForTest( |
| 79 new message_center::FakeMessageCenterTrayDelegate( |
| 80 message_center::MessageCenter::Get())); |
| 81 |
| 82 network_portal_detector::InitializeForTesting( |
| 83 &mock_network_portal_detector_); |
| 84 } |
| 85 |
| 86 void TearDown() override { |
| 87 g_browser_process->notification_ui_manager()->CancelAll(); |
| 88 profile_manager_.reset(); |
| 89 network_portal_detector::InitializeForTesting(nullptr); |
| 90 BrowserWithTestWindowTest::TearDown(); |
| 91 } |
| 92 |
| 93 scoped_refptr<HatsNotificationController> InstantiateHatsController() { |
| 94 // The initialization will fail since the function IsNewDevice() will return |
| 95 // true. |
| 96 scoped_refptr<HatsNotificationController> hats_notification_controller = |
| 97 new HatsNotificationController(&profile_); |
| 98 |
| 99 // HatsController::IsNewDevice() is run on a blocking thread. |
| 100 content::RunAllBlockingPoolTasksUntilIdle(); |
| 101 |
| 102 // Send a callback to the observer to simulate internet connectivity is |
| 103 // present on device. |
| 104 ON_CALL(mock_network_portal_detector_, |
| 105 AddAndFireObserver(hats_notification_controller.get())) |
| 106 .WillByDefault(Invoke( |
| 107 [&hats_notification_controller](NetworkPortalDetector::Observer*) { |
| 108 NetworkPortalDetector::CaptivePortalState online_state; |
| 109 NetworkState network_state(""); |
| 110 online_state.status = |
| 111 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; |
| 112 hats_notification_controller->OnPortalDetectionCompleted( |
| 113 &network_state, online_state); |
| 114 })); |
| 115 |
| 116 return hats_notification_controller; |
| 117 } |
| 118 |
| 119 TestingProfile profile_; |
| 120 StrictMock<MockNetworkPortalDetector> mock_network_portal_detector_; |
| 121 |
| 122 private: |
| 123 std::unique_ptr<TestingProfileManager> profile_manager_; |
| 124 |
| 125 DISALLOW_COPY_AND_ASSIGN(HatsNotificationControllerTest); |
| 126 }; |
| 127 |
| 128 TEST_F(HatsNotificationControllerTest, NewDevice_ShouldNotShowNotification) { |
| 129 int64_t initial_timestamp = base::Time::Now().ToInternalValue(); |
| 130 PrefService* pref_service = profile_.GetPrefs(); |
| 131 pref_service->SetInt64(prefs::kHatsLastInteractionTimestamp, |
| 132 initial_timestamp); |
| 133 |
| 134 auto hats_notification_controller = InstantiateHatsController(); |
| 135 hats_notification_controller->Initialize(true); |
| 136 |
| 137 int64_t current_timestamp = |
| 138 pref_service->GetInt64(prefs::kHatsLastInteractionTimestamp); |
| 139 |
| 140 // When the device is new, the controller does not begin initialization and |
| 141 // simply updates the timestamp to Time::Now(). |
| 142 ASSERT_TRUE(base::Time::FromInternalValue(current_timestamp) > |
| 143 base::Time::FromInternalValue(initial_timestamp)); |
| 144 |
| 145 // Destructor for HatsController removes self from observer list. |
| 146 EXPECT_CALL(mock_network_portal_detector_, |
| 147 RemoveObserver(hats_notification_controller.get())) |
| 148 .Times(1); |
| 149 |
| 150 const Notification* notification = |
| 151 g_browser_process->notification_ui_manager()->FindById( |
| 152 HatsNotificationController::kDelegateId, &profile_); |
| 153 EXPECT_FALSE(notification); |
| 154 } |
| 155 |
| 156 TEST_F(HatsNotificationControllerTest, OldDevice_ShouldShowNotification) { |
| 157 auto hats_notification_controller = InstantiateHatsController(); |
| 158 |
| 159 // On initialization, HatsNotificationController adds itself as an observer to |
| 160 // NetworkPortalDetector to detect internet connectivity. |
| 161 EXPECT_CALL(mock_network_portal_detector_, |
| 162 AddAndFireObserver(hats_notification_controller.get())) |
| 163 .Times(1); |
| 164 // Observer is removed if an internet connection is detected. It is called |
| 165 // a second time when hats_notification_controller is destroyed. |
| 166 EXPECT_CALL(mock_network_portal_detector_, |
| 167 RemoveObserver(hats_notification_controller.get())) |
| 168 .Times(2); |
| 169 |
| 170 hats_notification_controller->Initialize(false); |
| 171 |
| 172 // Finally check if notification was launched to confirm initialization. |
| 173 const Notification* notification = |
| 174 g_browser_process->notification_ui_manager()->FindById( |
| 175 HatsNotificationController::kDelegateId, &profile_); |
| 176 EXPECT_TRUE(notification != nullptr); |
| 177 } |
| 178 |
| 179 TEST_F(HatsNotificationControllerTest, NoInternet_DoNotShowNotification) { |
| 180 auto hats_notification_controller = InstantiateHatsController(); |
| 181 |
| 182 // Upon destruction HatsNotificationController removes itself as an observer |
| 183 // from NetworkPortalDetector. This will only be called once from the |
| 184 EXPECT_CALL(mock_network_portal_detector_, |
| 185 RemoveObserver(hats_notification_controller.get())) |
| 186 .Times(1); |
| 187 |
| 188 NetworkState network_state(""); |
| 189 NetworkPortalDetector::CaptivePortalState online_state; |
| 190 hats_notification_controller->OnPortalDetectionCompleted(&network_state, |
| 191 online_state); |
| 192 |
| 193 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE; |
| 194 hats_notification_controller->OnPortalDetectionCompleted(&network_state, |
| 195 online_state); |
| 196 |
| 197 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; |
| 198 hats_notification_controller->OnPortalDetectionCompleted(&network_state, |
| 199 online_state); |
| 200 |
| 201 online_state.status = |
| 202 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED; |
| 203 hats_notification_controller->OnPortalDetectionCompleted(&network_state, |
| 204 online_state); |
| 205 |
| 206 const Notification* notification = |
| 207 g_browser_process->notification_ui_manager()->FindById( |
| 208 HatsNotificationController::kDelegateId, &profile_); |
| 209 EXPECT_FALSE(notification); |
| 210 } |
| 211 |
| 212 TEST_F(HatsNotificationControllerTest, DismissNotification_ShouldUpdatePref) { |
| 213 int64_t now_timestamp = base::Time::Now().ToInternalValue(); |
| 214 PrefService* pref_service = profile_.GetPrefs(); |
| 215 pref_service->SetInt64(prefs::kHatsLastInteractionTimestamp, now_timestamp); |
| 216 |
| 217 auto hats_notification_controller = InstantiateHatsController(); |
| 218 |
| 219 // Simulate closing notification via user interaction. |
| 220 hats_notification_controller->Close(true); |
| 221 |
| 222 int64_t new_timestamp = |
| 223 pref_service->GetInt64(prefs::kHatsLastInteractionTimestamp); |
| 224 // The flag should be updated to a new timestamp. |
| 225 ASSERT_TRUE(base::Time::FromInternalValue(new_timestamp) > |
| 226 base::Time::FromInternalValue(now_timestamp)); |
| 227 |
| 228 // Destructor for HatsController removes self from observer list. |
| 229 EXPECT_CALL(mock_network_portal_detector_, |
| 230 RemoveObserver(hats_notification_controller.get())) |
| 231 .Times(1); |
| 232 } |
| 233 |
| 234 } // namespace chromeos |
| OLD | NEW |