1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/network/network_state.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos { 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// StringValue that skips the DCHECK in the constructor for valid UTF8. 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestStringValue : public base::Value { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) explicit TestStringValue(const std::string& in_value) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : base::Value(TYPE_STRING), 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value_(in_value) { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual ~TestStringValue() { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from Value: 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool GetAsString(std::string* out_value) const OVERRIDE { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (out_value) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *out_value = value_; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual TestStringValue* DeepCopy() const OVERRIDE { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new TestStringValue(value_); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool Equals(const base::Value* other) const OVERRIDE { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (other->GetType() != GetType()) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string lhs, rhs; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string value_; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class NetworkStateTest : public testing::Test { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NetworkStateTest() : network_state_("test_path") { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool SetStringProperty(const std::string& key, const std::string& value) { 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TestStringValue* string_value = new TestStringValue(value); 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool res = network_state_.PropertyChanged(key, *string_value); 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) properties_.SetWithoutPathExpansion(key, string_value); 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return res; 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool SignalInitialPropertiesReceived() { 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return network_state_.InitialPropertiesReceived(properties_); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NetworkState network_state_; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue properties_; 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NetworkStateTest); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Setting kNameProperty should set network name after call to 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// InitialPropertiesReceived(). 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(NetworkStateTest, NameAscii) { 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeVPN)); 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string network_setname = "Name TEST"; 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kNameProperty, network_setname)); 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_FALSE(SignalInitialPropertiesReceived()); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(network_state_.name(), network_setname); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(NetworkStateTest, NameAsciiWithNull) { 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeVPN)); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string network_setname = "Name TEST\x00xxx"; 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string network_setname_result = "Name TEST"; 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kNameProperty, network_setname)); 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_FALSE(SignalInitialPropertiesReceived()); 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(network_state_.name(), network_setname_result); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Truncates invalid UTF-8 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(NetworkStateTest, NameTruncateInvalid) { 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeVPN)); 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string network_setname = "SSID TEST \x01\xff!"; 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string network_setname_result = "SSID TEST \xEF\xBF\xBD\xEF\xBF\xBD!"; 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kNameProperty, network_setname)); 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SignalInitialPropertiesReceived()); 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(network_state_.name(), network_setname_result); 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// If HexSSID doesn't exist, fallback to NameProperty. 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(NetworkStateTest, SsidFromName) { 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeWifi)); 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string wifi_utf8 = "UTF-8 \u3042\u3044\u3046"; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string wifi_utf8_result = "UTF-8 \xE3\x81\x82\xE3\x81\x84\xE3\x81\x86"; 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kNameProperty, wifi_utf8)); 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_FALSE(SignalInitialPropertiesReceived()); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(network_state_.name(), wifi_utf8_result); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// latin1 SSID -> UTF8 SSID (Hex) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkStateTest, SsidLatin) { 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeWifi)); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string wifi_latin1 = "latin-1 \xc0\xcb\xcc\xd6\xfb"; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string wifi_latin1_hex = 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::HexEncode(wifi_latin1.c_str(), wifi_latin1.length()); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string wifi_latin1_result = "latin-1 \u00c0\u00cb\u00cc\u00d6\u00fb"; 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_FALSE(SetStringProperty(shill::kWifiHexSsid, wifi_latin1_hex)); 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(SignalInitialPropertiesReceived()); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(network_state_.name(), wifi_latin1_result); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Hex SSID 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkStateTest, SsidHex) { 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeWifi)); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string wifi_hex_result = "This is HEX SSID!"; 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string wifi_hex = 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::HexEncode(wifi_hex_result.c_str(), wifi_hex_result.length()); 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_FALSE(SetStringProperty(shill::kWifiHexSsid, wifi_hex)); 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(SignalInitialPropertiesReceived()); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(network_state_.name(), wifi_hex_result); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 147