// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/bluetooth/bluetooth_device_list_item_multiple_battery_view.h"
#include <optional>
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/test/ash_test_base.h"
#include "base/strings/string_number_conversions.h"
#include "chromeos/ash/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/view_utils.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
using bluetooth_config::mojom::BatteryProperties;
using bluetooth_config::mojom::DeviceBatteryInfo;
using bluetooth_config::mojom::DeviceBatteryInfoPtr;
DeviceBatteryInfoPtr CreateBatteryInfo(
std::optional<uint8_t> left_battery_percentage,
std::optional<uint8_t> case_battery_percentage,
std::optional<uint8_t> right_battery_percentage) {
DeviceBatteryInfoPtr battery_info = DeviceBatteryInfo::New();
if (left_battery_percentage) {
battery_info->left_bud_info = BatteryProperties::New();
battery_info->left_bud_info->battery_percentage =
left_battery_percentage.value();
}
if (case_battery_percentage) {
battery_info->case_info = BatteryProperties::New();
battery_info->case_info->battery_percentage =
case_battery_percentage.value();
}
if (right_battery_percentage) {
battery_info->right_bud_info = BatteryProperties::New();
battery_info->right_bud_info->battery_percentage =
right_battery_percentage.value();
}
return battery_info;
}
} // namespace
class BluetoothDeviceListItemMultipleBatteryViewTest : public AshTestBase {
public:
void SetUp() override {
AshTestBase::SetUp();
widget_ =
CreateTestWidget(views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
bluetooth_device_list_multiple_battery_item_ =
std::make_unique<BluetoothDeviceListItemMultipleBatteryView>();
// Add the item to widget hierarchy to make sure `ui::ColorProvider` will
// not be nullptr while getting colors.
widget_->GetContentsView()->AddChildView(
bluetooth_device_list_multiple_battery_item_.get());
}
void TearDown() override {
bluetooth_device_list_multiple_battery_item_.reset();
AshTestBase::TearDown();
}
BluetoothDeviceListItemMultipleBatteryView*
bluetooth_device_list_multiple_battery_item() {
return bluetooth_device_list_multiple_battery_item_.get();
}
views::Label* GetLabel(int index) {
EXPECT_EQ(2u, bluetooth_device_list_multiple_battery_item()
->children()
.at(index)
->children()
.size());
return static_cast<views::Label*>(
bluetooth_device_list_multiple_battery_item()
->children()
.at(index)
->children()
.at(1));
}
void BatteryViewExistsAtIndex(int index) {
EXPECT_TRUE(views::IsViewClass<BluetoothDeviceListItemBatteryView>(
bluetooth_device_list_multiple_battery_item()->children().at(index)));
}
private:
std::unique_ptr<views::Widget> widget_;
std::unique_ptr<BluetoothDeviceListItemMultipleBatteryView>
bluetooth_device_list_multiple_battery_item_;
};
TEST_F(BluetoothDeviceListItemMultipleBatteryViewTest,
MultipleCorrectlyUpdatesIconAndLabel_OneBattery) {
EXPECT_EQ(0u,
bluetooth_device_list_multiple_battery_item()->children().size());
DeviceBatteryInfoPtr battery_info =
CreateBatteryInfo(/*left_battery_percentage=*/100,
/*case_battery_percentage=*/std::nullopt,
/*right_battery_percentage=*/std::nullopt);
bluetooth_device_list_multiple_battery_item()->UpdateBatteryInfo(
battery_info);
EXPECT_EQ(1u,
bluetooth_device_list_multiple_battery_item()->children().size());
BatteryViewExistsAtIndex(/*index=*/0);
}
TEST_F(BluetoothDeviceListItemMultipleBatteryViewTest,
CorrectlyUpdatesIconAndLabel_TwoBatteries) {
EXPECT_EQ(0u,
bluetooth_device_list_multiple_battery_item()->children().size());
DeviceBatteryInfoPtr battery_info = CreateBatteryInfo(
/*left_battery_percentage=*/100, /*case_battery_percentage=*/100,
/*right_battery_percentage=*/std::nullopt);
bluetooth_device_list_multiple_battery_item()->UpdateBatteryInfo(
battery_info);
EXPECT_EQ(2u,
bluetooth_device_list_multiple_battery_item()->children().size());
BatteryViewExistsAtIndex(/*index=*/0);
BatteryViewExistsAtIndex(/*index=*/1);
}
TEST_F(BluetoothDeviceListItemMultipleBatteryViewTest,
CorrectlyUpdatesIconAndLabel_BatteryRemoved) {
EXPECT_EQ(0u,
bluetooth_device_list_multiple_battery_item()->children().size());
DeviceBatteryInfoPtr battery_info = CreateBatteryInfo(
/*left_battery_percentage=*/100, /*case_battery_percentage=*/100,
/*right_battery_percentage=*/100);
bluetooth_device_list_multiple_battery_item()->UpdateBatteryInfo(
battery_info);
EXPECT_EQ(3u,
bluetooth_device_list_multiple_battery_item()->children().size());
BatteryViewExistsAtIndex(/*index=*/0);
BatteryViewExistsAtIndex(/*index=*/1);
BatteryViewExistsAtIndex(/*index=*/2);
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_LEFT_BUD_LABEL,
base::NumberToString16(
battery_info->left_bud_info->battery_percentage)),
GetLabel(/*index=*/0)->GetText());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_CASE_LABEL,
base::NumberToString16(battery_info->case_info->battery_percentage)),
GetLabel(/*index=*/1)->GetText());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_RIGHT_BUD_LABEL,
base::NumberToString16(
battery_info->right_bud_info->battery_percentage)),
GetLabel(/*index=*/2)->GetText());
DeviceBatteryInfoPtr battery_info2 = CreateBatteryInfo(
/*left_battery_percentage=*/std::nullopt,
/*case_battery_percentage=*/100, /*right_battery_percentage=*/100);
bluetooth_device_list_multiple_battery_item()->UpdateBatteryInfo(
battery_info2);
EXPECT_EQ(2u,
bluetooth_device_list_multiple_battery_item()->children().size());
BatteryViewExistsAtIndex(/*index=*/0);
BatteryViewExistsAtIndex(/*index=*/1);
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_CASE_LABEL,
base::NumberToString16(battery_info2->case_info->battery_percentage)),
GetLabel(/*index=*/0)->GetText());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_RIGHT_BUD_LABEL,
base::NumberToString16(
battery_info2->right_bud_info->battery_percentage)),
GetLabel(/*index=*/1)->GetText());
DeviceBatteryInfoPtr battery_info3 = CreateBatteryInfo(
/*left_battery_percentage=*/100, /*case_battery_percentage=*/100,
/*right_battery_percentage=*/100);
bluetooth_device_list_multiple_battery_item()->UpdateBatteryInfo(
battery_info3);
EXPECT_EQ(3u,
bluetooth_device_list_multiple_battery_item()->children().size());
BatteryViewExistsAtIndex(/*index=*/0);
BatteryViewExistsAtIndex(/*index=*/1);
BatteryViewExistsAtIndex(/*index=*/2);
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_LEFT_BUD_LABEL,
base::NumberToString16(
battery_info3->left_bud_info->battery_percentage)),
GetLabel(/*index=*/0)->GetText());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_CASE_LABEL,
base::NumberToString16(battery_info3->case_info->battery_percentage)),
GetLabel(/*index=*/1)->GetText());
EXPECT_EQ(
l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_BLUETOOTH_DEVICE_BATTERY_PERCENTAGE_RIGHT_BUD_LABEL,
base::NumberToString16(
battery_info3->right_bud_info->battery_percentage)),
GetLabel(/*index=*/2)->GetText());
}
} // namespace ash