bluetooth_device_list_item_battery_view_unittest.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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/bluetooth/bluetooth_device_list_item_battery_view.h"
  5. #include "ash/constants/ash_features.h"
  6. #include "ash/resources/vector_icons/vector_icons.h"
  7. #include "ash/strings/grit/ash_strings.h"
  8. #include "ash/test/ash_test_base.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "base/test/scoped_feature_list.h"
  11. #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
  12. #include "ui/base/l10n/l10n_util.h"
  13. #include "ui/gfx/image/image_skia.h"
  14. #include "ui/gfx/image/image_unittest_util.h"
  15. #include "ui/views/controls/image_view.h"
  16. #include "ui/views/controls/label.h"
  17. #include "ui/views/widget/widget.h"
  18. namespace ash {
  19. namespace {
  20. using chromeos::bluetooth_config::mojom::BatteryProperties;
  21. using chromeos::bluetooth_config::mojom::BatteryPropertiesPtr;
  22. } // namespace
  23. class BluetoothDeviceListItemBatteryViewTest : public AshTestBase {
  24. public:
  25. void SetUp() override {
  26. AshTestBase::SetUp();
  27. feature_list_.InitAndEnableFeature(features::kBluetoothRevamp);
  28. widget_ = CreateTestWidget();
  29. bluetooth_device_list_battery_item_ =
  30. std::make_unique<BluetoothDeviceListItemBatteryView>();
  31. // Add the item to widget hierarchy to make sure `ui::ColorProvider` will
  32. // not be nullptr while getting colors.
  33. widget_->GetContentsView()->AddChildView(
  34. bluetooth_device_list_battery_item_.get());
  35. }
  36. void TearDown() override {
  37. bluetooth_device_list_battery_item_.reset();
  38. AshTestBase::TearDown();
  39. }
  40. // Updates the view with |battery_percentage|, checks that the label is
  41. // correct, and returns whether the icon has been updated.
  42. bool UpdateBatteryPercentageAndCheckIfUpdated(uint8_t battery_percentage) {
  43. gfx::Image image;
  44. if (!bluetooth_device_list_battery_item_->children().empty())
  45. image = gfx::Image(GetIcon()->GetImage());
  46. bluetooth_device_list_battery_item_->UpdateBatteryInfo(
  47. battery_percentage,
  48. IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_ONLY_LABEL);
  49. EXPECT_EQ(
  50. l10n_util::GetStringFUTF16(
  51. IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_ONLY_LABEL,
  52. base::NumberToString16(battery_percentage)),
  53. GetLabel()->GetText());
  54. return !gfx::test::AreImagesEqual(image, gfx::Image(GetIcon()->GetImage()));
  55. }
  56. BluetoothDeviceListItemBatteryView* bluetooth_device_list_battery_item() {
  57. return bluetooth_device_list_battery_item_.get();
  58. }
  59. private:
  60. views::ImageView* GetIcon() {
  61. EXPECT_EQ(2u, bluetooth_device_list_battery_item()->children().size());
  62. return static_cast<views::ImageView*>(
  63. bluetooth_device_list_battery_item()->children().at(0));
  64. }
  65. views::Label* GetLabel() {
  66. EXPECT_EQ(2u, bluetooth_device_list_battery_item()->children().size());
  67. return static_cast<views::Label*>(
  68. bluetooth_device_list_battery_item()->children().at(1));
  69. }
  70. base::test::ScopedFeatureList feature_list_;
  71. std::unique_ptr<views::Widget> widget_;
  72. std::unique_ptr<BluetoothDeviceListItemBatteryView>
  73. bluetooth_device_list_battery_item_;
  74. };
  75. TEST_F(BluetoothDeviceListItemBatteryViewTest, CorrectlyUpdatesIconAndLabel) {
  76. EXPECT_EQ(0u, bluetooth_device_list_battery_item()->children().size());
  77. uint8_t battery_percentage = 0;
  78. EXPECT_TRUE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  79. // The label should be updated regardless of the change, but the icon should
  80. // only update if the percentage is different enough.
  81. battery_percentage = 3;
  82. EXPECT_FALSE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  83. battery_percentage = 20;
  84. EXPECT_TRUE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  85. const uint8_t percent_change_threshold = 20;
  86. // The icon should be updated if there are enough small changes.
  87. for (int i = 0; i < percent_change_threshold; ++i) {
  88. battery_percentage++;
  89. if (UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage))
  90. break;
  91. // Check that the loop isn't ending.
  92. EXPECT_NE(percent_change_threshold - 1, i);
  93. }
  94. // The icon should be updated when going to/from 25% since the color should be
  95. // updated to alert the user.
  96. battery_percentage = 24;
  97. UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage);
  98. battery_percentage = 25;
  99. EXPECT_TRUE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  100. battery_percentage = 24;
  101. EXPECT_TRUE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  102. // The icon should be updated when going to/from 100% since the icon shown
  103. // will be distinct from any other percentage.
  104. battery_percentage = 99;
  105. UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage);
  106. battery_percentage = 100;
  107. EXPECT_TRUE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  108. battery_percentage = 99;
  109. EXPECT_TRUE(UpdateBatteryPercentageAndCheckIfUpdated(battery_percentage));
  110. }
  111. } // namespace ash