1// Copyright 2014 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
5#include "ash/system/chromeos/power/power_status_view.h"
6
7#include "ash/system/chromeos/power/power_status.h"
8#include "ash/test/ash_test_base.h"
9#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
10#include "grit/ash_strings.h"
11#include "ui/base/l10n/l10n_util.h"
12#include "ui/base/l10n/time_format.h"
13#include "ui/views/controls/label.h"
14
15using power_manager::PowerSupplyProperties;
16
17namespace ash {
18
19class PowerStatusViewTest : public test::AshTestBase {
20 public:
21  PowerStatusViewTest() {}
22  virtual ~PowerStatusViewTest() {}
23
24  // Overridden from testing::Test:
25  virtual void SetUp() OVERRIDE {
26    test::AshTestBase::SetUp();
27    view_.reset(new PowerStatusView(GetViewType(), false));
28  }
29
30  virtual void TearDown() OVERRIDE {
31    view_.reset();
32    test::AshTestBase::TearDown();
33  }
34
35 protected:
36  virtual PowerStatusView::ViewType GetViewType() = 0;
37  PowerStatusView* view() { return view_.get(); }
38
39  void UpdatePowerStatus(const power_manager::PowerSupplyProperties& proto) {
40    PowerStatus::Get()->SetProtoForTesting(proto);
41    view_->OnPowerStatusChanged();
42  }
43
44 private:
45  scoped_ptr<PowerStatusView> view_;
46
47  DISALLOW_COPY_AND_ASSIGN(PowerStatusViewTest);
48};
49
50class PowerStatusDefaultViewTest : public PowerStatusViewTest {
51 public:
52  PowerStatusDefaultViewTest() {}
53  virtual ~PowerStatusDefaultViewTest() {}
54
55 protected:
56  virtual PowerStatusView::ViewType GetViewType() OVERRIDE {
57    return PowerStatusView::VIEW_DEFAULT;
58  }
59
60  bool IsPercentageVisible() {
61    return view()->percentage_label_->visible();
62  }
63
64  bool IsTimeStatusVisible() {
65    return view()->time_status_label_->visible();
66  }
67
68  base::string16 RemainingTimeInView() {
69    return view()->time_status_label_->text();
70  }
71
72 private:
73  DISALLOW_COPY_AND_ASSIGN(PowerStatusDefaultViewTest);
74};
75
76class PowerStatusNotificationViewTest : public PowerStatusViewTest {
77 public:
78  PowerStatusNotificationViewTest() {}
79  virtual ~PowerStatusNotificationViewTest() {}
80
81 protected:
82  virtual PowerStatusView::ViewType GetViewType() OVERRIDE {
83    return PowerStatusView::VIEW_NOTIFICATION;
84  }
85
86  base::string16 StatusInView() {
87    return view()->status_label_->text();
88  }
89
90  base::string16 RemainingTimeInView() {
91    return view()->time_label_->text();
92  }
93
94 private:
95  DISALLOW_COPY_AND_ASSIGN(PowerStatusNotificationViewTest);
96};
97
98TEST_F(PowerStatusDefaultViewTest, Basic) {
99  EXPECT_FALSE(IsPercentageVisible());
100  EXPECT_TRUE(IsTimeStatusVisible());
101
102  // Disconnect the power.
103  PowerSupplyProperties prop;
104  prop.set_external_power(PowerSupplyProperties::DISCONNECTED);
105  prop.set_battery_state(PowerSupplyProperties::DISCHARGING);
106  prop.set_battery_percent(99.0);
107  prop.set_battery_time_to_empty_sec(120);
108  prop.set_is_calculating_battery_time(true);
109  UpdatePowerStatus(prop);
110
111  EXPECT_TRUE(IsPercentageVisible());
112  EXPECT_TRUE(IsTimeStatusVisible());
113  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING),
114            RemainingTimeInView());
115
116  prop.set_is_calculating_battery_time(false);
117  UpdatePowerStatus(prop);
118  EXPECT_NE(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING),
119            RemainingTimeInView());
120  EXPECT_NE(
121      l10n_util::GetStringUTF16(
122          IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE),
123      RemainingTimeInView());
124
125  prop.set_external_power(PowerSupplyProperties::AC);
126  prop.set_battery_state(PowerSupplyProperties::CHARGING);
127  prop.set_battery_time_to_full_sec(120);
128  UpdatePowerStatus(prop);
129  EXPECT_TRUE(IsPercentageVisible());
130  EXPECT_TRUE(IsTimeStatusVisible());
131  EXPECT_NE(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING),
132            RemainingTimeInView());
133  EXPECT_NE(
134      l10n_util::GetStringUTF16(
135          IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE),
136      RemainingTimeInView());
137
138  prop.set_external_power(PowerSupplyProperties::USB);
139  UpdatePowerStatus(prop);
140  EXPECT_TRUE(IsPercentageVisible());
141  EXPECT_TRUE(IsTimeStatusVisible());
142  EXPECT_EQ(
143      l10n_util::GetStringUTF16(
144          IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE),
145      RemainingTimeInView());
146
147  // Tricky -- connected to non-USB but still discharging. Not likely happening
148  // on production though.
149  prop.set_external_power(PowerSupplyProperties::AC);
150  prop.set_battery_state(PowerSupplyProperties::DISCHARGING);
151  prop.set_battery_time_to_full_sec(120);
152  UpdatePowerStatus(prop);
153  EXPECT_TRUE(IsPercentageVisible());
154  EXPECT_FALSE(IsTimeStatusVisible());
155}
156
157TEST_F(PowerStatusNotificationViewTest, Basic) {
158  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_FULL),
159            StatusInView());
160  EXPECT_TRUE(RemainingTimeInView().empty());
161
162  // Disconnect the power.
163  PowerSupplyProperties prop;
164  prop.set_external_power(PowerSupplyProperties::DISCONNECTED);
165  prop.set_battery_state(PowerSupplyProperties::DISCHARGING);
166  prop.set_battery_percent(99.0);
167  prop.set_battery_time_to_empty_sec(125);
168  prop.set_is_calculating_battery_time(true);
169  UpdatePowerStatus(prop);
170
171  EXPECT_NE(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_FULL),
172            StatusInView());
173  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING),
174            RemainingTimeInView());
175
176  prop.set_is_calculating_battery_time(false);
177  UpdatePowerStatus(prop);
178  // Low power warning has to be calculated by ui::TimeFormat, but ignore
179  // seconds.
180  EXPECT_EQ(ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_REMAINING,
181                                   ui::TimeFormat::LENGTH_LONG,
182                                   base::TimeDelta::FromMinutes(2)),
183            RemainingTimeInView());
184
185  prop.set_external_power(PowerSupplyProperties::AC);
186  prop.set_battery_state(PowerSupplyProperties::CHARGING);
187  prop.set_battery_time_to_full_sec(120);
188  UpdatePowerStatus(prop);
189  EXPECT_NE(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_FULL),
190            StatusInView());
191  // Charging time is somehow using another format?
192  EXPECT_NE(ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_REMAINING,
193                                   ui::TimeFormat::LENGTH_LONG,
194                                   base::TimeDelta::FromMinutes(2)),
195            RemainingTimeInView());
196
197  // Unreliable connection.
198  prop.set_external_power(PowerSupplyProperties::USB);
199  UpdatePowerStatus(prop);
200  EXPECT_EQ(
201      l10n_util::GetStringUTF16(
202          IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE),
203      RemainingTimeInView());
204
205  // Tricky -- connected to non-USB but still discharging. Not likely happening
206  // on production though.
207  prop.set_external_power(PowerSupplyProperties::AC);
208  prop.set_battery_state(PowerSupplyProperties::DISCHARGING);
209  prop.set_battery_time_to_full_sec(120);
210  UpdatePowerStatus(prop);
211  EXPECT_TRUE(RemainingTimeInView().empty());
212}
213
214}  // namespace ash
215