1 // Copyright 2014 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.
5 #include "base/compiler_specific.h"
6 #include "base/macros.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/chromeos/login/login_manager_test.h"
11 #include "chrome/browser/chromeos/login/startup_utils.h"
12 #include "chrome/browser/chromeos/net/network_portal_detector.h"
13 #include "chrome/browser/chromeos/net/network_portal_detector_impl.h"
14 #include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
15 #include "chrome/browser/chromeos/net/network_portal_detector_test_utils.h"
16 #include "chromeos/chromeos_switches.h"
17 #include "chromeos/dbus/dbus_thread_manager.h"
18 #include "chromeos/dbus/shill_service_client.h"
19 #include "components/captive_portal/captive_portal_testing_utils.h"
20 #include "content/public/test/test_utils.h"
21 #include "dbus/object_path.h"
22 #include "third_party/cros_system_api/dbus/service_constants.h"
23 #include "ui/message_center/message_center.h"
24 #include "ui/message_center/message_center_observer.h"
26 using base::MessageLoop;
27 using message_center::MessageCenter;
28 using message_center::MessageCenterObserver;
34 const char* kNotificationId =
35 NetworkPortalNotificationController::kNotificationId;
36 const char* kNotificationMetric =
37 NetworkPortalNotificationController::kNotificationMetric;
38 const char* kUserActionMetric =
39 NetworkPortalNotificationController::kUserActionMetric;
41 const char kTestUser[] = "test-user@gmail.com";
42 const char kWifi[] = "wifi";
44 void ErrorCallbackFunction(const std::string& error_name,
45 const std::string& error_message) {
46 CHECK(false) << "Shill Error: " << error_name << " : " << error_message;
49 void SetConnected(const std::string& service_path) {
50 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
51 dbus::ObjectPath(service_path),
52 base::Bind(&base::DoNothing),
53 base::Bind(&ErrorCallbackFunction));
54 base::RunLoop().RunUntilIdle();
57 class TestObserver : public MessageCenterObserver {
59 TestObserver() : run_loop_(new base::RunLoop()) {
60 MessageCenter::Get()->AddObserver(this);
63 virtual ~TestObserver() {
64 MessageCenter::Get()->RemoveObserver(this);
69 run_loop_.reset(new base::RunLoop());
72 virtual void OnNotificationDisplayed(
73 const std::string& notification_id,
74 const message_center::DisplaySource source)
76 if (notification_id == kNotificationId)
77 MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure());
80 virtual void OnNotificationRemoved(const std::string& notification_id,
81 bool by_user) OVERRIDE {
82 if (notification_id == kNotificationId && by_user)
83 MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure());
87 scoped_ptr<base::RunLoop> run_loop_;
89 DISALLOW_COPY_AND_ASSIGN(TestObserver);
94 class NetworkPortalDetectorImplBrowserTest
95 : public LoginManagerTest,
96 public captive_portal::CaptivePortalDetectorTestBase {
98 NetworkPortalDetectorImplBrowserTest()
99 : LoginManagerTest(false), network_portal_detector_(NULL) {}
100 virtual ~NetworkPortalDetectorImplBrowserTest() {}
102 virtual void SetUpOnMainThread() OVERRIDE {
103 LoginManagerTest::SetUpOnMainThread();
105 ShillServiceClient::TestInterface* service_test =
106 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
107 service_test->ClearServices();
108 service_test->AddService(kWifi,
110 shill::kTypeEthernet,
112 true /* add_to_visible */);
113 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
114 dbus::ObjectPath(kWifi),
115 shill::kStateProperty,
116 base::StringValue(shill::kStatePortal),
117 base::Bind(&base::DoNothing),
118 base::Bind(&ErrorCallbackFunction));
120 network_portal_detector_ = new NetworkPortalDetectorImpl(
121 g_browser_process->system_request_context());
122 NetworkPortalDetector::InitializeForTesting(network_portal_detector_);
123 network_portal_detector_->Enable(false /* start_detection */);
124 set_detector(network_portal_detector_->captive_portal_detector_.get());
125 PortalDetectorStrategy::set_delay_till_next_attempt_for_testing(
127 base::RunLoop().RunUntilIdle();
130 void RestartDetection() {
131 network_portal_detector_->StopDetection();
132 network_portal_detector_->StartDetection();
133 base::RunLoop().RunUntilIdle();
136 PortalDetectorStrategy* strategy() {
137 return network_portal_detector_->strategy_.get();
140 MessageCenter* message_center() { return MessageCenter::Get(); }
143 NetworkPortalDetectorImpl* network_portal_detector_;
145 DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImplBrowserTest);
148 IN_PROC_BROWSER_TEST_F(NetworkPortalDetectorImplBrowserTest,
149 PRE_InSessionDetection) {
150 RegisterUser(kTestUser);
151 StartupUtils::MarkOobeCompleted();
152 ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN, strategy()->Id());
155 IN_PROC_BROWSER_TEST_F(NetworkPortalDetectorImplBrowserTest,
156 InSessionDetection) {
157 typedef NetworkPortalNotificationController Controller;
159 TestObserver observer;
161 EnumHistogramChecker ui_checker(
162 kNotificationMetric, Controller::NOTIFICATION_METRIC_COUNT, NULL);
163 EnumHistogramChecker action_checker(
164 kUserActionMetric, Controller::USER_ACTION_METRIC_COUNT, NULL);
166 LoginUser(kTestUser);
167 content::RunAllPendingInMessageLoop();
169 // User connects to wifi.
172 ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_SESSION, strategy()->Id());
174 // No notification until portal detection is completed.
175 ASSERT_FALSE(message_center()->FindVisibleNotificationById(kNotificationId));
177 CompleteURLFetch(net::OK, 200, NULL);
179 // Check that wifi is marked as behind the portal and that notification
181 ASSERT_TRUE(message_center()->FindVisibleNotificationById(kNotificationId));
182 ASSERT_EQ(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL,
183 NetworkPortalDetector::Get()->GetCaptivePortalState(kWifi).status);
185 // Wait until notification is displayed.
186 observer.WaitAndReset();
189 ui_checker.Expect(Controller::NOTIFICATION_METRIC_DISPLAYED, 1)->Check());
190 ASSERT_TRUE(action_checker.Check());
192 // User explicitly closes the notification.
193 message_center()->RemoveNotification(kNotificationId, true);
195 // Wait until notification is closed.
196 observer.WaitAndReset();
198 ASSERT_TRUE(ui_checker.Check());
200 action_checker.Expect(Controller::USER_ACTION_METRIC_CLOSED, 1)->Check());
203 } // namespace chromeos