1 // Copyright 2015 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.
7 #include "base/message_loop/message_loop.h"
8 #include "base/values.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/chromeos/net/network_portal_detector_impl.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "chromeos/dbus/shill_device_client.h"
14 #include "chromeos/dbus/shill_profile_client.h"
15 #include "chromeos/dbus/shill_service_client.h"
16 #include "components/captive_portal/captive_portal_testing_utils.h"
17 #include "content/public/test/test_utils.h"
18 #include "extensions/test/result_catcher.h"
19 #include "net/base/net_errors.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h"
21 #include "ui/message_center/message_center.h"
22 #include "ui/message_center/message_center_observer.h"
24 using base::MessageLoop
;
25 using chromeos::DBusThreadManager
;
26 using chromeos::NetworkPortalDetector
;
27 using chromeos::NetworkPortalDetectorImpl
;
28 using chromeos::NetworkPortalNotificationController
;
29 using chromeos::ShillDeviceClient
;
30 using chromeos::ShillProfileClient
;
31 using chromeos::ShillServiceClient
;
32 using message_center::MessageCenter
;
33 using message_center::MessageCenterObserver
;
37 const char kWifiDevicePath
[] = "/device/stub_wifi_device1";
38 const char kWifi1ServicePath
[] = "stub_wifi1";
39 const char kWifi1ServiceGUID
[] = "wifi1_guid";
41 class TestNotificationObserver
: public MessageCenterObserver
{
43 TestNotificationObserver() {
44 MessageCenter::Get()->AddObserver(this);
47 ~TestNotificationObserver() override
{
48 MessageCenter::Get()->RemoveObserver(this);
51 void WaitForNotificationToDisplay() {
55 void OnNotificationDisplayed(
56 const std::string
& notification_id
,
57 const message_center::DisplaySource source
) override
{
58 if (notification_id
==
59 NetworkPortalNotificationController::kNotificationId
) {
60 MessageLoop::current()->PostTask(FROM_HERE
, run_loop_
.QuitClosure());
65 base::RunLoop run_loop_
;
67 DISALLOW_COPY_AND_ASSIGN(TestNotificationObserver
);
72 class NetworkingConfigTest
73 : public ExtensionApiTest
,
74 public captive_portal::CaptivePortalDetectorTestBase
{
76 void SetUpOnMainThread() override
{
77 ExtensionApiTest::SetUpOnMainThread();
78 content::RunAllPendingInMessageLoop();
80 DBusThreadManager
* const dbus_manager
= DBusThreadManager::Get();
81 ShillServiceClient::TestInterface
* const service_test
=
82 dbus_manager
->GetShillServiceClient()->GetTestInterface();
83 ShillDeviceClient::TestInterface
* const device_test
=
84 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
85 ShillProfileClient::TestInterface
* const profile_test
=
86 dbus_manager
->GetShillProfileClient()->GetTestInterface();
88 device_test
->ClearDevices();
89 service_test
->ClearServices();
91 device_test
->AddDevice(kWifiDevicePath
, shill::kTypeWifi
,
94 service_test
->AddService(kWifi1ServicePath
, kWifi1ServiceGUID
, "wifi1",
95 shill::kTypeWifi
, shill::kStateOnline
,
96 true /* add_to_visible */);
97 service_test
->SetServiceProperty(kWifi1ServicePath
, shill::kWifiBSsid
,
98 base::StringValue("01:02:ab:7f:90:00"));
99 service_test
->SetServiceProperty(kWifi1ServicePath
,
100 shill::kSignalStrengthProperty
,
101 base::FundamentalValue(40));
102 profile_test
->AddService(ShillProfileClient::GetSharedProfilePath(),
105 content::RunAllPendingInMessageLoop();
107 network_portal_detector_
= new NetworkPortalDetectorImpl(
108 g_browser_process
->system_request_context());
109 NetworkPortalDetector::InitializeForTesting(network_portal_detector_
);
110 network_portal_detector_
->Enable(false /* start_detection */);
111 set_detector(network_portal_detector_
->captive_portal_detector_
.get());
114 void LoadTestExtension() {
115 extension_
= LoadExtension(test_data_dir_
.AppendASCII("networking_config"));
118 bool RunExtensionTest(const std::string
& path
) {
119 return RunExtensionSubtest("networking_config",
120 extension_
->GetResourceURL(path
).spec());
123 void SimulateCaptivePortal() {
124 network_portal_detector_
->StartDetection();
125 content::RunAllPendingInMessageLoop();
127 // Simulate a captive portal reply.
128 CompleteURLFetch(net::OK
, 200, nullptr);
131 void SimulateSuccessfulCaptivePortalAuth() {
132 content::RunAllPendingInMessageLoop();
133 CompleteURLFetch(net::OK
, 204, nullptr);
136 NetworkPortalDetectorImpl
* network_portal_detector_
= nullptr;
139 const extensions::Extension
* extension_
= nullptr;
142 IN_PROC_BROWSER_TEST_F(NetworkingConfigTest
, ApiAvailability
) {
143 ASSERT_TRUE(RunExtensionSubtest("networking_config", "api_availability.html"))
147 IN_PROC_BROWSER_TEST_F(NetworkingConfigTest
, RegisterNetworks
) {
149 RunExtensionSubtest("networking_config", "register_networks.html"))
153 // Test the full, positive flow starting with the extension registration and
154 // ending with the captive portal being authenticated.
155 IN_PROC_BROWSER_TEST_F(NetworkingConfigTest
, FullTest
) {
157 // This will cause the extension to register for wifi1.
158 ASSERT_TRUE(RunExtensionTest("full_test.html")) << message_
;
160 TestNotificationObserver observer
;
162 SimulateCaptivePortal();
164 // Wait until a captive portal notification is displayed and verify that it is
165 // the expected captive portal notification.
166 observer
.WaitForNotificationToDisplay();
167 EXPECT_TRUE(MessageCenter::Get()->FindVisibleNotificationById(
168 NetworkPortalNotificationController::kNotificationId
));
170 // Simulate the user click which leads to the extension being notified.
171 MessageCenter::Get()->ClickOnNotificationButton(
172 NetworkPortalNotificationController::kNotificationId
,
173 NetworkPortalNotificationController::kUseExtensionButtonIndex
);
175 extensions::ResultCatcher catcher
;
176 EXPECT_TRUE(catcher
.GetNextResult());
178 // Simulate the captive portal vanishing.
179 SimulateSuccessfulCaptivePortalAuth();
181 NetworkPortalDetector::CaptivePortalState state
=
182 network_portal_detector_
->GetCaptivePortalState(kWifi1ServiceGUID
);
183 ASSERT_EQ(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
, state
.status
);