network_portal_detector_impl_browsertest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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.
4
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"
25
26using base::MessageLoop;
27using message_center::MessageCenter;
28using message_center::MessageCenterObserver;
29
30namespace chromeos {
31
32namespace {
33
34const char* kNotificationId =
35    NetworkPortalNotificationController::kNotificationId;
36const char* kNotificationMetric =
37    NetworkPortalNotificationController::kNotificationMetric;
38const char* kUserActionMetric =
39    NetworkPortalNotificationController::kUserActionMetric;
40
41const char kTestUser[] = "test-user@gmail.com";
42const char kWifi[] = "wifi";
43
44void ErrorCallbackFunction(const std::string& error_name,
45                           const std::string& error_message) {
46  CHECK(false) << "Shill Error: " << error_name << " : " << error_message;
47}
48
49void 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();
55}
56
57class TestObserver : public MessageCenterObserver {
58 public:
59  TestObserver() : run_loop_(new base::RunLoop()) {
60    MessageCenter::Get()->AddObserver(this);
61  }
62
63  virtual ~TestObserver() {
64    MessageCenter::Get()->RemoveObserver(this);
65  }
66
67  void WaitAndReset() {
68    run_loop_->Run();
69    run_loop_.reset(new base::RunLoop());
70  }
71
72  virtual void OnNotificationDisplayed(
73      const std::string& notification_id,
74      const message_center::DisplaySource source)
75      OVERRIDE {
76    if (notification_id == kNotificationId)
77      MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure());
78  }
79
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());
84  }
85
86 private:
87  scoped_ptr<base::RunLoop> run_loop_;
88
89  DISALLOW_COPY_AND_ASSIGN(TestObserver);
90};
91
92}  // namespace
93
94class NetworkPortalDetectorImplBrowserTest
95    : public LoginManagerTest,
96      public captive_portal::CaptivePortalDetectorTestBase {
97 public:
98  NetworkPortalDetectorImplBrowserTest()
99      : LoginManagerTest(false), network_portal_detector_(NULL) {}
100  virtual ~NetworkPortalDetectorImplBrowserTest() {}
101
102  virtual void SetUpOnMainThread() OVERRIDE {
103    LoginManagerTest::SetUpOnMainThread();
104
105    ShillServiceClient::TestInterface* service_test =
106        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
107    service_test->ClearServices();
108    service_test->AddService(kWifi,
109                             kWifi,
110                             shill::kTypeEthernet,
111                             shill::kStateIdle,
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));
119
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(
126        base::TimeDelta());
127    base::RunLoop().RunUntilIdle();
128  }
129
130  void RestartDetection() {
131    network_portal_detector_->StopDetection();
132    network_portal_detector_->StartDetection();
133    base::RunLoop().RunUntilIdle();
134  }
135
136  PortalDetectorStrategy* strategy() {
137    return network_portal_detector_->strategy_.get();
138  }
139
140  MessageCenter* message_center() { return MessageCenter::Get(); }
141
142 private:
143  NetworkPortalDetectorImpl* network_portal_detector_;
144
145  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImplBrowserTest);
146};
147
148IN_PROC_BROWSER_TEST_F(NetworkPortalDetectorImplBrowserTest,
149                       PRE_InSessionDetection) {
150  RegisterUser(kTestUser);
151  StartupUtils::MarkOobeCompleted();
152  ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN, strategy()->Id());
153}
154
155IN_PROC_BROWSER_TEST_F(NetworkPortalDetectorImplBrowserTest,
156                       InSessionDetection) {
157  typedef NetworkPortalNotificationController Controller;
158
159  TestObserver observer;
160
161  EnumHistogramChecker ui_checker(
162      kNotificationMetric, Controller::NOTIFICATION_METRIC_COUNT, NULL);
163  EnumHistogramChecker action_checker(
164      kUserActionMetric, Controller::USER_ACTION_METRIC_COUNT, NULL);
165
166  LoginUser(kTestUser);
167  content::RunAllPendingInMessageLoop();
168
169  // User connects to wifi.
170  SetConnected(kWifi);
171
172  ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_SESSION, strategy()->Id());
173
174  // No notification until portal detection is completed.
175  ASSERT_FALSE(message_center()->FindVisibleNotificationById(kNotificationId));
176  RestartDetection();
177  CompleteURLFetch(net::OK, 200, NULL);
178
179  // Check that wifi is marked as behind the portal and that notification
180  // is displayed.
181  ASSERT_TRUE(message_center()->FindVisibleNotificationById(kNotificationId));
182  ASSERT_EQ(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL,
183            NetworkPortalDetector::Get()->GetCaptivePortalState(kWifi).status);
184
185  // Wait until notification is displayed.
186  observer.WaitAndReset();
187
188  ASSERT_TRUE(
189      ui_checker.Expect(Controller::NOTIFICATION_METRIC_DISPLAYED, 1)->Check());
190  ASSERT_TRUE(action_checker.Check());
191
192  // User explicitly closes the notification.
193  message_center()->RemoveNotification(kNotificationId, true);
194
195  // Wait until notification is closed.
196  observer.WaitAndReset();
197
198  ASSERT_TRUE(ui_checker.Check());
199  ASSERT_TRUE(
200      action_checker.Expect(Controller::USER_ACTION_METRIC_CLOSED, 1)->Check());
201}
202
203}  // namespace chromeos
204