// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <stddef.h> #include <map> #include <utility> #include <vector> #include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "build/build_config.h" #include "chrome/browser/extensions/extension_apitest.h" #include "components/keyed_service/core/keyed_service.h" #include "components/onc/onc_constants.h" #include "content/public/test/test_utils.h" #include "extensions/browser/api/networking_private/networking_private_delegate.h" #include "extensions/browser/api/networking_private/networking_private_delegate_factory.h" #include "extensions/common/switches.h" namespace extensions { // This tests just the interface for the networkingPrivate API, i.e. it ensures // that the delegate methods are called as expected. // The implementations (which differ significantly between chromeos and // windows/mac) are tested independently in // networking_private_[chromeos|service_client]_apitest.cc. // See also crbug.com/460119. namespace { const char kFailure[] = "Failure"; const char kSuccess[] = "Success"; const char kGuid[] = "SOME_GUID"; class TestDelegate : public NetworkingPrivateDelegate { public: explicit TestDelegate(scoped_ptr<VerifyDelegate> verify_delegate) : NetworkingPrivateDelegate(std::move(verify_delegate)), fail_(false) {} ~TestDelegate() override {} // Asynchronous methods void GetProperties(const std::string& guid, const DictionaryCallback& success_callback, const FailureCallback& failure_callback) override { DictionaryResult(guid, success_callback, failure_callback); } void GetManagedProperties(const std::string& guid, const DictionaryCallback& success_callback, const FailureCallback& failure_callback) override { DictionaryResult(guid, success_callback, failure_callback); } void GetState(const std::string& guid, const DictionaryCallback& success_callback, const FailureCallback& failure_callback) override { DictionaryResult(guid, success_callback, failure_callback); } void SetProperties(const std::string& guid, scoped_ptr<base::DictionaryValue> properties, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } void CreateNetwork(bool shared, scoped_ptr<base::DictionaryValue> properties, const StringCallback& success_callback, const FailureCallback& failure_callback) override { StringResult(success_callback, failure_callback); } void ForgetNetwork(const std::string& guid, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } void GetNetworks(const std::string& network_type, bool configured_only, bool visible_only, int limit, const NetworkListCallback& success_callback, const FailureCallback& failure_callback) override { if (fail_) { failure_callback.Run(kFailure); } else { scoped_ptr<base::ListValue> result(new base::ListValue); scoped_ptr<base::DictionaryValue> network(new base::DictionaryValue); network->SetString(::onc::network_config::kType, ::onc::network_config::kEthernet); network->SetString(::onc::network_config::kGUID, kGuid); result->Append(network.release()); success_callback.Run(std::move(result)); } } void StartConnect(const std::string& guid, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } void StartDisconnect(const std::string& guid, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } void StartActivate(const std::string& guid, const std::string& carrier, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } void SetWifiTDLSEnabledState( const std::string& ip_or_mac_address, bool enabled, const StringCallback& success_callback, const FailureCallback& failure_callback) override { StringResult(success_callback, failure_callback); } void GetWifiTDLSStatus(const std::string& ip_or_mac_address, const StringCallback& success_callback, const FailureCallback& failure_callback) override { StringResult(success_callback, failure_callback); } void GetCaptivePortalStatus( const std::string& guid, const StringCallback& success_callback, const FailureCallback& failure_callback) override { StringResult(success_callback, failure_callback); } void UnlockCellularSim(const std::string& guid, const std::string& pin, const std::string& puk, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } void SetCellularSimState(const std::string& guid, bool require_pin, const std::string& current_pin, const std::string& new_pin, const VoidCallback& success_callback, const FailureCallback& failure_callback) override { VoidResult(success_callback, failure_callback); } // Synchronous methods scoped_ptr<base::ListValue> GetEnabledNetworkTypes() override { scoped_ptr<base::ListValue> result; if (!fail_) { result.reset(new base::ListValue); result->AppendString(::onc::network_config::kEthernet); } return result; } scoped_ptr<DeviceStateList> GetDeviceStateList() override { scoped_ptr<DeviceStateList> result; if (fail_) return result; result.reset(new DeviceStateList); scoped_ptr<api::networking_private::DeviceStateProperties> properties( new api::networking_private::DeviceStateProperties); properties->type = api::networking_private::NETWORK_TYPE_ETHERNET; properties->state = api::networking_private::DEVICE_STATE_TYPE_ENABLED; result->push_back(std::move(properties)); return result; } bool EnableNetworkType(const std::string& type) override { enabled_[type] = true; return !fail_; } bool DisableNetworkType(const std::string& type) override { disabled_[type] = true; return !fail_; } bool RequestScan() override { scan_requested_.push_back(true); return !fail_; } void set_fail(bool fail) { fail_ = fail; } bool GetEnabled(const std::string& type) { return enabled_[type]; } bool GetDisabled(const std::string& type) { return disabled_[type]; } size_t GetScanRequested() { return scan_requested_.size(); } void DictionaryResult(const std::string& guid, const DictionaryCallback& success_callback, const FailureCallback& failure_callback) { if (fail_) { failure_callback.Run(kFailure); } else { scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); result->SetString(::onc::network_config::kGUID, guid); result->SetString(::onc::network_config::kType, ::onc::network_config::kWiFi); success_callback.Run(std::move(result)); } } void StringResult(const StringCallback& success_callback, const FailureCallback& failure_callback) { if (fail_) { failure_callback.Run(kFailure); } else { success_callback.Run(kSuccess); } } void BoolResult(const BoolCallback& success_callback, const FailureCallback& failure_callback) { if (fail_) { failure_callback.Run(kFailure); } else { success_callback.Run(true); } } void VoidResult(const VoidCallback& success_callback, const FailureCallback& failure_callback) { if (fail_) { failure_callback.Run(kFailure); } else { success_callback.Run(); } } private: bool fail_; std::map<std::string, bool> enabled_; std::map<std::string, bool> disabled_; std::vector<bool> scan_requested_; DISALLOW_COPY_AND_ASSIGN(TestDelegate); }; class TestVerifyDelegate : public NetworkingPrivateDelegate::VerifyDelegate { public: TestVerifyDelegate() : owner_(NULL) {} ~TestVerifyDelegate() override {} void VerifyDestination( const VerificationProperties& verification_properties, const BoolCallback& success_callback, const FailureCallback& failure_callback) override { owner_->BoolResult(success_callback, failure_callback); } void VerifyAndEncryptCredentials( const std::string& guid, const VerificationProperties& verification_properties, const StringCallback& success_callback, const FailureCallback& failure_callback) override { owner_->StringResult(success_callback, failure_callback); } void VerifyAndEncryptData( const VerificationProperties& verification_properties, const std::string& data, const StringCallback& success_callback, const FailureCallback& failure_callback) override { owner_->StringResult(success_callback, failure_callback); } void set_owner(TestDelegate* owner) { owner_ = owner; } private: TestDelegate* owner_; DISALLOW_COPY_AND_ASSIGN(TestVerifyDelegate); }; class NetworkingPrivateApiTest : public ExtensionApiTest { public: NetworkingPrivateApiTest() { if (!s_test_delegate_) { TestVerifyDelegate* verify_delegate = new TestVerifyDelegate; scoped_ptr<NetworkingPrivateDelegate::VerifyDelegate> verify_delegate_ptr( verify_delegate); s_test_delegate_ = new TestDelegate(std::move(verify_delegate_ptr)); verify_delegate->set_owner(s_test_delegate_); } } static scoped_ptr<KeyedService> GetNetworkingPrivateDelegate( content::BrowserContext* profile) { CHECK(s_test_delegate_); return make_scoped_ptr(s_test_delegate_); } void SetUpCommandLine(base::CommandLine* command_line) override { ExtensionApiTest::SetUpCommandLine(command_line); // Whitelist the extension ID of the test extension. command_line->AppendSwitchASCII( extensions::switches::kWhitelistedExtensionID, "epcifkihnkjgphfkloaaleeakhpmgdmn"); } void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); NetworkingPrivateDelegateFactory::GetInstance()->SetTestingFactory( profile(), &NetworkingPrivateApiTest::GetNetworkingPrivateDelegate); content::RunAllPendingInMessageLoop(); } bool GetEnabled(const std::string& type) { return s_test_delegate_->GetEnabled(type); } bool GetDisabled(const std::string& type) { return s_test_delegate_->GetDisabled(type); } size_t GetScanRequested() { return s_test_delegate_->GetScanRequested(); } protected: bool RunNetworkingSubtest(const std::string& subtest) { return RunExtensionSubtest("networking_private", "main.html?" + subtest, kFlagEnableFileAccess | kFlagLoadAsComponent); } // Static pointer to the TestDelegate so that it can be accessed in // GetNetworkingPrivateDelegate() passed to SetTestingFactory(). static TestDelegate* s_test_delegate_; DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateApiTest); }; // static TestDelegate* NetworkingPrivateApiTest::s_test_delegate_ = NULL; } // namespace // Place each subtest into a separate browser test so that the stub networking // library state is reset for each subtest run. This way they won't affect each // other. TODO(stevenjb): Use extensions::ApiUnitTest once moved to // src/extensions. // These fail on Windows due to crbug.com/177163. Note: we still have partial // coverage in NetworkingPrivateServiceClientApiTest. TODO(stevenjb): Enable // these on Windows once we switch to extensions::ApiUnitTest. #if !defined(OS_WIN) IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetProperties) { EXPECT_TRUE(RunNetworkingSubtest("getProperties")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetManagedProperties) { EXPECT_TRUE(RunNetworkingSubtest("getManagedProperties")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetState) { EXPECT_TRUE(RunNetworkingSubtest("getState")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, SetProperties) { EXPECT_TRUE(RunNetworkingSubtest("setProperties")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, CreateNetwork) { EXPECT_TRUE(RunNetworkingSubtest("createNetwork")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, ForgetNetwork) { EXPECT_TRUE(RunNetworkingSubtest("forgetNetwork")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetNetworks) { EXPECT_TRUE(RunNetworkingSubtest("getNetworks")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetVisibleNetworks) { EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworks")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetEnabledNetworkTypes) { EXPECT_TRUE(RunNetworkingSubtest("getEnabledNetworkTypes")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetDeviceStates) { EXPECT_TRUE(RunNetworkingSubtest("getDeviceStates")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, EnableNetworkType) { EXPECT_TRUE(RunNetworkingSubtest("enableNetworkType")) << message_; EXPECT_TRUE(GetEnabled(::onc::network_config::kEthernet)); } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, DisableNetworkType) { EXPECT_TRUE(RunNetworkingSubtest("disableNetworkType")) << message_; EXPECT_TRUE(GetDisabled(::onc::network_config::kEthernet)); } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, RequestNetworkScan) { EXPECT_TRUE(RunNetworkingSubtest("requestNetworkScan")) << message_; EXPECT_EQ(1u, GetScanRequested()); } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, StartConnect) { EXPECT_TRUE(RunNetworkingSubtest("startConnect")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, StartDisconnect) { EXPECT_TRUE(RunNetworkingSubtest("startDisconnect")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, StartActivate) { EXPECT_TRUE(RunNetworkingSubtest("startActivate")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, VerifyDestination) { EXPECT_TRUE(RunNetworkingSubtest("verifyDestination")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, VerifyAndEncryptCredentials) { EXPECT_TRUE(RunNetworkingSubtest("verifyAndEncryptCredentials")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, VerifyAndEncryptData) { EXPECT_TRUE(RunNetworkingSubtest("verifyAndEncryptData")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, SetWifiTDLSEnabledState) { EXPECT_TRUE(RunNetworkingSubtest("setWifiTDLSEnabledState")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetWifiTDLSStatus) { EXPECT_TRUE(RunNetworkingSubtest("getWifiTDLSStatus")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, GetCaptivePortalStatus) { EXPECT_TRUE(RunNetworkingSubtest("getCaptivePortalStatus")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, UnlockCellularSim) { EXPECT_TRUE(RunNetworkingSubtest("unlockCellularSim")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTest, SetCellularSimState) { EXPECT_TRUE(RunNetworkingSubtest("setCellularSimState")) << message_; } // Test failure case class NetworkingPrivateApiTestFail : public NetworkingPrivateApiTest { public: NetworkingPrivateApiTestFail() { s_test_delegate_->set_fail(true); } protected: DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateApiTestFail); }; IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetProperties) { EXPECT_FALSE(RunNetworkingSubtest("getProperties")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetManagedProperties) { EXPECT_FALSE(RunNetworkingSubtest("getManagedProperties")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetState) { EXPECT_FALSE(RunNetworkingSubtest("getState")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, SetProperties) { EXPECT_FALSE(RunNetworkingSubtest("setProperties")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, CreateNetwork) { EXPECT_FALSE(RunNetworkingSubtest("createNetwork")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, ForgetNetwork) { EXPECT_FALSE(RunNetworkingSubtest("forgetNetwork")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetNetworks) { EXPECT_FALSE(RunNetworkingSubtest("getNetworks")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetVisibleNetworks) { EXPECT_FALSE(RunNetworkingSubtest("getVisibleNetworks")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetEnabledNetworkTypes) { EXPECT_FALSE(RunNetworkingSubtest("getEnabledNetworkTypes")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetDeviceStates) { EXPECT_FALSE(RunNetworkingSubtest("getDeviceStates")) << message_; } // Note: Synchronous methods never fail: // * disableNetworkType // * enableNetworkType // * requestNetworkScan IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, StartConnect) { EXPECT_FALSE(RunNetworkingSubtest("startConnect")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, StartDisconnect) { EXPECT_FALSE(RunNetworkingSubtest("startDisconnect")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, StartActivate) { EXPECT_FALSE(RunNetworkingSubtest("startActivate")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, VerifyDestination) { EXPECT_FALSE(RunNetworkingSubtest("verifyDestination")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, VerifyAndEncryptCredentials) { EXPECT_FALSE(RunNetworkingSubtest("verifyAndEncryptCredentials")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, VerifyAndEncryptData) { EXPECT_FALSE(RunNetworkingSubtest("verifyAndEncryptData")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, SetWifiTDLSEnabledState) { EXPECT_FALSE(RunNetworkingSubtest("setWifiTDLSEnabledState")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetWifiTDLSStatus) { EXPECT_FALSE(RunNetworkingSubtest("getWifiTDLSStatus")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, GetCaptivePortalStatus) { EXPECT_FALSE(RunNetworkingSubtest("getCaptivePortalStatus")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, UnlockCellularSim) { EXPECT_FALSE(RunNetworkingSubtest("unlockCellularSim")) << message_; } IN_PROC_BROWSER_TEST_F(NetworkingPrivateApiTestFail, SetCellularSimState) { EXPECT_FALSE(RunNetworkingSubtest("setCellularSimState")) << message_; } #endif // defined(OS_WIN) } // namespace extensions