network_info_bubble_unittest.cc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright 2021 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. #include "ash/system/network/network_info_bubble.h"
  5. #include <string>
  6. #include "ash/constants/ash_features.h"
  7. #include "ash/strings/grit/ash_strings.h"
  8. #include "ash/test/ash_test_base.h"
  9. #include "base/memory/weak_ptr.h"
  10. #include "base/strings/strcat.h"
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "base/test/scoped_feature_list.h"
  13. #include "base/time/time.h"
  14. #include "base/values.h"
  15. #include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
  16. #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
  17. #include "ui/base/l10n/l10n_util.h"
  18. #include "ui/events/event.h"
  19. #include "ui/gfx/geometry/point_f.h"
  20. #include "ui/views/controls/label.h"
  21. #include "ui/views/view.h"
  22. namespace ash {
  23. namespace {
  24. using chromeos::network_config::CrosNetworkConfigTestHelper;
  25. const char kIPv4ConfigPath[] = "/ipconfig/stub_ipv4_config";
  26. const char kIPv6ConfigPath[] = "/ipconfig/stub_ipv6_config";
  27. const char kWiFiServiceGuid[] = "wifi_guid";
  28. const char kWiFiServiceName[] = "stub_wifi_service";
  29. const char kWiFiServicePath[] = "/service/stub_wifi_service";
  30. const char kStubEthernetDeviceName[] = "stub_ethernet_device";
  31. const char kStubEthernetDevicePath[] = "/device/stub_ethernet_device";
  32. const char kStubWiFiDeviceName[] = "stub_wifi_device";
  33. const char kStubWiFiDevicePath[] = "/device/stub_wifi_device";
  34. const char kStubCellularDeviceName[] = "stub_cellular_device";
  35. const char kStubCellularDevicePath[] = "/device/stub_cellular_device";
  36. const char* kEthernetMacAddress = "33:33:33:33:33:33";
  37. const char* kWiFiMacAddress = "44:44:44:44:44:44";
  38. const char* kCellularMacAddress = "55:55:55:55:55:55";
  39. const char* kIpv4Address = "1.1.1.1";
  40. const char* kIpv6Address = "2222:2222:2222:2222:2222:2222:2222:2222";
  41. class FakeNetworkInfoBubbleDelegate : public NetworkInfoBubble::Delegate {
  42. public:
  43. FakeNetworkInfoBubbleDelegate() = default;
  44. ~FakeNetworkInfoBubbleDelegate() override = default;
  45. void SetShouldIncludeDeviceAddresses(bool should_include_device_addresses) {
  46. should_include_device_addresses_ = should_include_device_addresses;
  47. }
  48. bool should_include_device_addresses() const {
  49. return should_include_device_addresses_;
  50. }
  51. size_t on_info_bubble_destroyed_call_count() const {
  52. return on_info_bubble_destroyed_call_count_;
  53. }
  54. private:
  55. // NetworkInfoBubble::Delegate:
  56. bool ShouldIncludeDeviceAddresses() override {
  57. return should_include_device_addresses_;
  58. }
  59. void OnInfoBubbleDestroyed() override {
  60. ++on_info_bubble_destroyed_call_count_;
  61. }
  62. bool should_include_device_addresses_ = true;
  63. size_t on_info_bubble_destroyed_call_count_ = 0;
  64. };
  65. } // namespace
  66. class NetworkInfoBubbleTest : public AshTestBase {
  67. public:
  68. void SetUp() override {
  69. AshTestBase::SetUp();
  70. feature_list_.InitAndEnableFeature(features::kQuickSettingsNetworkRevamp);
  71. network_state_helper()->ClearDevices();
  72. network_state_helper()->manager_test()->AddTechnology(shill::kTypeCellular,
  73. /*enabled=*/true);
  74. network_state_helper()->AddDevice(
  75. kStubCellularDevicePath, shill::kTypeCellular, kStubCellularDeviceName);
  76. network_state_helper()->AddDevice(
  77. kStubEthernetDevicePath, shill::kTypeEthernet, kStubEthernetDeviceName);
  78. network_state_helper()->AddDevice(kStubWiFiDevicePath, shill::kTypeWifi,
  79. kStubWiFiDeviceName);
  80. widget_ = CreateFramelessTestWidget();
  81. base::RunLoop().RunUntilIdle();
  82. }
  83. void TearDown() override {
  84. widget_.reset();
  85. AshTestBase::TearDown();
  86. }
  87. void OpenBubble() {
  88. ASSERT_FALSE(network_info_bubble_);
  89. std::unique_ptr<NetworkInfoBubble> network_info_bubble =
  90. std::make_unique<NetworkInfoBubble>(weak_factory_.GetWeakPtr(),
  91. widget_->GetRootView());
  92. network_info_bubble_ = network_info_bubble.get();
  93. views::BubbleDialogDelegateView::CreateBubble(network_info_bubble.release())
  94. ->Show();
  95. }
  96. void CloseBubble() {
  97. ASSERT_TRUE(network_info_bubble_);
  98. network_info_bubble_->GetWidget()->Close();
  99. network_info_bubble_ = nullptr;
  100. base::RunLoop().RunUntilIdle();
  101. }
  102. void AddDefaultNetworkWithIPAddresses() {
  103. base::DictionaryValue ipv4;
  104. ipv4.SetKey(shill::kAddressProperty, base::Value(kIpv4Address));
  105. ipv4.SetKey(shill::kMethodProperty, base::Value(shill::kTypeIPv4));
  106. base::DictionaryValue ipv6;
  107. ipv6.SetKey(shill::kAddressProperty, base::Value(kIpv6Address));
  108. ipv6.SetKey(shill::kMethodProperty, base::Value(shill::kTypeIPv6));
  109. network_config_helper_.network_state_helper().ip_config_test()->AddIPConfig(
  110. kIPv4ConfigPath, ipv4);
  111. network_config_helper_.network_state_helper().ip_config_test()->AddIPConfig(
  112. kIPv6ConfigPath, ipv6);
  113. base::ListValue ip_configs;
  114. ip_configs.Append(kIPv4ConfigPath);
  115. ip_configs.Append(kIPv6ConfigPath);
  116. network_config_helper_.network_state_helper()
  117. .device_test()
  118. ->SetDeviceProperty(kStubWiFiDevicePath, shill::kIPConfigsProperty,
  119. ip_configs, /*notify_changed=*/true);
  120. network_config_helper_.network_state_helper().service_test()->AddService(
  121. kWiFiServicePath, kWiFiServiceGuid, kWiFiServiceName, shill::kTypeWifi,
  122. shill::kStateOnline, true);
  123. base::RunLoop().RunUntilIdle();
  124. }
  125. void SetDeviceMacAddress(const std::string& device_path,
  126. const std::string& mac_address) {
  127. network_config_helper_.network_state_helper()
  128. .device_test()
  129. ->SetDeviceProperty(device_path, shill::kAddressProperty,
  130. base::Value(mac_address), true);
  131. base::RunLoop().RunUntilIdle();
  132. }
  133. void SimulateMouseExit() {
  134. ASSERT_TRUE(network_info_bubble_);
  135. static_cast<views::View*>(network_info_bubble_)
  136. ->OnMouseExited(ui::MouseEvent(ui::ET_MOUSE_EXITED, gfx::PointF(),
  137. gfx::PointF(), base::TimeTicks(), 0, 0));
  138. network_info_bubble_ = nullptr;
  139. base::RunLoop().RunUntilIdle();
  140. }
  141. void InvalidateDelegate() { weak_factory_.InvalidateWeakPtrs(); }
  142. views::Label* FindLabelView() {
  143. return static_cast<views::Label*>(network_info_bubble_->GetViewByID(
  144. NetworkInfoBubble::kNetworkInfoBubbleLabelViewId));
  145. }
  146. NetworkStateTestHelper* network_state_helper() {
  147. return &network_config_helper_.network_state_helper();
  148. }
  149. FakeNetworkInfoBubbleDelegate* fake_delegate() { return &fake_delegate_; }
  150. private:
  151. CrosNetworkConfigTestHelper network_config_helper_;
  152. FakeNetworkInfoBubbleDelegate fake_delegate_;
  153. NetworkInfoBubble* network_info_bubble_ = nullptr;
  154. base::test::ScopedFeatureList feature_list_;
  155. std::string wifi_path_;
  156. std::unique_ptr<views::Widget> widget_;
  157. base::WeakPtrFactory<FakeNetworkInfoBubbleDelegate> weak_factory_{
  158. &fake_delegate_};
  159. };
  160. TEST_F(NetworkInfoBubbleTest, NotifiesDelegateOnDestruction) {
  161. OpenBubble();
  162. EXPECT_EQ(0u, fake_delegate()->on_info_bubble_destroyed_call_count());
  163. CloseBubble();
  164. EXPECT_EQ(1u, fake_delegate()->on_info_bubble_destroyed_call_count());
  165. }
  166. TEST_F(NetworkInfoBubbleTest, BubbleClosesOnMouseExit) {
  167. OpenBubble();
  168. EXPECT_EQ(0u, fake_delegate()->on_info_bubble_destroyed_call_count());
  169. SimulateMouseExit();
  170. EXPECT_EQ(1u, fake_delegate()->on_info_bubble_destroyed_call_count());
  171. }
  172. TEST_F(NetworkInfoBubbleTest, DoesNotNotifyDelegateIfDelegateInvalid) {
  173. OpenBubble();
  174. EXPECT_EQ(0u, fake_delegate()->on_info_bubble_destroyed_call_count());
  175. InvalidateDelegate();
  176. CloseBubble();
  177. EXPECT_EQ(0u, fake_delegate()->on_info_bubble_destroyed_call_count());
  178. }
  179. TEST_F(NetworkInfoBubbleTest, HasCorrectText) {
  180. OpenBubble();
  181. EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_NETWORKS),
  182. FindLabelView()->GetText());
  183. CloseBubble();
  184. std::u16string expected_text =
  185. l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_ETHERNET_ADDRESS,
  186. base::UTF8ToUTF16(kEthernetMacAddress));
  187. SetDeviceMacAddress(kStubEthernetDevicePath, kEthernetMacAddress);
  188. OpenBubble();
  189. EXPECT_EQ(expected_text, FindLabelView()->GetText());
  190. CloseBubble();
  191. base::StrAppend(
  192. &expected_text,
  193. {u"\n", l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_WIFI_ADDRESS,
  194. base::UTF8ToUTF16(kWiFiMacAddress))});
  195. SetDeviceMacAddress(kStubWiFiDevicePath, kWiFiMacAddress);
  196. OpenBubble();
  197. EXPECT_EQ(expected_text, FindLabelView()->GetText());
  198. CloseBubble();
  199. base::StrAppend(&expected_text,
  200. {u"\n", l10n_util::GetStringFUTF16(
  201. IDS_ASH_STATUS_TRAY_CELLULAR_ADDRESS,
  202. base::UTF8ToUTF16(kCellularMacAddress))});
  203. SetDeviceMacAddress(kStubCellularDevicePath, kCellularMacAddress);
  204. OpenBubble();
  205. EXPECT_EQ(expected_text, FindLabelView()->GetText());
  206. CloseBubble();
  207. fake_delegate()->SetShouldIncludeDeviceAddresses(false);
  208. OpenBubble();
  209. EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_NETWORKS),
  210. FindLabelView()->GetText());
  211. CloseBubble();
  212. const std::u16string expected_text_ip_addresses = base::StrCat(
  213. {l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_IP_ADDRESS,
  214. base::UTF8ToUTF16(kIpv4Address)),
  215. u"\n",
  216. l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_IPV6_ADDRESS,
  217. base::UTF8ToUTF16(kIpv6Address))});
  218. AddDefaultNetworkWithIPAddresses();
  219. OpenBubble();
  220. EXPECT_EQ(expected_text_ip_addresses, FindLabelView()->GetText());
  221. CloseBubble();
  222. fake_delegate()->SetShouldIncludeDeviceAddresses(true);
  223. expected_text = expected_text_ip_addresses + u"\n" + expected_text;
  224. OpenBubble();
  225. EXPECT_EQ(expected_text, FindLabelView()->GetText());
  226. CloseBubble();
  227. }
  228. } // namespace ash